use newt_core::agentic::newt_line;
use newt_core::role_profile::Cognition;
pub(super) fn canonical_help_topic(cmd: &str) -> &str {
match cmd {
"quit" => "exit",
"end" | "restart" | "clear" => "new",
"allow" => "permissions",
"plan" => "roadmap",
"compact" => "compress",
"vi" | "vim" | "emacs" | "nano" | "edit-mode" => "editor",
"tool-rounds" | "max-rounds" => "rounds",
_ => cmd,
}
}
static COGNITION_PAGE: std::sync::LazyLock<String> = std::sync::LazyLock::new(|| {
let all = Cognition::all();
let levels: Vec<&str> = all.into_iter().map(Cognition::label).collect();
let (light, deep) = (all[0], all[all.len() - 1]);
format!(
"\
/cognition — folded into /psyche (#1665)
/psyche open the dial panel (TTY); ←/→ dials cognition
/psyche cognition <level> set {levels}
/psyche cognition off send no reasoning controls (override any persona)
/psyche cognition auto follow the active persona's cognition (default)
/psyche cognition list list every level, light → deep
Responses maps the level to OpenAI reasoning.effort ({light}={} …
{deep}={}). Chat Completions maps it to local generation controls only
when the endpoint explicitly advertises that capability; unknown endpoints are
unchanged. The session override beats the active persona's cognition; a
persona sets its own default via `cognition:`.",
light.reasoning_effort(),
deep.reasoning_effort(),
levels = levels.join(" | "),
)
});
static TENACITY_PAGE: std::sync::LazyLock<String> = std::sync::LazyLock::new(|| {
let levels: Vec<&str> = newt_core::Tenacity::all()
.into_iter()
.map(newt_core::Tenacity::label)
.collect();
format!(
"\
/tenacity — folded into /psyche (#1665)
/psyche open the dial panel (TTY); ←/→ dials tenacity
/psyche tenacity <level> set {levels}
/psyche tenacity auto clear the override (back to normal)
/psyche tenacity list list every level
Tenacity is how long the agent pursues the task. `relentless` lifts the
initial tool-round allowance; an explicit `/rounds` overrides that initial value.
Fresh progress can renew either allowance; `workflow_grace_rounds = 0` makes
it a hard cap. Tenacity is set only explicitly (flag, /psyche, a conversation's pin, obsessive), never by a
persona or config. How soon the agent acts is initiative: /help initiative.",
levels = levels.join(" | "),
)
});
static INITIATIVE_PAGE: std::sync::LazyLock<String> = std::sync::LazyLock::new(|| {
let levels: Vec<&str> = newt_core::Initiative::all()
.into_iter()
.map(newt_core::Initiative::label)
.collect();
format!(
"\
/psyche initiative — how much the agent looks before acting
/psyche open the dial panel (TTY); ←/→ dials initiative
/psyche initiative <level> set {levels}
/psyche initiative auto clear the override; inherit persona / config / family
/psyche initiative list list every level with its round count
Higher initiative nudges the model to edit after fewer read-only rounds, and
decisive / eager make exit_plan_mode require a concrete edit. The session
override wins over the persona's `initiative` and the [initiative] config;
`auto` (aliases `inherit` / `reset`) releases it. The model family supplies
the default ([initiative.families]); the rounds per level are
[initiative.rounds].",
levels = levels.join(" | "),
)
});
pub(super) fn command_help_page(cmd: &str) -> Option<&'static str> {
let page = match canonical_help_topic(cmd) {
"settings" => {
"\
/settings [field value] — the main entry point for session controls
On a rich terminal, /settings opens an index:
Session model, editor, reasoning, effort dials, prompt, and rounds
Permissions permission posture and prompted-decision audit
Workspaces saved directories and access for the next process launch
Audit settings receipts and verification
Backends choose, edit, add, or remove a backend
Themes presets, per-role colors and attributes, live preview, and save
Use arrows then Enter, or a section's letter (t for Themes); / filters the
index. Esc clears the filter, then leaves the index for chat.
In Themes, Enter accepts a typed color; Enter again applies and persists the
draft. Applying or cancelling with Esc returns to Settings. Ctrl-S saves a
named copy; Enter applies it. Backends opens its
separate chooser, which returns to chat when closed.
The text form works everywhere; bare /settings uses it outside a rich terminal:
/settings thinking fold
/settings rounds 40
/settings workspaces interactive operator editor for next-launch access
/model, /backends, /permissions, and /workspace remain direct shortcuts."
}
"models" => {
"\
/models · /models capabilities — inspect the active endpoint's models
/models arrow-key model picker on a rich terminal; text list otherwise
/models capabilities the matrix: Tool Use, Think (reasoning), Ctx Win,
Safe Ctx, tuning Conf, and tested date
Untested rows show '—'; classify one with /probe <model>. Per-model overrides
live in [model_tuning] (see /config)."
}
"model" => {
"\
/model [name] — choose or switch the model on the active backend
Changes the model newt talks to. The choice sticks across runs (saved to
~/.newt/settings.toml) but does not edit config; switching backends clears it.
On a rich terminal, /model opens the live model list: arrows move, Enter
selects, Esc cancels. /models opens the same picker. Resident models show a
[loaded] badge after the name; the active model and badge use theme colors.
On a llama.cpp router: l loads the highlighted model, u unloads it, x unloads
other resident models then loads the highlighted one. Unloading requires
confirmation. These controls change memory residency, not files; Enter picks
the model for chat. r refreshes server state.
In a lean or piped session, /models prints the list and /model <name> switches.
/model qwen3:30b"
}
"backend" => {
"\
/backend — an alias of /backends (#2048)
They were never two commands the operator should have had to tell apart, and
the slash registry always described them as one. See /help backends."
}
"backends" => {
"\
/backends [name] — the backend panel, the text list, or a switch by name
Bare /backends on a rich interactive terminal opens the panel: ←/→ spins
through the configured backends, ◀ marks the active one; Enter applies the
pick; Esc leaves silently. `e` edits the selected entry, `a` adds one (name,
kind, url, model, api-key env/file — written crash-safe to
~/.newt/backends/<name>.toml), and `d` removes one after confirming, naming
what is lost and where from.
The text forms work everywhere (piped, lean build, headless):
/backends list every configured backend, ◀ the active one
/backends dgx1 repoint this session at the 'dgx1' backend
A backend's WIRE KIND (openai / ollama) is a field on the backend itself,
edited with `e` in the panel. `/backend <kind>` used to set it globally,
detached from the endpoint it applied to — which is how a session ends up
pointed at an OpenAI-wire URL in Ollama mode. Pick a named backend that
already has the kind you want instead.
Your choice sticks across runs (~/.newt/settings.toml); an explicit
NEWT_PROVIDER or a --loadout still overrides it."
}
"crew" => {
"\
/crew edit [name] — edit a crew's settings interactively
Prompts field-by-field (planner/navigator/triage loadouts, control loop, test
command, and budgets), previews the result, then writes it as a bare-Crew TOML
to ~/.newt/crews/<name>.toml. Enter keeps the [current] value; '-' clears an
optional field. Same form as `newt crew --edit`.
/crew edit edit the sole crew (or be prompted for a name)
/crew edit home edit (or create) the 'home' crew"
}
"thinking" => {
"\
/thinking — folded into /settings (#2044)
/settings open the form; the reasoning row is in it
/settings thinking fold (default) the first `/spill N` rows of
reasoning, then one line saying how long it
thought and what is behind the fold, reopenable
with the `/spill open <id>` it names
/settings thinking stream every line, unbounded — the historical trickle
/settings thinking off just the answer
`on` is an alias for `fold`. Reasoning is dimmed and sits above the answer
either way; TTY only. Persist with [tui] thinking in config."
}
"tenacity" => TENACITY_PAGE.as_str(),
"initiative" => INITIATIVE_PAGE.as_str(),
"cognition" => COGNITION_PAGE.as_str(),
"psyche" => {
"\
/psyche — the agent's effort posture: cognition, tenacity, initiative, crew
/psyche open the dial panel (TTY): ↑↓ select, ←→ dial,
Enter apply, Esc leave (nothing changed → just exits)
rows: persona · model (spins the backend's served
models, applied via the /model path) · cognition ·
tenacity · initiative
/psyche status the read-only text view (also what piped/lean gets)
/psyche cognition <level|off|auto|list> text setter for the cognition dial
/psyche tenacity <level|auto|list> text setter for the tenacity dial
/psyche initiative <level|auto|list> text setter for the initiative dial
/psyche obsessive engage the max-effort posture's live dials
The orthogonal psyche dials:
cognition backend-specific reasoning depth per call
tenacity how long it pursues the task (relentless lifts the round limit)
initiative how much it looks before acting (the read → act nudge)
crew how many minds work the task (NEWT_TEAM / newt crew)
obsessive = cognition meticulous + tenacity relentless + crew on — newt's
'ultra'. Initiative is left alone: the deepest thinking and acting after one
round pull against each other. In-session /psyche obsessive sets cognition +
tenacity live; crew is a launch gate, so start with `newt --obsessive` to
include the crew this session."
}
"probe" => {
"\
/probe [model|all] · /probe window <model> · /probe reset
Classify models empirically; results feed /models capabilities.
/probe <model> warm up, then test: tool conformance, context window,
thinking quirk, token calibration
/probe probe the active model
/probe all RE-probe every model on the endpoint (a long sweep —
press Esc to cancel; finishes the current model first)
/probe window <model> empirical input-boundary search (max input at High conf)
/probe reset wipe all learned values (conformance, windows,
calibration) so the next /probe re-learns from scratch"
}
"memory" => {
"\
/memory — show context-window and notes usage
Read-only: how full the context window is, persistent NOTES usage, and the
session compression counters. Add facts with /remember; compact with /compress."
}
"compress" => {
"\
/compress [focus] — compress the conversation context now
Summarize-and-prune the in-flight context to reclaim window, optionally biased
toward a topic. Runs automatically when the window fills; this forces it early.
/compress
/compress the auth refactor"
}
"summarizer" => {
"\
/summarizer [subcommand] — inspect or manage the mid-loop summarizer
/summarizer show the effective backend + knobs
/summarizer setup [alias] provision the default/named embedded mini-model
/summarizer embedded [alias] pin an explicit embedded summarizer override
/summarizer fallback <m> set fallback_model (use 'none' to clear)
/summarizer timeout <secs> set timeout_secs
/summarizer retries <n> set retries
/summarizer keep-alive <v> set keep_alive (use 'none' to clear)
/summarizer clear remove summarizer.toml, return to built-in default
This is the interactive wrapper around `newt summarizer ...`."
}
"rounds" => {
"\
/rounds [show|<n>|double|reset|config|unlimited] — initial tool-call round allowance
Human-only override for the initial allowance in each turn. Fresh evidence,
workspace changes, and new verification can renew it automatically without
operator nudges. Set `workflow_grace_rounds = 0` for a hard round cap.
Explicit inference budgets, cancellation, and the no-progress brake still apply.
This command does not edit config and lasts only for this session.
/rounds show the initial allowance
/rounds 50 start with 50 tool-call rounds per turn
/rounds double double the current initial allowance
/rounds reset clear the override; derive from tenacity + config/model
(`default` and `auto` are aliases)
/rounds config use config/model tuning even under relentless tenacity
/rounds unlimited raise to at least 10000 rounds (effectively run-until-finished)
Aliases: /tool-rounds, /max-rounds."
}
"remember" => {
"\
/remember <fact> — add a fact to persistent NOTES.md
Writes a durable note the agent carries across turns and sessions (workspace
NOTES). Survives /new. View usage with /memory.
/remember the staging DB is read-only"
}
"new" => {
"\
/new · /end · /restart · /start — begin a new conversation
/new, /end, and /restart FINALIZE the current conversation (its summary is
extracted to memory) and start a fresh one, staying in the session. /start
switches to a fresh one too but leaves the previous conversation OPEN so you can
/resume it. /start <title> and /rename <title> name a conversation so it is easy
to find in /resume. Nothing auto-resumes on next launch (#1030) — use /resume to
reopen a past conversation. /exit · /quit · vi :wq leave the session."
}
"conversation" => {
"\
/conversation <sub> — manage saved conversations
/conversation list list saved conversations
/conversation show <id> print one
/conversation restore <id> switch the session to it
/conversation rename <id> <t> retitle it
/conversation delete <id> delete it (alias: rm)
ids accept a unique prefix. Search bodies with /recall."
}
"recall" => {
"\
/recall [query] — browse or search past conversations
/recall recent conversations in this workspace
/recall <query> full-text search across this workspace's turns
Read-only and workspace-fenced. Bring one back with /conversation restore <id>
or /resume."
}
"resume" => {
"\
/resume [query|n|id] — find and REOPEN a past conversation (#1030)
/resume list recent conversations, annotated by liveness
/resume <query> full-text search this workspace's turns
/resume <n> reopen the n-th row from the last listing
/resume <id> reopen by id or unique prefix
Markers: ▶ current · ● open in another newt · ○ resumable. Reopening a
conversation another live newt holds is refused (it would mix turns) —
this is how #1030 keeps multiple newts from colliding."
}
"transcript" => {
"\
/transcript — review the WHOLE current conversation (#1670)
On the RICH surface: a full-screen pager where the conversation spine —
your › prompts and the model's ▸ replies — is the structure. Scroll
freely; the grey per-turn tool blocks are folded behind ⚙ headers.
q / Esc leave the pager (the screen is restored)
↑↓ / j k scroll by line PgUp/PgDn page
Ctrl-U / Ctrl-D half page g / G top / bottom
n / p next / previous message (jump the spine)
Enter/Space/Tab fold or unfold the current turn's tool block
On the LEAN surface the same command PRINTS the spine into scrollback —
the plain scroller has no scroll regions, by charter. Tool detail shown
is the stored summary (name · ok · duration); raw tool output is never
persisted."
}
"roadmap" => {
"\
/roadmap [sub] — manage the per-session planning roadmap
/roadmap list list open roadmaps
/roadmap show render the active roadmap tree
/roadmap new create a new roadmap
/roadmap use <n> bind a roadmap by number
/roadmap add <title> add a roadmap item
/roadmap task <n> show one task
/tree render the active roadmap tree (alias of /roadmap show)
Alias: /plan"
}
"persona" => {
"\
/persona <sub> — configured personas
/persona list list configured personas
/persona show show the active persona
/persona <name> start a fresh conversation with that persona
/persona switch <name> same as /persona <name> (an explicit verb)
/persona clear start fresh with no persona
Setting or clearing a persona starts a new conversation (the system prompt
changes). Define personas in config."
}
"dgx" => {
"\
/dgx <sub> — NVIDIA DGX endpoint operations
/dgx status endpoint health + currently-loaded models
/dgx models models installed on the DGX
/dgx ps models currently loaded in VRAM
/dgx warm [model] pre-load a model into VRAM (cuts first-token latency)
/dgx pull <model> pull an Ollama or HuggingFace GGUF model onto the node
/dgx rm <model> delete a model from the DGX
/dgx route <task> recommend a formation for a task
/dgx doctor probe every configured endpoint
Note: flags like --dry-run/--force/--name are CLI-only; use
`newt dgx pull ...` from a shell for the full pull workflow."
}
"permissions" => {
"\
/permissions — review prompted permission decisions + the active posture
Read-only: what you've allowed/denied this session and the posture's optional
authority floor, when configured. This view does not change grants. Eligible
permission prompts can save approvals; /settings workspaces edits saved
directory profiles for the next process launch.
For full access inside one directory, start:
newt --workspace-access code <directory>
Commands can create, change, rename, and delete inside that workspace; native
filesystem confinement still rejects outside targets, including symlink and
parent-directory escapes. Network access remains separately configured.
The default preset can also be set in trusted [tui.permissions] configuration.
This startup choice does not change a running session's authority.
For full access inside one directory, start:
newt --workspace-access code <directory>
Commands can create, change, rename, and delete inside that workspace; native
filesystem confinement still rejects outside targets, including symlink and
parent-directory escapes. Network access remains separately configured.
The trusted-config equivalent is [tui.permissions] preset = \"workspace_full_access\".
This startup choice does not change a running session's authority.
Usage:
/permissions overview of this session's prompt flow
/permissions audit [N] newest N audit rows from the persisted permission log
/allow alias for /permissions
Examples:
/permissions # show current session decisions
/permissions audit 25 # show newest 25 rows from permission-log.jsonl
/allow # alias for /permissions"
}
"status" => {
"\
/status — show session status and environment summary
workspace, backend, mode, posture, permissions state, and active identifiers.
Tip: use /info for a slightly richer version, and /permissions for full
prompted-decisions history."
}
"info" => {
"\
/info — show machine-readable context for the current session
Shows the same status surface as /status, plus the version, active model
identity, and resolved backend details that drive this prompt.
"
}
"byline" => {
"\
/byline — show the Co-authored-by block the next commit would carry
Read-only. Prints the exact trailer block, in commit order:
every model that has contributed since the last commit (a /model,
/backend, loadout, or crew switch ADDS one — it never replaces one),
then the model driving this turn, then the human operator when a real
email is known, then the Harness: provenance line.
The email in a trailer identifies the HARNESS, not the model, so a
harness signs its own address and never another's. Under newt's own
address the account name is not repeated: the qualifier carries only
what the address does not already say — `(v<version> <build>)`, or
`(crew v<version> <build>)` for a crew leaf. A foreign harness keeps its
full name, e.g. `(Claude Code v2.1.239)`.
The operator by-line comes from your git identity (user.name +
user.email). If no real email is known it is OMITTED, never invented —
so a missing operator line means \"unknown\", not \"nobody\".
This is rendered by the same finalizer the commit path runs, so it
cannot show a shape a commit would not produce. Do not hand-write these
trailers: the `git` tool stamps them itself."
}
"docs" => {
"\
/docs — open the right docs quickly
GitHub README: https://github.com/Gilamonster-Foundation/newt-agent
issue tracker: https://github.com/Gilamonster-Foundation/newt-agent/issues
architecture docs: https://github.com/Gilamonster-Foundation/newt-agent/tree/main/docs
Use /help for the in-session command list."
}
"mcp" => {
"\
/mcp — manage MCP servers for this session
/mcp server manager (text status without a rich TTY)
/mcp off [name] mute this session (tools leave the catalog now;
connection stays — /mcp on restores instantly)
/mcp on [name] unmute this session (bare = unmute all)
/mcp disable <name> durable: write enabled=false to config + drop now
/mcp enable <name> durable: write enabled=true; choose Reconnect in MCP
/mcp auth <name> how to (re)authenticate (`newt auth <name>`)
The same manager is under /settings → MCP. Enter opens server → tools → details;
Up/Down navigates, Esc returns one level. Login reconnects after successful
authentication; Reconnect refreshes the child/catalog; Test lists tools only.
Tool effect hints are metadata, never permission grants.
on/off is session-scoped (like /nudge) — use it while testing schema budget.
enable/disable rewrites ~/.newt/config.toml."
}
"mode" => {
"\
/mode [name] — show or choose the session's operating mode
/mode show the active mode and describe every available mode
/mode list same as bare /mode
/mode show show only the active mode
/mode <name> select chat, dev, admin, plan, diagnose, auto, or full-auto
/mode reset return to chat (the default)
Modes guide working style. Plan may update Newt's plan ledger but cannot mutate
the workspace; diagnose is bounded read-only research. In Auto, the model may
select chat, dev, admin, plan, or diagnose for a later action-shaped turn;
protected intake still wins, and only the human can select full-auto. No mode
grants authority or bypasses the active permission posture."
}
"posture" => {
"\
/posture [name] — show or choose a configured permission posture
/posture show the active posture and configured names
/posture list same as bare /posture
/posture show show only the active posture
/posture status same as /posture show
/posture <name> preload skill/framing and apply its optional preset floor
/posture off clear the active posture
/posture clear
Configured postures continue to use [modes.<name>] entries for compatibility.
A configured preset can only NARROW authority, never widen it; a posture with
no preset leaves authority unchanged."
}
"loadout" => {
"\
/loadout — show the active loadout
Prints the declared axes (backend, model, persona, mode, …) and what each
actually resolved to, so you can see why the session is configured as it is."
}
"workspace" => {
"\
/workspace — operator editor for saved workspace access
/settings workspaces the same interactive editor
/status workspace read-only current workspace path
Choose a workspace, additional read/write directories, a confined command/write
preset, and a default working directory inside the workspace. Optionally select
a default workspace for future launches. Review the resolved paths and confirm;
Cancel is the default. Settings and keys must remain protected from model access.
Saved changes require a real Newt process restart; /restart only resets the
conversation. Current authority and jobs stay unchanged. Removing a profile or
directory does not remove separate approvals or access through a parent grant.
Network permissions and configured development-command extras remain separate.
The model and noninteractive surfaces cannot approve changes in this editor."
}
"spill" => {
"\
/spill [status|N|reset|summary|excerpt|last|open ID] — tool-output controls
/spill show the effective row count and live availability
/spill <N> set collapsed live and completed rows for later tools
/spill reset return to the configured [tui] spill_lines value
/spill 0 disable live display; show completed output unbounded
/spill summary collapse spilled results to one line (rich default)
/spill excerpt restore the multi-row excerpt for spilled results
/spill last open the newest retained result (rich, this session)
/spill open <ID> open the retained result named by a collapse marker
F4 (cockpit) choose retained output without submitting a prompt
F4 (decision prompt) inspect the pending request; Esc returns without answering
While a tool is active, Up/Down scroll retained output. Space or Enter toggles
the boundary: ⧉ expands up to the terminal's safe capacity; ▣ collapses it.
Completed bodies are memory-only and bounded; older IDs can expire."
}
"config" => {
"\
/config — dump the resolved configuration (secrets redacted)
Shows the effective config after merging /etc/newt, ~/.newt, and ./.newt — the
source of truth for backends, loadouts, model tuning, and [tui] settings.
api_key_file/env values are redacted."
}
"prompt" => {
"\
/prompt · /prompt set \"<tmpl>\" · /prompt reset — customize the input prompt
/prompt list tokens ($MODEL/$DATE/…, \\m/\\t/\\M/…) + current
/prompt set \"<template>\" set the prompt for this session
/prompt reset revert to [tui] prompt / the built-in default
Tokens: \\t time · \\m model · \\M edit mode · \\w workspace · \\u user · \\h host ·
\\v version. Persist by putting a template in [tui] prompt (prefer the $NAME
macros there to dodge TOML escaping)."
}
"editor" => {
"\
/vi · /emacs · /nano — switch line-editor key bindings for this session
/vi modal vi keys (Esc=NORMAL; i/a/o insert; :w send, :wq send+end+quit)
/emacs emacs/readline keys (Enter sends; Ctrl-O newline; C-x C-c exit)
/nano nano-style (Enter sends; ^X exit; ^G help)
Persist with [tui] edit_mode. Press Ctrl-h/^G/:help in-editor for the cheatsheet."
}
"version" => {
"\
/version — print the newt-agent version."
}
"exit" => {
"\
/exit · /quit (or bare exit/quit, Ctrl-D) — leave the session
Ends the session. Conversations do NOT auto-resume on next launch (#1030): each
launch starts fresh — use /resume to reopen a past conversation. (Opt into
auto-resuming the folder's latest with [conversations] resume = true.)"
}
"help" => {
"\
/help [command] — command help
/help list every command
/help <command> this page for one command (same as /<command> --help)
Add --help (or -h) to any command for its page."
}
_ => return None,
};
Some(page)
}
fn command_help_output(cmd: &str, color: bool, verbose: bool) -> (String, bool) {
match command_help_page(cmd) {
Some(page) => {
let mut out = newt_line(
&format!("/{} help", canonical_help_topic(cmd)),
color,
verbose,
);
out.push('\n');
for line in page.lines() {
out.push_str(line);
out.push('\n');
}
(out, true)
}
None => {
let mut out = newt_line(
&format!("no help for '/{cmd}' — /help lists every command"),
color,
verbose,
);
out.push('\n');
(out, false)
}
}
}
fn help_list_output(color: bool, verbose: bool) -> String {
let mut out = newt_line("Available commands:", color, verbose);
out.push('\n');
for line in help_lines() {
out.push_str(line);
out.push('\n');
}
out
}
fn help_list_markdown() -> String {
let mut out = String::from("## Available commands\n\n");
for line in help_lines() {
let line = line.trim();
if line.is_empty() {
out.push('\n');
} else if let Some((usage, description)) = line.split_once(" - ") {
out.push_str(&format!("- `{usage}` — {description}\n"));
} else {
out.push_str(line);
out.push('\n');
}
}
out
}
fn command_help_markdown(cmd: &str) -> Option<String> {
let page = command_help_page(cmd)?;
let mut out = format!("## /{} help\n\n", canonical_help_topic(cmd));
for line in page.lines() {
if line.starts_with(" ") {
out.push_str("- ");
out.push_str(line.trim());
} else {
out.push_str(line);
}
out.push('\n');
}
Some(out)
}
pub(super) fn render_help_for_tui(
topic: Option<&str>,
color: bool,
verbose: bool,
markdown: bool,
cols: usize,
) -> String {
if !markdown {
return render_help(topic, color, verbose);
}
let source = match topic {
None => help_list_markdown(),
Some(cmd) => match command_help_markdown(cmd) {
Some(source) => source,
None => return render_help(topic, color, verbose),
},
};
let rendered = newt_core::agentic::render_markdown(
&source,
newt_core::agentic::RenderOpts { color, cols },
);
format!("{}{rendered}\n", newt_line("", color, verbose))
}
pub(super) fn print_command_help(cmd: &str, color: bool, verbose: bool, markdown: bool) -> bool {
let found = command_help_page(cmd).is_some();
print!(
"{}",
render_help_for_tui(
Some(cmd),
color,
verbose,
markdown,
newt_core::tty::term_cols(),
)
);
found
}
pub fn render_help(topic: Option<&str>, color: bool, verbose: bool) -> String {
match topic {
None => help_list_output(color, verbose),
Some(cmd) => command_help_output(cmd, color, verbose).0,
}
}
pub(crate) fn help_lines() -> &'static [&'static str] {
&[
" /settings [field value] - main settings index: Session · Permissions · Audit · Backends · Themes; text setters also work",
" /models - list the models the active backend serves, marking the active one",
" /models capabilities - the same list as a matrix: tool use, thinking, context window, tuning",
" /model [name] - pick a model, or switch by name (sticks across runs)",
" /backends [name] - backend panel on a rich TTY (choose · edit · add · remove); text: list, or switch by name",
" /backend - alias of /backends",
" /probe [model|all] - classify tool use, context window, thinking, calibration (all = re-probe every model; Esc cancels)",
" /probe window [model] - empirical input-boundary search (records max input at High confidence)",
" /probe reset - wipe all learned probe values (conformance, windows, calibration)",
" /compress [focus] - compress context now, optionally focused on a topic (alias: /compact)",
" /summarizer - show or change the summarizer backend and knobs",
" /rounds [n|double|reset|config|unlimited] - set this session's initial tool-call round allowance",
" /context - show the active context manager + features",
" /context manager [preset] - show or set the strategy preset (standard; progressive/distributed pending #546)",
" /context feature <name> [on|off] - toggle a composable context feature (all pending #582-#586)",
" /context compaction [headroom_aware|message_count|reset] - set this session's automatic-compaction trigger policy",
" /context stats - experimentation dashboard: budget, compression, feature states",
" /search <query> - semantic code search cockpit (#1387): preview · model · rejects · pin · exclude · status",
" /remember <fact> - add a fact to persistent NOTES.md",
" /discuss [text] - talk through a pending clarification batch instead of answering it (alias: /chat); \
says so if nothing is pending",
" /new - finalize this conversation and start a fresh one (stays in the session; alias: /clear)",
" /end - the same, recorded as ended by /end rather than /new (it no longer exits — use /exit)",
" /restart - the same, recorded as a restart",
" /start [title] - begin a new conversation, leaving the current one open to /resume",
" /resume [name|search|n|id] - find & reopen a past conversation: bare lists recent, then match by name/title, id, or full-text search",
" /resume find [query] - search conversations WITHOUT reopening one (bare: browse)",
" /resume list - list saved conversations",
" /resume show <id> - show a saved conversation",
" /resume restore <id> - restore a saved conversation",
" /resume rename <id> <title> - rename a saved conversation",
" /resume delete <id> - delete a saved conversation (asks first; alias: rm)",
" /name <title> - retitle the current conversation so it is easy to find in /resume (alias: /rename)",
" /transcript - review this conversation: full-screen pager (rich) / printed spine (lean)",
" /roadmap [sub] - #1030 plan tree: new·list·show·use·add · next·bind·done·eval·drive · task <n> commit [sha] · issue <n> <#> · export·import [path]",
" /roadmap tree - render the active roadmap tree (▶ marks the next-ready node / DFS cursor)",
" /persona list - list configured personas",
" /persona show - show the active persona",
" /persona <name> - start fresh with a persona",
" /persona switch <name> - same as /persona <name> (an explicit verb)",
" /persona clear - start fresh with no persona",
" /crew edit [name] - edit a crew's settings (roles, control loop, test, budgets)",
" /setup [host] - configure an inference backend (wizard, or probe a host); \
pasted keys are stored encrypted",
" /dgx status - DGX endpoint health + running models",
" /dgx models - list models installed on the DGX",
" /dgx ps - models currently loaded in VRAM",
" /dgx warm [model] - pre-load a model into VRAM",
" /dgx pull <model> - pull an Ollama/HuggingFace GGUF model onto the node",
" /dgx rm <model> - delete a model from the DGX",
" /dgx route <task> - recommend a formation for a task",
" /dgx doctor - probe every configured endpoint",
" /mode [name] - show/set operating style: chat, dev, admin, plan, diagnose, auto, full-auto",
" /posture [name] - show/set configured posture; permission floor is optional",
" /permissions - prompted decisions + active permission posture",
" /ocap propose - show this session's grant candidates from its flight-recorder capture",
" /ocap propose save - also write them, unsigned, to approve.toml (existing entries kept)",
" /workspace - review and save workspace access for the next process launch",
" /settings workspaces - open the same operator workspace editor",
" /status - session and environment summary (the default view)",
" /status <topic> - config · version · workspace · loadout · byline · memory · models · info",
" /dock [status|disable|enable] - remote-HTMX docking kill-switch (req 7): disable forcibly undocks THIS box from every hub; status lists approved peers",
" /allow - alias for /permissions",
" /nudge <on|off|status> - action-pressure nudges (narration rescue etc.); off = answer-in-peace mode",
" /psyche - effort dial panel: cognition, tenacity, initiative, persona (Esc exits; /psyche obsessive = max)",
" /mcp [on|off|enable|disable|auth] [name] - MCP manager; session mute (on/off) or durable config (enable/disable)",
" /spill [status|N|reset|summary|excerpt|last|open ID] - tool output",
" /prompt - list prompt tokens ($MODEL, $DATE, …) + current prompt",
" /prompt set \"<template>\" - set the prompt for this session; /prompt reset to revert",
" /vi /emacs /nano - switch line-editor key bindings for this session",
" ! <command> - run a host command interactively (e.g. ! pa login) — you, not the agent",
" /cd [dir] - change the session working dir (shown in prompt), confined below the start dir; bare /cd returns to the root — use ! for pwd/ls/rm/…",
" Esc - while the agent is working: interrupt the turn, back to your prompt",
" Up/Down - while a tool is active: scroll its retained output",
" Space/Enter - while a tool is active: toggle ⧉ expand / ▣ collapse",
" /search [query|preview|model|rejects|pin|exclude|status|clear] - #1387 semantic search cockpit",
" /nav - the code navigator; bare lists its verbs",
" /nav def <symbol> - goto definition ([SYMBOL])",
" /nav text <regex> - lexical search ([LEXICAL])",
" /nav uses <symbol> - find references (usage index)",
" /nav tests <symbol> - related tests (heuristic)",
" /nav map [unit] - project map; optional expand unit",
" /nav callers <symbol> - inbound edges (GRAPH regex-floor)",
" /nav callees <symbol> - outbound edges (GRAPH regex-floor)",
" /nav implementations <symbol> - implementors (GRAPH regex-floor)",
" /nav hierarchy <symbol> - type hierarchy (GRAPH regex-floor)",
" /nav type <symbol> - inspect_type (not typechecker-proved)",
" /nav impact <unit> - outbound/reverse deps (+ optional lcov)",
" /nav retrieval [turn N] [human|model|diff] - retrieval ledger",
" /nav compare <what> - compare retrieval: semantic lexical · turn A B · index",
" /nav export <json|markdown> - export retrieval ledger",
" /help [command] - this command list, or one command's detail page",
" /exit /quit exit quit - leave the session",
"",
" Add --help (or -h) to any command — or /help <command> — for its detail page.",
]
}