Commands and Keybindings
Slash commands
| Command | Description |
|---|---|
/help |
Show in-app help text. |
/exit, /quit |
Quit Spettro. |
/update |
Install a newer Spettro release and restart into it. The startup notice may rest on a release check up to 24 hours old; /update always asks GitHub again, so a release published since then is found and installed. |
/mode, /next |
Cycle active manifest agent/mode. |
/theme |
Open the theme picker: pick dark, light or auto from a list with a live preview panel. Also reports the selection, the palette it resolved to, and which source decided (env / config / detection / default). |
/theme <dark|light|auto> |
Switch palette immediately and persist it to ~/.spettro/config.json. auto detects the terminal background and falls back to dark. SPETTRO_THEME picks the palette at startup; /theme still overrides it for the rest of the session. |
/connect |
Open provider/local-endpoint connect dialog. |
/login |
Sign in to a Spettro subscription (device flow). See Subscription. |
/logout |
Sign out and remove the saved Spettro subscription key. See Subscription. |
/models |
Open model selector dialog (connected providers). |
/models <provider:model> [api_key] |
Set model directly; optional API key saves for provider. |
/goal <objective> |
Start an autonomous goal-mode run. See Goal Mode. |
/goal stop |
Abandon the active goal and cancel any in-flight run. |
/goal status |
Show the current goal's iteration count, no-progress counter, and elapsed time. |
/goal resume |
Resume an unfinished goal from a loaded session. |
/loop <time> <prompt> |
Run a prompt (or slash command) on a recurring interval, e.g. /loop 5m check CI status or /loop 30m /compact. Intervals use duration syntax (30s, 5m, 1h30m, minimum 10s); the first run fires immediately. A firing that lands while a run is still in progress is skipped, not queued. |
/loop stop |
Stop the recurring loop (an in-flight iteration keeps running; Esc interrupts it). |
/loop status |
Show the active loop's prompt, interval, iteration count, and next firing. |
/permission <ask-first|restricted|yolo> |
Set execution policy. |
/permissions [ask-first|restricted|yolo] |
Show or set policy alias. |
/permissions debug <on|off> |
Toggle permission diagnostics in UI. |
/budget <n|0> |
Set request token budget (0 = unlimited). |
/thinking <off|low|medium|high|x-high|max> |
Set the reasoning/thinking level for the active model. Maps to Anthropic's thinking token budget and to reasoning_effort on OpenAI and OpenAI-compatible backends. Hidden for models the catalog does not flag as reasoning-capable; if a model rejects the chosen level, Spettro silently retries at a lower one. |
/ultra [on|off] |
Toggle ultra (no argument flips it). Ultracode: substantive tasks run as dynamic workflows, as if every message contained the ultracode keyword. Saved to ~/.spettro/config.json as ultra. The status bar shows ultra while it is on. It is suspended while the agent the message goes to would run under ask-first (status bar ultra:suspended, dimmed), since workflows need restricted or yolo; the setting stays saved. An agent's own permission counts: under the default user-level ask-first, coding (whose own level is restricted) still runs with ultra, while plan and ask are suspended. Writing ultracode in a message turns the mode on for that turn only. |
/workflows |
List saved workflow scripts from .spettro/workflows and ~/.spettro/workflows, with their descriptions and phases. |
/workflows show <name> |
Print a saved workflow's header and source. |
/workflows run <name> [json | text] |
Run a saved workflow as a template: dispatches a turn in which the agent reads the script, adapts anything task-specific or stale, and runs it (by name with the JSON args when it fits as it is). Text that is not JSON is passed along as the task description. |
/workflows size [small|medium|large|unbounded] |
Show or set the workflow size tier, a guideline for how many agents one workflow should use. Saved to ~/.spettro/config.json as workflow_size. |
/workflows where |
Show the directories scanned for saved workflows. |
/plan [prompt] |
Switch to plan mode or run a planning request directly. |
/approve |
Execute pending plan through coding agent. |
/tasks [list|add|done|set|show|rm|clear] |
Manage the session task graph. list prints tasks in dependency order with deps: and [blocked] markers; set accepts pending, in_progress, completed, blocked or cancelled; rm <id> deletes a task (stripping references to it from other tasks' dependencies); clear prunes all completed/cancelled tasks. |
/mcp <list|read|auth> |
Manage MCP resources and auth. |
/skills (or /skill list) |
List Agent Skills: who can run each, its source folder and SKILL.md path, shadowed skills and warnings. |
/<skill-name> [args] |
Run a skill: its instructions, with the arguments substituted, become the prompt. Listed in the / menu with the skill's description; built-in and custom commands win a name clash. $<skill-name> in any prompt pulls the skill in too. |
/skill install <source> |
Install a skill from a local path, https git URL, or owner/repo shorthand into ~/.spettro/skills (--project: .spettro/skills). |
/skill info <name> |
Show metadata, bundled files and the start of the instructions. |
/skill enable <name> / disable <name> |
Show or hide a skill for the agent and the / menu (saved as disabled_skills in config.json). |
/skill uninstall <name> |
Remove a skill installed in .spettro/skills (Claude Code / Codex folders are never written to). |
/skill where |
Show the discovery folders, in priority order. |
/skill reload |
Force a re-scan of the skill folders (changes on disk are otherwise picked up on the next use). |
/stats |
Show session token usage and prompt-cache metrics. |
/hooks |
Show effective runtime hooks (project + global). |
/memory [show] |
Show persistent cross-session memory (user + project). See Persistent Memory. |
/memory edit [user|project] |
Edit a memory file in $EDITOR. |
/memory clear [user|project|all] |
Erase saved memory. |
/memory mine [n] |
Scan recent saved sessions in the background and draft candidate memories into the review inbox. |
/memory review |
Approve or discard drafted memory candidates (nothing saves without approval). |
/compact [focus...] |
Compact the current conversation (two-stage: offload oversized tool results to re-readable references, then summarize). |
/compact auto <status|on|off> |
Show/configure auto-compact. |
/compact policy |
Show compact thresholds and failure counters. |
/clear |
Save and clear the current conversation. |
/diff [path...] |
Show diffs of files modified this session (all, or given paths). |
/resume |
Open saved conversation picker. |
/rewind |
Restore files and/or conversation to a pre-edit checkpoint. See Checkpointing. |
/checkpoints |
Show checkpoint count and shadow-store disk usage (this project and all projects). |
/storage |
Report what Spettro stores on disk, per artifact class. See Storage. |
/storage clean |
Interactive multi-select cleanup with safe defaults preselected; also available headless as spettro clean. |
/init |
Analyze codebase and create/update SPETTRO.md. |
/jobs [list] |
List background shell jobs started by the agent. |
/jobs kill <id|all> |
Terminate a background job (or all of them). |
job-output |
Tool-only (not a slash command): fetches accumulated output of a background shell job (job-N), or pages through a spooled truncated tool result (spool:N). See Session Lifecycle. |
tool-output |
Tool-only: re-reads the full output of an earlier tool call that was offloaded to the session spool (by truncation or by compaction), with id/offset/limit paging. See Session Lifecycle. |
pty-start / pty-write / pty-kill |
Tool-only: interactive terminal sessions (REPLs, debuggers, ssh, watch-mode servers) the agent can type into. See Interactive PTY sessions. |
/remote |
Start the local HTTP/SSE control plane on 127.0.0.1 (default port 7878). |
/remote :PORT |
Start the control plane on a specific port; falls back to a free port if it is busy. |
/remote local |
Start the LAN HTTP/SSE control plane on 0.0.0.0 (default port 7878). |
/remote local :PORT |
Start the LAN control plane on a specific port; falls back to a free port if it is busy. |
/remote stop |
Stop the running control plane. |
/remote status |
Print the current URL and bearer token. |
/telegram setup <token> |
Save a Telegram BotFather token (encrypted) and validate it via getMe. Alias: /tg. |
/telegram allow <@u|id> |
Add a Telegram username or chat ID to the allowlist. |
/telegram start / /telegram stop |
Start or stop the relay's long-poll worker. Autostarted on next launch when previously running. |
/telegram status / /telegram list |
Print runtime state, bound chats and allowlist. |
/telegram deny <@u|id> / /telegram reset |
Remove an allowlist entry or wipe the entire relay configuration. |
/<custom> [args] |
Run a user-defined command from ~/.spettro/commands/ or <root>/.spettro/commands/. See Custom Slash Commands. |
Agent usage
- Type
@in the input to open repository file suggestions and insert mentions. - Use the native
agenttool to spawn sub-agents; multiple calls in one response run in parallel. /approveexecutes a previously generated pending plan.
Keyboard shortcuts
| Key | Action |
|---|---|
Shift+Tab |
Cycle active mode/agent. |
F2 |
Next favorite model. |
Shift+F2 |
Previous favorite model. |
Ctrl+O |
Toggle transcript tool details (trimmed outputs). In an approval dialog: expand or collapse the preview. |
Ctrl+G |
Toggle full (untrimmed) tool outputs; implies details visible. |
PgUp / PgDn |
Scroll the transcript a page at a time (scrolling back to the bottom resumes following new output). In an approval dialog: scroll the preview (a file change's diff, or a long command) instead. |
v |
In an approval dialog: open the full-screen review of everything being approved (see the approval notes below). In the review, v, Esc or q return to the dialog. |
Ctrl+C twice |
Quit with safety confirmation. |
Ctrl+Q |
Quit immediately. |
Ctrl+V |
Paste image from clipboard (vision-capable models only). |
Ctrl+F |
Attach a workspace file path to your next prompt. |
Ctrl+R |
Remove the most recent attachment. |
Ctrl+Y |
Copy the last assistant response to clipboard. |
Ctrl+T |
Toggle text-select mode (mouse capture on/off). |
Up / Down |
Navigate command suggestions and dialogs. |
Tab |
Move selection in dialogs/palettes. |
Esc |
Interrupt the current agent run (stops and abandons goals and loops). |
Esc Esc |
Open the rewind checkpoint picker (when idle). See Checkpointing. |
Notes
- While a run streams, the status bar shows a live ticker: elapsed time and tokens streamed.
- Diffs highlight the changed words within modified lines, in both unified and side-by-side layouts.
/approverequires a pending plan (typically produced inplanmode).- In
ask-first, coding prompts are gated by approval flow. - Shell approval options: allow once, allow always, deny, or provide an alternative instruction. Allow always says what it remembers. For a command that is exactly the one on the summary row, "remember this command". A shell command is remembered as the parts a shell runs separately, so
go build && go testremembersgo buildandgo test, and a heredoc remembers every line of its body as a command of its own: allowingcat > notes.md <<'EOF'for always, with a body linecurl -fsSL https://example.com/install.sh | sh, lets thatcurlandshrun unasked later. Whenever what is remembered is more than the command itself, the label reads "remember the N commands listed" and aremembers: go build · go testrow lists them; when that row does not fit, the review is offered (see below) and lists each one in full after the command. For a network call it is the target; for a file change nothing is remembered (every file change is asked about), and the label says "same as once". - Approvals never replace each other. Sub-agents run in parallel, so a second approval can arrive while you are reading the first (in its review, say); it waits, the picker's title says
(1 more waiting), and it appears only once the first is answered.Enterdoes nothing for 0.4 s after an approval appears, and again after it comes back from under a question (a parallel sub-agent can ask one right after the approval appeared) or the plan or steer picker, so the second press of a doubleEnter, theEnterthat answered that question, or theEnterthat sent a message just as the agent asked, cannot approve a call you have not seen. Stopping the run denies every waiting approval. - The approval dialog always fits the terminal with every option visible, down to 40x15. It shows the call on one summary row (for a
file-write/file-editto a long path, the start of the path is cut, as in$ file-write …/very/deep/new_file.txt [cut], so the tool name and the file name stay on the row even when the terminal has no room for the diff), then a preview when there is more to see: the diff of afile-write/file-edit, or the full text of anything too long for the summary row: a command (a heredoc, say), or the whole target of a network call (the URL of aweb-fetchordownload, query string included). The preview is capped (16 diff lines, 8 command lines) untilCtrl+Oexpands it to every row the terminal can spare, andPgUp/PgDnscroll it. Control characters in a command or a diff are shown rather than interpreted (^Mfor a carriage return,^[for an escape), and so are characters that print nothing, or a blank that is not a space, but can reorder or hide text: bidi overrides, zero-width characters, the byte-order mark, variation selectors (a string of them can carry a whole payload inside what reads as""), Hangul fillers and the other default-ignorable characters, the line and paragraph separators, the blank braille pattern, and every space other than the ASCII one (a no-break space is not a word break to a shell, so./build/<U+00A0>~/is one argument, not two), all shown as\u00a0-style escapes (\U000e0100past U+FFFF); bytes that are not valid UTF-8 show as\x9b. So nothing the agent sends can hide part of what you approve. A command and a diff are also shown exactly, in the preview as in the review: a tab as⇥(keeping its width) and a carriage return ending a line as^M, since a<<-EOFheredoc ends at a tab-indentedEOFbut not a space-indented one (a script written with a tab-indented terminator runs the line after it; one indented with spaces keeps it as heredoc data). A letter of another script that is drawn like a Latin one (the Cyrillic small i, U+0456, ofg\u0456thub.com, which names another host thangithub.com; fullwidth and mathematical letters; the Kelvin sign) is written out as such an escape wherever it sits in a word that reads as Latin text (a word with ASCII letters or digits, or a host or path); a word wholly in another script (Russian prose, say) is left alone. Only the spaces, tabs and newlines a shell ignores are trimmed from the ends of a command: a trailing no-break space, vertical tab or line separator is shown. Abashcall with acwdshows it as a leadingcd <dir> &&, and a write through a symlink names the file it writes ($ file-edit notes.md (through a symlink: writes /home/me/.zshrc)). With permission debug on, thesegments:row escapes each segment the same way. A command too long for a row continues on the next under a↪mark (a new line of the command has none), with every character kept: a row breaks between two visible characters wherever it can, so no space is lost at the edge of a row, and./build/aaa/ ~/and./build/aaa/~/never wrap to the same rows. Text that legitimately uses such a character (an emoji with a variation selector, French text with no-break spaces) shows the escape instead. - Nothing you approve is out of reach. Whenever part of the call is not on screen (the preview is capped, scrolled or has no room at all, a diff line is cut at the dialog's width, or the summary row is cut), the dialog says so in words and adds a first option, Review full diff (Review full command for a command, Review full request for a network call), selected by default, so
Enteropens the review instead of approving. What is not shown is always named: a cut summary row ends with[cut]; the preview's footer sayslines 1-4 of 903, long lines cut · v review all · …; a preview with no room reads903 lines not shown - press v to review(shortened to fit a narrow terminal, and moved to the picker's title row when even the footer has no room, as at 40x15 during a run). A command whose long lines are wrapped onto several preview rows is counted in rows instead (rows 1-4 of 163,243 rows not shown - v to review), as the review counts them.vopens the review from the picker, whether or not the option is offered. - The review takes the whole terminal (down to 40x15) and shows everything being approved: the tool, the path (and the absolute file, and whether it is a new file), the agent and its directory, the reason, and then the complete diff (for a new file, its whole content) or the whole command with numbered lines, or the whole network target. Nothing is cut: a line wider than the screen continues on the next rows under a blank gutter, with every character kept (spaces included, never at the edge of a row), the escaping of control, bidi, zero-width and other invisible characters is the same as in the preview, and nothing is shown as something else (a tab is
⇥, a carriage return ending a line^M, in a diff too). A diff's body lines are read by the hunk's line counts, so deleting the SQL comment-- noteshows as a deletion (- -- note), not as a file header. The bottom row says where you are (rows 902-921 of 921 · end). Keys:Up/Down(ork/j) scroll a row,PgUp/PgDn(orb/space) a page,Home/End(org/G) jump, the mouse wheel scrolls;Esc,q,vorEnterreturn to the dialog. The review never approves or denies anything: back in the dialog the review row is markedseenand the cursor moves to Allow once, so reviewing and approving isv,Esc,Enter. - When the whole call is on screen, the dialog is unchanged: four options with Allow once selected, so a short command costs no extra key. Once the review has been offered for a request it stays for that request, even if you then enlarge the terminal or expand the preview, so the options never move under the cursor. Allow always, Deny and Tell the agent what to do instead work as before;
Escin the dialog still denies (in the review it only returns to the dialog). - For maintainers: the dialog lives in
internal/tui/dialog_approval_view.go(layout, summary row, footer), the picker's options and keys indialog_approvals.go(the review option is latched on the pending request,reviewOffered, and the cursor stores an action rather than a row index, so a row appearing above it never changes whatEnterdoes), and the review indialog_approval_review.go(a modal,modalApprovalReview, rendered once per width and cached on the request). What counts as "not on screen" isapprovalHidesContent; the reason is commentary and does not count, but what Allow always remembers does when it is more than the command (approvalRemembered,approvalRemembersOther; the runtime keys a remembered command withagent.RememberedCommandKey, which folds only the runs of spaces and tabs a shell splits words at: outside quotes and not escaped). Approvals that arrive while one is on screen wait inapprovalQueueand are shown bypresentApproval;approvalEnterGuardis the pause after one appears. The diff renderer'sWrapandExactoptions (internal/diff),termtext.HardWrapandtermtext.EscapeExactkeep every character of a wide line and show it as itself;termtext.Hiddenis the list of characters written out as escapes, andinternal/termtext/lookalike.gothe look-alike letters.trackApprovalCoverrestarts the Enter pause when the approval comes back from under a question or the plan or steer picker.internal/tui/approval_review_test.gochecks the option order and default in both states, the review at 40x15/80x24/120x40 (every row within the terminal, every row of a 900-line diff reached by paging, its last line included) and the escaping;approval_trust_test.gochecks that commands differing by a space never look the same, an invisible payload is written out, a look-alike host is written out, a second approval waits its turn, the Enter pause restarts after a question, Allow always lists what it remembers, and tabs show as tabs in the command and the diff preview alike. - Approvals that leave the terminal carry the whole call too, with the same characters written out: an ACP editor's permission prompt includes the whole command (or network target) as a code block next to the diff, escaped, and a file change whose text holds an invisible character gets an escaped copy of its diff (ACP); the remote control plane's
approval_requestevent carries the wholecommandanddiffwith explicit*_truncatedflags past a 4 MiB bound, and a*_visiblecopy when they hold hidden characters (Remote Control); a Telegram notice writes them out too and sends a long command or diff as a file attachment after a message that says it is not the whole text (Telegram). - Tool calls and outputs of any size stay inside the terminal. A tool's header row is one line (a multi-line command is folded onto it, a long path is cut from the left so the file name stays visible); output lines wider than the transcript are cut with
…and along lines cut · ctrl+g for full outputnote, andCtrl+Gshows them whole, wrapped. Escape sequences in output (and in model replies and the activity panel's details) are dropped, bytes that are not valid UTF-8 show as�, and progress meters that redraw with carriage returns show their final state. After a resize the transcript is redrawn at the new width; a transcript scrolled up keeps showing the message it showed (so does toggling the activity panel orCtrl+O/Ctrl+G). A call of a tool you defined yourself (see Tools of your own with a built-in's name) is labelled with its own name, never as the built-in it shares a name with. - With the activity panel open (
Ctrl+B), the task list moves into the panel (the footer under the transcript is not drawn then); it shows live tasks first and counts completed ones. The panel needs a terminal at least 110 columns wide and 15 rows tall; on a smaller one it is not drawn until the terminal grows again, andCtrl+Bsays so (activity panel on, shown from 110x15). On a short terminal the footer shrinks, down to nothing, so the transcript keeps at least a row (three on a normal terminal) and whatever is in the input box keeps the rows it needs: the text input during a run, the steer or plan picker, an approval or a question. - Markdown tables follow their delimiter row's alignment (
---:right,:---:centred, by display width, so CJK and emoji cells line up), and tables wider than the transcript have their widest columns narrowed (cells cut with…) instead of wrapping, and code-block lines are cut with…rather than clipped silently. Wrapped list items and quotes keep their indent (a list item's text lines up under its first word, nested items stay nested, a quote keeps its│bar on every row) and their styling (a bold phrase or a code span that crosses a row break stays bold or shaded on the next row), and an underscore inside a word is literal, sosnake_casenames and paths likefile_name.goare not turned into italics. - The full-screen pickers (
/models,/connect,/resume,/theme, the onboarding model list) fit the terminal whole, borders and key hints included, down to 40x15: rows too long for the dialog are cut with…, the key hints wrap onto a second row when they do not fit one, and a list that scrolls says how much is above and below it (↑ 3 more,↓ 12 more). - Command output in the transcript (
/help,/skills,/stats, ...) that is too long for the pane wraps under its second column, so a wrapped description never reads as a new entry. - "Allow always" persists normalized command approvals in
.spettro/allowed_commands.json; see Configuration for what normalizing folds (only the word breaks a shell sees). /connectincludesLocal endpoints (LM Studio/Ollama/llama.cpp/…)and probes/v1/models. Multiple local endpoints can be connected side by side; each can optionally carry an API key (for servers started with authentication, e.g.llama-server --api-key), and existing endpoints can be managed (edit key / remove) from the same dialog.- In
/models, pressfto toggle favorites for highlighted model. - Pressing
Enteron a highlighted command suggestion inserts it first; pressingEnteragain executes it. When what you typed is a whole command name (/clear,/skills) it is the highlighted suggestion andEnterruns it at once: suggestions are ordered by how well their name matches (exact name, then names starting with what you typed, then names containing it, then commands matched only by their description), and every change to the input moves the highlight back to the top. /goalruns the coding orchestrator autonomously. Interrupt withEscor/goal stop. Permissionyolois required for fully unattended operation; otherwise approval prompts pause the loop. See Goal Mode.- A command's output (
/skills,/jobs,/tasks, ...) shows in the transcript as soon as the command runs. /clearsaves the session first, then starts fresh. The saved session is available via/resume. See Session Lifecycle./compactcompacts the conversation in two stages: old oversized tool outputs are first replaced with[output elided: …]stubs the agent can re-read viatool-output, then the older turns are replaced by a structured summary. The original task, the latest user messages and the most recent tool calls are always kept verbatim. Auto-compact triggers at 85 % context window by default and skips the summary entirely when pruning alone frees enough space. See Session Lifecycle./loginand/logoutmanage your Spettro Subscription. See Subscription.- Clipboard pasting (
Ctrl+V), file attachments (Ctrl+F), and text-select mode (Ctrl+T) are described in Clipboard and Attachments. - The first-launch onboarding wizard is documented in Onboarding.
- Runtime hooks (
/hooks) are documented in Runtime Hooks. - User-defined slash commands (reusable prompt files with
{{args}}and shell interpolation) are documented in Custom Slash Commands.
