App-Raider

 view release on metacpan or  search on metacpan

bin/raider  view on Meta::CPAN

#!/usr/bin/env perl
# PODNAME: raider
# ABSTRACT: Autonomous CLI agent with filesystem and bash access

use strict;
use warnings;
use utf8;
use Getopt::Long qw( GetOptions :config no_ignore_case bundling );
use JSON::MaybeXS ();
use YAML::PP ();
use Term::ANSIColor qw( colored color );
use Term::ReadLine;                   # Core; upgrades to Gnu if installed
use IO::Prompt::Tiny qw( prompt );    # Fallback when Gnu is not available
use Path::Tiny;
use App::Raider;
use App::Raider::Skill;
use Langertha::Raider;

binmode STDOUT, ':encoding(UTF-8)';
binmode STDIN,  ':encoding(UTF-8)';

# --- Palette: blue tones + yellow accents -------------------------------

my %C = (
  brand  => 'bold bright_blue',
  title  => 'bold blue',
  prompt => 'bold cyan',
  agent  => 'bright_green',
  meta   => 'bright_black',
  accent => 'yellow',
  warn   => 'yellow',
  err    => 'red',
);

sub c { my ($k, @t) = @_; -t STDOUT ? colored([$C{$k}], join('', @t)) : join('', @t) }

# --- Options ------------------------------------------------------------

my %opt;
my @raw_engine_opts;

GetOptions(
  'e|engine=s'       => \$opt{engine},
  'm|model=s'        => \$opt{model},
  'r|root=s'         => \$opt{root},
  'M|mission=s'      => \$opt{mission},
  'k|api-key=s'      => \$opt{api_key},
  'o|option=s@'      => \@raw_engine_opts,
  'i|interactive'    => \$opt{interactive},
  'json'             => \$opt{json},
  'max-iterations=i' => \$opt{max_iterations},
  'no-color'         => \$opt{no_color},
  'trace!'           => \$opt{trace},
  'customize-prompt'     => \$opt{customize_prompt},
  'claude'               => \$opt{profile_claude},
  'openai|codex'         => \$opt{profile_openai},
  'skills=s@'            => \@{ $opt{skill_dirs} //= [] },
  'export-skill:s'       => \$opt{export_skill},
  'export-claude-skill:s'=> \$opt{export_claude_skill},
  'h|help'               => \$opt{help},
) or die "Bad options. Try --help.\n";

my %engine_opts;
for my $pair (@raw_engine_opts) {
  my ($k, $v) = split /=/, $pair, 2;
  die "bad -o spec '$pair' (expected key=value)\n" unless defined $k && defined $v;
  # Auto-coerce simple numerics so temperature=0.2 lands as a number.
  if    ($v =~ /\A-?\d+\z/)                { $v = 0 + $v }
  elsif ($v =~ /\A-?\d*\.\d+(?:[eE]-?\d+)?\z/) { $v = 0 + $v }
  elsif ($v eq 'true')                     { $v = 1 }
  elsif ($v eq 'false')                    { $v = 0 }
  $engine_opts{$k} = $v;
}

$ENV{ANSI_COLORS_DISABLED} = 1 if $opt{no_color} || $opt{json};

if ($opt{help}) {
  print <<'USAGE';
Usage: raider [options] [prompt...]

Options:
  -e, --engine NAME        anthropic, openai, deepseek, groq, mistral, gemini,
                           minimax, cerebras, openrouter, ollama
                           (default: auto-detected from available *_API_KEY
                           env var — anthropic > openai > deepseek > ...)
  -m, --model NAME         Model identifier (engine-specific cheap default)
  -k, --api-key KEY        API key (overrides *_API_KEY env var)



( run in 0.764 second using v1.01-cache-2.11-cpan-cdf2f3d4e48 )