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:
2026-05-07 20:51:13 +02:00
parent c624eafe64
commit e47cbe5795
3 changed files with 230 additions and 105 deletions
+8 -1
View File
@@ -170,9 +170,16 @@ Registers `/ext` — a slash command that lists extensions in `~/.pi/agent/exten
**Usage:**
```
/ext # opens a picker; ● = active, ○ = disabled
/ext # opens the multi-toggle overlay
```
- `↑` / `↓` — navigate
- `space` — stage a toggle (visual `●` / `○` flip; not yet applied)
- `enter` — commit all staged changes and reload pi
- `esc` — cancel, no changes
A footer line shows pending changes (e.g. `pending: notify→off, foo→on`) so you can see exactly what `enter` will apply. Guard rejections appear there too (`⊘ ssh-controlmaster: …`).
**Notes:**
- Subdirectory-style extensions (`name/index.ts`) are listed read-only — v1 doesn't toggle them. Move the directory aside manually if needed.
- `install.sh --uninstall` cleans up both `.ts` and `.ts.off` symlinks pointing into this repo, so a disabled extension won't be left behind.