synabun 2.0.7 → 2.0.10
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +67 -0
- package/README.md +1 -1
- package/THIRD-PARTY-LICENSES.md +46 -4
- package/hooks/claude-code/post-plan.mjs +6 -30
- package/hooks/claude-code/session-start.mjs +1 -4
- package/hooks/claude-code/shared.mjs +106 -72
- package/launcher.mjs +9 -3
- package/lib/package-processes.js +670 -0
- package/lib/runtime-dependencies.js +225 -0
- package/lib/start-launcher.js +6 -1
- package/mcp-server/dist/services/browser-bench.d.ts +1 -1
- package/mcp-server/dist/services/browser-bench.d.ts.map +1 -1
- package/mcp-server/dist/services/browser-bench.js +1 -1
- package/mcp-server/dist/services/browser-bench.js.map +1 -1
- package/mcp-server/dist/services/categories.d.ts +35 -2
- package/mcp-server/dist/services/categories.d.ts.map +1 -1
- package/mcp-server/dist/services/categories.js +77 -33
- package/mcp-server/dist/services/categories.js.map +1 -1
- package/mcp-server/dist/services/desktop-bench.d.ts +7 -7
- package/mcp-server/dist/services/desktop-bench.d.ts.map +1 -1
- package/mcp-server/dist/services/desktop-bench.js +1 -1
- package/mcp-server/dist/services/desktop-bench.js.map +1 -1
- package/mcp-server/dist/tools/agents.d.ts +1 -1
- package/mcp-server/dist/tools/agents.d.ts.map +1 -1
- package/mcp-server/dist/tools/agents.js +1 -1
- package/mcp-server/dist/tools/agents.js.map +1 -1
- package/mcp-server/dist/tools/bluesky.js +1 -1
- package/mcp-server/dist/tools/bluesky.js.map +1 -1
- package/mcp-server/dist/tools/browser-advanced.d.ts +1 -1
- package/mcp-server/dist/tools/browser-advanced.d.ts.map +1 -1
- package/mcp-server/dist/tools/browser-advanced.js +1 -1
- package/mcp-server/dist/tools/browser-advanced.js.map +1 -1
- package/mcp-server/dist/tools/browser-batch.d.ts +1 -1
- package/mcp-server/dist/tools/browser-batch.d.ts.map +1 -1
- package/mcp-server/dist/tools/browser-batch.js +1 -1
- package/mcp-server/dist/tools/browser-batch.js.map +1 -1
- package/mcp-server/dist/tools/browser-cheatsheet.d.ts +1 -1
- package/mcp-server/dist/tools/browser-cheatsheet.d.ts.map +1 -1
- package/mcp-server/dist/tools/browser-cheatsheet.js +1 -1
- package/mcp-server/dist/tools/browser-cheatsheet.js.map +1 -1
- package/mcp-server/dist/tools/browser-interact.d.ts +1 -1
- package/mcp-server/dist/tools/browser-interact.d.ts.map +1 -1
- package/mcp-server/dist/tools/browser-interact.js +1 -1
- package/mcp-server/dist/tools/browser-interact.js.map +1 -1
- package/mcp-server/dist/tools/browser-navigate.d.ts +1 -1
- package/mcp-server/dist/tools/browser-navigate.d.ts.map +1 -1
- package/mcp-server/dist/tools/browser-navigate.js +1 -1
- package/mcp-server/dist/tools/browser-navigate.js.map +1 -1
- package/mcp-server/dist/tools/browser-observe.d.ts +1 -1
- package/mcp-server/dist/tools/browser-observe.d.ts.map +1 -1
- package/mcp-server/dist/tools/browser-observe.js +1 -1
- package/mcp-server/dist/tools/browser-observe.js.map +1 -1
- package/mcp-server/dist/tools/card-tools.d.ts +1 -1
- package/mcp-server/dist/tools/card-tools.d.ts.map +1 -1
- package/mcp-server/dist/tools/card-tools.js +1 -1
- package/mcp-server/dist/tools/card-tools.js.map +1 -1
- package/mcp-server/dist/tools/category.d.ts +1 -1
- package/mcp-server/dist/tools/category.d.ts.map +1 -1
- package/mcp-server/dist/tools/category.js +5 -1
- package/mcp-server/dist/tools/category.js.map +1 -1
- package/mcp-server/dist/tools/choice.d.ts +1 -1
- package/mcp-server/dist/tools/choice.d.ts.map +1 -1
- package/mcp-server/dist/tools/choice.js +1 -1
- package/mcp-server/dist/tools/choice.js.map +1 -1
- package/mcp-server/dist/tools/computer.d.ts +1 -1
- package/mcp-server/dist/tools/computer.d.ts.map +1 -1
- package/mcp-server/dist/tools/computer.js +1 -1
- package/mcp-server/dist/tools/computer.js.map +1 -1
- package/mcp-server/dist/tools/discord-channel.d.ts +1 -1
- package/mcp-server/dist/tools/discord-channel.d.ts.map +1 -1
- package/mcp-server/dist/tools/discord-channel.js +1 -1
- package/mcp-server/dist/tools/discord-channel.js.map +1 -1
- package/mcp-server/dist/tools/discord-guild.d.ts +1 -1
- package/mcp-server/dist/tools/discord-guild.d.ts.map +1 -1
- package/mcp-server/dist/tools/discord-guild.js +1 -1
- package/mcp-server/dist/tools/discord-guild.js.map +1 -1
- package/mcp-server/dist/tools/discord-member.d.ts +1 -1
- package/mcp-server/dist/tools/discord-member.d.ts.map +1 -1
- package/mcp-server/dist/tools/discord-member.js +1 -1
- package/mcp-server/dist/tools/discord-member.js.map +1 -1
- package/mcp-server/dist/tools/discord-message.d.ts +1 -1
- package/mcp-server/dist/tools/discord-message.d.ts.map +1 -1
- package/mcp-server/dist/tools/discord-message.js +1 -1
- package/mcp-server/dist/tools/discord-message.js.map +1 -1
- package/mcp-server/dist/tools/discord-onboarding.d.ts +1 -1
- package/mcp-server/dist/tools/discord-onboarding.d.ts.map +1 -1
- package/mcp-server/dist/tools/discord-onboarding.js +1 -1
- package/mcp-server/dist/tools/discord-onboarding.js.map +1 -1
- package/mcp-server/dist/tools/discord-role.d.ts +1 -1
- package/mcp-server/dist/tools/discord-role.d.ts.map +1 -1
- package/mcp-server/dist/tools/discord-role.js +1 -1
- package/mcp-server/dist/tools/discord-role.js.map +1 -1
- package/mcp-server/dist/tools/discord-thread.d.ts +1 -1
- package/mcp-server/dist/tools/discord-thread.d.ts.map +1 -1
- package/mcp-server/dist/tools/discord-thread.js +1 -1
- package/mcp-server/dist/tools/discord-thread.js.map +1 -1
- package/mcp-server/dist/tools/discord-webhook.d.ts +1 -1
- package/mcp-server/dist/tools/discord-webhook.d.ts.map +1 -1
- package/mcp-server/dist/tools/discord-webhook.js +1 -1
- package/mcp-server/dist/tools/discord-webhook.js.map +1 -1
- package/mcp-server/dist/tools/fb-groups.d.ts +1 -1
- package/mcp-server/dist/tools/fb-groups.d.ts.map +1 -1
- package/mcp-server/dist/tools/fb-groups.js +1 -1
- package/mcp-server/dist/tools/fb-groups.js.map +1 -1
- package/mcp-server/dist/tools/forget.d.ts +1 -1
- package/mcp-server/dist/tools/forget.d.ts.map +1 -1
- package/mcp-server/dist/tools/forget.js +1 -1
- package/mcp-server/dist/tools/forget.js.map +1 -1
- package/mcp-server/dist/tools/git-tools.d.ts +1 -1
- package/mcp-server/dist/tools/git-tools.d.ts.map +1 -1
- package/mcp-server/dist/tools/git-tools.js +1 -1
- package/mcp-server/dist/tools/git-tools.js.map +1 -1
- package/mcp-server/dist/tools/gsc/experience.d.ts +1 -1
- package/mcp-server/dist/tools/gsc/experience.d.ts.map +1 -1
- package/mcp-server/dist/tools/gsc/experience.js +1 -1
- package/mcp-server/dist/tools/gsc/experience.js.map +1 -1
- package/mcp-server/dist/tools/gsc/indexing.d.ts +1 -1
- package/mcp-server/dist/tools/gsc/indexing.d.ts.map +1 -1
- package/mcp-server/dist/tools/gsc/indexing.js +1 -1
- package/mcp-server/dist/tools/gsc/indexing.js.map +1 -1
- package/mcp-server/dist/tools/gsc/inspect.d.ts +1 -1
- package/mcp-server/dist/tools/gsc/inspect.d.ts.map +1 -1
- package/mcp-server/dist/tools/gsc/inspect.js +1 -1
- package/mcp-server/dist/tools/gsc/inspect.js.map +1 -1
- package/mcp-server/dist/tools/gsc/navigate.d.ts +1 -1
- package/mcp-server/dist/tools/gsc/navigate.d.ts.map +1 -1
- package/mcp-server/dist/tools/gsc/navigate.js +1 -1
- package/mcp-server/dist/tools/gsc/navigate.js.map +1 -1
- package/mcp-server/dist/tools/gsc/performance.d.ts +1 -1
- package/mcp-server/dist/tools/gsc/performance.d.ts.map +1 -1
- package/mcp-server/dist/tools/gsc/performance.js +1 -1
- package/mcp-server/dist/tools/gsc/performance.js.map +1 -1
- package/mcp-server/dist/tools/gsc/settings.d.ts +1 -1
- package/mcp-server/dist/tools/gsc/settings.d.ts.map +1 -1
- package/mcp-server/dist/tools/gsc/settings.js +1 -1
- package/mcp-server/dist/tools/gsc/settings.js.map +1 -1
- package/mcp-server/dist/tools/image-tools.d.ts +1 -1
- package/mcp-server/dist/tools/image-tools.d.ts.map +1 -1
- package/mcp-server/dist/tools/image-tools.js +1 -1
- package/mcp-server/dist/tools/image-tools.js.map +1 -1
- package/mcp-server/dist/tools/leonardo-browser-tools.d.ts +1 -1
- package/mcp-server/dist/tools/leonardo-browser-tools.d.ts.map +1 -1
- package/mcp-server/dist/tools/leonardo-browser-tools.js +1 -1
- package/mcp-server/dist/tools/leonardo-browser-tools.js.map +1 -1
- package/mcp-server/dist/tools/loop.d.ts +1 -1
- package/mcp-server/dist/tools/loop.d.ts.map +1 -1
- package/mcp-server/dist/tools/loop.js +1 -1
- package/mcp-server/dist/tools/loop.js.map +1 -1
- package/mcp-server/dist/tools/memories.d.ts +1 -1
- package/mcp-server/dist/tools/memories.d.ts.map +1 -1
- package/mcp-server/dist/tools/memories.js +1 -1
- package/mcp-server/dist/tools/memories.js.map +1 -1
- package/mcp-server/dist/tools/morelogin.d.ts +1 -1
- package/mcp-server/dist/tools/morelogin.d.ts.map +1 -1
- package/mcp-server/dist/tools/morelogin.js +1 -1
- package/mcp-server/dist/tools/morelogin.js.map +1 -1
- package/mcp-server/dist/tools/profile.d.ts +1 -1
- package/mcp-server/dist/tools/profile.d.ts.map +1 -1
- package/mcp-server/dist/tools/profile.js +1 -1
- package/mcp-server/dist/tools/profile.js.map +1 -1
- package/mcp-server/dist/tools/recall.d.ts +1 -1
- package/mcp-server/dist/tools/recall.d.ts.map +1 -1
- package/mcp-server/dist/tools/recall.js +1 -1
- package/mcp-server/dist/tools/recall.js.map +1 -1
- package/mcp-server/dist/tools/reflect.d.ts +1 -1
- package/mcp-server/dist/tools/reflect.d.ts.map +1 -1
- package/mcp-server/dist/tools/reflect.js +1 -1
- package/mcp-server/dist/tools/reflect.js.map +1 -1
- package/mcp-server/dist/tools/remember.d.ts +1 -1
- package/mcp-server/dist/tools/remember.d.ts.map +1 -1
- package/mcp-server/dist/tools/remember.js +13 -11
- package/mcp-server/dist/tools/remember.js.map +1 -1
- package/mcp-server/dist/tools/restore.d.ts +1 -1
- package/mcp-server/dist/tools/restore.d.ts.map +1 -1
- package/mcp-server/dist/tools/restore.js +1 -1
- package/mcp-server/dist/tools/restore.js.map +1 -1
- package/mcp-server/dist/tools/style-guide-tools.d.ts +1 -1
- package/mcp-server/dist/tools/style-guide-tools.d.ts.map +1 -1
- package/mcp-server/dist/tools/style-guide-tools.js +1 -1
- package/mcp-server/dist/tools/style-guide-tools.js.map +1 -1
- package/mcp-server/dist/tools/sync.d.ts +1 -1
- package/mcp-server/dist/tools/sync.d.ts.map +1 -1
- package/mcp-server/dist/tools/sync.js +1 -1
- package/mcp-server/dist/tools/sync.js.map +1 -1
- package/mcp-server/dist/tools/tictactoe-tools.d.ts +1 -1
- package/mcp-server/dist/tools/tictactoe-tools.d.ts.map +1 -1
- package/mcp-server/dist/tools/tictactoe-tools.js +1 -1
- package/mcp-server/dist/tools/tictactoe-tools.js.map +1 -1
- package/mcp-server/dist/tools/utils.d.ts +1 -1
- package/mcp-server/dist/tools/utils.d.ts.map +1 -1
- package/mcp-server/dist/tools/utils.js +1 -1
- package/mcp-server/dist/tools/utils.js.map +1 -1
- package/mcp-server/dist/tools/whatsapp-send-file.d.ts +1 -1
- package/mcp-server/dist/tools/whatsapp-send-file.d.ts.map +1 -1
- package/mcp-server/dist/tools/whatsapp-send-file.js +1 -1
- package/mcp-server/dist/tools/whatsapp-send-file.js.map +1 -1
- package/mcp-server/dist/tools/whiteboard-tools.d.ts +3 -3
- package/mcp-server/dist/tools/whiteboard-tools.d.ts.map +1 -1
- package/mcp-server/dist/tools/whiteboard-tools.js +1 -1
- package/mcp-server/dist/tools/whiteboard-tools.js.map +1 -1
- package/mcp-server/dist/tools/youtube/analytics.d.ts +1 -1
- package/mcp-server/dist/tools/youtube/analytics.d.ts.map +1 -1
- package/mcp-server/dist/tools/youtube/analytics.js +1 -1
- package/mcp-server/dist/tools/youtube/analytics.js.map +1 -1
- package/mcp-server/dist/tools/youtube/download.d.ts +1 -1
- package/mcp-server/dist/tools/youtube/download.d.ts.map +1 -1
- package/mcp-server/dist/tools/youtube/download.js +1 -1
- package/mcp-server/dist/tools/youtube/download.js.map +1 -1
- package/mcp-server/dist/tools/youtube/media.d.ts +1 -1
- package/mcp-server/dist/tools/youtube/media.d.ts.map +1 -1
- package/mcp-server/dist/tools/youtube/media.js +1 -1
- package/mcp-server/dist/tools/youtube/media.js.map +1 -1
- package/mcp-server/dist/tools/youtube/metadata.d.ts +1 -1
- package/mcp-server/dist/tools/youtube/metadata.d.ts.map +1 -1
- package/mcp-server/dist/tools/youtube/metadata.js +1 -1
- package/mcp-server/dist/tools/youtube/metadata.js.map +1 -1
- package/mcp-server/dist/tools/youtube/navigate.d.ts +1 -1
- package/mcp-server/dist/tools/youtube/navigate.d.ts.map +1 -1
- package/mcp-server/dist/tools/youtube/navigate.js +1 -1
- package/mcp-server/dist/tools/youtube/navigate.js.map +1 -1
- package/mcp-server/dist/tools/youtube/playlist.d.ts +1 -1
- package/mcp-server/dist/tools/youtube/playlist.d.ts.map +1 -1
- package/mcp-server/dist/tools/youtube/playlist.js +1 -1
- package/mcp-server/dist/tools/youtube/playlist.js.map +1 -1
- package/mcp-server/dist/tools/youtube/schedule.d.ts +1 -1
- package/mcp-server/dist/tools/youtube/schedule.d.ts.map +1 -1
- package/mcp-server/dist/tools/youtube/schedule.js +1 -1
- package/mcp-server/dist/tools/youtube/schedule.js.map +1 -1
- package/mcp-server/dist/tools/youtube/source.d.ts +1 -1
- package/mcp-server/dist/tools/youtube/source.d.ts.map +1 -1
- package/mcp-server/dist/tools/youtube/source.js +1 -1
- package/mcp-server/dist/tools/youtube/source.js.map +1 -1
- package/mcp-server/dist/tools/youtube/upload.d.ts +1 -1
- package/mcp-server/dist/tools/youtube/upload.d.ts.map +1 -1
- package/mcp-server/dist/tools/youtube/upload.js +4 -9
- package/mcp-server/dist/tools/youtube/upload.js.map +1 -1
- package/mcp-server/dist/tui.js +16 -4
- package/mcp-server/dist/tui.js.map +1 -1
- package/mcp-server/package-lock.json +3 -3
- package/mcp-server/package.json +3 -3
- package/mcp-server/src/services/browser-bench.ts +1 -1
- package/mcp-server/src/services/categories.ts +77 -32
- package/mcp-server/src/services/desktop-bench.ts +1 -1
- package/mcp-server/src/tools/agents.ts +1 -1
- package/mcp-server/src/tools/bluesky.ts +1 -1
- package/mcp-server/src/tools/browser-advanced.ts +1 -1
- package/mcp-server/src/tools/browser-batch.ts +1 -1
- package/mcp-server/src/tools/browser-cheatsheet.ts +1 -1
- package/mcp-server/src/tools/browser-interact.ts +1 -1
- package/mcp-server/src/tools/browser-navigate.ts +1 -1
- package/mcp-server/src/tools/browser-observe.ts +1 -1
- package/mcp-server/src/tools/card-tools.ts +1 -1
- package/mcp-server/src/tools/category.ts +6 -1
- package/mcp-server/src/tools/choice.ts +1 -1
- package/mcp-server/src/tools/computer.ts +1 -1
- package/mcp-server/src/tools/discord-channel.ts +1 -1
- package/mcp-server/src/tools/discord-guild.ts +1 -1
- package/mcp-server/src/tools/discord-member.ts +1 -1
- package/mcp-server/src/tools/discord-message.ts +1 -1
- package/mcp-server/src/tools/discord-onboarding.ts +1 -1
- package/mcp-server/src/tools/discord-role.ts +1 -1
- package/mcp-server/src/tools/discord-thread.ts +1 -1
- package/mcp-server/src/tools/discord-webhook.ts +1 -1
- package/mcp-server/src/tools/fb-groups.ts +1 -1
- package/mcp-server/src/tools/forget.ts +1 -1
- package/mcp-server/src/tools/git-tools.ts +1 -1
- package/mcp-server/src/tools/gsc/experience.ts +1 -1
- package/mcp-server/src/tools/gsc/indexing.ts +1 -1
- package/mcp-server/src/tools/gsc/inspect.ts +1 -1
- package/mcp-server/src/tools/gsc/navigate.ts +1 -1
- package/mcp-server/src/tools/gsc/performance.ts +1 -1
- package/mcp-server/src/tools/gsc/settings.ts +1 -1
- package/mcp-server/src/tools/image-tools.ts +1 -1
- package/mcp-server/src/tools/leonardo-browser-tools.ts +1 -1
- package/mcp-server/src/tools/loop.ts +1 -1
- package/mcp-server/src/tools/memories.ts +1 -1
- package/mcp-server/src/tools/morelogin.ts +1 -1
- package/mcp-server/src/tools/profile.ts +1 -1
- package/mcp-server/src/tools/recall.ts +1 -1
- package/mcp-server/src/tools/reflect.ts +1 -1
- package/mcp-server/src/tools/remember.ts +13 -12
- package/mcp-server/src/tools/restore.ts +1 -1
- package/mcp-server/src/tools/style-guide-tools.ts +1 -1
- package/mcp-server/src/tools/sync.ts +1 -1
- package/mcp-server/src/tools/tictactoe-tools.ts +1 -1
- package/mcp-server/src/tools/utils.ts +1 -1
- package/mcp-server/src/tools/whatsapp-send-file.ts +1 -1
- package/mcp-server/src/tools/whiteboard-tools.ts +1 -1
- package/mcp-server/src/tools/youtube/analytics.ts +1 -1
- package/mcp-server/src/tools/youtube/download.ts +1 -1
- package/mcp-server/src/tools/youtube/media.ts +1 -1
- package/mcp-server/src/tools/youtube/metadata.ts +1 -1
- package/mcp-server/src/tools/youtube/navigate.ts +1 -1
- package/mcp-server/src/tools/youtube/playlist.ts +1 -1
- package/mcp-server/src/tools/youtube/schedule.ts +1 -1
- package/mcp-server/src/tools/youtube/source.ts +1 -1
- package/mcp-server/src/tools/youtube/upload.ts +4 -12
- package/mcp-server/src/tui.ts +22 -9
- package/neural-interface/i18n/en.json +236 -7
- package/neural-interface/i18n/pt-BR.json +238 -9
- package/neural-interface/lib/account-usage.js +5 -3
- package/neural-interface/lib/agent-sandbox-elevation.js +102 -0
- package/neural-interface/lib/agent-sandbox-setting.js +57 -0
- package/neural-interface/lib/app-controls-api.js +161 -0
- package/neural-interface/lib/assistant-api.js +40 -7
- package/neural-interface/lib/assistant-brains/opencode.js +13 -1
- package/neural-interface/lib/assistant-brains/opencode2-browser-policy/index.js +44 -0
- package/neural-interface/lib/assistant-brains/opencode2-route-gate/index.js +57 -0
- package/neural-interface/lib/assistant-catalog.js +17 -2
- package/neural-interface/lib/assistant-dispatch.js +3 -0
- package/neural-interface/lib/assistant-envelope.js +19 -1
- package/neural-interface/lib/assistant-route-gate-codex.js +3 -1
- package/neural-interface/lib/assistant-runtime.js +131 -8
- package/neural-interface/lib/claude-model-catalog.js +64 -14
- package/neural-interface/lib/codex-account-auth.js +4 -2
- package/neural-interface/lib/codex-accounts.js +14 -1
- package/neural-interface/lib/codex-settings-schema.js +111 -47
- package/neural-interface/lib/editor-completion-opencode.js +132 -35
- package/neural-interface/lib/exec-loop-command.js +11 -2
- package/neural-interface/lib/install-details.js +23 -5
- package/neural-interface/lib/launch-cache.js +293 -0
- package/neural-interface/lib/login-start.js +524 -0
- package/neural-interface/lib/native-loop-providers.js +24 -4
- package/neural-interface/lib/native-loop-runtime.js +19 -0
- package/neural-interface/lib/opencode-db-schema.js +75 -0
- package/neural-interface/lib/opencode-history.js +16 -1
- package/neural-interface/lib/opencode-protocol.js +173 -0
- package/neural-interface/lib/opencode-provider-view.js +81 -0
- package/neural-interface/lib/opencode-runtime-config.js +10 -3
- package/neural-interface/lib/opencode-serve-records.js +606 -0
- package/neural-interface/lib/opencode-v2-client.js +33 -6
- package/neural-interface/lib/opencode-v2-ws-requests.js +19 -5
- package/neural-interface/lib/opencode-worker-activity.js +229 -0
- package/neural-interface/lib/opencode2-client.js +760 -0
- package/neural-interface/lib/opencode2-proxy.js +116 -0
- package/neural-interface/lib/opencode2-translate.js +1008 -0
- package/neural-interface/lib/process-identity.js +361 -0
- package/neural-interface/lib/provider-panel-terminal-auth.js +3 -2
- package/neural-interface/lib/session-cache-builder.js +26 -5
- package/neural-interface/lib/session-indexer.js +3 -1
- package/neural-interface/lib/session-title-generator.js +20 -0
- package/neural-interface/lib/style-guide/api.js +4 -3
- package/neural-interface/lib/untrusted-file-headers.js +27 -0
- package/neural-interface/package-lock.json +1342 -44
- package/neural-interface/package.json +5 -1
- package/neural-interface/public/index.html +2 -2
- package/neural-interface/public/shared/account-menu.js +4 -1
- package/neural-interface/public/shared/account-usage.js +62 -2
- package/neural-interface/public/shared/account-view.js +2 -1
- package/neural-interface/public/shared/agent-runtime-options.js +55 -11
- package/neural-interface/public/shared/assistant/asst-account-menu.js +298 -0
- package/neural-interface/public/shared/assistant/asst-agents-dock.js +172 -17
- package/neural-interface/public/shared/assistant/asst-api.js +18 -3
- package/neural-interface/public/shared/assistant/asst-brain-picker.js +424 -152
- package/neural-interface/public/shared/assistant/asst-composer.js +1 -1
- package/neural-interface/public/shared/assistant/asst-hosts.js +49 -2
- package/neural-interface/public/shared/assistant/asst-menu.js +275 -77
- package/neural-interface/public/shared/assistant/asst-model-chip.js +135 -0
- package/neural-interface/public/shared/assistant/asst-panel.js +236 -35
- package/neural-interface/public/shared/assistant/asst-rack-styles.js +28 -10
- package/neural-interface/public/shared/assistant/asst-redact.js +186 -0
- package/neural-interface/public/shared/assistant/asst-render.js +382 -36
- package/neural-interface/public/shared/assistant/asst-run-stage.js +231 -0
- package/neural-interface/public/shared/assistant/asst-sanitize.js +193 -3
- package/neural-interface/public/shared/assistant/asst-scene-styles.js +273 -0
- package/neural-interface/public/shared/assistant/asst-scenes.js +528 -0
- package/neural-interface/public/shared/assistant/asst-sidepanel-styles.js +3 -15
- package/neural-interface/public/shared/assistant/asst-state.js +14 -0
- package/neural-interface/public/shared/assistant/asst-styles.js +109 -17
- package/neural-interface/public/shared/assistant/asst-tool-kinds.js +13 -1
- package/neural-interface/public/shared/cc-dropdown.js +480 -0
- package/neural-interface/public/shared/cdx/cdx-panel.js +14 -2
- package/neural-interface/public/shared/cdx/cdx-render.js +15 -3
- package/neural-interface/public/shared/cdx/cdx-styles.js +49 -5
- package/neural-interface/public/shared/cdx/cdx-tabs.js +152 -35
- package/neural-interface/public/shared/cp/cp-markdown.js +4 -57
- package/neural-interface/public/shared/data-cache.js +223 -0
- package/neural-interface/public/shared/desktop-bridge.js +11 -0
- package/neural-interface/public/shared/desktop-titlebar-view.js +78 -1
- package/neural-interface/public/shared/desktop-titlebar.js +214 -28
- package/neural-interface/public/shared/desktop-update-view.js +15 -5
- package/neural-interface/public/shared/file-links.js +73 -8
- package/neural-interface/public/shared/html-shell.js +74 -80
- package/neural-interface/public/shared/launch-prefetch.js +59 -0
- package/neural-interface/public/shared/ocp-v2/ocp-v2-caps.js +3 -2
- package/neural-interface/public/shared/ocp-v2/ocp-v2-childpanel.js +11 -3
- package/neural-interface/public/shared/ocp-v2/ocp-v2-modelpicker.js +54 -17
- package/neural-interface/public/shared/ocp-v2/ocp-v2-panel.js +97 -3
- package/neural-interface/public/shared/ocp-v2/ocp-v2-projectbar.js +3 -2
- package/neural-interface/public/shared/ocp-v2/ocp-v2-providers.js +11 -9
- package/neural-interface/public/shared/ocp-v2/ocp-v2-rehydrate.js +15 -4
- package/neural-interface/public/shared/ocp-v2/ocp-v2-render.js +1 -1
- package/neural-interface/public/shared/ocp-v2/ocp-v2-send-logic.js +401 -0
- package/neural-interface/public/shared/ocp-v2/ocp-v2-send.js +16 -9
- package/neural-interface/public/shared/ocp-v2/ocp-v2-sessions-logic.js +60 -0
- package/neural-interface/public/shared/ocp-v2/ocp-v2-styles.js +83 -5
- package/neural-interface/public/shared/ocp-v2/ocp-v2-ws.js +195 -19
- package/neural-interface/public/shared/opencode-providers.js +39 -0
- package/neural-interface/public/shared/schedules-view.js +318 -0
- package/neural-interface/public/shared/settings/settings-app-pane.js +335 -0
- package/neural-interface/public/shared/settings/settings-app.js +243 -0
- package/neural-interface/public/shared/settings/settings-data.js +88 -0
- package/neural-interface/public/shared/settings/settings-ia.js +17 -0
- package/neural-interface/public/shared/showcase-privacy.js +2 -1
- package/neural-interface/public/shared/sidepanel-session-status.js +49 -0
- package/neural-interface/public/shared/styles.css +543 -372
- package/neural-interface/public/shared/ui-assistant.js +27 -5
- package/neural-interface/public/shared/ui-automation-studio.js +67 -27
- package/neural-interface/public/shared/ui-bookmarks.js +2 -1
- package/neural-interface/public/shared/ui-claude-panel.js +126 -12
- package/neural-interface/public/shared/ui-codex-panel.js +1 -0
- package/neural-interface/public/shared/ui-detail.js +6 -6
- package/neural-interface/public/shared/ui-explorer.js +2 -0
- package/neural-interface/public/shared/ui-file-links.js +1 -0
- package/neural-interface/public/shared/ui-image-gallery.js +6 -5
- package/neural-interface/public/shared/ui-invite.js +18 -2
- package/neural-interface/public/shared/ui-link.js +9 -9
- package/neural-interface/public/shared/ui-menubar.js +232 -33
- package/neural-interface/public/shared/ui-native-loop-router.js +2 -0
- package/neural-interface/public/shared/ui-opencode-panel-v2.js +1 -0
- package/neural-interface/public/shared/ui-schedules-studio.js +2099 -869
- package/neural-interface/public/shared/ui-sessions.js +15 -4
- package/neural-interface/public/shared/ui-settings.js +87 -36
- package/neural-interface/public/shared/ui-sidebar.js +4 -4
- package/neural-interface/public/shared/ui-sidepanel-session-entry.js +13 -0
- package/neural-interface/public/shared/ui-sidepanel-sessions.js +55 -4
- package/neural-interface/public/shared/ui-sidepanel-tray.js +84 -8
- package/neural-interface/public/shared/ui-skills.js +70 -12
- package/neural-interface/public/shared/ui-sync.js +9 -0
- package/neural-interface/public/shared/ui-terminal.js +36 -20
- package/neural-interface/public/shared/ui-trash.js +8 -1
- package/neural-interface/public/shared/ui-tutorial-steps.js +7 -3
- package/neural-interface/public/shared/ui-tutorial.js +15 -5
- package/neural-interface/public/shared/ui-update.js +87 -16
- package/neural-interface/public/shared/ui-whiteboard.js +2 -1
- package/neural-interface/public/variant/2d/main.js +4 -1
- package/neural-interface/public/variant/3d/main.js +3 -0
- package/neural-interface/public/vendor/highlight/LICENSE +29 -0
- package/neural-interface/public/vendor/highlight/github-dark-dimmed-11.12.0.min.css +9 -0
- package/neural-interface/public/vendor/highlight/highlight-11.12.0.min.js +1262 -0
- package/neural-interface/public/vendor/highlight/manifest.json +5 -0
- package/neural-interface/public/vendor/html2canvas/LICENSE +22 -0
- package/neural-interface/public/vendor/html2canvas/html2canvas-1.4.1.min.js +20 -0
- package/neural-interface/public/vendor/html2canvas/manifest.json +4 -0
- package/neural-interface/public/vendor/marked/LICENSE.md +44 -0
- package/neural-interface/public/vendor/marked/manifest.json +4 -0
- package/neural-interface/public/vendor/marked/marked-14.1.4.esm.js +2502 -0
- package/neural-interface/public/vendor/mermaid/LICENSE +21 -0
- package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/abnfDiagram-PAR5IXJI.mjs +1 -0
- package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/architecture-7GRP2DOG-M7G3SWCO.mjs +1 -0
- package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/architectureDiagram-2PNWDENW.mjs +36 -0
- package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/blockDiagram-PUWGUBOA.mjs +129 -0
- package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/c4Diagram-3NLNHZP5.mjs +38 -0
- package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/chunk-2NMSUPJH.mjs +1 -0
- package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/chunk-32MCUW2P.mjs +206 -0
- package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/chunk-3NPNU5GP.mjs +1 -0
- package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/chunk-3SMGFRGC.mjs +1 -0
- package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/chunk-4CAJECRU.mjs +14 -0
- package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/chunk-4OADUZ5Q.mjs +10 -0
- package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/chunk-5IMINLNL.mjs +1 -0
- package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/chunk-5IQCK5RY.mjs +3 -0
- package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/chunk-5MVFYWFU.mjs +1 -0
- package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/chunk-AQ6EADP3.mjs +1 -0
- package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/chunk-AZZRMDJM.mjs +15 -0
- package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/chunk-CLS4B6BI.mjs +168 -0
- package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/chunk-DZP67EKU.mjs +70 -0
- package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/chunk-EICP7K5X.mjs +1 -0
- package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/chunk-GDY2UAB4.mjs +1 -0
- package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/chunk-H7VHZCWX.mjs +1 -0
- package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/chunk-IJBDOHL6.mjs +1 -0
- package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/chunk-JFFVMJIA.mjs +1 -0
- package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/chunk-JQRUD6KW.mjs +1 -0
- package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/chunk-JZGDI5JK.mjs +1 -0
- package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/chunk-KD6SPIPN.mjs +2 -0
- package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/chunk-NF366YI6.mjs +231 -0
- package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/chunk-NUDPKBEF.mjs +32 -0
- package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/chunk-OJINMHTS.mjs +1 -0
- package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/chunk-Q6NGPIAH.mjs +2 -0
- package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/chunk-QJSWEUOL.mjs +132 -0
- package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/chunk-R7JDMUKV.mjs +1 -0
- package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/chunk-RCXAM2GK.mjs +1 -0
- package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/chunk-RT4MAWR3.mjs +1 -0
- package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/chunk-SFMINX4W.mjs +1 -0
- package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/chunk-SLDQ463B.mjs +88 -0
- package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/chunk-STOV2HOB.mjs +1 -0
- package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/chunk-T5OCTHI4.mjs +1 -0
- package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/chunk-TCEHX7R3.mjs +1 -0
- package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/chunk-VQC2EELJ.mjs +1 -0
- package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/chunk-VRZKL3EH.mjs +1 -0
- package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/chunk-VTHDQ7BV.mjs +1 -0
- package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/chunk-VY2OSTJR.mjs +2 -0
- package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/chunk-WUBWJARI.mjs +1 -0
- package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/chunk-YBMQ5JGJ.mjs +2 -0
- package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/chunk-YDMLL4PJ.mjs +1 -0
- package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/chunk-Z6V44ARX.mjs +62 -0
- package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/chunk-ZJJ7VQJP.mjs +339 -0
- package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/chunk-ZNLK7HRR.mjs +1 -0
- package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/chunk-ZQN7UHIL.mjs +1 -0
- package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/chunk-ZS6VBONO.mjs +174 -0
- package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/chunk-ZUNWM646.mjs +1 -0
- package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/classDiagram-FGAMPOII.mjs +1 -0
- package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/classDiagram-v2-AI5RJEK4.mjs +1 -0
- package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/cose-bilkent-Q72C2OJ3.mjs +1 -0
- package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/cynefin-OW5HDTMX-6OCTWOGG.mjs +1 -0
- package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/cynefinDiagram-2OOWUY4M.mjs +62 -0
- package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/dagre-MPVFI544.mjs +4 -0
- package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/diagram-AE4NWXFW.mjs +24 -0
- package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/diagram-BUJID5UG.mjs +41 -0
- package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/diagram-C44CZ5NI.mjs +24 -0
- package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/diagram-EYOLEXXS.mjs +30 -0
- package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/diagram-P7B6PWOJ.mjs +3 -0
- package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/ebnfDiagram-FTPZ3PV6.mjs +1 -0
- package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/erDiagram-H3ERR26V.mjs +99 -0
- package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/eventmodeling-NTZA5JFV-WKSWQHFS.mjs +1 -0
- package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/flowDiagram-YHGXBVSY.mjs +1 -0
- package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/ganttDiagram-RWFTB7ED.mjs +292 -0
- package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/gitGraph-4MIJSDKK-JH2HKYUO.mjs +1 -0
- package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/gitGraphDiagram-MAR6GKOP.mjs +106 -0
- package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/info-A6RAGUB7-3TX3OFWW.mjs +1 -0
- package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/infoDiagram-LV547AFH.mjs +2 -0
- package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/ishikawaDiagram-PUJQGNDS.mjs +70 -0
- package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/journeyDiagram-EW5QJT4W.mjs +139 -0
- package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/kanban-definition-JSQERAZB.mjs +89 -0
- package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/katex-CZ4GXH2S.mjs +257 -0
- package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/mindmap-definition-VBJCLQLM.mjs +96 -0
- package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/packet-AYTQ26CC-MKII6P3Y.mjs +1 -0
- package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/pegDiagram-7WILOQTJ.mjs +1 -0
- package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/pie-WAS4IAKB-6B4OPMJ5.mjs +1 -0
- package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/pieDiagram-EFA7CBSB.mjs +39 -0
- package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/quadrantDiagram-WARVYA7P.mjs +7 -0
- package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/radar-RG4KPBEZ-UPTR3XUL.mjs +1 -0
- package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/railroad-74A4TZTK-MEFUPFMS.mjs +1 -0
- package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/railroad-abnf-HS5TGJTU-R5YG2S5D.mjs +1 -0
- package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/railroad-ebnf-LZEXJU2U-G5QEX2L6.mjs +1 -0
- package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/railroad-peg-WCYAUIDC-H5I2ZRY2.mjs +1 -0
- package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/railroadDiagram-5NIQVNLQ.mjs +1 -0
- package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/requirementDiagram-SXREGOKZ.mjs +84 -0
- package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/sankeyDiagram-VV74M2VP.mjs +40 -0
- package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/sequenceDiagram-52ZFIFDL.mjs +162 -0
- package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/sizeCapture-FGA5AGYP.mjs +1 -0
- package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/stateDiagram-3QAKPIVI.mjs +1 -0
- package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/stateDiagram-v2-HN2P4RDZ.mjs +1 -0
- package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/swimlanes-QLVP42QD.mjs +1 -0
- package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/swimlanesDiagram-JKPDBFCN.mjs +8 -0
- package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/timeline-definition-GS45XAXW.mjs +120 -0
- package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/treeView-Q6P3EWNA-ZRJGANNQ.mjs +1 -0
- package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/treemap-WGGIJYW6-K64VN5AS.mjs +1 -0
- package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/vennDiagram-QIQU2ZRJ.mjs +34 -0
- package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/wardley-WFR3VGLG-D67OWCCH.mjs +1 -0
- package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/wardleyDiagram-U6YNM66N.mjs +78 -0
- package/neural-interface/public/vendor/mermaid/chunks/mermaid.esm.min/xychartDiagram-XJAZEDNM.mjs +7 -0
- package/neural-interface/public/vendor/mermaid/manifest.json +4 -0
- package/neural-interface/public/vendor/mermaid/mermaid-11.17.2.esm.min.mjs +14 -0
- package/neural-interface/scripts/build-vendor.mjs +84 -3
- package/neural-interface/scripts/rebuild-pty.js +14 -2
- package/neural-interface/server.js +1279 -372
- package/npm-shrinkwrap.json +4424 -0
- package/package.json +54 -2
- package/postinstall.js +61 -47
- package/preuninstall.js +8 -35
- package/setup.js +76 -44
- package/skills/synabun/modules/idea.md +1 -1
- package/skills/synabun/modules/schedule.md +2 -2
- package/updater.cmd +2 -2
- package/updater.mjs +97 -3
|
@@ -9,7 +9,7 @@
|
|
|
9
9
|
// obligation nudges. All server dependencies are injected.
|
|
10
10
|
|
|
11
11
|
import { createHash, randomBytes, randomUUID, timingSafeEqual } from 'node:crypto';
|
|
12
|
-
import { appendFileSync, existsSync, mkdirSync, readFileSync, renameSync, rmSync, writeFileSync } from 'node:fs';
|
|
12
|
+
import { appendFileSync, existsSync, mkdirSync, readFileSync, renameSync, rmSync, statSync, writeFileSync } from 'node:fs';
|
|
13
13
|
import { dirname, resolve } from 'node:path';
|
|
14
14
|
import { createClaudeBrain } from './assistant-brains/claude.js';
|
|
15
15
|
import { createCodexBrain } from './assistant-brains/codex.js';
|
|
@@ -246,10 +246,14 @@ export function createAssistantRuntime({
|
|
|
246
246
|
// (capability) → boolean, the verifier of lib/remote-policy.js createPhoneAuthority(): is this the
|
|
247
247
|
// capability of the one WhatsApp bridge? Without a verifier nothing can grant computer use remotely.
|
|
248
248
|
phoneAuthority = null,
|
|
249
|
+
// The Admin sandbox setting (lib/agent-sandbox-setting.js): global, shown in every session view.
|
|
250
|
+
adminSandbox = null,
|
|
249
251
|
} = {}) {
|
|
250
252
|
if (!dataDir) throw new Error('createAssistantRuntime requires dataDir');
|
|
251
253
|
const settings = {
|
|
252
254
|
idleDisposeMs: Math.max(60_000, Number(config.idleDisposeMinutes || 120) * 60_000),
|
|
255
|
+
// A draft (a session the panel opened, before its first prompt) with no socket attached goes after this.
|
|
256
|
+
draftIdleMs: Math.max(60_000, Number(config.draftIdleMinutes || 10) * 60_000),
|
|
253
257
|
// A remote session on OpenCode waits this long for its gate plugin's hello before a turn (else refused).
|
|
254
258
|
remoteGateHelloMs: Math.max(0, Number(config.remoteGateHelloMs ?? 5000)),
|
|
255
259
|
// An OpenCode turn's end waits this long for the serve's stored messages (the usage meter's
|
|
@@ -293,11 +297,30 @@ export function createAssistantRuntime({
|
|
|
293
297
|
|
|
294
298
|
// ── persistence ────────────────────────────────────────────────────────────
|
|
295
299
|
function transcriptPath(id) { return resolve(dataDir, 'assistant', id, 'transcript.jsonl'); }
|
|
300
|
+
function transcriptHasEntries(id) { try { return statSync(transcriptPath(id)).size > 0; } catch { return false; } }
|
|
301
|
+
function transcriptHasPrompt(id) { try { return readFileSync(transcriptPath(id), 'utf8').includes('"synabun.user_prompt"'); } catch { return false; } }
|
|
302
|
+
/**
|
|
303
|
+
* A record from before `chatStartedAt`: its chat started when it ran a turn, adopted a provider
|
|
304
|
+
* conversation or holds a human prompt (the time is its best guess). One that never did is listed
|
|
305
|
+
* nowhere; with nothing in it at all (no transcript, no runs, not remote, no spend) it is dropped.
|
|
306
|
+
*/
|
|
307
|
+
function settleLegacyRow(row) {
|
|
308
|
+
if (row.chatStartedAt) return 'started';
|
|
309
|
+
if (Number(row.turns) > 0 || row.providerSessionId || row.providerThreadId || transcriptHasPrompt(row.id)) {
|
|
310
|
+
row.chatStartedAt = row.lastActiveAt || row.updatedAt || row.createdAt || iso(now());
|
|
311
|
+
return 'started';
|
|
312
|
+
}
|
|
313
|
+
const holds = transcriptHasEntries(row.id) || (Array.isArray(row.dispatchRunIds) && row.dispatchRunIds.length > 0)
|
|
314
|
+
|| !!row.remote || !!row.channel || Number(row.costUsd) > 0;
|
|
315
|
+
return holds ? 'unstarted' : 'empty';
|
|
316
|
+
}
|
|
296
317
|
function loadIndex() {
|
|
297
318
|
const rows = readJson(indexPath, []);
|
|
298
319
|
if (!Array.isArray(rows)) return;
|
|
320
|
+
let dropped = 0;
|
|
299
321
|
for (const row of rows) {
|
|
300
322
|
if (!row?.id) continue;
|
|
323
|
+
if (settleLegacyRow(row) === 'empty') { dropped += 1; continue; }
|
|
301
324
|
sessions.set(row.id, makeLive({ ...row, status: row.status === 'ended' ? 'ended' : 'idle', windowIds: [] }));
|
|
302
325
|
// A remote session nobody registered again since the restart reads as read-only.
|
|
303
326
|
if (row.remote) {
|
|
@@ -305,11 +328,14 @@ export function createAssistantRuntime({
|
|
|
305
328
|
try { remotePolicy?.setSessionBrain?.(row.id, row.brain?.provider || null); } catch {}
|
|
306
329
|
}
|
|
307
330
|
}
|
|
331
|
+
// The index is written again without them (and with the started marks).
|
|
332
|
+
if (dropped) { log('assistant:index', `${dropped} session record(s) without a conversation dropped`); persist(); }
|
|
308
333
|
}
|
|
309
334
|
let persistTimer = null;
|
|
310
335
|
function persist({ force = false } = {}) {
|
|
311
336
|
const write = () => {
|
|
312
|
-
|
|
337
|
+
// A draft is never written: it exists on disk only once its first prompt was sent (startChat).
|
|
338
|
+
const rows = [...sessions.values()].filter((live) => !live.draft).map((live) => publicRecord(live.record, { withLive: false, persisted: true }))
|
|
313
339
|
.sort((a, b) => String(b.updatedAt || '').localeCompare(String(a.updatedAt || '')))
|
|
314
340
|
.slice(0, settings.retention);
|
|
315
341
|
try { writeJsonAtomic(indexPath, rows); } catch (error) { log('assistant:index-error', error?.message || String(error)); }
|
|
@@ -339,6 +365,9 @@ export function createAssistantRuntime({
|
|
|
339
365
|
function makeLive(record) {
|
|
340
366
|
return {
|
|
341
367
|
record, brain: null, brainProvider: null, brainMeter: null, brainMeterProvider: null, turnTaskId: null, turnTasks: [], sockets: new Set(), buffer: [], running: false, pendingControls: new Map(), controlTimers: new Map(),
|
|
368
|
+
// A draft: opened by a panel and not chatted in yet. Kept in memory only, listed nowhere, and
|
|
369
|
+
// gone when it is closed or left without a socket (draftTimer); its first prompt stores it (startChat).
|
|
370
|
+
draft: false, draftTimer: null,
|
|
342
371
|
mailbox: [], mailboxTimer: null, obligations: new Set(), rememberedThisTurn: false, disposeTimer: null, personaText: '',
|
|
343
372
|
// The last human prompt and where it came from ('ui', 'whatsapp', 'api'): a route continuation
|
|
344
373
|
// answers there (lastPromptOrigin; the transcript's after a restart).
|
|
@@ -906,7 +935,11 @@ export function createAssistantRuntime({
|
|
|
906
935
|
out.testDensity = testDensityOf(record);
|
|
907
936
|
out.testDensityExplicit = normalizeTestDensity(record.testDensity, null);
|
|
908
937
|
// `rename`: this server keeps a rename on the record (userRenamed), so a panel writes it here.
|
|
909
|
-
|
|
938
|
+
// `adminSandbox`: the global setting is served here (PUT /api/assistant/admin-sandbox).
|
|
939
|
+
// `drafts`: a session is stored and listed from its first prompt on; `remove`: DELETE stops its work and purges it.
|
|
940
|
+
out.features = { routing: !!router, computer: computerSupported(), testDensity: true, rename: true, adminSandbox: !!adminSandbox, drafts: true, remove: true };
|
|
941
|
+
out.draft = live.draft === true;
|
|
942
|
+
if (adminSandbox) { try { out.adminSandbox = adminSandbox.enabled() === true; } catch { out.adminSandbox = false; } }
|
|
910
943
|
out.budget = sessionMoney(record.id);
|
|
911
944
|
out.remoteLevel = policy ? effectiveLevel(policy, { untrusted: live.turnUntrusted === true, now: now() }) : null;
|
|
912
945
|
}
|
|
@@ -2298,6 +2331,8 @@ export function createAssistantRuntime({
|
|
|
2298
2331
|
live.lastPromptOrigin = origin ? String(origin) : null;
|
|
2299
2332
|
// A prompt from elsewhere (WhatsApp, the API) is news to the panel: it goes live too.
|
|
2300
2333
|
const promptPacket = { type: 'event', event: { type: 'synabun.user_prompt', text: prompt, images: images.length, ...(origin && origin !== 'ui' ? { origin: String(origin) } : {}) } };
|
|
2334
|
+
// The chat starts with its first human prompt: from here on the session is stored and listed.
|
|
2335
|
+
startChat(live);
|
|
2301
2336
|
appendTranscript(live.record.id, { at: iso(now()), packet: promptPacket });
|
|
2302
2337
|
if (origin && origin !== 'ui') sendToSockets(live, promptPacket);
|
|
2303
2338
|
if (live.brainProvider !== 'claude-code' && memory?.recallForPrompt) {
|
|
@@ -2668,8 +2703,56 @@ export function createAssistantRuntime({
|
|
|
2668
2703
|
}
|
|
2669
2704
|
|
|
2670
2705
|
// ── public API ─────────────────────────────────────────────────────────────
|
|
2706
|
+
/**
|
|
2707
|
+
* Every session list (REST, the socket's list_sessions, the catalog view) reads this: only sessions
|
|
2708
|
+
* whose chat started. A draft, or a record nobody ever prompted, is in none of them. `activeRuns`:
|
|
2709
|
+
* the workers it dispatched that still run (a removal stops them, and its question says so).
|
|
2710
|
+
*/
|
|
2671
2711
|
function listSessions() {
|
|
2672
|
-
|
|
2712
|
+
const runs = new Map();
|
|
2713
|
+
try {
|
|
2714
|
+
for (const run of dispatcher?.list?.({ activeOnly: true, limit: 500 }) || []) {
|
|
2715
|
+
if (run?.assistantSessionId) runs.set(run.assistantSessionId, (runs.get(run.assistantSessionId) || 0) + 1);
|
|
2716
|
+
}
|
|
2717
|
+
} catch {}
|
|
2718
|
+
return [...sessions.values()].filter((live) => !live.draft && !!live.record.chatStartedAt)
|
|
2719
|
+
.map((live) => ({ ...view(live), activeRuns: runs.get(live.record.id) || 0 }))
|
|
2720
|
+
.sort((a, b) => String(b.updatedAt || '').localeCompare(String(a.updatedAt || '')));
|
|
2721
|
+
}
|
|
2722
|
+
/**
|
|
2723
|
+
* The first human prompt (or a provider conversation adopted with `resume`) starts the chat: the
|
|
2724
|
+
* record is marked, and a draft becomes a stored session (written now, listed from now on).
|
|
2725
|
+
*/
|
|
2726
|
+
function startChat(live) {
|
|
2727
|
+
if (live.record.chatStartedAt && !live.draft) return;
|
|
2728
|
+
live.record.chatStartedAt ||= iso(now());
|
|
2729
|
+
const wasDraft = live.draft;
|
|
2730
|
+
live.draft = false;
|
|
2731
|
+
if (live.draftTimer) { clearTimeout(live.draftTimer); live.draftTimer = null; }
|
|
2732
|
+
persist({ force: true });
|
|
2733
|
+
if (wasDraft) broadcast('assistant:session-created', live);
|
|
2734
|
+
}
|
|
2735
|
+
/** A draft with no socket attached is removed after settings.draftIdleMs (a page that went and never came back). */
|
|
2736
|
+
function armDraftExpiry(live) {
|
|
2737
|
+
if (live.draftTimer) { clearTimeout(live.draftTimer); live.draftTimer = null; }
|
|
2738
|
+
if (!live.draft || live.sockets.size || shuttingDown || sessions.get(live.record.id) !== live) return;
|
|
2739
|
+
live.draftTimer = setTimeout(() => {
|
|
2740
|
+
live.draftTimer = null;
|
|
2741
|
+
if (!live.draft || live.sockets.size || sessions.get(live.record.id) !== live || sessionBusy(live) || live.closing) return;
|
|
2742
|
+
destroySession(live.record.id).catch((error) => log('assistant:draft-expiry', error?.message || String(error)));
|
|
2743
|
+
}, settings.draftIdleMs);
|
|
2744
|
+
live.draftTimer.unref?.();
|
|
2745
|
+
}
|
|
2746
|
+
/**
|
|
2747
|
+
* Whether closing a session keeps its record (ended, reopenable) or removes it: a session that
|
|
2748
|
+
* never held a conversation (no prompt, no turn, no runs, nothing in its transcript, not remote,
|
|
2749
|
+
* no work under way) leaves nothing behind.
|
|
2750
|
+
*/
|
|
2751
|
+
function holdsConversation(live) {
|
|
2752
|
+
const r = live.record;
|
|
2753
|
+
return !!r.chatStartedAt || Number(r.turns) > 0 || (Array.isArray(r.dispatchRunIds) && r.dispatchRunIds.length > 0)
|
|
2754
|
+
|| !!r.providerSessionId || !!r.providerThreadId || !!r.remote || !!r.channel || Number(r.costUsd) > 0
|
|
2755
|
+
|| sessionBusy(live) || !!workReserved(live) || transcriptHasEntries(r.id);
|
|
2673
2756
|
}
|
|
2674
2757
|
function getSession(id, { transcript = true, limit = 400 } = {}) {
|
|
2675
2758
|
const live = sessions.get(id);
|
|
@@ -2694,7 +2777,7 @@ export function createAssistantRuntime({
|
|
|
2694
2777
|
if (!row) throw Object.assign(new Error('Auto requires a signed-in subscription account.'), { code: 'ACCOUNT_NO_SUBSCRIPTION', status: 409 });
|
|
2695
2778
|
return { ...brain, accountId: row.id };
|
|
2696
2779
|
}
|
|
2697
|
-
async function createSession({ brain = {}, label = null, cwd = null, windowId = null, fallback = false, channel = null } = {}, internal = {}) {
|
|
2780
|
+
async function createSession({ brain = {}, label = null, cwd = null, windowId = null, fallback = false, channel = null, draft = false } = {}, internal = {}) {
|
|
2698
2781
|
const id = `assistant-${randomUUID()}`;
|
|
2699
2782
|
const requested = normalizeBrain({ ...brain, cwd: brain?.cwd || cwd || settings.defaultBrain.cwd || PACKAGE_ROOT }, settings.defaultBrain, { catalog: catalog?.peek?.() || null });
|
|
2700
2783
|
const enabled = await enabledBrain(requested, { fallback: fallback === true, named: !!brain?.model });
|
|
@@ -2725,8 +2808,16 @@ export function createAssistantRuntime({
|
|
|
2725
2808
|
live.creating = false;
|
|
2726
2809
|
record.brain = clampedBrain(live, record.brain);
|
|
2727
2810
|
}
|
|
2728
|
-
|
|
2729
|
-
|
|
2811
|
+
// `draft` (a panel's new session, POST /sessions): stored and announced by its first prompt
|
|
2812
|
+
// (startChat); until then it lives here only, and is removed when it is closed or left (armDraftExpiry).
|
|
2813
|
+
// A remote session is never one: its bridge sends the prompt it was made for.
|
|
2814
|
+
if (draft === true && !remote && !record.channel) {
|
|
2815
|
+
live.draft = true;
|
|
2816
|
+
armDraftExpiry(live);
|
|
2817
|
+
} else {
|
|
2818
|
+
persist({ force: true });
|
|
2819
|
+
broadcast('assistant:session-created', live);
|
|
2820
|
+
}
|
|
2730
2821
|
return enabled.fallback ? { ...view(live), fallback: enabled.fallback } : view(live);
|
|
2731
2822
|
}
|
|
2732
2823
|
function applyRouteMode(live, mode) {
|
|
@@ -2826,6 +2917,12 @@ export function createAssistantRuntime({
|
|
|
2826
2917
|
}
|
|
2827
2918
|
async function closeSession(id) {
|
|
2828
2919
|
const live = requireLive(id);
|
|
2920
|
+
// Never chatted in (a draft, a record nobody prompted): closing it leaves nothing behind.
|
|
2921
|
+
if (!holdsConversation(live)) {
|
|
2922
|
+
const gone = { ...view(live), status: 'destroyed', removed: true };
|
|
2923
|
+
await destroySession(id);
|
|
2924
|
+
return gone;
|
|
2925
|
+
}
|
|
2829
2926
|
const closed = await endSessionWork(live);
|
|
2830
2927
|
try {
|
|
2831
2928
|
await disposeBrain(live, 'closed');
|
|
@@ -2843,6 +2940,9 @@ export function createAssistantRuntime({
|
|
|
2843
2940
|
if (!live) return false;
|
|
2844
2941
|
const closed = await endSessionWork(live);
|
|
2845
2942
|
try {
|
|
2943
|
+
if (sessions.get(id) !== live) return false; // another removal got there first
|
|
2944
|
+
if (live.draftTimer) { clearTimeout(live.draftTimer); live.draftTimer = null; }
|
|
2945
|
+
if (live.disposeTimer) { clearTimeout(live.disposeTimer); live.disposeTimer = null; }
|
|
2846
2946
|
await disposeBrain(live, 'closed');
|
|
2847
2947
|
for (const ws of live.sockets) { try { ws.close(1000, 'session destroyed'); } catch {} }
|
|
2848
2948
|
sessions.delete(id);
|
|
@@ -2859,6 +2959,24 @@ export function createAssistantRuntime({
|
|
|
2859
2959
|
} finally { closed(); }
|
|
2860
2960
|
return true;
|
|
2861
2961
|
}
|
|
2962
|
+
/**
|
|
2963
|
+
* The Sessions menu's Remove (DELETE /api/assistant/sessions/:id): the session goes for good, in
|
|
2964
|
+
* every host and list, and its work goes with it: the workers it dispatched that still run are
|
|
2965
|
+
* stopped (no orphaned run is left), then the running turn and the brain (destroySession). Only
|
|
2966
|
+
* the record, its transcript and its usage journal are removed: memories made from it (its
|
|
2967
|
+
* assistant-threads record included) stay, and so do the dispatcher's records of its runs.
|
|
2968
|
+
*/
|
|
2969
|
+
async function removeSession(id) {
|
|
2970
|
+
const live = sessions.get(String(id || ''));
|
|
2971
|
+
if (!live) return { removed: false, stoppedRuns: [] };
|
|
2972
|
+
let stoppedRuns = [];
|
|
2973
|
+
try {
|
|
2974
|
+
const result = await dispatcher?.killAll?.({ assistantSessionId: live.record.id, reason: 'session_removed' });
|
|
2975
|
+
stoppedRuns = Array.isArray(result?.stopped) ? result.stopped : [];
|
|
2976
|
+
} catch (error) { log('assistant:remove', `${live.record.id}: stopping its runs failed (${error?.message || error})`); }
|
|
2977
|
+
const removed = await destroySession(live.record.id);
|
|
2978
|
+
return { removed, stoppedRuns };
|
|
2979
|
+
}
|
|
2862
2980
|
/**
|
|
2863
2981
|
* MCP terminal pin → assistant session id. Claude brains pin the session id
|
|
2864
2982
|
* itself; the OpenCode brain pins `assistant-oc-<24>` (its isolated serve).
|
|
@@ -3123,6 +3241,7 @@ export function createAssistantRuntime({
|
|
|
3123
3241
|
ws.on('close', () => {
|
|
3124
3242
|
live.sockets.delete(ws);
|
|
3125
3243
|
scheduleDispose(live);
|
|
3244
|
+
armDraftExpiry(live);
|
|
3126
3245
|
});
|
|
3127
3246
|
if (held) {
|
|
3128
3247
|
while (live.closing) await live.closing;
|
|
@@ -3133,6 +3252,7 @@ export function createAssistantRuntime({
|
|
|
3133
3252
|
if (ws.readyState !== 1) return; // gone while it waited
|
|
3134
3253
|
}
|
|
3135
3254
|
if (live.disposeTimer) { clearTimeout(live.disposeTimer); live.disposeTimer = null; }
|
|
3255
|
+
if (live.draftTimer) { clearTimeout(live.draftTimer); live.draftTimer = null; }
|
|
3136
3256
|
live.sockets.add(ws);
|
|
3137
3257
|
live.record.status = live.record.status === 'ended' ? 'idle' : live.record.status;
|
|
3138
3258
|
const engine = live.brain ? { type: 'engine', engine: live.brainProvider === 'claude-code' ? 'sdk' : live.brainProvider, brain: live.brainProvider, sdkVersion } : { type: 'engine', engine: 'assistant', brain: live.record.brain.provider, sdkVersion };
|
|
@@ -3264,6 +3384,8 @@ export function createAssistantRuntime({
|
|
|
3264
3384
|
if (msg.providerSessionId) {
|
|
3265
3385
|
const moved = msg.providerSessionId !== live.record.providerSessionId;
|
|
3266
3386
|
live.record.providerSessionId = msg.providerSessionId;
|
|
3387
|
+
// A provider conversation adopted (/resume <id>): the session holds a chat now.
|
|
3388
|
+
startChat(live);
|
|
3267
3389
|
// Another provider session: the meter's baseline was the old one's.
|
|
3268
3390
|
if (moved) resetMeterIdentity(live, msg.providerSessionId);
|
|
3269
3391
|
// …and so was the frozen user-context digest.
|
|
@@ -3724,6 +3846,7 @@ export function createAssistantRuntime({
|
|
|
3724
3846
|
for (const live of sessions.values()) {
|
|
3725
3847
|
if (live.mailboxTimer) clearTimeout(live.mailboxTimer);
|
|
3726
3848
|
if (live.disposeTimer) clearTimeout(live.disposeTimer);
|
|
3849
|
+
if (live.draftTimer) clearTimeout(live.draftTimer);
|
|
3727
3850
|
if (live.workTimer) clearTimeout(live.workTimer);
|
|
3728
3851
|
await disposeBrain(live, 'shutdown').catch(() => {});
|
|
3729
3852
|
live.record.status = 'idle';
|
|
@@ -3750,7 +3873,7 @@ export function createAssistantRuntime({
|
|
|
3750
3873
|
broadcastSync = (message) => { try { originalBroadcast(message); } catch {} if (message?.type === 'assistant:permission-request' || message?.type === 'assistant:permission-resolved') onPermissionBroadcast(message); };
|
|
3751
3874
|
|
|
3752
3875
|
return {
|
|
3753
|
-
handleWebSocket, listSessions, getSession, createSession, updateSession, closeSession, destroySession,
|
|
3876
|
+
handleWebSocket, listSessions, getSession, createSession, updateSession, closeSession, destroySession, removeSession,
|
|
3754
3877
|
resolveTerminal, accountInUse, ownsIsolatedServe, noteDispatch, subscribe, shutdown,
|
|
3755
3878
|
observeBroadcast: onPermissionBroadcast,
|
|
3756
3879
|
testDensityFor, routerSession, routerSend, routerEvent, routerMailbox, routerContinue, routerSinks, routerRouted, routerRouteFailed, routerComputerApproved, gateCheck, isPlanning, isPlanReadOnly,
|
|
@@ -43,7 +43,39 @@ const DISCOVERY_TIMEOUT_MS = 15000;
|
|
|
43
43
|
const CACHE_TTL_MS = 10 * 60 * 1000;
|
|
44
44
|
|
|
45
45
|
let _cache = { at: 0, key: '', models: [] };
|
|
46
|
-
|
|
46
|
+
const _inflight = new Map(); // cache key → the discovery running for it
|
|
47
|
+
// Where the last verified list is kept across restarts ({ read(), write(entry) },
|
|
48
|
+
// lib/launch-cache.js createSnapshotStore): a start answers with it at once and
|
|
49
|
+
// asks the CLI again in the background.
|
|
50
|
+
let _store = null;
|
|
51
|
+
let _storeRead = false;
|
|
52
|
+
|
|
53
|
+
export function setClaudeModelStore(store) {
|
|
54
|
+
_store = store && typeof store.read === 'function' && typeof store.write === 'function' ? store : null;
|
|
55
|
+
_storeRead = false;
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
// The list the last run verified, for this very binary and account: given at once
|
|
59
|
+
// after a restart (as an old answer, so the first read asks the CLI again).
|
|
60
|
+
function adoptStoredModels(key) {
|
|
61
|
+
if (_storeRead || !_store) return;
|
|
62
|
+
_storeRead = true;
|
|
63
|
+
if (_cache.models.length) return;
|
|
64
|
+
try {
|
|
65
|
+
const saved = _store.read();
|
|
66
|
+
const models = saved?.key === key && Array.isArray(saved.models)
|
|
67
|
+
? saved.models.filter(m => m && typeof m === 'object' && typeof m.id === 'string' && m.id)
|
|
68
|
+
: [];
|
|
69
|
+
if (models.length) _cache = { at: 0, key, models };
|
|
70
|
+
} catch { /* nothing kept: the first read asks the CLI */ }
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
// What the list depends on: the binary (an update changes it, binaryIdentity) and
|
|
74
|
+
// the account it was read under (another account can be entitled to other models).
|
|
75
|
+
function cacheKeyOf(bin, account) {
|
|
76
|
+
const who = String(account || '');
|
|
77
|
+
return who ? `${binaryIdentity(bin)}#${who}` : binaryIdentity(bin);
|
|
78
|
+
}
|
|
47
79
|
|
|
48
80
|
// Who else keeps a copy of this list (the Assistant's model catalog). Told when a
|
|
49
81
|
// discovery returns a list that differs from the one before it, so a copy is
|
|
@@ -286,37 +318,55 @@ export function queryClaudeCliModels(claudeBin, { cwd, timeoutMs = DISCOVERY_TIM
|
|
|
286
318
|
}
|
|
287
319
|
|
|
288
320
|
// Cached discovery. `source` lets the UI distinguish a verified list from the
|
|
289
|
-
// baked-in fallback. Cache is keyed on the binary's identity
|
|
290
|
-
//
|
|
291
|
-
|
|
321
|
+
// baked-in fallback. Cache is keyed on the binary's identity (and the account
|
|
322
|
+
// the list was read under, `account`), so switching the configured CLI
|
|
323
|
+
// (Settings > Terminal), updating it or signing in to another account
|
|
324
|
+
// re-discovers. A list that is merely old is still given at once, and the CLI is
|
|
325
|
+
// asked again in the background (one discovery at a time): only a first read, a
|
|
326
|
+
// changed key or `force` waits for the CLI.
|
|
327
|
+
export async function discoverClaudeModels(claudeBin, { force = false, cwd, query = queryClaudeCliModels, account = '' } = {}) {
|
|
292
328
|
const bin = String(claudeBin || '');
|
|
293
|
-
const key =
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
329
|
+
const key = cacheKeyOf(bin, account);
|
|
330
|
+
adoptStoredModels(key);
|
|
331
|
+
const known = _cache.models.length && _cache.key === key;
|
|
332
|
+
if (!force && known) {
|
|
333
|
+
if (Date.now() - _cache.at >= CACHE_TTL_MS) discover(bin, key, cwd, query).catch(() => {});
|
|
334
|
+
return { source: 'cache', models: _cache.models };
|
|
335
|
+
}
|
|
336
|
+
return discover(bin, key, cwd, query);
|
|
337
|
+
}
|
|
338
|
+
|
|
339
|
+
function discover(bin, key, cwd, query) {
|
|
340
|
+
if (_inflight.has(key)) return _inflight.get(key);
|
|
341
|
+
const job = (async () => {
|
|
301
342
|
try {
|
|
302
343
|
const raw = await query(bin, { cwd });
|
|
303
344
|
const models = normalizeClaudeModels(raw);
|
|
304
345
|
if (models.length) {
|
|
305
346
|
const changed = claudeModelsSignature(models) !== claudeModelsSignature(_cache.models);
|
|
306
347
|
_cache = { at: Date.now(), key, models };
|
|
348
|
+
try { _store?.write({ key, at: _cache.at, models }); } catch { /* kept in memory still */ }
|
|
307
349
|
if (changed) notifyModelsChanged(models);
|
|
308
350
|
return { source: 'cli', models };
|
|
309
351
|
}
|
|
310
352
|
return { source: 'fallback', models: [...CLAUDE_FALLBACK_MODELS] };
|
|
311
353
|
} finally {
|
|
312
|
-
_inflight
|
|
354
|
+
if (_inflight.get(key) === job) _inflight.delete(key);
|
|
313
355
|
}
|
|
314
356
|
})();
|
|
315
|
-
|
|
357
|
+
_inflight.set(key, job);
|
|
358
|
+
return job;
|
|
359
|
+
}
|
|
360
|
+
|
|
361
|
+
/** The kept list is due again: the next read still answers with it and asks the CLI in the background. */
|
|
362
|
+
export function markClaudeModelsStale() {
|
|
363
|
+
_cache = { ..._cache, at: 0 };
|
|
316
364
|
}
|
|
317
365
|
|
|
318
366
|
export function clearClaudeModelCache() {
|
|
319
367
|
_cache = { at: 0, key: '', models: [] };
|
|
368
|
+
_inflight.clear();
|
|
369
|
+
_storeRead = !!_store;
|
|
320
370
|
_skewCache = { key: null, result: undefined };
|
|
321
371
|
_skewInflight.clear();
|
|
322
372
|
}
|
|
@@ -9,7 +9,7 @@
|
|
|
9
9
|
import { spawn } from 'node:child_process';
|
|
10
10
|
import { verifyOpenAiApiKey } from './claude-profile-api-key.js';
|
|
11
11
|
import { validateProviderApiKey } from './provider-panel-api-key-auth.js';
|
|
12
|
-
import { applyCodexLaunchEnv } from './codex-accounts.js';
|
|
12
|
+
import { applyCodexLaunchEnv, codexLaunchArgs } from './codex-accounts.js';
|
|
13
13
|
|
|
14
14
|
const fail = (message, status = 409, code = null) => Object.assign(new Error(message), { status, ...(code ? { code } : {}) });
|
|
15
15
|
|
|
@@ -32,13 +32,15 @@ export function createCodexAccountAuth({
|
|
|
32
32
|
}
|
|
33
33
|
// Codex run under the account's own store: inherited credentials out, its
|
|
34
34
|
// CODEX_HOME in, never the key SynaBun holds (that is not Codex's store).
|
|
35
|
-
|
|
35
|
+
// The launch's overrides (the Windows sandbox of the Admin sandbox setting) follow the subcommand.
|
|
36
|
+
function launch(id, words) {
|
|
36
37
|
account(id);
|
|
37
38
|
const plan = accounts.launchFor(id);
|
|
38
39
|
if (!plan.ok) throw fail(plan.message, 404);
|
|
39
40
|
prepareConfig(plan.home);
|
|
40
41
|
let file = codexBin();
|
|
41
42
|
if (!file) throw fail('Codex CLI not found. Install Codex to sign in.', 503);
|
|
43
|
+
const args = [...words, ...codexLaunchArgs(plan)];
|
|
42
44
|
const script = /\.[cm]?js$/i.test(file);
|
|
43
45
|
const shell = process.platform === 'win32' && /\.(cmd|bat)$/i.test(file);
|
|
44
46
|
const proc = spawnProcess(script ? process.execPath : file, script ? [file, ...args] : args, {
|
|
@@ -32,6 +32,7 @@ import { dirname, join, resolve, sep } from 'node:path';
|
|
|
32
32
|
import { homedir } from 'node:os';
|
|
33
33
|
import { readProfileApiKey, saveProfileApiKey, clearProfileApiKey } from './claude-profile-api-key.js';
|
|
34
34
|
import { apiKeyHint, resolveClaudeAuth } from './claude-accounts.js';
|
|
35
|
+
import { normalizeAdminSandbox, sandboxElevationFor } from './agent-sandbox-elevation.js';
|
|
35
36
|
|
|
36
37
|
export const CODEX_DEFAULT_ACCOUNT_ID = 'default';
|
|
37
38
|
export const CODEX_AUTH_MODES = Object.freeze(['subscription', 'apiKey']);
|
|
@@ -123,9 +124,13 @@ export function applyCodexLaunchEnv(base, launch) {
|
|
|
123
124
|
export function codexExecEnv(launch) {
|
|
124
125
|
return { ...(launch?.env || {}), ...(launch?.apiKey ? { CODEX_API_KEY: launch.apiKey } : {}) };
|
|
125
126
|
}
|
|
127
|
+
/** The `-c` overrides every Codex process of the launch starts with: the Windows sandbox the Admin sandbox setting allows. */
|
|
128
|
+
export function codexLaunchArgs(launch) {
|
|
129
|
+
return [...(launch?.configArgs || [])];
|
|
130
|
+
}
|
|
126
131
|
/** The `-c` overrides an app-server of the account starts with (before the subcommand). */
|
|
127
132
|
export function codexAppServerArgs(launch) {
|
|
128
|
-
return launch?.apiKey ?
|
|
133
|
+
return [...codexLaunchArgs(launch), ...(launch?.apiKey ? CODEX_EPHEMERAL_STORE_ARGS : [])];
|
|
129
134
|
}
|
|
130
135
|
|
|
131
136
|
export function createCodexAccounts({
|
|
@@ -141,6 +146,8 @@ export function createCodexAccounts({
|
|
|
141
146
|
statusTimeoutMs = 20_000,
|
|
142
147
|
// Called before a new account links Default's config.toml (server.js repairs it there).
|
|
143
148
|
prepareDefaultConfig = () => {},
|
|
149
|
+
// () => the Admin sandbox setting (lib/agent-sandbox-setting.js): which Windows sandbox every launch may use.
|
|
150
|
+
adminSandbox = () => false,
|
|
144
151
|
} = {}) {
|
|
145
152
|
if (!dataHome) throw new Error('createCodexAccounts requires dataHome');
|
|
146
153
|
const registryPath = resolve(dataHome, 'data', 'codex-accounts.json');
|
|
@@ -273,11 +280,17 @@ export function createCodexAccounts({
|
|
|
273
280
|
}
|
|
274
281
|
const { row, key } = describeProfile(profile, data);
|
|
275
282
|
const apiKey = row.mode === 'apiKey' && row.apiKey.source === 'synabun' && key ? key : null;
|
|
283
|
+
// A launch override, never written into config.toml: Default's home is the user's own ~/.codex.
|
|
284
|
+
let on = false;
|
|
285
|
+
try { on = normalizeAdminSandbox(adminSandbox()); } catch { on = false; }
|
|
286
|
+
const sandbox = sandboxElevationFor('codex', on);
|
|
276
287
|
return {
|
|
277
288
|
ok: true, accountId: wanted, label: row.label, mode: row.mode, signedIn: row.signedIn, identity: row.identity, home: row.home,
|
|
278
289
|
env: { CODEX_HOME: row.home }, unset: [...CODEX_CREDENTIAL_ENV], apiKey,
|
|
279
290
|
// Which credential a process started with: a change means the account's idle processes restart.
|
|
280
291
|
credential: [row.mode || 'none', row.apiKey.source || '', row.apiKey.hint || '', row.subscription.email || ''].join(':'),
|
|
292
|
+
// The Windows sandbox it may use ('elevated' | 'unelevated'): a change restarts idle app-servers too.
|
|
293
|
+
windowsSandbox: sandbox.value, configArgs: sandbox.args,
|
|
281
294
|
};
|
|
282
295
|
}
|
|
283
296
|
|