NAME

Langertha::Raider::CLI::Commands - Internal slash commands of the raider REPL

VERSION

version 0.504

SYNOPSIS

# Internal to Langertha-Raider -- no API promise.
my $commands = Langertha::Raider::CLI::Commands->new(app => $app, output => $out);
$commands->dispatch('/pack on polite');

DESCRIPTION

Internal module. Its interface may change without notice.

The slash commands of the raider REPL (/help, /clear, /metrics, /stats, /reload, /prompt, /skill, /skill-claude, /config, /permissions, /mcp, /model, /packs, /pack). /permissions prints the permission mode with its source and every rule with its source, session rules included (ADR 0021); /permissions mode MODE switches the mode. Each command /name is the method cmd_name (dashes become underscores) and gets the rest of the line as its argument. Leaving the REPL (/quit) is the REPL's business.

The commands of ADR 0030 §5 (every report prints plain lines and works without a terminal, for a one-shot run):

  • /help -- the built-in commands, then the user-invocable skills and custom commands of the catalogue ("user_invocable" in Langertha::Raider::Context::Skills), sorted, each as /name argument-hint description (source).

  • /clear, /reset, /new -- forget the conversation history.

  • /skills -- every catalogue entry: name, kind (skill or command), source, whether the model and the user may invoke it, the paths: of a conditional skill that is not active yet; then the shadowed entries and files that could not be read.

  • /compact [INSTRUCTIONS] -- summarise the history now ("compress_history" in Langertha::Raider), the instructions passed as focus for the summary: history compacted (N messages → summary, ~T tokens), or nothing to compact.

  • /context -- the context by part with estimated tokens ("estimate_tokens"): the system prompt (the instructions item, the instructions file, each memory file, the skill listing, the rest), the tool definitions, the history, the total and the compaction budget.

  • /memory [N] -- the numbered instruction files ("memory_files"): those loaded, and the editable targets (Claude layout ./CLAUDE.md and ~/.claude/CLAUDE.md, the native instructions file outside Claude mode), (not there) when missing. /memory N opens file N in $VISUAL or $EDITOR ("run_editor") when input and output are a terminal -- creating it -- and reloads the context and the mission; otherwise it prints the path.

  • /agents -- the agent catalogue (ADR 0020): name, source, the first line of the description, the tools; then the shadowed agents.

  • /hooks -- the hooks of the Claude layout (ADR 0022) by event: matcher, command (or type), timeout, source; no hooks configured. otherwise.

  • /init -- returns a run request { prompt => $text } with Claude Code's /init request ("init_prompt_claude") for CLAUDE.md in the Claude layout, else the same request for the native instructions file ("init_prompt_native"). Sending it is the caller's business.

app

The Langertha::Raider::CLI the commands act on. Required.

output

The Langertha::Raider::CLI::Output to print to. Required.

in

Filehandle /prompt reads its conversation from. Defaults to STDIN.

dispatch

my $r = $commands->dispatch('/model list gpt');
my $r = $commands->dispatch('/review src/App.pm', session => sub { $session });
if ( ref $r eq 'HASH' ) { run_prompt( $r->{prompt}, %$r ) }   # a run request

Resolves one /name rest line (ADR 0030 §3) and runs it:

1. A first word that holds another / (/etc/hosts is broken) is no command: the run request { prompt => $line }, an ordinary prompt.
2. A user-invocable catalogue entry of that name ("find_user_invocable" in Langertha::Raider::Context::Skills) -- it beats a built-in of the same name, not the built-in's aliases: rendered with the rest of the line ("slash_run_request" in Langertha::Raider::Application, with @file attachments) into a run request. A render that aborts is printed as an error and nothing runs. session (a Langertha::Raider::Session or a code reference returning one, called only here) gives ${CLAUDE_SESSION_ID}.
3. /mcp__SERVER__PROMPT ARGS: a prompt of a configured MCP server ("mcp_prompt_request" in Langertha::Raider::Application, ADR 0029 Addendum 1), a run request; a server or prompt that does not exist is an unknown command.
4. A built-in: the method cmd_NAME ("command_method") with the rest of the line.
5. Anything else: unknown command: /NAME (try /help).

