permission-mode control beside the Claude composer (T-275)

Build the T-275 picker on the new popover primitive (D-88): an icon-only,
per-mode-coloured button trailing the composer text box opens a ClideMenu of
the safe trio (default/acceptEdits/plan, active marked) plus a divided, disabled
bypass row (the footgun stays behind the cockpit guard, T-181). The label lives
in the tooltip, the menu, and the status bar — the resting button is the glyph
alone. Coexists with the composer's Stop row when busy.

- new permission_mode_control.dart (PermissionModeControl + per-mode
  icon/colour helpers); shieldCheck/shieldWarning glyphs added to PhosphorIcons.
- claude_composer.dart: permissionMode + onSetPermissionMode props; control
  trails the text box (bottom-aligned), shown only when wired.
- claude_pane.dart: pass the current mode + a setter; demote the status-bar
  _ModeBadge to a passive, per-mode-coloured text indicator (no click). Ctrl/Cmd+M
  still cycles (onCycleMode unchanged).

Regenerated the phosphor-glyphs reference (47 defined). Tests: menu opens with
the trio + disabled bypass, select sets the mode, helpers map colours/icons,
control coexists with Stop, hidden when no mode.

Note: claude_pane.dart also carries the earlier T-274 resume diagnostic log line
(uncommitted in the working tree, reviewed as benign) — it rides along here.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-06-08 18:52:29 +02:00
co-authored by Claude Opus 4.8
parent 3550f10dfc
commit a95b332925
9 changed files with 347 additions and 67 deletions
@@ -8,7 +8,7 @@ tags: [icons, phosphor, ui-design]
All **1512** glyphs bundled in clide's Phosphor font (`assets/fonts/phosphor/`, MIT). Generated from `assets/fonts/phosphor/codepoints.csv` — **do not hand-edit**; regenerate with `python3 .claude/skills/ui-design/scripts/gen-phosphor-glyphs.py`.
The **In clide** column flags the **45** glyphs already wired into `PhosphorIcons` (`lib/widgets/src/icons/phosphor.dart`) — reach for those first. To use any other glyph, add a one-line `static const` to that class with the codepoint below, then `ClideIcon(PhosphorIcons.<name>, size: 13)`. Keep additions to icons we actually use — don't bulk-import.
The **In clide** column flags the **47** glyphs already wired into `PhosphorIcons` (`lib/widgets/src/icons/phosphor.dart`) — reach for those first. To use any other glyph, add a one-line `static const` to that class with the codepoint below, then `ClideIcon(PhosphorIcons.<name>, size: 13)`. Keep additions to icons we actually use — don't bulk-import.
| Codepoint | Name (kebab) | Pascal | In clide |
|---|---|---|---|
@@ -518,10 +518,10 @@ The **In clide** column flags the **45** glyphs already wired into `PhosphorIcon
| `0xe406` | share | Share | |
| `0xe408` | share-network | ShareNetwork | |
| `0xe40a` | shield | Shield | |
| `0xe40c` | shield-check | ShieldCheck | |
| `0xe40c` | shield-check | ShieldCheck | `PhosphorIcons.shieldCheck` |
| `0xe40e` | shield-chevron | ShieldChevron | |
| `0xe410` | shield-slash | ShieldSlash | |
| `0xe412` | shield-warning | ShieldWarning | |
| `0xe412` | shield-warning | ShieldWarning | `PhosphorIcons.shieldWarning` |
| `0xe416` | shopping-bag | ShoppingBag | |
| `0xe418` | shopping-bag-open | ShoppingBagOpen | |
| `0xe41e` | shopping-cart | ShoppingCart | |