fix(web): bridge path-access approval modal to the dashboard (#1538)#1540
Merged
Conversation
When the model asked for file access outside the sandbox, the TUI opened PathConfirm but the web dashboard stayed blank — the loop hung waiting for a decision the web user couldn't make. Same shape as #832 (plan-checkpoint). - `ActiveModal` gains a `path` variant carrying path / intent / toolName / sandboxRoot / allowPrefix. - `DashboardContext.resolvePathConfirm` mirrors `resolveShellConfirm`. - `App.tsx` broadcasts `modal-up` / `modal-down` for `pendingPath`, surfaces it in `getActiveModal` (so reconnects mid-modal repaint), and wires `resolvePathConfirm` to `handlePathConfirmRef`. - `/api/modal/resolve` accepts `kind: "path"` with the same run_once / always_allow / deny choices the shell modal already uses. - New `PathModal` Preact component renders the prompt with sandbox / allow-prefix rows and the three resolution buttons. `chat.ts` dispatches it next to `ShellModal`. EN + zh-CN strings added. Audit of the other gates while I was in there: | gate | TUI state | web bridge | |---|---|---| | run_command / run_background | `pendingShell` | ✓ | | path_access | `pendingPath` | ✓ (this PR) | | plan_proposed | `pendingPlan` | ✓ | | plan_checkpoint | `pendingCheckpoint` | ✓ (fixed in #832) | | plan_revision | `pendingRevision` | ✓ | | choice | `pendingChoice` | ✓ | | edit_review | `pendingEditReview` | ✓ | Slash-command pickers (`ModelPicker`, `ThemePicker`, `EditPicker`, `WorkspacePicker`) are still TUI-only — they're user-initiated and don't block the loop, so they're not on the same critical path. Out of scope here; can ship later if web users want to drive them too. Closes #1538.
esengine
pushed a commit
that referenced
this pull request
May 22, 2026
…, theme) (#1524) Localizes the remaining hardcoded CLI output strings — `reasonix mcp list / search / install` flow, `sessions` listing, `prune-sessions`, and the `/theme` slash handler — so zh-CN users see translated text instead of mixed EN/CN output. 31 new keys across `sessions` / `mcpCli` / `app` namespaces with full EN ↔ zh-CN parity. Mechanical migration — `t()` calls replace each string with the same parameters; no behavior change. Verified clean rebase on top of the stage-1-through-4 refactor (#1530 / #1534 / #1536 / #1537) plus the path-approval bridge (#1540): typecheck + lint + 3528 tests all pass.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
When the model asked for file access outside the sandbox, the TUI opened
PathConfirmbut the web dashboard stayed blank — the loop hung waiting for a decision the web user couldn't make. Same shape as #832 (plan-checkpoint). This PR bridges the path-approval gate end-to-end.ActiveModal(src/server/context.ts) gains apathvariant carryingpath/intent/toolName/sandboxRoot/allowPrefix.DashboardContext.resolvePathConfirmmirrorsresolveShellConfirm.App.tsxbroadcastsmodal-up/modal-downforpendingPath, surfaces it ingetActiveModal(so reconnects mid-modal repaint), and wiresresolvePathConfirmtohandlePathConfirmRef./api/modal/resolveacceptskind: "path"with the samerun_once/always_allow/denychoices the shell modal already uses.PathModalPreact component renders the prompt with sandbox / allow-prefix rows and the three resolution buttons.chat.tsdispatches it next toShellModal. EN + zh-CN strings added.Audit of the other gates while I was in there
pendingShellpendingPathpendingPlanpendingCheckpointpendingRevisionpendingChoicependingEditReviewSo after this lands every gate that blocks the assistant loop has a TUI ↔ web bridge.
Slash-command pickers (
ModelPicker,ThemePicker,EditPicker,WorkspacePicker) are still TUI-only — they're user-initiated and don't block the loop, so they're not on the same critical path. Out of scope here; can ship later if web users want to drive them too.Test plan
npm run typecheck(main + dashboard)npm run lintnpm run buildnpm run test— 3528 tests passCloses #1538.