ext-toggle: stage-then-commit UX (space stages, enter applies)
Replaces the single-pick + immediate-apply flow with a SettingsList overlay where: - ↑/↓ navigate - space stages a toggle (●/○ flip in-place; not yet applied) - enter commits all staged renames at once and triggers ctx.reload() - esc cancels, no changes applied Implementation: ctx.ui.custom() builds a Container with header, a SettingsList (which cycles values on space), and a footer status line showing pending changes (e.g. 'pending: notify→off, foo→on'). The wrapper's handleInput intercepts Enter via matchesKey(data, Key.enter) before SettingsList sees it — SettingsList would otherwise consume Enter for cycling. Disable guards still fire on the space-stage attempt: a refused toggle is reverted via settingsList.updateValue and the reason shown in the footer. ssh-controlmaster guard during --ssh therefore now refuses at stage time, not commit time — clearer feedback. Subdir extensions render as read-only rows (no , so SettingsList will not cycle them). Batches multiple toggles into a single ctx.reload() instead of one reload per change, which was awkward when flipping several at once.
This commit is contained in:
@@ -162,11 +162,15 @@ Notification text: `Pi — Done (Ns)` where N is the rounded elapsed seconds.
|
||||
|
||||
### `ext-toggle.ts`
|
||||
|
||||
Registers `/ext` slash command. Lists files in `~/.pi/agent/extensions/`,
|
||||
shows `●` (active) / `○` (disabled) plus dir/symlink hints, and lets the
|
||||
user toggle individual extensions by renaming them between `name.ts` and
|
||||
`name.ts.off`. Calls `ctx.reload()` after a toggle so the change takes
|
||||
effect without restarting pi.
|
||||
Registers `/ext` slash command. Opens a multi-toggle overlay built on
|
||||
`SettingsList` from pi-tui. Lists files in `~/.pi/agent/extensions/` with
|
||||
`● enabled` / `○ disabled` values. Space stages a toggle; Enter commits
|
||||
all pending renames at once and calls `ctx.reload()`; Escape cancels.
|
||||
|
||||
**UX rationale:** the previous single-pick + immediate-apply flow made
|
||||
it awkward to flip several extensions in a row (every toggle reloaded
|
||||
the whole runtime). Stage-then-commit batches reloads to one per
|
||||
session.
|
||||
|
||||
**Key design decisions:**
|
||||
|
||||
@@ -203,10 +207,16 @@ effect without restarting pi.
|
||||
**API used:**
|
||||
|
||||
- `pi.registerCommand(name, { description, handler })` — registers `/ext`.
|
||||
- `ctx.ui.select(title, items)` — picker; returns selected string or `undefined`.
|
||||
- `ctx.ui.confirm(title, message)` — yes/no dialog returning `boolean`.
|
||||
- `ctx.ui.notify(message, level)` — transient toast.
|
||||
- `ctx.reload()` — reloads extensions/skills/prompts/themes; same as `/reload`.
|
||||
- `ctx.ui.custom<T>((tui, theme, kb, done) => Component)` — full-overlay
|
||||
with own keyboard handling. The wrapper component intercepts `enter`
|
||||
via `matchesKey(data, Key.enter)` before forwarding to `SettingsList`,
|
||||
which would otherwise consume Enter for value-cycling.
|
||||
- `SettingsList` from pi-tui — the list itself. Cycles values on space
|
||||
(and on enter, but enter is intercepted upstream). `onChange` fires
|
||||
per cycle and is where staging happens.
|
||||
- `getSettingsListTheme()` from pi-coding-agent — themed colors.
|
||||
- `ctx.ui.notify(message, level)` — toast for post-commit status / errors.
|
||||
- `ctx.reload()` — same reload as `/reload` command.
|
||||
|
||||
No flags, no `agent_*` event handlers — fully passive until `/ext` is invoked.
|
||||
|
||||
|
||||
Reference in New Issue
Block a user