Skip to content

feat: Plan-mode plugin tools with planSafeActions + summonWindow shortcut (ADR 0207, issue #167) - #185

Merged
vastsa merged 13 commits into
vastsa:mainfrom
yexisu:fix/issue-167-plan-safe-browser
Sep 10, 2026
Merged

feat: Plan-mode plugin tools with planSafeActions + summonWindow shortcut (ADR 0207, issue #167)#185
vastsa merged 13 commits into
vastsa:mainfrom
yexisu:fix/issue-167-plan-safe-browser

Conversation

@yexisu

@yexisu yexisu commented Sep 10, 2026

Copy link
Copy Markdown
Contributor

Resolves #167.

Problem

Plan (and Goal) mode could not invoke any plugin tool, even for read-only
actions like fetching a URL through the bundled pi.browser plugin. The
keyboard shortcut catalog only exposed closeWindow (Mod+W) with no
symmetric way to bring a tray-hidden window back into focus.

Solution

Part 1 - Plan-mode plugin tools (ADR 0207)

A plugin tool may now declare a planSafeActions array naming the exact
actions it considers safe in Plan and Goal modes. The opt-in is enforced in
three places so a misdeclaration cannot turn a Plan call into a mutation:

  1. Runtime (packages/agent-runtime/src/runtime.ts): hides plugin
    tools without a non-empty planSafeActions list from the model in
    Plan/Goal modes and annotates the description with the allowed action
    list so the model knows which calls are valid.
  2. Host-core (crates/host-core/src/permissions.rs): admits the
    listed plugin tool in ools.execute; without the list the contract-
    mode hard deny from ADR 0052 / ADR 0053 stays in force.
  3. Plugin-runtime (�pps/desktop/electron/main/plugin-runtime.ts):
    the desktop runner now carries the session mode in the plugin's
    execute ctx and rejects any action outside the declared list with
    PERMISSION_DENIED, even if a bug earlier in the chain let an unsafe
    call through.

The bundled pi.browser plugin (ADR 0170) opts in with
planSafeActions: ["navigate", "snapshot", "screenshot", "console"].
Mutating actions (click, ill, evaluate, cdp) stay Agent-only.

Part 2 - summonWindow shortcut (D380)

Adds summonWindow (Mod+Shift+W) to the window shortcut group,
paired with closeWindow (Mod+W). The desktop main process registers
it through globalShortcut, and the native File menu gains a "Summon
Window" item next to the existing settings and close entries. The action
calls the existing
estoreMainWindow helper so a hidden or
minimized-to-tray window is brought back to focus.

Commits

  • eat(plugin-sdk): declare planSafeActions on plugin tools
  • eat(host-core): admit plan-safe plugin tools in Plan and Goal modes
  • eat(runtime): expose plan-safe plugin tools and forward list to host
  • eat(desktop): propagate session mode to plugin tool execution
  • eat(browser-plugin): declare plan-safe actions for read-only inspection
  • est(runtime): cover plan-safe plugin filtering and mode prompt wording
  • eat(shortcut): add summonWindow paired with closeWindow
  • eat(desktop): wire summonWindow shortcut and native menu action
  • eat(desktop): add summonWindow menu item next to settings and close
  • docs: add ADR 0207 and update spec, E2E, decisions log

Docs

  • New ADR: docs/adr/0207-plan-safe-plugin-actions.md
  • Spec update: docs/spec/03-runtime/03-tools-and-permissions.md
  • E2E scenario: E2E-PLAN-005 in docs/spec/06-delivery/04-e2e-test-plan.md
  • Decisions log: D380 in docs/spec/08-meta/decisions-log.md
  • i18n: summonWindow menu and shortcut strings in en, zh-CN, zh-TW, de,
    es, fr, ko, tr

Validation

  • �pps/desktop/test/bundled-plugins.test.mjs adds a test that asserts
    the Browser plugin declares exactly the four read-only actions in
    PLAN_SAFE_ACTIONS.
  • packages/plugin-sdk/src/index.test.ts adds tests covering the new
    planSafeActions field shape and absence as plan-denied.
  • packages/agent-runtime/src/runtime.test.ts covers Plan-mode plugin
    tool filtering (hidden without list, exposed with list, description
    suffix).
  • packages/agent-runtime/src/mode-prompts.test.ts updates the existing
    assertions for the new wording.
  • packages/shared/src/keyboard-shortcuts.test.ts covers the new
    summonWindow id, group, default binding, and non-collision with
    closeWindow.
  • Rust host-core changes were not compiled in this environment (no
    cargo on PATH); manual review of the permission gate and RPC
    payload followed the existing mcp_* / plugin_* patterns.

@vercel

vercel Bot commented Sep 10, 2026

Copy link
Copy Markdown

@yexisu is attempting to deploy a commit to the vastsa's projects Team on Vercel.

A member of the Team first needs to authorize it.

Resolve the decisions-log collision by keeping D377–D383 from main and
recording the plan-safe plugin / summonWindow change as D384 (ADR 0211).
Renumber the new ADR/decision off the taken 0207/D380 slots, fix the
i18n shortcutAction type, wire summonWindow, and keep host-core durable
session mode as the plugin execute authority.
@vastsa
vastsa merged commit ea6b993 into vastsa:main Sep 10, 2026
1 of 4 checks passed
@vastsa

vastsa commented Sep 10, 2026

Copy link
Copy Markdown
Owner

Reviewed and merged.

Principle: sound. Issue #167 is real: Plan/Goal currently hard-deny every plugin tool (ADR 0052 / ADR 0053 / ADR 0170), so the planner cannot inspect a live URL through pi.browser, and the shortcut catalog had close without a matching summon. An opt-in planSafeActions list, default-deny, enforced in runtime + host-core + plugin-runtime is a justified amendment of that frozen deny. summonWindow is the same issue's second request, not a drive-by.

Merged: PR #185 as merge commit ea6b9936, preserving the contributor commits, plus landing commits on top of the author's work:

  • fdd762fe merge current main (conflict was decisions-log.md)
  • c42d1410 landing: ADR/decision numbers (0207/D380 were already taken → ADR 0211 / D384), i18n shortcutAction type, actually register summonWindow, pass durable session mode into plugins.execute, admit plan-safe plugins through the deferred-tool catalog, keep PERMISSION_DENIED

Follow-up still open (not a merge rewrite):

  • Chinese spec pair for 03-tools-and-permissions.md (docs locale check)
  • host-core still admits the whole plugin tool when the list is non-empty; per-action deny is in plugin-runtime
  • Mod+Shift+W is a global shortcut (needed for tray restore; may collide with browser Ctrl+Shift+W)

Thank you for the three-layer design and the Browser opt-in.

vastsa added a commit that referenced this pull request Sep 10, 2026
Sign up for free to 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.

[Bug] 规划模式始终无法调用浏览器插件,智能体模式正常

2 participants