diff options
| author | t <t@tjp.lol> | 2026-07-06 15:00:37 -0600 |
|---|---|---|
| committer | t <t@tjp.lol> | 2026-07-06 15:00:48 -0600 |
| commit | b350e4dee2412e450b3844061f5c1bc2ec995923 (patch) | |
| tree | c518b3c14af460f31c624f9ba84902713cb8a117 /cli.html | |
| parent | c21a4ebd001ca305d862b5390f090f2ef14163cf (diff) | |
Diffstat (limited to 'cli.html')
| -rw-r--r-- | cli.html | 9 |
1 files changed, 3 insertions, 6 deletions
@@ -20,13 +20,10 @@ <div class="pd-header__right"><a class="pd-ghlink" href="https://code.tjp.lol/pantograph.git/" target="_blank" rel="noreferrer"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" width="1em" height="1em"><path d="M15 22v-4a4.8 4.8 0 0 0-1-3.5c3 0 6-2 6-5.5.08-1.25-.27-2.48-1-3.5.28-1.15.28-2.35 0-3.5 0 0-1 0-3 1.5-2.64-.5-5.36-.5-8 0C6 .5 5 .5 5 .5c-.3 1.15-.3 2.35 0 3.5A5.4 5.4 0 0 0 4 7.5c0 3.5 3 5.5 6 5.5-.39.49-.68 1.05-.85 1.65-.17.6-.22 1.23-.15 1.85v4"/><path d="M9 18c-4.51 2-5-2-7-2"/></svg> Source</a></div> </header> <div class="pd-shell"> -<aside class="pd-sidebar"><div class="pd-sidebar__scroll"><div class="pd-navsec"><p class="pd-navsec__title"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" width="1em" height="1em"><path d="m16.24 7.76-1.804 5.411a2 2 0 0 1-1.265 1.265L7.76 16.24l1.804-5.411a2 2 0 0 1 1.265-1.265z"/><circle cx="12" cy="12" r="10"/></svg>Getting started</p><ul class="pd-navsec__list"><li><a href="index.html#overview" class="pd-navsec__link">Overview</a></li><li><a href="index.html#install" class="pd-navsec__link">Install</a></li><li><a href="index.html#first-run" class="pd-navsec__link">First run</a></li><li><a href="index.html#authenticate" class="pd-navsec__link">Authenticate</a></li></ul></div><div class="pd-navsec pd-navsec--current"><p class="pd-navsec__title"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" width="1em" height="1em"><path d="m4 17 6-6-6-6"/><path d="M12 19h8"/></svg>Command line</p><ul class="pd-navsec__list"><li><a href="cli.html#starting" class="pd-navsec__link pd-navsec__link--active">Starting a session</a></li><li><a href="cli.html#sessions" class="pd-navsec__link"><code>panto sessions</code></a></li><li><a href="cli.html#models" class="pd-navsec__link"><code>panto models</code></a></li><li><a href="cli.html#auth" class="pd-navsec__link"><code>panto auth</code></a></li><li><a href="cli.html#bootstrap" class="pd-navsec__link"><code>panto bootstrap</code></a></li><li><a href="cli.html#lua" class="pd-navsec__link"><code>panto lua</code></a></li><li><a href="cli.html#slash-commands" class="pd-navsec__link">Slash commands</a></li><li><a href="cli.html#environment" class="pd-navsec__link">Environment</a></li></ul></div><div class="pd-navsec"><p class="pd-navsec__title"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" width="1em" height="1em"><path d="M3 5h11"/><path d="M19 5h2"/><path d="M3 12h6"/><path d="M14 12h7"/><path d="M3 19h10"/><path d="M18 19h3"/><circle cx="16" cy="5" r="2"/><circle cx="11" cy="12" r="2"/><circle cx="15" cy="19" r="2"/></svg>Configuration</p><ul class="pd-navsec__list"><li><a href="configuration.html#files" class="pd-navsec__link">Files & layers</a></li><li><a href="configuration.html#providers" class="pd-navsec__link"><code>[providers]</code></a></li><li><a href="configuration.html#auth" class="pd-navsec__link"><code>[auth]</code></a></li><li><a href="configuration.html#defaults" class="pd-navsec__link"><code>[defaults]</code></a></li><li><a href="configuration.html#policies" class="pd-navsec__link">Tools & extensions</a></li><li><a href="configuration.html#compaction" class="pd-navsec__link"><code>[compaction]</code></a></li><li><a href="configuration.html#models" class="pd-navsec__link"><code>models.toml</code></a></li><li><a href="configuration.html#system-prompt" class="pd-navsec__link">System prompt</a></li></ul></div><div class="pd-navsec"><p class="pd-navsec__title"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" width="1em" height="1em"><rect x="2" y="4" width="20" height="16" rx="2"/><path d="M6 8h.001"/><path d="M10 8h.001"/><path d="M14 8h.001"/><path d="M18 8h.001"/><path d="M8 12h.001"/><path d="M12 12h.001"/><path d="M16 12h.001"/><path d="M7 16h10"/></svg>Key bindings</p><ul class="pd-navsec__list"><li><a href="keybindings.html#editing" class="pd-navsec__link">Editing & cursor</a></li><li><a href="keybindings.html#submit" class="pd-navsec__link">Submit & newline</a></li><li><a href="keybindings.html#control" class="pd-navsec__link">Selectors & control</a></li><li><a href="keybindings.html#terminal" class="pd-navsec__link">Terminal protocol</a></li></ul></div><div class="pd-navsec"><p class="pd-navsec__title"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" width="1em" height="1em"><path d="M2.97 12.92A2 2 0 0 0 2 14.63v3.24a2 2 0 0 0 .97 1.71l3 1.8a2 2 0 0 0 2.06 0L12 19v-5.5l-5-3-4.03 2.42Z"/><path d="m7 16.5-4.74-2.85"/><path d="m7 16.5 5-3"/><path d="M7 16.5v5.17"/><path d="M12 13.5V19l3.97 2.38a2 2 0 0 0 2.06 0l3-1.8a2 2 0 0 0 .97-1.71v-3.24a2 2 0 0 0-.97-1.71L17 10.5l-5 3Z"/><path d="m17 16.5-5-3"/><path d="m17 16.5 4.74-2.85"/><path d="M17 16.5v5.17"/><path d="M7.97 4.42A2 2 0 0 0 7 6.13v4.37l5 3 5-3V6.13a2 2 0 0 0-.97-1.71l-3-1.8a2 2 0 0 0-2.06 0l-3 1.8Z"/><path d="M12 8 7.26 5.15"/><path d="m12 8 4.74-2.85"/><path d="M12 13.5V8"/></svg>Lua extensions</p><ul class="pd-navsec__list"><li><a href="lua.html#overview" class="pd-navsec__link">Overview</a></li><li><a href="lua.html#loading" class="pd-navsec__link">Loading extensions</a></li><li><a href="lua.html#tools" class="pd-navsec__link"><code>register_tool</code></a></li><li><a href="lua.html#commands" class="pd-navsec__link"><code>register_command</code></a></li><li><a href="lua.html#events" class="pd-navsec__link">Events: on & emit</a></li><li><a href="lua.html#components" class="pd-navsec__link">Lua components</a></li><li><a href="lua.html#runtime" class="pd-navsec__link">Runtime & luarocks</a></li></ul></div></div></aside> +<aside class="pd-sidebar"><div class="pd-sidebar__scroll"><div class="pd-navsec"><p class="pd-navsec__title"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" width="1em" height="1em"><path d="m16.24 7.76-1.804 5.411a2 2 0 0 1-1.265 1.265L7.76 16.24l1.804-5.411a2 2 0 0 1 1.265-1.265z"/><circle cx="12" cy="12" r="10"/></svg>Getting started</p><ul class="pd-navsec__list"><li><a href="index.html#overview" class="pd-navsec__link">Overview</a></li><li><a href="index.html#install" class="pd-navsec__link">Install</a></li><li><a href="index.html#first-run" class="pd-navsec__link">First run</a></li><li><a href="index.html#authenticate" class="pd-navsec__link">Authenticate</a></li></ul></div><div class="pd-navsec pd-navsec--current"><p class="pd-navsec__title"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" width="1em" height="1em"><path d="m4 17 6-6-6-6"/><path d="M12 19h8"/></svg>Command line</p><ul class="pd-navsec__list"><li><a href="cli.html#starting" class="pd-navsec__link pd-navsec__link--active">Starting a session</a></li><li><a href="cli.html#sessions" class="pd-navsec__link"><code>panto sessions</code></a></li><li><a href="cli.html#models" class="pd-navsec__link"><code>panto models</code></a></li><li><a href="cli.html#auth" class="pd-navsec__link"><code>panto auth</code></a></li><li><a href="cli.html#bootstrap" class="pd-navsec__link"><code>panto bootstrap</code></a></li><li><a href="cli.html#lua" class="pd-navsec__link"><code>panto lua</code></a></li><li><a href="cli.html#slash-commands" class="pd-navsec__link">Slash commands</a></li><li><a href="cli.html#environment" class="pd-navsec__link">Environment</a></li></ul></div><div class="pd-navsec"><p class="pd-navsec__title"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" width="1em" height="1em"><path d="M3 5h11"/><path d="M19 5h2"/><path d="M3 12h6"/><path d="M14 12h7"/><path d="M3 19h10"/><path d="M18 19h3"/><circle cx="16" cy="5" r="2"/><circle cx="11" cy="12" r="2"/><circle cx="15" cy="19" r="2"/></svg>Configuration</p><ul class="pd-navsec__list"><li><a href="configuration.html#files" class="pd-navsec__link">Files & layers</a></li><li><a href="configuration.html#providers" class="pd-navsec__link"><code>[providers]</code></a></li><li><a href="configuration.html#auth" class="pd-navsec__link"><code>[auth]</code></a></li><li><a href="configuration.html#defaults" class="pd-navsec__link"><code>[defaults]</code></a></li><li><a href="configuration.html#policies" class="pd-navsec__link">Extensions policy</a></li><li><a href="configuration.html#compaction" class="pd-navsec__link"><code>[compaction]</code></a></li><li><a href="configuration.html#models" class="pd-navsec__link"><code>models.toml</code></a></li><li><a href="configuration.html#system-prompt" class="pd-navsec__link">System prompt</a></li></ul></div><div class="pd-navsec"><p class="pd-navsec__title"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" width="1em" height="1em"><rect x="2" y="4" width="20" height="16" rx="2"/><path d="M6 8h.001"/><path d="M10 8h.001"/><path d="M14 8h.001"/><path d="M18 8h.001"/><path d="M8 12h.001"/><path d="M12 12h.001"/><path d="M16 12h.001"/><path d="M7 16h10"/></svg>Key bindings</p><ul class="pd-navsec__list"><li><a href="keybindings.html#editing" class="pd-navsec__link">Editing & cursor</a></li><li><a href="keybindings.html#submit" class="pd-navsec__link">Submit & newline</a></li><li><a href="keybindings.html#control" class="pd-navsec__link">Selectors & control</a></li><li><a href="keybindings.html#terminal" class="pd-navsec__link">Terminal protocol</a></li></ul></div><div class="pd-navsec"><p class="pd-navsec__title"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" width="1em" height="1em"><path d="M2.97 12.92A2 2 0 0 0 2 14.63v3.24a2 2 0 0 0 .97 1.71l3 1.8a2 2 0 0 0 2.06 0L12 19v-5.5l-5-3-4.03 2.42Z"/><path d="m7 16.5-4.74-2.85"/><path d="m7 16.5 5-3"/><path d="M7 16.5v5.17"/><path d="M12 13.5V19l3.97 2.38a2 2 0 0 0 2.06 0l3-1.8a2 2 0 0 0 .97-1.71v-3.24a2 2 0 0 0-.97-1.71L17 10.5l-5 3Z"/><path d="m17 16.5-5-3"/><path d="m17 16.5 4.74-2.85"/><path d="M17 16.5v5.17"/><path d="M7.97 4.42A2 2 0 0 0 7 6.13v4.37l5 3 5-3V6.13a2 2 0 0 0-.97-1.71l-3-1.8a2 2 0 0 0-2.06 0l-3 1.8Z"/><path d="M12 8 7.26 5.15"/><path d="m12 8 4.74-2.85"/><path d="M12 13.5V8"/></svg>Lua extensions</p><ul class="pd-navsec__list"><li><a href="lua.html#overview" class="pd-navsec__link">Overview</a></li><li><a href="lua.html#loading" class="pd-navsec__link">Loading extensions</a></li><li><a href="lua.html#tools" class="pd-navsec__link"><code>register_tool</code></a></li><li><a href="lua.html#commands" class="pd-navsec__link"><code>register_command</code></a></li><li><a href="lua.html#events" class="pd-navsec__link">Events: on & emit</a></li><li><a href="lua.html#components" class="pd-navsec__link">Lua components</a></li><li><a href="lua.html#runtime" class="pd-navsec__link">Runtime & luarocks</a></li></ul></div></div></aside> <div class="pd-scrim"></div> -<main class="pd-main"><article class="pd-doc" data-screen-label="Command line"><p class="panto-eyebrow pd-eyebrow">Reference</p><h1 class="pd-doc__h1">Command line</h1><p class="pd-lead"><code>panto</code> dispatches on its first argument. A handful of subcommands (<code>lua</code>, <code>bootstrap</code>, <code>sessions</code>, <code>models</code>, <code>auth</code>, <code>help</code>) short out before the agent loop; anything else — or nothing — starts the agent in the current directory.</p><div class="pd-table-wrap"><table class="pd-table"><thead><tr><th>Command</th><th>Does</th></tr></thead><tbody><tr><td class="mono">panto</td><td>Start a new conversation in the current directory.</td></tr><tr><td class="mono">panto --resume [<id>]</td><td>Resume the most recent session, or one by id prefix.</td></tr><tr><td class="mono">panto sessions</td><td>List saved sessions for this directory.</td></tr><tr><td class="mono">panto models sync</td><td>Fetch models.dev and rebuild the base models.toml.</td></tr><tr><td class="mono">panto auth …</td><td>Inspect and manage auth sessions (status / login / logout).</td></tr><tr><td class="mono">panto bootstrap [--force]</td><td>Run the luarocks bootstrap and exit.</td></tr><tr><td class="mono">panto lua [args…]</td><td>Drop into the embedded Lua interpreter.</td></tr><tr><td class="mono">panto help</td><td>Print the usage summary (also --help, -h).</td></tr></tbody></table></div><h2 id="starting" class="pd-h2">Starting a session</h2><div class="pd-cmd"><span class="pd-cmd__sig">panto</span><span class="pd-cmd__note">Start a new conversation in the current directory.</span></div><div class="pd-cmd"><span class="pd-cmd__sig">panto --resume <span class="opt">[<id>]</span></span><span class="pd-cmd__note">Resume a previous session.</span></div><p class="pd-body">With no flag, <code>panto</code> opens a fresh session. <code>--resume</code> on its own reattaches the most recent session in this directory; <code>--resume <id></code> resumes the session whose id begins with <code><id></code>. Unknown arguments are tolerated (and ignored with a warning), so passing flags panto doesn’t recognise won’t stop it from starting.</p><div class="pg-callout pg-callout--warn"><span class="pg-callout__icon"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="m21.73 18-8-14a2 2 0 0 0-3.48 0l-8 14A2 2 0 0 0 4 21h16a2 2 0 0 0 1.73-3Z"/><path d="M12 9v4"/><path d="M12 17h.01"/></svg></span><div class="pg-callout__body"><p class="pg-callout__title">Needs a terminal</p>The UI runs in raw mode and requires an interactive tty on stdin/stdout. Piping input or redirecting output will refuse with an error rather than half-start.</div></div><h2 id="sessions" class="pd-h2">panto sessions</h2><div class="pd-cmd"><span class="pd-cmd__sig">panto sessions</span><span class="pd-cmd__note">List saved sessions for the current directory.</span></div><p class="pd-body">Sessions are grouped per working directory. Each line is the short id (the first eight hex characters of the session’s UUIDv7), the creation time trimmed to the minute, and the message count:</p><div class="pg-term"><div class="pg-term__bar"><span class="pg-term__dot" style="background:var(--red)"></span><span class="pg-term__dot" style="background:var(--brass)"></span><span class="pg-term__dot" style="background:var(--green)"></span><span class="pg-term__title">panto · sessions</span></div><div class="pg-term__body"><div class="pg-term__line pg-term__line--cmd"><span class="pg-term__prompt">$ </span>panto sessions</div><div class="pg-term__line pg-term__line--out">7f3a9c2b 2026-06-12 09:41 24 messages</div><div class="pg-term__line pg-term__line--out">b81e0d44 2026-06-11 17:03 6 messages</div><div class="pg-term__line pg-term__line--out">a0c7f190 2026-06-10 22:18 41 messages</div></div></div><p class="pd-body">When a directory has no sessions yet, panto prints <code>no sessions for <cwd></code>. Use any unambiguous id prefix from this list with <code>panto --resume</code>.</p><h2 id="models" class="pd-h2">panto models</h2><div class="pd-cmd"><span class="pd-cmd__sig">panto models sync</span><span class="pd-cmd__note">Fetch models.dev and rebuild the base <code>models.toml</code>.</span></div><p class="pd-body"><code>sync</code> is the only action. It fetches the <a href="https://models.dev" target="_blank" rel="noreferrer">models.dev</a> catalog, walks the providers in your merged <a href="configuration.html#providers"><code>[providers]</code></a> config, and for each one cross-checks the catalog against the models that provider actually serves — then writes the result to the <strong>base-layer</strong> <code>models.toml</code> (<code>$PANTO_HOME/models.toml</code>, else <code>$XDG_DATA_HOME/panto/models.toml</code>). Aliases, wire names, context windows, token caps, and pricing come along for the ride. A provider maps onto a catalog entry via <a href="configuration.html#providers"><code>model_catalog_name</code></a> (falling back to the provider name); providers with no matching entry — or no usable synced models — are skipped.</p><div class="pg-term"><div class="pg-term__bar"><span class="pg-term__dot" style="background:var(--red)"></span><span class="pg-term__dot" style="background:var(--brass)"></span><span class="pg-term__dot" style="background:var(--green)"></span><span class="pg-term__title">panto · models sync</span></div><div class="pg-term__body"><div class="pg-term__line pg-term__line--cmd"><span class="pg-term__prompt">$ </span>panto models sync</div><div class="pg-term__line pg-term__line--out">synced 42 model(s) across 3 provider(s) to ~/.local/share/panto/models.toml</div></div></div><p class="pd-body">Because it writes the base layer, your own user/project <code>models.toml</code> entries always layer on top and win. Re-run it whenever you want to refresh the catalog after providers ship new models.</p><h2 id="auth" class="pd-h2">panto auth</h2><p class="pd-body">Manage the credentials behind your providers. With no action, <code>panto auth</code> defaults to <code>status</code>.</p><div class="pd-opts"><div class="pd-opt"><div class="pd-opt__key"><span class="pd-opt__name">panto auth status</span></div><div class="pd-opt__desc">List every configured auth session and its state. <code>api_key</code> sessions read <em>resolved</em> or <em>unresolved (key/env missing)</em>; <code>oauth_device</code> sessions show whether you’re logged in and roughly when the access token expires.</div></div><div class="pd-opt"><div class="pd-opt__key"><span class="pd-opt__name">panto auth login <name></span></div><div class="pd-opt__desc">Run the OAuth device flow for the named session. panto prints a verification URL and a user code, then stores (and, if configured, exchanges) the token. An <code>api_key</code> session has nothing to log in to.</div></div><div class="pd-opt"><div class="pd-opt__key"><span class="pd-opt__name">panto auth logout <name></span></div><div class="pd-opt__desc">Forget the stored token set for the named session.</div></div></div><div class="pg-term"><div class="pg-term__bar"><span class="pg-term__dot" style="background:var(--red)"></span><span class="pg-term__dot" style="background:var(--brass)"></span><span class="pg-term__dot" style="background:var(--green)"></span><span class="pg-term__title">panto · auth status</span></div><div class="pg-term__body"><div class="pg-term__line pg-term__line--cmd"><span class="pg-term__prompt">$ </span>panto auth status</div><div class="pg-term__line pg-term__line--ok">anthropic_api api_key resolved</div><div class="pg-term__line pg-term__line--err">openai_api api_key unresolved (key/env missing)</div><div class="pg-term__line pg-term__line--out">github_copilot oauth_device logged in (access expires in ~58m)</div></div></div><p class="pd-body">Auth sessions themselves are declared in config under <a href="configuration.html#auth"><code>[auth.<name>]</code></a>. The provider that uses a session names it with <code>auth = "<name>"</code>.</p><h2 id="bootstrap" class="pd-h2">panto bootstrap</h2><div class="pd-cmd"><span class="pd-cmd__sig">panto bootstrap <span class="opt">[--force]</span></span><span class="pd-cmd__note">Run the luarocks bootstrap, then exit.</span></div><p class="pd-body">The bootstrap pipeline prepares the embedded Lua runtime: it stages headers and the base agent tree, materialises the default config, and installs panto’s pinned <a href="lua.html#runtime">batteries</a> under <code>$PANTO_HOME</code>. The agent runs the very same pipeline on startup, so you rarely need this by hand — it’s here for first-run setup on a clean machine and for scripted / CI installs. Repeat runs no-op quickly.</p><div class="pd-opts"><div class="pd-opt"><div class="pd-opt__key"><span class="pd-opt__name">--force</span></div><div class="pd-opt__desc">Wipe the per-Lua-version rocks tree (<code>$PANTO_HOME/rocks/lua-X.Y.Z/</code>) before reinstalling everything from scratch.</div></div></div><h2 id="lua" class="pd-h2">panto lua</h2><div class="pd-cmd"><span class="pd-cmd__sig">panto lua <span class="opt">[args…]</span></span><span class="pd-cmd__note">Drop into the embedded Lua interpreter.</span></div><p class="pd-body">This is panto’s bundled Lua standalone (the same <code>lua.c</code> the agent embeds), with the luarocks runtime already bootstrapped — so <code>require("luarocks.*")</code> and any rocks installed under <code>$PANTO_HOME</code> resolve exactly as they do inside a session. Arguments after <code>lua</code> are passed straight through to the interpreter. Use it to experiment, or to drive luarocks to install extra rocks for your extensions:</p><div class="pg-code"><div class="pg-code__bar"><span class="pg-code__name">shell</span><span class="pg-code__lang">bash</span><button class="pg-code__copy" type="button" aria-label="Copy code"><svg class="pg-code__copyglyph" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><rect x="9" y="9" width="11" height="11" rx="2"/><path d="M5 15V5a2 2 0 0 1 2-2h10"/></svg><svg class="pg-code__check" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5" stroke-linecap="round" stroke-linejoin="round"><path d="m20 6-11 11-5-5"/></svg><span class="pg-code__label">Copy</span></button></div><div class="pg-code__scroll"><pre><code># run a script with panto’s Lua + rocks tree -panto lua my-script.lua - -# install an extra rock into panto’s tree via the embedded luarocks -panto lua -e 'arg[0]="luarocks"; require("luarocks.cmd").run_command("install","lpeg")'</code></pre></div></div><h2 id="slash-commands" class="pd-h2">Slash commands</h2><p class="pd-body">Inside a session, any line that begins with <code>/</code> is a <strong>slash command</strong> rather than a prompt — it is handled locally and never sent to the model. The first word (after the slash) is the command name; the trimmed remainder is passed as its arguments.</p><div class="pd-opts"><div class="pd-opt"><div class="pd-opt__key"><span class="pd-opt__name">/compact</span><span class="pg-badge pg-badge--neutral">builtin</span></div><div class="pd-opt__desc">Compact the conversation now — summarise older turns to reclaim context while keeping a verbatim recent tail. (Compaction also runs automatically; see <a href="configuration.html#compaction"><code>[compaction]</code></a>.)</div></div></div><p class="pd-body"><code>/compact</code> is the only built-in. Every other slash command comes from a Lua extension via <code>panto.ext.register_command</code> — see <a href="lua.html#commands">Lua extensions → register_command</a>. An unrecognised command reports an error instead of reaching the model.</p><h2 id="environment" class="pd-h2">Environment</h2><p class="pd-body">panto reads a few environment variables — for credentials and for locating its files. Configuration values can also pull from the environment via <code>${env:VAR}</code> substitution (see <a href="configuration.html#auth">Configuration</a>).</p><div class="pd-table-wrap"><table class="pd-table"><thead><tr><th>Variable</th><th>Effect</th></tr></thead><tbody><tr><td class="mono">ANTHROPIC_API_KEY</td><td>Consumed by the default Anthropic provider.</td></tr><tr><td class="mono">OPENAI_API_KEY</td><td>Consumed by the default OpenAI provider.</td></tr><tr><td class="mono">PANTO_HOME</td><td>Override the runtime / rocks-tree location. Also where the base config.toml and agent tree are staged.</td></tr><tr><td class="mono">PANTO_SESSION_DIR</td><td>Override the base sessions directory. Defaults to $XDG_DATA_HOME/panto/sessions (or ~/.local/share/panto/sessions).</td></tr><tr><td class="mono">XDG_CONFIG_HOME</td><td>Locates the user config: $XDG_CONFIG_HOME/panto/ (else ~/.config/panto/).</td></tr><tr><td class="mono">XDG_DATA_HOME</td><td>Locates the base config + data: $XDG_DATA_HOME/panto/ (else ~/.local/share/panto/).</td></tr></tbody></table></div><nav class="pd-prevnext"><a class="pd-pn pd-pn--prev" href="index.html"><span class="pd-pn__dir">← Previous</span><span class="pd-pn__title">Getting started</span></a><a class="pd-pn pd-pn--next" href="configuration.html"><span class="pd-pn__dir">Next →</span><span class="pd-pn__title">Configuration</span></a></nav></article></main> +<main class="pd-main"><article class="pd-doc" data-screen-label="Command line"><p class="panto-eyebrow pd-eyebrow">Reference</p><h1 class="pd-doc__h1">Command line</h1><p class="pd-lead"><code>panto</code> dispatches on its first argument. Some names are true subcommands (<code>sessions</code>, <code>models</code>, <code>auth</code>, <code>bootstrap</code>, <code>update</code>, <code>lua</code>, <code>help</code>); the flag forms start the agent itself, either interactively or in one-shot print mode.</p><div class="pd-table-wrap"><table class="pd-table"><thead><tr><th>Command</th><th>Does</th></tr></thead><tbody><tr><td class="mono">panto</td><td>Start a new interactive conversation in the current directory.</td></tr><tr><td class="mono">panto --resume [<id>]</td><td>Resume the most recent session, or a specific session by id prefix.</td></tr><tr><td class="mono">panto -c</td><td>Alias for bare <code>--resume</code>.</td></tr><tr><td class="mono">panto -p [prompt]</td><td>Run one non-interactive turn, print assistant text, exit 0/1.</td></tr><tr><td class="mono">panto sessions</td><td>List saved sessions for this directory.</td></tr><tr><td class="mono">panto models sync</td><td>Fetch models.dev and rebuild the base <code>models.toml</code>.</td></tr><tr><td class="mono">panto auth …</td><td>Show auth status, log in, or log out.</td></tr><tr><td class="mono">panto bootstrap [--force]</td><td>Prepare the bundled Lua / luarocks runtime and exit.</td></tr><tr><td class="mono">panto update</td><td>Install or refresh every rock listed in <code>extensions.rocks</code>.</td></tr><tr><td class="mono">panto lua [args…]</td><td>Run the embedded Lua interpreter.</td></tr><tr><td class="mono">panto --version</td><td>Print the panto version.</td></tr></tbody></table></div><h2 id="starting" class="pd-h2">Starting a session</h2><div class="pd-cmd"><span class="pd-cmd__sig">panto</span><span class="pd-cmd__note">Start a fresh interactive conversation.</span></div><div class="pd-cmd"><span class="pd-cmd__sig">panto --resume <span class="opt">[<id>]</span></span><span class="pd-cmd__note">Resume the latest or a specific saved session.</span></div><div class="pd-cmd"><span class="pd-cmd__sig">panto -p, --print <span class="opt">[<prompt>]</span></span><span class="pd-cmd__note">Run one turn without the TUI.</span></div><p class="pd-body">Interactive mode requires a tty on stdin and stdout. Print mode does not: the prompt can come from the flag argument or from piped stdin, and the command prints only the assistant text before exiting.</p><div class="pd-opts"><div class="pd-opt"><div class="pd-opt__key"><span class="pd-opt__name">-c, --continue</span></div><div class="pd-opt__desc">Alias for bare <code>--resume</code>.</div></div><div class="pd-opt"><div class="pd-opt__key"><span class="pd-opt__name">-m, --model <provider:alias></span></div><div class="pd-opt__desc">Override the model for this run. A bare alias also works when it is unique across providers.</div></div><div class="pd-opt"><div class="pd-opt__key"><span class="pd-opt__name">--effort <level></span></div><div class="pd-opt__desc">Override the reasoning level for this run. This beats both <code>models.toml</code> knobs and <code>[defaults] reasoning</code>.</div></div><div class="pd-opt"><div class="pd-opt__key"><span class="pd-opt__name">--no-extensions</span></div><div class="pd-opt__desc">Skip the Lua runtime entirely. The core still starts, but because the shipped tools are extensions the agent runs with no tools.</div></div></div><div class="pg-callout pg-callout--warn"><span class="pg-callout__icon"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="m21.73 18-8-14a2 2 0 0 0-3.48 0l-8 14A2 2 0 0 0 4 21h16a2 2 0 0 0 1.73-3Z"/><path d="M12 9v4"/><path d="M12 17h.01"/></svg></span><div class="pg-callout__body"><p class="pg-callout__title">Unknown arguments are errors now</p>Agent-mode flag parsing is strict. An unrecognized argument prints an error and exits instead of being ignored.</div></div><h2 id="sessions" class="pd-h2">panto sessions</h2><div class="pd-cmd"><span class="pd-cmd__sig">panto sessions</span><span class="pd-cmd__note">List sessions for the current directory.</span></div><p class="pd-body">Sessions are stored per working directory. The listing is newest-modified first and prints the shortest unambiguous id prefix, the modified timestamp, message count, model, and last user message:</p><div class="pg-term"><div class="pg-term__bar"><span class="pg-term__dot" style="background:var(--red)"></span><span class="pg-term__dot" style="background:var(--brass)"></span><span class="pg-term__dot" style="background:var(--green)"></span><span class="pg-term__title">panto · sessions</span></div><div class="pg-term__body"><div class="pg-term__line pg-term__line--cmd"><span class="pg-term__prompt">$ </span>panto sessions</div><div class="pg-term__line pg-term__line--out">ID MODIFIED MSGS MODEL LAST MESSAGE</div><div class="pg-term__line pg-term__line--out">0197c2a4 2026-07-01 14:32 18 sonnet add json mode to stats</div><div class="pg-term__line pg-term__line--out">0197bfe1 2026-06-30 09:11 6 gpt-5 clean up the parser errors</div><div class="pg-term__line pg-term__line--out">~/.local/share/panto/sessions/--Users-travis-Code-ledger--</div></div></div><p class="pd-body">If there are no sessions yet, panto prints <code>no sessions for <cwd></code> and then the directory it would use.</p><h2 id="models" class="pd-h2">panto models</h2><div class="pd-cmd"><span class="pd-cmd__sig">panto models sync</span><span class="pd-cmd__note">Fetch models.dev and rebuild the base <code>models.toml</code>.</span></div><p class="pd-body">The sync command looks at the providers that resolved from your layered config, maps each one to a models.dev catalog entry, optionally intersects that with the provider's own live <code>/models</code> listing, and writes the result to the base-layer <code>models.toml</code> at <code>$XDG_DATA_HOME/panto/models.toml</code> (or <code>~/.local/share/panto/models.toml</code>).</p><div class="pg-term"><div class="pg-term__bar"><span class="pg-term__dot" style="background:var(--red)"></span><span class="pg-term__dot" style="background:var(--brass)"></span><span class="pg-term__dot" style="background:var(--green)"></span><span class="pg-term__title">panto · models sync</span></div><div class="pg-term__body"><div class="pg-term__line pg-term__line--cmd"><span class="pg-term__prompt">$ </span>panto models sync</div><div class="pg-term__line pg-term__line--out">synced 42 model(s) across 3 provider(s) to ~/.local/share/panto/models.toml</div></div></div><p class="pd-body">Your user and project <code>models.toml</code> layers still sit on top and win.</p><h2 id="auth" class="pd-h2">panto auth</h2><p class="pd-body">With no action, <code>panto auth</code> defaults to <code>status</code>.</p><div class="pd-opts"><div class="pd-opt"><div class="pd-opt__key"><span class="pd-opt__name">panto auth status</span></div><div class="pd-opt__desc">Show every configured auth session. API-key sessions report <em>resolved</em> or <em>unresolved (key/env missing)</em>; OAuth sessions report whether they are logged in and when the current access token expires.</div></div><div class="pd-opt"><div class="pd-opt__key"><span class="pd-opt__name">panto auth login <name></span></div><div class="pd-opt__desc">Run the OAuth device flow for the named session and persist the resulting token set.</div></div><div class="pd-opt"><div class="pd-opt__key"><span class="pd-opt__name">panto auth logout <name></span></div><div class="pd-opt__desc">Delete the stored token set for the named session.</div></div></div><h2 id="bootstrap" class="pd-h2">panto bootstrap</h2><div class="pd-cmd"><span class="pd-cmd__sig">panto bootstrap <span class="opt">[--force]</span></span><span class="pd-cmd__note">Run the runtime bootstrap pipeline, then exit.</span></div><p class="pd-body">Bootstrap stages the base agent tree, creates the generated base config as needed, and prepares the versioned luarocks tree under the data home. The normal agent startup path runs the same bootstrap automatically.</p><div class="pd-cmd"><span class="pd-cmd__sig">panto update</span><span class="pd-cmd__note">Install or refresh the rocks listed in <code>extensions.rocks</code>.</span></div><p class="pd-body"><code>panto update</code> is the explicit “go hit luarocks again” command. Startup only installs missing rocks; changing a version pin or forcing a re-resolve is what <code>update</code> is for.</p><h2 id="lua" class="pd-h2">panto lua</h2><div class="pd-cmd"><span class="pd-cmd__sig">panto lua <span class="opt">[args…]</span></span><span class="pd-cmd__note">Run the embedded Lua interpreter with panto's runtime wired in.</span></div><p class="pd-body">This is the same embedded Lua build panto uses internally, with package paths and luarocks configured the same way a session sees them. It is handy both for experiments and for driving luarocks manually:</p><div class="pg-code"><div class="pg-code__bar"><span class="pg-code__name">shell</span><span class="pg-code__lang">bash</span><button class="pg-code__copy" type="button" aria-label="Copy code"><svg class="pg-code__copyglyph" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><rect x="9" y="9" width="11" height="11" rx="2"/><path d="M5 15V5a2 2 0 0 1 2-2h10"/></svg><svg class="pg-code__check" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5" stroke-linecap="round" stroke-linejoin="round"><path d="m20 6-11 11-5-5"/></svg><span class="pg-code__label">Copy</span></button></div><div class="pg-code__scroll"><pre><code>panto lua my-script.lua +panto lua -e 'arg[0]="luarocks"; require("luarocks.cmd").run_command("install","lpeg")'</code></pre></div></div><h2 id="slash-commands" class="pd-h2">Slash commands</h2><p class="pd-body">Lines beginning with <code>/</code> are handled locally inside the TUI and never sent to the model.</p><div class="pd-opts"><div class="pd-opt"><div class="pd-opt__key"><span class="pd-opt__name">Built in</span></div><div class="pd-opt__desc"><code>/help</code>, <code>/quit</code>, <code>/model</code>, <code>/reasoning</code>, <code>/new</code>, <code>/resume</code>, <code>/status</code>, and <code>/compact</code>.</div></div><div class="pd-opt"><div class="pd-opt__key"><span class="pd-opt__name">Extension-defined</span></div><div class="pd-opt__desc">Lua extensions can register more slash commands with <code>panto.ext.register_command</code>.</div></div></div><h2 id="environment" class="pd-h2">Environment</h2><div class="pd-table-wrap"><table class="pd-table"><thead><tr><th>Variable</th><th>Effect</th></tr></thead><tbody><tr><td class="mono">ANTHROPIC_API_KEY</td><td>Consumed by the default Anthropic provider.</td></tr><tr><td class="mono">OPENAI_API_KEY</td><td>Consumed by the default OpenAI provider.</td></tr><tr><td class="mono">PANTO_DEBUG</td><td>When non-zero, route <code>std.log</code> output to <code><data home>/debug/<session>.log</code> instead of the terminal.</td></tr><tr><td class="mono">PANTO_SESSION_DIR</td><td>Override the base sessions directory. panto still appends one encoded subdirectory per working directory.</td></tr><tr><td class="mono">XDG_CONFIG_HOME</td><td>Locates the user config and user extensions directories.</td></tr><tr><td class="mono">XDG_DATA_HOME</td><td>Locates the data home: base config, base models, sessions, auth cache, agent tree, and rocks.</td></tr></tbody></table></div><nav class="pd-prevnext"><a class="pd-pn pd-pn--prev" href="index.html"><span class="pd-pn__dir">← Previous</span><span class="pd-pn__title">Getting started</span></a><a class="pd-pn pd-pn--next" href="configuration.html"><span class="pd-pn__dir">Next →</span><span class="pd-pn__title">Configuration</span></a></nav></article></main> <aside class="pd-toc"><p class="pd-toc__title">On this page</p><ul class="pd-toc__list"><li><a href="#starting" class="pd-toc__link pd-toc__link--active">Starting a session</a></li><li><a href="#sessions" class="pd-toc__link">panto sessions</a></li><li><a href="#models" class="pd-toc__link">panto models</a></li><li><a href="#auth" class="pd-toc__link">panto auth</a></li><li><a href="#bootstrap" class="pd-toc__link">panto bootstrap</a></li><li><a href="#lua" class="pd-toc__link">panto lua</a></li><li><a href="#slash-commands" class="pd-toc__link">Slash commands</a></li><li><a href="#environment" class="pd-toc__link">Environment</a></li></ul></aside> </div> </div> |
