What happened?
I saved an Agent Switching choice in the Plannotator UI Settings. On every later submit, my OpenCode session was still switched to build.
The UI opens in Glimpse (glimpseui installed, so openGlimpse() wins the open path). The Glimpse window is a standalone WKWebView process with its own storage. The agent-switch setting is persisted as a cookie (plannotator-agent-switch) via document.cookie. Inside the Glimpse webview that cookie does not survive between runs, so each submit page falls back to the default 'build' and posts agentSwitch: "build".
Result: plan approval, code-review feedback, and annotate feedback all hand the session back to build, even after I saved "Disabled" or a custom agent.
Evidence from the affected machine (macOS):
~/Library/WebKit/glimpse/WebsiteData/ exists and ITP statistics databases update during use, so the data store is real.
- No cookie store directory is ever created under it.
WebsiteData/LocalStorage/ stays empty.
- Saving a choice works within the same window/session, but the next run starts with defaults again.
Side note: even where persistence works, WebKit ITP caps script-written cookies to 7 days, shorter than the 1-year TTL intended in packages/ui/utils/storage.ts.
Steps to reproduce
- Install
glimpseui so the Glimpse open path activates.
- Run any flow with the OpenCode plugin:
submit_plan approval, /plannotator-review, or /plannotator-annotate.
- In the Glimpse window, open Settings → Agent Switching → pick "Disabled" (or any custom agent).
- Submit once. That submit honors the choice.
- Trigger another review or plan in a new session/window.
- Observe: the choice is gone and OpenCode switches to
build.
Root cause (code refs)
packages/ui/utils/storage.ts — cookie-based storage. Cookies avoid the random-port problem (host-scoped), but they still live inside one browser engine's jar.
packages/ui/utils/agentSwitch.ts — getAgentSwitchSettings() falls back to { switchTo: 'build' } when the cookie is absent.
packages/editor/App.tsx and packages/review-editor/App.tsx — attach agentSwitch from those settings to every /api/approve and /api/feedback POST.
- OpenCode plugin — switches whenever the delivered decision carries a non-
disabled value.
Failure chain: separate engine (WKWebView) → empty or purged jar → silent fallback to build.
Feature request: expose the target in config
Please consider exposing the agent-switch target (and ideally other UI-only prefs) as server-side config, so behavior does not depend on webview storage:
Suggested precedence, matching the existing PLANNOTATOR_GLIMPSE / config.glimpse and PLANNOTATOR_SHARE patterns:
PLANNOTATOR_AGENT_SWITCH (env) → config.agentSwitch → cookie → current default.
An alternative or complementary fix: when the UI runs inside Glimpse, persist UI preferences through the embedded server into ~/.plannotator/ instead of cookies, since the page already talks to the local server over HTTP.
Current workaround
Disable the Glimpse opener and use a normal browser, where cookies persist:
or export PLANNOTATOR_GLIMPSE=0, then save the choice once in that browser.
Environment
What happened?
I saved an Agent Switching choice in the Plannotator UI Settings. On every later submit, my OpenCode session was still switched to
build.The UI opens in Glimpse (
glimpseuiinstalled, soopenGlimpse()wins the open path). The Glimpse window is a standalone WKWebView process with its own storage. The agent-switch setting is persisted as a cookie (plannotator-agent-switch) viadocument.cookie. Inside the Glimpse webview that cookie does not survive between runs, so each submit page falls back to the default'build'and postsagentSwitch: "build".Result: plan approval, code-review feedback, and annotate feedback all hand the session back to
build, even after I saved "Disabled" or a custom agent.Evidence from the affected machine (macOS):
~/Library/WebKit/glimpse/WebsiteData/exists and ITP statistics databases update during use, so the data store is real.WebsiteData/LocalStorage/stays empty.Side note: even where persistence works, WebKit ITP caps script-written cookies to 7 days, shorter than the 1-year TTL intended in
packages/ui/utils/storage.ts.Steps to reproduce
glimpseuiso the Glimpse open path activates.submit_planapproval,/plannotator-review, or/plannotator-annotate.build.Root cause (code refs)
packages/ui/utils/storage.ts— cookie-based storage. Cookies avoid the random-port problem (host-scoped), but they still live inside one browser engine's jar.packages/ui/utils/agentSwitch.ts—getAgentSwitchSettings()falls back to{ switchTo: 'build' }when the cookie is absent.packages/editor/App.tsxandpackages/review-editor/App.tsx— attachagentSwitchfrom those settings to every/api/approveand/api/feedbackPOST.disabledvalue.Failure chain: separate engine (WKWebView) → empty or purged jar → silent fallback to
build.Feature request: expose the target in config
Please consider exposing the agent-switch target (and ideally other UI-only prefs) as server-side config, so behavior does not depend on webview storage:
Suggested precedence, matching the existing
PLANNOTATOR_GLIMPSE/config.glimpseandPLANNOTATOR_SHAREpatterns:PLANNOTATOR_AGENT_SWITCH(env) →config.agentSwitch→ cookie → current default.An alternative or complementary fix: when the UI runs inside Glimpse, persist UI preferences through the embedded server into
~/.plannotator/instead of cookies, since the page already talks to the local server over HTTP.Current workaround
Disable the Glimpse opener and use a normal browser, where cookies persist:
or export
PLANNOTATOR_GLIMPSE=0, then save the choice once in that browser.Environment
@plannotator/opencode@latest)