Skip to content

emrg: gui — restore three-tier sandbox switcher in chat composer - #1077

Merged
argszero merged 1 commit into
argszero:masterfrom
how2how2how2-arch:feature/gui-sandbox-switcher
Aug 30, 2026
Merged

emrg: gui — restore three-tier sandbox switcher in chat composer#1077
argszero merged 1 commit into
argszero:masterfrom
how2how2how2-arch:feature/gui-sandbox-switcher

Conversation

@how2how2how2-arch

Copy link
Copy Markdown
Contributor

Restore the three-tier sandbox switcher in the chat composer (rant 2026-08-30T16:34:29 — regression from the React renderer migration).

Problem: the vanilla renderer shipped a per-message sandbox tier switcher (read-only / workspace-write / danger-full-access, rant 2026-08-20T18:18). The React migration dropped the UI: Composer accepted a sandbox prop but rendered no switcher, so every message went out with sandbox: null — and the daemon treats None as danger-full-access. The chat window silently regressed to full access with no way to switch tiers.

Changes:

  • Composer.tsx — added SANDBOX_TIERS + sanitizeSandbox validation (mirrors vanilla setSandbox allow-list), local tier state defaulting to workspace-write (vanilla default), and a .mode-switcher button group above the composer card; the selected tier is sent with every message (normal + busy-queue paths).
  • shell.css.mode-switcher / .mode-btn / .mode-btn.active styles (ported from vanilla components.css, adapted to React CSS vars).
  • i18n-dicts.ts — 3 short-label keys added to both zh/en dicts (parity kept; composer.sandbox* title keys already existed from the migration).
  • i18n.test.ts — key-count assertion 389 -> 392.
  • Composer.test.tsx — 3 new cases: default active tier, switch to read-only carries the tier into sendMessage, switch to danger-full-access likewise.
  • Agent.md — renderer test breakdown 31 Composer -> 34, headline 476 -> 479.

Verification:

  • Renderer: npm test -> 45 files / 479 passed; npm run typecheck clean.
  • Python: pytest tests/ -> 1176 passed, 1 skipped (doc-count guard synced).
  • Import + CLI OK.

@argszeroargszero left a comment

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

✅ LGTM — cycle. Verified against daemon semantics:

Regression claim confirmed & fixed. React Composer previously threaded the sandbox prop (default null) with no UI. Daemon only injects args["sandbox"] when truthy (daemon.py:2753), so null fell through to the bash tool default = danger-full-access (bash_tool.py:99) — React messages ran with full access where vanilla defaulted to workspace-write. This PR always sends an explicit tier (default workspace-write), restoring vanilla behavior.

Correctness checks:

  • SANDBOX_TIERS (read-only / workspace-write / danger-full-access) matches SANDBOX_MODES exactly (bash_tool.py:119)
  • Vanilla parity: #898's implementation defaulted to sandbox: "workspace-write" (sendTask default + state default + active button); this port uses the same class names (mode-btn/active), data-sandbox attrs, and i18n structure — faithful
  • sanitizeSandbox: invalid → null → caller falls back to workspace-write, mirroring vanilla setSandbox validation
  • i18n: 3 new keys × 2 dicts (392), parity guard updated and passing

Verification (local, PR head 343682e):

  • Composer.test.tsx 34/34 (3 new switcher tests meaningful: default-active assertion + per-tier sandbox payload on send)
  • Full renderer suite 479/479 — matches the Agent.md count update exactly
  • tsc --noEmit clean
  • CI: test + test-windows both green (run 33305134177)

@argszeroargszero left a comment

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

✅ LGTM — cycle. Re-verified on unchanged head 343682e:

  • Head identical to previous LGTM (343682e) — no new commits since last review
  • CI: test + test-windows both green (run 33305134177)
  • mergeable: MERGEABLE / CLEAN, maintainerCanModify

Prior verification stands: SANDBOX_TIERS matches SANDBOX_MODES exactly, vanilla #898 parity (default workspace-write, mode-btn/active classes), i18n parity 392, full renderer suite 479/479 + typecheck clean. LGTM 2/3.

@argszeroargszero left a comment

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

✅ LGTM — cycle. Third consecutive approval on unchanged head 343682e (distinct cycles, no ❌ between).

Head identical to prior verifications: SANDBOX_TIERS matches SANDBOX_MODES (bash_tool.py:119), vanilla #898 parity (default workspace-write, mode-btn/active), i18n parity 392, full renderer suite 479/479 + typecheck clean, CI test + test-windows green (run 33305134177). Merge condition met.

@argszero
argszero merged commit 981f037 into argszero:masterAug 30, 2026
2 checks passed
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants

@how2how2how2-arch@argszero