Returns false for an unknown command or a failed render (after saying so), a run request when the line is to be sent to the model, true otherwise. A run request is a hash { prompt => $text }, for a catalogue entry with allow_rules, allow_source, model and attach_reads -- the run options of "run_prompt" in Langertha::Raider::CLI::Runner. A built-in that wants a model turn (/init) returns one too.

resolve

my $r = $commands->resolve('/review src/App.pm');
# { kind => 'entry', name => 'review', arguments => 'src/App.pm', entry => {...} }

How "dispatch" reads the line, without running anything: kind is prompt (a path-like first word), entry (with the catalogue entry), mcp_prompt (a name mcp__SERVER__PROMPT), builtin (with its method) or unknown; name is the word after the /, arguments the rest of the line, trimmed (undef when empty). A catalogue that cannot be read (a broken config file) holds no entry: the built-ins still resolve, and its error is in catalog_error, which "dispatch" adds to an unknown command.

command_method

my $method = $commands->command_method('skill-claude');   # 'cmd_skill_claude'

The method of the built-in command /NAME (dashes become underscores), or nothing when there is none.

cmd_mcp

$commands->cmd_mcp('');               # /mcp
$commands->cmd_mcp('reconnect db');   # /mcp reconnect db (or all / no name)

Without an argument the configured MCP servers (ADR 0029), started first when they are not yet (in parallel, each within MCP_TIMEOUT): status, source, scope, transport, reason, approval, the last stderr lines of a failed one and every server's tools ("mcp_report" in Langertha::Raider::CLI::Output). A one-shot raider /mcp prints the same ("oneshot_command" in Langertha::Raider::CLI::Main). reconnect restarts a server (all of them without a name or with all) and shows the list again.

collapse_model_list

my @rows = $commands->collapse_model_list(\@ids, $current);

Folds dated snapshots (gpt-4o-2024-08-06, claude-3-5-sonnet-20241022 style -YYYY suffixes) under their base model. Returns sorted rows { id, snaps, current, orphan }; orphan marks a snapshot family whose base is not listed itself.

estimate_tokens

my $n = $commands->estimate_tokens($text);       # or a message / schema hash

Rough token count: the characters over four, the rule Langertha::Raider's in-loop compaction estimates with; a reference is counted as its JSON. 0 for undef.

memory_files

for my $f ($commands->memory_files) { say $f->{label}.' '.$f->{file} }

The files /memory numbers, each { label, file, loaded, exists }: first the instruction files in the prompt ("instruction_items" in Langertha::Raider::Context, and the native instructions file when the instructions item holds it), then the editable targets not listed yet -- in the Claude layout CLAUDE.md of the project directory and CLAUDE.md of the Claude home, outside Claude mode the native instructions file ("file" in Langertha::Raider::Instructions).

editor

The editor command /memory N runs: $VISUAL, else $EDITOR; undef without either.

is_terminal

True when "in" and the output are terminals -- only then /memory N starts an editor.

run_editor

my $ok = $commands->run_editor($editor, $file);

Runs $editor on $file through sh -c (so $EDITOR may carry arguments, code -w) and waits. True when it exited with 0. Override point for tests.

init_prompt_claude

The prompt /init sends in the Claude layout: Claude Code's /init request for CLAUDE.md.

init_prompt_native

my $text = $commands->init_prompt_native('.raider.md');

The same request for raider's native instructions file $label.

init_prompt

my $text = $commands->init_prompt($file, $agent, $preamble);

The request both are made of: $file the file to write, $agent who reads it, $preamble the text the file must start with.

SEE ALSO

SUPPORT

Issues

Please report bugs and feature requests at https://github.com/Getty/langertha-raider/issues.

IRC

Join #langertha on irc.perl.org or message Getty directly.

CONTRIBUTING

Contributions are welcome! Please fork the repository and submit a pull request.

AUTHOR

Torsten Raudssus <torsten@raudssus.de> https://raudssus.de/

COPYRIGHT AND LICENSE

This software is copyright (c) 2026 by Torsten Raudssus.

This is free software; you can redistribute it and/or modify it under the same terms as the Perl 5 programming language system itself.

https://raudssus.de/