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 (skillorcommand), source, whether the model and the user may invoke it, thepaths: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), ornothing 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 Nopens file N in$VISUALor$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/initrequest ("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
@fileattachments) 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.