SalmonLoop provides a chat-first command-line interface (s8p) for repository work.
Unless you explicitly pin a flow, both chat and one-shot run default to autopilot.
Enter the interactive chat mode to provide instructions and receive patches in real-time.
In chat mode, SalmonLoop exposes a few UI-related controls:
/config log-mode <quiet|normal|debug>: controls how much output the TUI shows (recommended for new users:normal).- Aliases:
/config mode,/config log,/log-mode
- Aliases:
/config view <full|standard|compact>: controls how dense the TUI renders the output./mode <interactive|yolo>: controls the permission mode used for tool authorization decisions.- Aliases:
/config permission-mode,/permission-mode,/perm-mode
- Aliases:
/flow-mode <patch|review|debug|research|answer|autopilot>: controls the current chat flow mode for this session.autopilotis the default when no session flow mode has been set yet.
All settings are persisted to the repo config at <repoRoot>/.salmonloop/config/config.json.
Advanced settings:
/config output <...>: controls which LLM sections are shown in the UI (useful for debugging; does not affect the patch result)./config allowlist ...: manages persistent tool authorization rules (repo/user scope).
When you type a slash command, the Omni-Tray shows context-aware suggestions.
- Command names: Typing
/(or a prefix like/se) suggests matching commands. - Subcommands: Commands that define
subcommandswill suggest them after a space (e.g.,/config->view). - Deep suggestions: Some subcommands provide their own suggestions (e.g.,
/snapshot restoresuggests snapshot hashes).
Notes:
- Unknown slash commands are blocked (see Command Interception below).
- Suggestions are best-effort and may be empty for commands that do not define suggestions.
While in chat mode you can inspect running Smallfry sub-agents without letting the LLM mutate your main worktree:
/smallfry listlists the registered agents (id | status | role | summary)./smallfry info <agentId>shows metadata for a specific agent./smallfry log <agentId> [tail=<n>]prints the buffered audit log (maxtail=50, defaults to 20)./smallfry stop <agentId>politely requests cancellation; theSubAgentControllertoggles a flag so the manager can abort the agent safely.
The slug /smallfry also accepts /subagent and /sub-agent aliases; suggestions drop in after you type the verb and begin entering the agent ID. The command relies on SubAgentController snapshots updated by SubAgentManager, so the list/log output reflects the latest state while the manager keeps each Smallfry in an isolated runtime.
Commands marked hidden: true (e.g., /mode, /output, /allowlist, /smallfry, /parallel) stay executable but do not surface in the Omni-Tray suggestions; the command registry orders slashes by their order metadata. /exit still honors /quit as an alias for convenience.
For security and clarity, SalmonLoop strictly manages inputs starting with / in chat mode:
- Valid Commands: Known commands like
/help,/exit, or/statusare executed immediately. - Unknown Commands: Any other input starting with
/(including typos or absolute paths) is blocked and an error is shown. This prevents the LLM from misinterpreting system commands or leaking sensitive paths into instructions.
s8p
# or explicitly
s8p chatExecute a single-turn task and exit.
s8p run --instruction "..." --verify "..."run defaults to autopilot unless you explicitly pass --act-mode <mode>.
Use --act-mode patch|review|debug|research|answer|autopilot when you want to pin the flow instead of letting SalmonLoop choose.
Builds and prints the assembled context prompt without calling the LLM.
s8p context -i "..." [-f src/file.ts | -s "..."] [--diff-scope primary|ast_related] [--budget-chars 30000]Start the A2A HTTP server and the ACP stdio bridge.
s8p serveConfiguration defaults come from the server section of the config file.
See docs/user/config.md for the server.a2a and server.acp fields.
-r, --repo <path>: Path to the git repository root. Defaults to the current directory.--continue: Continue the most recent session in this repository (applies tochatandrun).- In
run, this also injects the persisted conversation history into message-based LLM prompts by default (token-budgeted and truncated).
- In
--resume <sessionId>: Resume a specific session by ID (applies tochatandrun).- In
run, this also injects the persisted conversation history into message-based LLM prompts by default (token-budgeted and truncated).
- In
--config <path>: Path to a SalmonLoop config JSON file (default:<repoRoot>/.salmonloop/config/config.json).--no-config-file: Disable loading the repo config file.--print-config: Print the resolved config (redacted) and exit.--verbose [level]: Enable verbose logging (basicorextended).--audit-scope <scope>: Audit log scope (repooruser). Overridesobservability.audit.scopeconfig.--stream-output: Stream LLM responses to the CLI as they arrive.- Behavior: Real-time display of text deltas during the PLAN phase.
- Tool Status: Reports when a tool starts and completes (e.g.,
[TOOL: code_search] Start... Done). - Safety: Raw tool payloads and results are never streamed to the terminal to prevent sensitive data leakage. Only the tool name and execution status are shown.
- Troubleshooting: If no output appears, ensure your LLM provider supports streaming and that your
SALMONLOOP_API_KEYis valid.
--output-format <format>: Control CLI output format for headless usage.text(default): Human-readable output.json: Single JSON object on stdout withresult,structured_output,session_id, andmetadata.stream-json: Newline-delimited JSON (JSONL) on stdout. All human logs are routed to stderr to keep stdout machine-readable.
--output-profile <profile>: Select the event protocol profile for--output-format stream-json.native(default): SalmonLoop native protocol (Claude-inspired, but versioned and extensible).anthropic: Strict Anthropic/Claude Code headless-compatible JSONL protocol.openai: Strict OpenAI Responses API streaming event protocol (1:1 schema alignment).
See docs/reference/headless.md for a short headless overview.
SalmonLoop distinguishes two related but different tool timelines:
- Model tool request: the model indicates it wants to call a tool (e.g. tool name + call id). This is exposed as
normalized.tool_request_start/end. - Host tool execution: the CLI/runtime actually executes the tool and returns a status/result summary. This is exposed as
normalized.tool_call_start/end.
Headless protocol profiles map these timelines as follows:
native/anthropic:tool_useblocks are derived fromnormalized.tool_request_start.tool_resultblocks are derived fromnormalized.tool_call_end.
openai(strict Responses streaming):function_calloutput items are derived fromnormalized.tool_request_start(default redacted arguments:{}).- There is no protocol extension for host execution payloads; execution status remains CLI-internal.
These flags are intended for CI/headless environments. They are off by default.
--headless-include-tool-input: Include redacted tool input intool_useblocks.--headless-include-tool-output: Include tool output summary intool_resultblocks.
Notes:
- Only valid with
--output-format stream-json. - Not supported with
--output-profile openai(strict OpenAI profile rejects protocol extensions).
--headless-include-authorization-decisions: Include tool authorization decisions (source/outcome/reason/ttl/persist/toolName/callId).
Notes:
- Only valid with
--output-format jsonor--output-format stream-json. - For
--output-format stream-json, only supported with--output-profile native(strict profiles do not emit extension events).
-i, --instruction <string>: (Required) Instruction for the LLM to follow.-v, --verify <command>: (Required) Verification command to run after applying the patch (e.g.,bun run test,pytest).--act-mode <mode>: Flow mode forrun. Defaults toautopilot.-f, --file <path>: Path to a specific file to provide as primary context (repo-relative or absolute).-s, --selection <text>: Direct text selection to provide as context.
SalmonLoop (s8p) includes a robust snapshot system that captures the exact state of your repository (staged + unstaged changes) before execution.
Alias: You can use s8p snap instead of s8p snapshot.
Manually create a snapshot of the current workspace state.
s8p snap create -m "Backup before refactor"List all available snapshots. Alias: ls.
s8p snap lsView detailed information. Use --files to list all files contained in the snapshot.
s8p snap show <hash> [--files]Compare changes between a snapshot and the current workspace, or between two snapshots.
# Show summary stats
s8p snap diff <hash>
# Show full code diff
s8p snap diff <hash> --code
# Compare two snapshots
s8p snap diff <hash1> <hash2>Read the content of a file directly from a snapshot ("Source is Truth").
s8p snapshot cat <hash> <file_path>Export the entire content of a snapshot to a directory.
s8p snapshot export <hash> <target_directory>Manually restore the workspace to a specific snapshot state. Alias: checkout.
s8p checkout <hash> [--force]Manage snapshot lifecycle. Alias: rm.
# Delete a single snapshot
s8p snap rm <hash>
# Clear ALL snapshots (requires confirmation)
s8p snap clear --force-cs, --checkpoint-strategy <direct|worktree>: (Default:direct) Checkpoint strategy.worktreeis safer and ignores dirty state by running in an isolated temporary directory.--apply-back-on-dirty <3way|abort>: (Default:3way) When usingworktree, choose how to handle a dirty main workspace during apply-back.--worktree-prepare <command>: Command to run inside the worktree before processing (e.g.,bun install --frozen-lockfile).--dry-run: Generate and validate the patch, but do not apply it to the disk (preview mode).--force-reset: Force a hard reset (git reset --hard) on failure. Use with caution as it discards all uncommitted changes.--stream-output: Emit streaming LLM output during phases that support it (currently PLAN).
--verbose [level]: Enable verbose logging with different levels:basic: Outputs basic logs and execution steps (default when flag is present).extended: Outputs detailed logs, including internal states and debug information.
--validate: Run code quality checks (lint and tests) before starting the loop.--allowedTools <rules>: Allow tool calls by permission rules (comma-separated; repeatable).--disallowedTools <rules>: Deny tool calls by permission rules (comma-separated; repeatable).
Rules use the form Tool(specifier):
Bash(*)orBash: allow all shell commands (highly permissive).Bash(bun run *): allow shell commands that start withbun run.Read(src/**): allow reading files undersrc/recursively.
Notes:
- For Bash patterns, a space before
*enforces a word boundary:Bash(ls *)matchesls -labut notlsof. - Wildcard Bash rules do not allow shell operator chaining (e.g.
&&,||,;,|,>,<). Use an exact match rule if you truly intend to allow an operator sequence.
SalmonLoop features a visual progress bar that tracks the execution through various phases:
- Preflight: Safety checks.
- Context: Gathering codebase context.
- Plan: Creating the modification plan.
- Patch: Generating the unified diff.
- Validate: Enforcing safety limits.
- Apply: Writing changes to disk.
- Verify: Running the verification command.
- Rollback: Restoring state on failure.
When a loop fails, SalmonLoop provides actionable suggestions based on the failure type:
- Compilation Errors: Suggestions to check syntax or imports.
- Linting Errors: Suggestions to run local linters.
- Test Failures: Guidance to inspect test output.
- Workspace Safety: Reminders to commit or stash changes.
SALMONLOOP_API_KEY: Your LLM provider API key (preferred).S8P_API_KEY: (Legacy) Fallback for backward compatibility.SALMONLOOP_BASE_URL: (Optional) Provider base URL (preferred).S8P_BASE_URL: (Legacy) Base URL alias.SALMONLOOP_MODEL: (Optional) LLM model to use (preferred).S8P_MODEL: (Legacy) Model alias.
SALMONLOOP_UI_LOG_MODE:quiet|normal|debug(preferred).SALMONLOOP_UI_MODE: alias.