summaryrefslogtreecommitdiff
path: root/docs
diff options
context:
space:
mode:
Diffstat (limited to 'docs')
-rw-r--r--docs/cli-tui-gaps.md321
1 files changed, 0 insertions, 321 deletions
diff --git a/docs/cli-tui-gaps.md b/docs/cli-tui-gaps.md
deleted file mode 100644
index 6791941..0000000
--- a/docs/cli-tui-gaps.md
+++ /dev/null
@@ -1,321 +0,0 @@
-# panto CLI/TUI: gaps and proposals
-
-Survey of the current CLI/TUI surface (2026-07-03) and what to do about it.
-
-Framing first, because it decides everything below: panto's job is not to
-do everything, it's to make everything possible. It is a minimal
-interactive shell over libpanto plus a powerful Lua extension API, in the
-spirit of pi (https://pi.dev) — users build their own ideal agent on top,
-and that agent need not be a coding agent at all (the shipped coding tools
-are themselves deny-able Lua extensions). So every "gap" lands in one of
-three buckets:
-
-- **Core** — makes the shell itself usable and scriptable. Baseline,
- not coding-specific. Ships in Zig (and should generally also be
- reachable from Lua).
-- **Extension API** — core shouldn't do the thing; core should make the
- thing *buildable*. New API surfaces are co-designed with Travis before
- building.
-- **Not ours** — coding-agent conveniences. Belongs in `../panto-agent`
- or other out-of-tree extensions; listed only so we stop re-proposing it.
-
-Priorities within a bucket: **P0** = bug or table-stakes, **P1** = next
-tranche, **P2** = deliberate deferral.
-
----
-
-## 1. Bugs (core, P0, all small)
-
-Fix regardless of anything else below.
-
-1. **Duplicate short session IDs.** `panto sessions` shows `id[0..8]`
- (`src/subcommand.zig:374`), but IDs are UUIDv7 and the first 8 hex chars
- are the top 32 bits of the millisecond timestamp — no randomness until
- char 15. Two sessions created within ~65 s in one project display
- identical short IDs. Fix: shortest-unambiguous prefix per listing
- (extend past 8 while any two collide).
-
-2. **`AmbiguousSessionId` exits silently.** `--resume <prefix>` matching
- two files propagates the error to a bare `exit(1)` at
- `src/main.zig:282-283` — no message. Only `SessionNotFound` gets a tidy
- error (`main.zig:724-727`). Fix: print the candidates and exit.
-
-3. **`--resume` (bare) and `panto sessions` disagree on "most recent".**
- `findMostRecentSession` takes the lexicographic filename max =
- newest-*created* (`file_system_jsonl_store.zig:981-1010`); the listing
- sorts by newest-*modified*. Fix: make `latest()` use `modified`.
-
-4. **`trimCreated` doesn't trim.** Promises `YYYY-MM-DD HH:MM`, returns
- `iso[0..16]` with the `T` intact (`src/subcommand.zig:386-394`).
-
-5. **`--resume` flag peeking can't rewind.** A `-`-leading token after
- `--resume` is warned-and-dropped instead of parsed as its own flag
- (`main.zig:676-688`). Becomes real once a second agent flag exists (§2).
-
-6. **Base config template comment says `[tools]`** where the code reads
- `[extensions]` (`luarocks_runtime.zig:460` vs `config_file.zig:201`).
-
----
-
-## 2. Core: command-line flags
-
-Today the entire agent-mode flag surface is `--resume [<id>]`
-(`main.zig:658-697`). For an "interactive agent SDK" the bar is: launch it,
-point it at a model, script it, resume it. That's about five flags.
-
-### P0
-
-- **`-p, --print <prompt>` — one-shot non-interactive mode.** One agent
- turn (tools and all), text to stdout, meaningful exit code; prompt from
- the arg or stdin when piped. panto currently *requires* a tty
- (`main.zig:494-503`) and cannot be scripted at all — the biggest gap in
- the product. Composes with `--resume` for headless continuation. Pairs
- with libpanto's "one-shot simple API" todo (`docs/todos.md:12`).
-- **`-m, --model <provider:alias>`.** Already anticipated:
- `selectModel(model_override)` exists and `main.zig:227` passes `null`.
- Wire it through; accept a bare alias when unambiguous.
-- **`--version`.** Embed at build time; print `panto <ver>`.
-- **Unknown flags error, don't warn-and-continue** (`main.zig:686,693`).
- A typo silently launching a TUI is how scripts hang.
-
-### P1
-
-- **`-c, --continue`** — ergonomic alias for bare `--resume`.
-- **`--no-extensions`** — skip the Lua runtime: fast `-p` in CI, and the
- escape hatch when an extension breaks startup. Given that even the
- shipped tools are extensions, define semantics as "built-ins only,
- policy-denied everything else".
-- **`--effort <level>`** — same pattern as `--model`.
-
-### Skip
-
-- `--config <path>` — the 4-layer TOML merge already covers it.
-- `--output-format json` for `-p` — wait for a real consumer.
-- `--cwd` — `cd && panto`.
-
-### `panto sessions` output (P0)
-
-Currently `<8-char-id> <created-with-T> <N> messages`, while the useful
-fields (`last_user_message`, `model`, `modified`) are computed by
-`buildFileInfo` and discarded. Proposal:
-
-```
-ID MODIFIED MSGS MODEL LAST MESSAGE
-0197c2a4 2026-07-01 14:32 18 anthropic:sonnet fix the segfault in tui_engine when…
-0197b1f0 2026-06-30 09:15 4 openai:gpt add a --version flag
-```
-
-Sort and *show* by modified; shortest-unique IDs (§1.1); truncate last
-message to width; plain aligned columns, no box-drawing. Print the sessions
-dir path as the last line so the storage is discoverable. Keep resume as a
-flag (it composes with `-p`/`-m`; `sessions` stays list-only) — the real
-contract is that listed IDs paste into `--resume` without ambiguity.
-
----
-
-## 3. Core: slash commands
-
-Current inventory: **`/compact`** (`src/compaction.zig:13`). The framework
-(registry, Lua `panto.ext.register_command`, capture-to-transcript, error
-rendering) is complete — and mostly-empty is correct for panto. But a shell
-whose product *is* its extension points still has to be self-describing and
-steerable. These are baseline and coding-agnostic, so they're core Zig;
-each should also be achievable from Lua via `panto.ext.agent` (the
-sufficiency audit in §7).
-
-### P0
-
-- **`/help`** — registered commands (`Registry.list()` exists solely for
- this and tab completion) plus the key bindings. Today nothing in the
- product reveals that `/compact` or Ctrl+G exist. For an
- extensions-first tool, discoverability of what's currently loaded is not
- a convenience — it's how users see their own extensions.
-- **`/quit`** — trivial; the only exit today is Ctrl+C/D.
-- **`/model [provider:alias]`**, **`/reasoning [level]`** — no arg opens
- the existing selector; with arg sets directly. Makes the selectors
- discoverable and terminal-agnostic (see the Ctrl+M problem, §4).
-- **`/new`** — fresh session in place; today you quit and relaunch.
-
-### P1
-
-- **`/resume [<id>]`** — in-TUI session switcher; no arg opens a fuzzy
- `Selector` over sessions (short-id + modified + last message rows).
-- **`/status`** — provider, model, reasoning, session id, message count,
- context used vs window. All already in `command.Context` or computable.
-
-### Completion and typeahead (P1)
-
-The fuzzy machinery already exists and is good — the model selector does
-case-insensitive subsequence filtering with Ctrl+N/P + Enter. Extend the
-same feel to the input box (`docs/todos.md:22` tracks this):
-
-- **Leading-`/` typeahead**: when the buffer starts with `/`, surface a
- live-filtered command list (from `Registry.list()`, which exists for
- exactly this) in the same selector idiom; Tab or Enter-on-selection
- completes. Registered Lua commands appear automatically — this is
- another discoverability channel for extensions, like `/help`.
-- **Tab completes file/dir names from cwd** anywhere in the buffer:
- complete the token under the cursor against the filesystem, common-prefix
- first, selector on ambiguity. Coding-agnostic (paths are universal).
-- Later: **per-command argument completion** declared by the command
- (e.g. `/model` completing `provider:alias`, Lua commands supplying a
- completion function). That's an extension API surface — §7.
-
----
-
-## 4. Core: key bindings
-
-Input box editing is solid (word motion, Ctrl+A/E/U/W, Shift+Enter
-multiline, bracketed paste). Gaps:
-
-### P0
-
-- **Input history (Up/Down recall).** Decoded and dropped today
- (`tui_components.zig:1207`). Up at buffer-top / Down at buffer-bottom
- navigate history so multiline arrow-editing still works; in-memory
- per-run is enough to start.
-- **Idle Escape clears the input buffer.** Makes Escape uniformly "cancel
- the thing in progress" (it already interrupts turns and closes
- selectors).
-- **Fix Ctrl+M.** Ctrl+M *is* carriage return; the model-selector binding
- only exists on Kitty-protocol terminals and silently vanishes on plain
- xterm/tmux. With `/model` (§3) as the discoverable path, move the chord
- to a legacy-safe key (Ctrl+T is free) or accept slash-only on legacy
- terminals — either way `/help` documents reality.
-
-### P1
-
-- **Ctrl+L** — clear/redraw (engine already has full-redraw machinery).
-- **Buffer typed input during a turn** and restore it to the input box
- after; full mid-turn steering waits on libpanto queueing
- (`docs/todos.md:15`).
-- **Dedup the chord dispatch**: Ctrl+O/M/R are re-implemented in both
- `handleBytes` (`tui_app.zig:1801-1842`) and `pumpTurnKeys`
- (`tui_app.zig:2286-2304`). One `appChord(key) -> ?Action` both call.
- This is also the seam the keybinding extension API (§7) slots into.
-
-### Deliberate non-features
-
-- Kill-ring/yank, undo — already deferred in-code ("plan P2"); agreed.
-- In-app transcript scrolling — engine delegates to native terminal
- scrollback by design (`tui_engine.zig:36-42`); keep.
-
----
-
-## 5. Core: config.toml settings
-
-The `[defaults]`/`[compaction]`/`[extensions]`/`[providers]`/`[auth]`
-sections cover the agent; the TUI itself has zero settings. A halfway
-decent agent TUI supports at least:
-
-### P1
-
-- **`[defaults] reasoning = "<level>"`** — today reasoning comes only from
- models.toml per-alias or the Ctrl+R selector; a session default belongs
- next to `defaults.model`.
-- **`[tui] editor = "..."`** — Ctrl+G honors only `$EDITOR`; a config
- override is the conventional courtesy.
-- **`[tui] tools_collapsed = true|false`** — the Ctrl+O collapse state's
- starting value.
-- **`[tui] theme`** — the palette is deliberately comptime-fixed today
- (`tui_theme.zig:5-6` says centralization, not theming). A minimal
- version: named color overrides for the existing `StyleName` slots.
- P1 only if cheap; a full theming system is P2 at best.
-
-### Skip
-
-- Keymap section — subsumed by the keybinding extension API (§7).
-- Footer layout config — subsumed by the footer segment API (§7).
-- Anything per-command/per-tool — that's extension config, which
- extensions can already read themselves (Lua reads files).
-
----
-
-## 6. Core: the footer
-
-Today the footer is one dim line: `provider:alias (reasoning)`, latest
-context tokens, session tokens, session cost (`tui_components.zig:1533`,
-all pushed from Zig via `setModel`/`setContextTokens`/...). Worth adding:
-
-### P1
-
-- **Context as a fraction, not a raw count.** `12.3k ctx` is meaningless
- without the window; models.toml already has `context_window`. Show
- `12.3k/200k ctx` or a percentage — this is the number that tells you
- when compaction looms, arguably the footer's whole job.
-- **Session short-id** — pairs with `/status` and `panto sessions`; makes
- "which session am I in" free.
-- **Transient key-hint slot** — e.g. `esc interrupt` while a turn runs.
- One hint at a time, context-dependent; not a permanent hint bar.
-
-### P2 / skip
-
-- git branch, cwd — coding/shell-flavored and knowable from the terminal;
- an extension can add these once the segment API (§7) exists. Skip in
- core.
-
----
-
-## 7. Extension API gaps (make it possible)
-
-The survey surfaced these as missing Lua surfaces. Per AGENTS.md, each gets
-co-designed before building — this list is scope, not spec.
-
-- **Keybinding registration.** Wanted: extensions can bind chords to Lua
- handlers (and presumably rebind/shadow core ones). Blocked on the
- `appChord` central dispatch (§4) existing first. Design questions for
- the co-design pass: conflict policy vs core chords, per-context bindings
- (idle vs during-turn vs selector), and whether declared bindings
- auto-appear in `/help`.
-- **Footer segments.** The footer is entirely Zig-fed today; extensions
- have no way to add a readout (git branch, active skill, queue depth).
- Likely shape: register a segment that returns a short string, repainted
- on demand — rhymes with the existing screen-component API.
-- **Completion providers.** Per-command argument completion for Lua slash
- commands (§3): a command optionally supplies a completion function.
-- **Session store access** from Lua (list/resolve/load). Needed for an
- extension to build its own `/resume`-like or archival behaviors; today
- sessions are invisible to extensions.
-- **Selector/prompt UI for extensions.** TUI screen components are done
- (`docs/todos.md:31`); a fuzzy-pick-from-list primitive is the missing
- interactive piece extensions keep needing (model pickers, skill pickers,
- session pickers all rhyme).
-
-Not a gap (previously misreported here): the current agent and
-conversation **are** exposed — `panto.ext.agent` wraps the live session
-agent with the full method surface (`lua_runtime.zig:219-242`), and the
-conversation hangs off it. What's worth auditing instead is whether that
-surface is *sufficient* for §3-parity from Lua: model/config switching,
-starting a fresh session, reading usage/config for a `/status`-alike.
-
----
-
-## 8. Not ours (so we stop re-proposing it)
-
-- **`/usage`, `/cost`** — buildable today-ish from the Lua usage-metrics
- API + models.toml pricing; panto-agent material.
-- **`/init`, `/review`, `/pr`, rules/skills injection** — coding-agent
- features; panto-agent already owns this space (`agent.rules`,
- `agent.skill`).
-- **`/undo` / checkpointing** — real design work and coding-flavored;
- out-of-tree when someone wants it.
-- **User keymap config file** — subsumed by the keybinding extension API
- (§7); a TOML keymap section can be revisited if non-extension users ask.
-
----
-
-## 9. Sequencing
-
-1. §1 bug fixes + `panto sessions` output + shortest-unique IDs — one PR,
- pure fixes.
-2. `--model`, `--version`, strict flag parsing — small PR.
-3. `-p/--print` — the headline; with libpanto's one-shot todo or a thin
- plain-text presenter over the existing loop.
-4. Slash commands P0 (`/help`, `/quit`, `/model`, `/reasoning`, `/new`).
-5. Keybindings P0 (history, idle-Escape, Ctrl+M move) + `appChord` dedup.
-6. Footer P1 (context fraction, session id) + config.toml `[defaults]
- reasoning` / `[tui]` basics.
-7. `/resume` switcher, `/status`, completion/typeahead (§3).
-8. Extension API co-design round: keybindings, footer segments, completion
- providers, session store, selector primitive (§7) — then panto-agent
- picks up §8.