@vantran-se/openchamber-web 1.24.4 → 2.0.1
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/README.md +2 -8
- package/bin/lib/commands-connect-url.js +3 -8
- package/bin/lib/commands-tunnel.js +3 -0
- package/dist/assets/{CodeMirrorCommentWidgets-B4a0JkUz.js → CodeMirrorCommentWidgets-ntXIbhV2.js} +1 -1
- package/dist/assets/DiffView-CjxUovbM.js +4 -0
- package/dist/assets/FilesView-DFWD0RQR.js +17 -0
- package/dist/assets/{GitView-Byu2DY7s.js → GitView-BWa7e5vw.js} +4 -4
- package/dist/assets/{GuestAttachDialog-B808E0-d.js → GuestAttachDialog-DdOuyZzp.js} +1 -1
- package/dist/assets/GuestSurfacePane-DDfzid3U.js +1 -0
- package/dist/assets/{JsonTreeView-VW_7czo3.js → JsonTreeView-3sGwqexh.js} +1 -1
- package/dist/assets/LinearIssuesView-C6dpIdjw.js +1 -0
- package/dist/assets/MarkdownImageGallery-Q7YR_tl4.js +1 -0
- package/dist/assets/MarkdownRendererImpl-DxDV56bL.js +12 -0
- package/dist/assets/OnboardingScreen-rK4Stg__.js +1 -0
- package/dist/assets/{PatchDiff-DCjGhlYV.js → PatchDiff-DS-IMU1j.js} +1 -1
- package/dist/assets/{PierreDiffViewer-CEDZNkU2.js → PierreDiffViewer-DW23KWKZ.js} +1 -1
- package/dist/assets/PlanView-BCk_VobP.js +5 -0
- package/dist/assets/PluginPane-BPP1dbck.js +3 -0
- package/dist/assets/SettingsView-kMmrpn43.js +29 -0
- package/dist/assets/SettingsWindow-BpvD6IYQ.js +1 -0
- package/dist/assets/SubmoduleDiffSummary-BLttSS1X.js +1 -0
- package/dist/assets/ToolOutputDialog-CtqDqbyr.js +15 -0
- package/dist/assets/ToolPartDiffPreview-5FcKdyRy.js +8 -0
- package/dist/assets/{VirtualizedFileDiff-NU0FHFhT.js → VirtualizedFileDiff-C763hNCR.js} +4 -4
- package/dist/assets/{WalkthroughView-BZyjhqHv.js → WalkthroughView-lap5btCF.js} +2 -2
- package/dist/assets/appThemeRegistry-u4zw1l0B.js +1 -0
- package/dist/assets/{commitAndPush-BDftrjr6.js → commitAndPush-CwGJfJG-.js} +1 -1
- package/dist/assets/{computeVirtualFileMetrics-DlWlEM3x.js → computeVirtualFileMetrics-DW5jjX4n.js} +1 -1
- package/dist/assets/de-CndEg67T.js +10 -0
- package/dist/assets/es-DglvPlaC.js +16 -0
- package/dist/assets/fr-DejPCpbS.js +14 -0
- package/dist/assets/index-C2r64QfD.js +1 -0
- package/dist/assets/index-CLcM8HKx.css +1 -0
- package/dist/assets/index-CvLgnuNI.js +41 -0
- package/dist/assets/{isDiffPlainText-CO4e5J_S.js → isDiffPlainText-D47a6hMP.js} +1 -1
- package/dist/assets/{isFilePlainText-ue6kCou7.js → isFilePlainText-B-mGgeKl.js} +1 -1
- package/dist/assets/ja-CVpQawCd.js +16 -0
- package/dist/assets/ko-Bw446h9j.js +16 -0
- package/dist/assets/main-Bz4WWXbr.js +2 -0
- package/dist/assets/main-oreqDsOV.js +896 -0
- package/dist/assets/{markdownCore-CK48LG0z.js → markdownCore-D2e5sp9y.js} +4 -4
- package/dist/assets/miniChat-D1v2gsBI.js +2 -0
- package/dist/assets/mobile-DBj3lCf2.js +2 -0
- package/dist/assets/{patchFileDiff-D7QVlovD.js → patchFileDiff-BpeUOV91.js} +3 -3
- package/dist/assets/pl-BYNlPdhm.js +16 -0
- package/dist/assets/pt-BR-CL-Yfv9H.js +16 -0
- package/dist/assets/renderElectronMiniChatApp-DVtfEB2z.js +2 -0
- package/dist/assets/renderMobileApp-DFp9-xbG.js +25 -0
- package/dist/assets/runtimeEndpointReset-CsIpUep1.js +27 -0
- package/dist/assets/scheduledTasksApi-B5OHVpPM.js +1 -0
- package/dist/assets/{shikiHighlight-BPu3JiQs.js → shikiHighlight-DNm2Z_Jc.js} +1 -1
- package/dist/assets/{textMateThemeFromAppTheme-DWqRPo9A.js → textMateThemeFromAppTheme-DGF2kG7g.js} +1 -1
- package/dist/assets/tr-DzmbxLy-.js +7 -0
- package/dist/assets/uk-C7vQnwro.js +16 -0
- package/dist/assets/useAppFontEffects-Ci3FEaPf.js +7337 -0
- package/dist/assets/{useInlineCommentController-CgS0fnw_.js → useInlineCommentController-CuUuakrt.js} +2 -2
- package/dist/assets/useRootScrollLock-CQIsyERq.js +2 -0
- package/dist/assets/{vendor-codemirror-language-data-Bx2EHc1O.js → vendor-codemirror-language-data-CQa7_1cr.js} +2 -2
- package/dist/assets/vendor-cron-parser-CjvYVigk.js +2 -0
- package/dist/assets/vendor-opencode-client-_BAHQo4R.js +12 -0
- package/dist/assets/{vendor-remixicon-react-BDmGmFCA.js → vendor-remixicon-react-D6dZ0UwF.js} +1 -1
- package/dist/assets/{vendor-zod-CgAdXWZO.js → vendor-zod-Gea9uBlY.js} +1 -1
- package/dist/assets/{web-components-DxX8bZ1o.js → web-components-B6tKQyJN.js} +2 -2
- package/dist/assets/zh-CN-Cl0srS-z.js +16 -0
- package/dist/assets/zh-TW-DtII5bDb.js +16 -0
- package/dist/index.html +13 -7
- package/dist/mini-chat.html +5 -5
- package/dist/mobile.html +5 -5
- package/package.json +6 -5
- package/server/index.d.ts +1 -0
- package/server/index.js +246 -91
- package/server/lib/agent-tool/DOCUMENTATION.md +32 -15
- package/server/lib/agent-tool/runtime.js +135 -54
- package/server/lib/agent-tool/runtime.test.js +155 -87
- package/server/lib/browser-control/DOCUMENTATION.md +37 -2
- package/server/lib/browser-control/provider.js +217 -0
- package/server/lib/browser-control/provider.test.js +251 -0
- package/server/lib/context-obligatory/runtime.js +61 -50
- package/server/lib/context-obligatory/runtime.test.js +62 -162
- package/server/lib/event-stream/DOCUMENTATION.md +12 -1
- package/server/lib/event-stream/delta-coalescer.js +0 -0
- package/server/lib/event-stream/delta-coalescer.test.js +68 -57
- package/server/lib/event-stream/directory-ws-bridge.js +1 -1
- package/server/lib/event-stream/global-hub.js +10 -1
- package/server/lib/event-stream/global-hub.test.js +27 -26
- package/server/lib/event-stream/index.js +6 -0
- package/server/lib/event-stream/protocol.js +26 -19
- package/server/lib/event-stream/protocol.test.js +18 -7
- package/server/lib/event-stream/rebind.test.js +5 -5
- package/server/lib/event-stream/runtime.test.js +17 -15
- package/server/lib/event-stream/translate-v2.js +313 -0
- package/server/lib/event-stream/translate-v2.test.js +209 -0
- package/server/lib/event-stream/upstream-reader.test.js +16 -16
- package/server/lib/fs/DOCUMENTATION.md +4 -2
- package/server/lib/fs/byte-range.js +35 -0
- package/server/lib/fs/byte-range.test.js +31 -0
- package/server/lib/fs/routes.js +47 -42
- package/server/lib/fs/routes.test.js +123 -18
- package/server/lib/git/service.js +12 -0
- package/server/lib/github/DOCUMENTATION.md +1 -1
- package/server/lib/github/pr-status.js +22 -2
- package/server/lib/github/pr-status.test.js +27 -14
- package/server/lib/guests/DOCUMENTATION.md +13 -0
- package/server/lib/guests/catalog.js +12 -0
- package/server/lib/guests/catalog.test.js +33 -0
- package/server/lib/guests/routes.js +10 -1
- package/server/lib/guests/service.js +192 -14
- package/server/lib/guests/service.test.js +201 -1
- package/server/lib/guests/surface.js +630 -0
- package/server/lib/guests/surface.test.js +486 -0
- package/server/lib/markdown-image-grants/routes.js +18 -5
- package/server/lib/markdown-image-grants/routes.test.js +9 -6
- package/server/lib/message-queue/DOCUMENTATION.md +33 -22
- package/server/lib/message-queue/runtime.js +155 -100
- package/server/lib/message-queue/runtime.test.js +168 -82
- package/server/lib/notifications/DOCUMENTATION.md +28 -0
- package/server/lib/notifications/control-stream.http.test.js +68 -0
- package/server/lib/notifications/emitter-runtime.js +15 -0
- package/server/lib/notifications/emitter-runtime.test.js +32 -0
- package/server/lib/notifications/push-runtime.js +5 -1
- package/server/lib/notifications/push-runtime.test.js +2 -2
- package/server/lib/notifications/routes.js +1 -1
- package/server/lib/notifications/runtime.js +115 -26
- package/server/lib/notifications/template-runtime.js +13 -15
- package/server/lib/notifications/template-runtime.test.js +16 -9
- package/server/lib/notifications/trigger-runtime.test.js +187 -0
- package/server/lib/openchamber-control/DOCUMENTATION.md +10 -0
- package/server/lib/openchamber-control/actions.js +3 -2
- package/server/lib/openchamber-control/error.js +1 -1
- package/server/lib/openchamber-control/file-open.js +59 -0
- package/server/lib/openchamber-control/file-open.test.js +57 -0
- package/server/lib/openchamber-control/routes.test.js +12 -0
- package/server/lib/openchamber-control/service.js +102 -49
- package/server/lib/openchamber-control/service.test.js +84 -44
- package/server/lib/openchamber-sessions/archive-store.js +224 -0
- package/server/lib/openchamber-sessions/archive-store.test.js +187 -0
- package/server/lib/openchamber-sessions/opencode-client.js +22 -0
- package/server/lib/openchamber-sessions/routes.js +398 -328
- package/server/lib/openchamber-sessions/routes.test.js +777 -740
- package/server/lib/openchamber-sessions/session-metadata-store.js +285 -0
- package/server/lib/openchamber-sessions/session-metadata-store.test.js +259 -0
- package/server/lib/opencode/DOCUMENTATION.md +449 -29
- package/server/lib/opencode/agents.js +233 -327
- package/server/lib/opencode/auth.js +41 -44
- package/server/lib/opencode/auth.test.js +92 -0
- package/server/lib/opencode/cli-upgrade.d.ts +4 -0
- package/server/lib/opencode/cli-upgrade.js +18 -0
- package/server/lib/opencode/cli-upgrade.test.js +36 -0
- package/server/lib/opencode/commands.js +164 -145
- package/server/lib/opencode/compatibility.d.ts +16 -0
- package/server/lib/opencode/compatibility.js +88 -0
- package/server/lib/opencode/compatibility.test.js +62 -0
- package/server/lib/opencode/config-entity-routes.js +58 -29
- package/server/lib/opencode/config-entity-v2.test.js +290 -0
- package/server/lib/opencode/config-mutation-response.js +17 -7
- package/server/lib/opencode/config-mutation-response.test.js +4 -7
- package/server/lib/opencode/config-paths.test.js +2 -2
- package/server/lib/opencode/config-v2.d.ts +183 -0
- package/server/lib/opencode/config-v2.js +801 -0
- package/server/lib/opencode/config-v2.test.js +466 -0
- package/server/lib/opencode/credential-db.js +144 -0
- package/server/lib/opencode/credential-db.test.js +104 -0
- package/server/lib/opencode/env-runtime.js +48 -9
- package/server/lib/opencode/env-runtime.test.js +45 -0
- package/server/lib/opencode/feature-routes-runtime.js +15 -5
- package/server/lib/opencode/lifecycle-process.test.js +7 -4
- package/server/lib/opencode/lifecycle.js +85 -30
- package/server/lib/opencode/lifecycle.test.js +80 -8
- package/server/lib/opencode/login-shell-env.js +27 -0
- package/server/lib/opencode/managed-config-file.js +119 -0
- package/server/lib/opencode/managed-config-file.test.js +152 -0
- package/server/lib/opencode/managed-plugin-config.js +33 -13
- package/server/lib/opencode/mcp.js +43 -149
- package/server/lib/opencode/network-runtime.js +6 -7
- package/server/lib/opencode/openchamber-routes.test.js +2 -5
- package/server/lib/opencode/plugin-routes.js +3 -3
- package/server/lib/opencode/plugin-routes.test.js +6 -24
- package/server/lib/opencode/plugins.js +91 -40
- package/server/lib/opencode/plugins.test.js +28 -15
- package/server/lib/opencode/providers.js +63 -83
- package/server/lib/opencode/providers.test.js +128 -59
- package/server/lib/opencode/proxy-agent-wiring.test.js +4 -2
- package/server/lib/opencode/proxy.js +179 -129
- package/server/lib/opencode/pwa-manifest-routes.js +4 -2
- package/server/lib/opencode/pwa-manifest-routes.test.js +3 -2
- package/server/lib/opencode/response-envelope.js +14 -0
- package/server/lib/opencode/response-envelope.test.js +23 -0
- package/server/lib/opencode/routes-upgrade.test.js +73 -116
- package/server/lib/opencode/routes.js +121 -428
- package/server/lib/opencode/server-utils-runtime.js +10 -4
- package/server/lib/opencode/session-activity.js +78 -0
- package/server/lib/opencode/session-runtime.js +21 -10
- package/server/lib/opencode/session-runtime.test.js +9 -9
- package/server/lib/opencode/settings-helpers.js +9 -9
- package/server/lib/opencode/settings-helpers.test.js +7 -12
- package/server/lib/opencode/settings-registry.json +6 -8
- package/server/lib/opencode/settings-runtime.js +18 -1
- package/server/lib/opencode/settings-runtime.test.js +31 -2
- package/server/lib/opencode/shared.js +54 -22
- package/server/lib/opencode/shared.test.js +8 -4
- package/server/lib/opencode/shutdown-runtime.js +54 -7
- package/server/lib/opencode/shutdown-runtime.test.js +224 -30
- package/server/lib/opencode/skill-routes.js +23 -24
- package/server/lib/opencode/skills.js +7 -5
- package/server/lib/opencode/tunnel-wiring-runtime.js +2 -1
- package/server/lib/opencode/upgrade-capability.test.js +1 -1
- package/server/lib/opencode/v1-migration-topup.js +288 -0
- package/server/lib/opencode/v1-migration-topup.test.js +266 -0
- package/server/lib/opencode/v2-install.d.ts +8 -0
- package/server/lib/opencode/v2-install.js +158 -0
- package/server/lib/opencode/v2-install.test.js +124 -0
- package/server/lib/opencode/watcher.js +10 -3
- package/server/lib/opencode/watcher.test.js +17 -21
- package/server/lib/opencode/websearch-config.js +66 -0
- package/server/lib/package-manager.js +55 -68
- package/server/lib/package-manager.test.js +241 -75
- package/server/lib/permission-auto-accept/runtime.js +38 -22
- package/server/lib/permission-auto-accept/runtime.test.js +39 -17
- package/server/lib/quota/DOCUMENTATION.md +4 -0
- package/server/lib/quota/providers/xai.js +4 -4
- package/server/lib/relay/tunnel-host.js +4 -1
- package/server/lib/relay/tunnel-host.test.js +7 -0
- package/server/lib/routing/DOCUMENTATION.md +52 -21
- package/server/lib/routing/defaults.js +23 -6
- package/server/lib/routing/jev.js +17 -7
- package/server/lib/routing/routes.http.test.js +68 -33
- package/server/lib/routing/routes.js +65 -22
- package/server/lib/routing/runtime.js +145 -48
- package/server/lib/routing/runtime.test.js +79 -55
- package/server/lib/scheduled-tasks/DOCUMENTATION.md +4 -0
- package/server/lib/scheduled-tasks/issue-2710-double-execution.test.js +51 -46
- package/server/lib/scheduled-tasks/runtime.js +81 -74
- package/server/lib/scheduled-tasks/runtime.test.js +53 -1
- package/server/lib/session-assist/DOCUMENTATION.md +8 -3
- package/server/lib/session-assist/context.js +122 -46
- package/server/lib/session-assist/context.test.js +117 -49
- package/server/lib/session-assist/runtime.js +52 -22
- package/server/lib/session-assist/runtime.test.js +145 -173
- package/server/lib/session-goal/DOCUMENTATION.md +23 -15
- package/server/lib/session-goal/create.js +9 -12
- package/server/lib/session-goal/create.test.js +27 -28
- package/server/lib/session-goal/runtime.js +164 -77
- package/server/lib/session-goal/runtime.test.js +271 -519
- package/server/lib/session-knowledge/DOCUMENTATION.md +5 -0
- package/server/lib/session-knowledge/runtime.js +59 -41
- package/server/lib/session-knowledge/runtime.test.js +90 -20
- package/server/lib/small-model/DOCUMENTATION.md +154 -208
- package/server/lib/small-model/client.js +113 -0
- package/server/lib/small-model/index.js +296 -158
- package/server/lib/small-model/index.test.js +423 -256
- package/server/lib/small-model/routes.js +1 -1
- package/server/lib/spaces/DOCUMENTATION.md +807 -0
- package/server/lib/spaces/code-in-bait.js +185 -0
- package/server/lib/spaces/code-in.js +641 -0
- package/server/lib/spaces/code-in.test.js +1048 -0
- package/server/lib/spaces/errors.js +8 -0
- package/server/lib/spaces/exec-http.js +94 -0
- package/server/lib/spaces/gatekeeper-channel.js +202 -0
- package/server/lib/spaces/gatekeeper-channel.test.js +215 -0
- package/server/lib/spaces/gatekeeper-program.cjs +914 -0
- package/server/lib/spaces/gatekeeper-program.test.js +1391 -0
- package/server/lib/spaces/hardening.js +457 -0
- package/server/lib/spaces/hardening.test.js +368 -0
- package/server/lib/spaces/host-git.js +127 -0
- package/server/lib/spaces/host-git.test.js +137 -0
- package/server/lib/spaces/labels.js +234 -0
- package/server/lib/spaces/labels.test.js +219 -0
- package/server/lib/spaces/layout.js +184 -0
- package/server/lib/spaces/layout.test.js +30 -0
- package/server/lib/spaces/manager.js +82 -0
- package/server/lib/spaces/manager.test.js +114 -0
- package/server/lib/spaces/places/code-in.docker.live.test.js +216 -0
- package/server/lib/spaces/places/contract-suite.js +156 -0
- package/server/lib/spaces/places/contract.docker.live.test.js +7 -0
- package/server/lib/spaces/places/contract.test.js +6 -0
- package/server/lib/spaces/places/docker-engine.js +126 -0
- package/server/lib/spaces/places/docker-live-support.js +202 -0
- package/server/lib/spaces/places/docker-tools.js +186 -0
- package/server/lib/spaces/places/docker.js +587 -0
- package/server/lib/spaces/places/docker.test.js +1610 -0
- package/server/lib/spaces/places/escape-suite.js +1018 -0
- package/server/lib/spaces/places/escape.docker.live.test.js +7 -0
- package/server/lib/spaces/places/fake-docker.js +375 -0
- package/server/lib/spaces/places/memory-place.js +103 -0
- package/server/lib/spaces/places/packed.docker.live.test.js +77 -0
- package/server/lib/spaces/places/registry.js +43 -0
- package/server/lib/spaces/places/registry.test.js +50 -0
- package/server/lib/spaces/places/server.docker.live.test.js +225 -0
- package/server/lib/spaces/run-command.js +261 -0
- package/server/lib/spaces/run-command.test.js +396 -0
- package/server/lib/spaces/space-server.js +190 -0
- package/server/lib/spaces/space-server.test.js +335 -0
- package/server/lib/spaces/tools-filler.js +82 -0
- package/server/lib/spaces/tools-filler.test.js +148 -0
- package/server/lib/spaces/tools-pack.js +49 -0
- package/server/lib/spaces/tools-pack.test.js +57 -0
- package/server/lib/spaces/tools.js +138 -0
- package/server/lib/spaces/tools.test.js +153 -0
- package/server/lib/tts/openai-sdk.js +11 -0
- package/server/lib/tts/service.js +7 -5
- package/server/lib/tts/stt.js +3 -2
- package/server/lib/tunnels/DOCUMENTATION.md +2 -0
- package/server/lib/tunnels/routes.js +7 -0
- package/server/lib/tunnels/routes.test.js +55 -0
- package/server/lib/ui-auth/ui-auth.js +38 -2
- package/server/lib/ui-auth/ui-auth.test.js +42 -0
- package/server/lib/ui-auth/ui-passkeys.js +12 -10
- package/server/lib/walkthrough/DOCUMENTATION.md +10 -1
- package/server/lib/walkthrough/pull-request.js +61 -8
- package/server/lib/walkthrough/pull-request.test.js +54 -1
- package/server/lib/walkthrough/routes.js +20 -0
- package/server/lib/walkthrough/routes.test.js +19 -0
- package/server/opencode-proxy.test.js +190 -166
- package/server/opencode-worktree-readiness.test.js +5 -4
- package/dist/assets/DiffView-B2CD9wC8.js +0 -4
- package/dist/assets/FilesView-C4vMFclc.js +0 -13
- package/dist/assets/LinearIssuesView-EzGNCGrd.js +0 -1
- package/dist/assets/MarkdownImageGallery-B2YUDFaB.js +0 -1
- package/dist/assets/MarkdownRendererImpl-B4ikIzR3.js +0 -12
- package/dist/assets/OnboardingScreen-CQHBSTEi.js +0 -1
- package/dist/assets/PlanView-D3x-pTkZ.js +0 -5
- package/dist/assets/PluginPane-DEcgDQ9h.js +0 -3
- package/dist/assets/SettingsView-CSinuH-1.js +0 -29
- package/dist/assets/SettingsWindow-B5CHoJFZ.js +0 -1
- package/dist/assets/SubmoduleDiffSummary-oxeACCWs.js +0 -1
- package/dist/assets/ToolOutputDialog-tLNWmfcW.js +0 -15
- package/dist/assets/ToolPartDiffPreview-CflzmK-x.js +0 -8
- package/dist/assets/appThemeRegistry-DLicw4dH.js +0 -1
- package/dist/assets/de-Bro6_zyl.js +0 -10
- package/dist/assets/es-Bb9XQZvd.js +0 -16
- package/dist/assets/fr-Dgfzn-IL.js +0 -14
- package/dist/assets/index-CtQNmqUL.js +0 -1
- package/dist/assets/index-DqaMWNrC.css +0 -1
- package/dist/assets/index-Dqc6USl3.js +0 -40
- package/dist/assets/ja-BYsakGFh.js +0 -16
- package/dist/assets/ko-BSaQz9aN.js +0 -16
- package/dist/assets/main-B62_pjL5.js +0 -2
- package/dist/assets/main-BEdcOI2P.js +0 -896
- package/dist/assets/miniChat-LT8Rqofr.js +0 -2
- package/dist/assets/mobile-CqarEynh.js +0 -2
- package/dist/assets/pl-OIviPdoj.js +0 -16
- package/dist/assets/pt-BR-Cltg-E6s.js +0 -16
- package/dist/assets/renderElectronMiniChatApp-COyLTtZx.js +0 -2
- package/dist/assets/renderMobileApp-BC1MHg6g.js +0 -25
- package/dist/assets/runtimeEndpointReset-DdrazOVH.js +0 -25
- package/dist/assets/scheduledTasksApi-B2SWMGEU.js +0 -1
- package/dist/assets/tr-CQI-KPre.js +0 -7
- package/dist/assets/uk-CqW7R4DA.js +0 -16
- package/dist/assets/useAppFontEffects-ne84JBVL.js +0 -7333
- package/dist/assets/useRootScrollLock-Cpf1qoGp.js +0 -2
- package/dist/assets/vendor-cron-parser-CUcP7OfX.js +0 -2
- package/dist/assets/vendor-opencode-sdk-BJ73u-bH.js +0 -7
- package/dist/assets/zh-CN-CVZG_o_J.js +0 -16
- package/dist/assets/zh-TW-D5ZxzCZp.js +0 -16
- package/server/lib/opencode/mcp-oauth-callback.test.js +0 -111
- package/server/lib/routing/feature-flag.js +0 -11
- package/server/lib/small-model/call.js +0 -851
- package/server/lib/small-model/call.test.js +0 -1292
- package/server/lib/small-model/catalog.js +0 -13
- package/server/lib/small-model/resolve.js +0 -131
- package/server/lib/small-model/resolve.test.js +0 -197
- package/server/lib/small-model/runtime-providers.js +0 -164
- package/server/lib/small-model/runtime-providers.test.js +0 -118
- package/server/lib/system-prompt/DOCUMENTATION.md +0 -36
- package/server/lib/system-prompt/runtime.js +0 -49
- package/server/lib/system-prompt/runtime.test.js +0 -76
- package/server/lib/walkthrough/reproduce-2607.test.js +0 -148
package/server/index.js
CHANGED
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
import { installOpenCodeV2, supportsOpenCodeV2Install } from './lib/opencode/v2-install.js';
|
|
2
|
+
import { describeOpenCodeCompatibility, readOpenCodeCliVersion, readExternalOpenCodeVersion } from './lib/opencode/compatibility.js';
|
|
1
3
|
import 'reflect-metadata';
|
|
2
4
|
import express from 'express';
|
|
3
5
|
import compression from 'compression';
|
|
@@ -41,6 +43,7 @@ import { createTerminalRuntime } from './lib/terminal/runtime.js';
|
|
|
41
43
|
import { createDictationRuntime } from './lib/dictation/runtime.js';
|
|
42
44
|
import {
|
|
43
45
|
createGlobalUiEventBroadcaster,
|
|
46
|
+
translateWireEvent,
|
|
44
47
|
createGlobalMessageStreamHub,
|
|
45
48
|
createMessageStreamWsRuntime,
|
|
46
49
|
resolveDeltaCoalesceWindowMs,
|
|
@@ -50,6 +53,7 @@ import {
|
|
|
50
53
|
import { createFsSearchRuntime as createFsSearchRuntimeFactory } from './lib/fs/search.js';
|
|
51
54
|
import { createOpenCodeLifecycleRuntime } from './lib/opencode/lifecycle.js';
|
|
52
55
|
import { createOpenCodeEnvRuntime } from './lib/opencode/env-runtime.js';
|
|
56
|
+
import { providedLoginShellEnvSnapshot } from './lib/opencode/login-shell-env.js';
|
|
53
57
|
import { resolveOpenCodeEnvConfig } from './lib/opencode/env-config.js';
|
|
54
58
|
import { createHmrStateRuntime } from './lib/opencode/hmr-state-runtime.js';
|
|
55
59
|
import { createOpenCodeNetworkRuntime } from './lib/opencode/network-runtime.js';
|
|
@@ -70,10 +74,11 @@ import { createServerUtilsRuntime } from './lib/opencode/server-utils-runtime.js
|
|
|
70
74
|
import { createStaticRoutesRuntime } from './lib/opencode/static-routes-runtime.js';
|
|
71
75
|
import { createSettingsRuntime } from './lib/opencode/settings-runtime.js';
|
|
72
76
|
import { createOpenCodeResolutionRuntime } from './lib/opencode/opencode-resolution-runtime.js';
|
|
77
|
+
import { runOpenCodeCliUpgrade } from './lib/opencode/cli-upgrade.js';
|
|
73
78
|
import { resolveOpenCodeUpgradeCapability } from './lib/opencode/upgrade-capability.js';
|
|
74
79
|
import { createBootstrapRuntime } from './lib/opencode/bootstrap-runtime.js';
|
|
75
80
|
import { createSessionRuntime } from './lib/opencode/session-runtime.js';
|
|
76
|
-
import { configureOpenCodeRuntimeProviders, resetOpenCodeRuntimeProviders } from './lib/small-model/
|
|
81
|
+
import { configureOpenCodeRuntimeProviders, resetOpenCodeRuntimeProviders } from './lib/small-model/client.js';
|
|
77
82
|
import { createOpenCodeWatcherRuntime } from './lib/opencode/watcher.js';
|
|
78
83
|
import { createSessionAssistRuntime } from './lib/session-assist/runtime.js';
|
|
79
84
|
import { createSessionGoalRuntime } from './lib/session-goal/runtime.js';
|
|
@@ -95,7 +100,11 @@ import { createPermissionAutoAcceptRuntime } from './lib/permission-auto-accept/
|
|
|
95
100
|
import { createMessageQueueRuntime } from './lib/message-queue/runtime.js';
|
|
96
101
|
import { createRoutingRuntime } from './lib/routing/runtime.js';
|
|
97
102
|
import { createGracefulShutdownRuntime } from './lib/opencode/shutdown-runtime.js';
|
|
98
|
-
import { stopAllGuestServices } from './lib/guests/service.js';
|
|
103
|
+
import { beginGuestServiceHost, beginGuestServiceShutdown, stopAllGuestServices } from './lib/guests/service.js';
|
|
104
|
+
import { findInstalledGuest } from './lib/guests/catalog.js';
|
|
105
|
+
import { extensionsPersistPath } from './lib/guests/persist.js';
|
|
106
|
+
import { createGuestSurfaceRuntime } from './lib/guests/surface.js';
|
|
107
|
+
import { BROWSER_PROVIDER_IDLE_MS } from '@openchamber/sdk';
|
|
99
108
|
import { createProjectConfigRuntime } from './lib/projects/project-config.js';
|
|
100
109
|
import { migrateLegacyUserDirs } from './lib/data-dir-migration.js';
|
|
101
110
|
import { createProjectContextRuntime } from './lib/project-context/runtime.js';
|
|
@@ -111,15 +120,17 @@ import { createRelayService } from './lib/relay/service.js';
|
|
|
111
120
|
import { createRelayHostLock } from './lib/relay/host-lock.js';
|
|
112
121
|
import { createAgentToolRuntime } from './lib/agent-tool/runtime.js';
|
|
113
122
|
import { createBrowserControlBroker } from './lib/browser-control/broker.js';
|
|
123
|
+
import { createBrowserControlRouter } from './lib/browser-control/provider.js';
|
|
114
124
|
import { createDevServerScanner } from './lib/dev-servers/routes.js';
|
|
115
125
|
import { createDevTunnelRuntime } from './lib/dev-tunnel/runtime.js';
|
|
116
126
|
import { registerBrowserControlRoutes } from './lib/browser-control/routes.js';
|
|
117
|
-
import {
|
|
127
|
+
import { createManagedConfigRuntime } from './lib/opencode/managed-config-file.js';
|
|
118
128
|
import { createOpenChamberSessionService } from './lib/openchamber-sessions/routes.js';
|
|
129
|
+
import { createSessionMetadataStore, createOpenCodeSessionMetadata } from './lib/openchamber-sessions/session-metadata-store.js';
|
|
119
130
|
import { createScheduledTaskService } from './lib/scheduled-tasks/service.js';
|
|
120
131
|
import { createOpenChamberControlService } from './lib/openchamber-control/service.js';
|
|
121
132
|
import { OpenChamberControlError } from './lib/openchamber-control/error.js';
|
|
122
|
-
import
|
|
133
|
+
import { createFileOpenRequester } from './lib/openchamber-control/file-open.js';
|
|
123
134
|
import { applyConnectAttemptTimeout } from './lib/network-defaults.js';
|
|
124
135
|
|
|
125
136
|
// Background CLI launches enter here in a fresh process, without CLI defaults.
|
|
@@ -305,7 +316,7 @@ const deleteImportedTheme = (...args) => themeRuntime.deleteImportedTheme(...arg
|
|
|
305
316
|
|
|
306
317
|
let notificationTemplateRuntime = null;
|
|
307
318
|
let agentToolRuntime = null;
|
|
308
|
-
let
|
|
319
|
+
let managedConfigRuntime = null;
|
|
309
320
|
|
|
310
321
|
const createTimeoutSignal = (...args) => notificationTemplateRuntime.createTimeoutSignal(...args);
|
|
311
322
|
const formatProjectLabel = (...args) => notificationTemplateRuntime.formatProjectLabel(...args);
|
|
@@ -399,6 +410,7 @@ const settingsRuntime = createSettingsRuntime({
|
|
|
399
410
|
normalizeManagedRemoteTunnelPresetTokens,
|
|
400
411
|
syncManagedRemoteTunnelConfigWithPresets,
|
|
401
412
|
upsertManagedRemoteTunnelToken,
|
|
413
|
+
onManagedPluginSettingsChanged: () => managedConfigRuntime?.refreshManagedConfigFile(),
|
|
402
414
|
});
|
|
403
415
|
|
|
404
416
|
const readSettingsFromDiskMigrated = (...args) => settingsRuntime.readSettingsFromDiskMigrated(...args);
|
|
@@ -416,7 +428,7 @@ const getUiSessionTokenFromRequest = (...args) => requestSecurityRuntime.getUiSe
|
|
|
416
428
|
const pushRuntime = createPushRuntime({
|
|
417
429
|
fsPromises,
|
|
418
430
|
path,
|
|
419
|
-
|
|
431
|
+
loadWebPush: () => import('web-push').then((module) => module.default),
|
|
420
432
|
PUSH_SUBSCRIPTIONS_FILE_PATH,
|
|
421
433
|
readSettingsFromDiskMigrated,
|
|
422
434
|
writeSettingsToDisk,
|
|
@@ -469,6 +481,7 @@ const notificationEmitterRuntime = createNotificationEmitterRuntime({
|
|
|
469
481
|
getDesktopNotifyEnabled: () => ENV_DESKTOP_NOTIFY,
|
|
470
482
|
desktopNotifyPrefix: DESKTOP_NOTIFY_PREFIX,
|
|
471
483
|
getUiNotificationClients: () => uiNotificationClients,
|
|
484
|
+
getOpenChamberEventClients: () => uiOpenChamberEventClients,
|
|
472
485
|
getBroadcastGlobalUiEvent: () => broadcastGlobalUiEvent,
|
|
473
486
|
});
|
|
474
487
|
|
|
@@ -481,6 +494,51 @@ const broadcastGlobalUiEvent = createGlobalUiEventBroadcaster({
|
|
|
481
494
|
});
|
|
482
495
|
const broadcastUiNotification = (...args) => notificationEmitterRuntime.broadcastUiNotification(...args);
|
|
483
496
|
|
|
497
|
+
// OpenChamber-owned events (queue changes, archive state) travel on the shared
|
|
498
|
+
// control stream, not on OpenCode's event proxy. One broadcaster so every owner
|
|
499
|
+
// reaches the same clients.
|
|
500
|
+
const broadcastOpenChamberUiEvent = createGlobalUiEventBroadcaster({
|
|
501
|
+
sseClients: uiOpenChamberEventClients,
|
|
502
|
+
wsClients: uiNotificationWsClients,
|
|
503
|
+
writeSseEvent,
|
|
504
|
+
});
|
|
505
|
+
|
|
506
|
+
/**
|
|
507
|
+
* Per-session OpenChamber state (goal progress, the assist recap, the
|
|
508
|
+
* obligatory-context cursor, pinned notes) lives in OpenCode's session
|
|
509
|
+
* metadata. The store merge-patches it there and migrates what older
|
|
510
|
+
* OpenChamber versions kept in `sessions-metadata.json`.
|
|
511
|
+
*/
|
|
512
|
+
const sessionMetadataStore = createSessionMetadataStore({
|
|
513
|
+
dataDir: OPENCHAMBER_DATA_DIR,
|
|
514
|
+
// Called, not captured: the OpenCode URL and auth helpers are declared
|
|
515
|
+
// further down and only ever used once a request arrives.
|
|
516
|
+
openCode: {
|
|
517
|
+
read: (...args) => createOpenCodeSessionMetadata({ buildOpenCodeUrl, getOpenCodeAuthHeaders }).read(...args),
|
|
518
|
+
write: (...args) => createOpenCodeSessionMetadata({ buildOpenCodeUrl, getOpenCodeAuthHeaders }).write(...args),
|
|
519
|
+
},
|
|
520
|
+
});
|
|
521
|
+
|
|
522
|
+
const readStoredSessionMetadata = (sessionID) => sessionMetadataStore.get(sessionID);
|
|
523
|
+
|
|
524
|
+
const persistSessionMetadataPatch = async (sessionID, patch, { directory = '' } = {}) => {
|
|
525
|
+
const metadata = await sessionMetadataStore.setSessionMetadata(sessionID, patch, { directory });
|
|
526
|
+
// The full merged object, so a client that missed an earlier patch does not
|
|
527
|
+
// have to reconstruct it.
|
|
528
|
+
broadcastOpenChamberUiEvent({
|
|
529
|
+
type: 'openchamber:session-metadata',
|
|
530
|
+
properties: { sessionID, metadata },
|
|
531
|
+
});
|
|
532
|
+
// The write itself arms the goal loop: it is the authoritative signal and
|
|
533
|
+
// does not depend on the event stream being connected.
|
|
534
|
+
// Called, not captured: the runtime is declared further down.
|
|
535
|
+
if (patch?.openchamber && 'goal' in patch.openchamber) {
|
|
536
|
+
void Promise.resolve(sessionGoalRuntime.notifyGoalChanged(sessionID, directory, metadata))
|
|
537
|
+
.catch((error) => console.warn('[session-goal] could not arm after a goal change:', error?.message ?? error));
|
|
538
|
+
}
|
|
539
|
+
return metadata;
|
|
540
|
+
};
|
|
541
|
+
|
|
484
542
|
const sessionRuntime = createSessionRuntime({
|
|
485
543
|
writeSseEvent,
|
|
486
544
|
getNotificationClients: () => uiNotificationClients,
|
|
@@ -583,6 +641,12 @@ let runtimeManagedRemoteTunnelToken = '';
|
|
|
583
641
|
let runtimeManagedRemoteTunnelHostname = '';
|
|
584
642
|
let terminalRuntime = null;
|
|
585
643
|
let dictationRuntime = null;
|
|
644
|
+
// Built once the HTTP server exists (it hooks `upgrade`); the browser
|
|
645
|
+
// provider router is built earlier and reaches it through this holder.
|
|
646
|
+
let guestSurfaceRuntime = null;
|
|
647
|
+
let realtimeProxyRuntime = null;
|
|
648
|
+
let relayServiceInstance = null;
|
|
649
|
+
let relayReconcileTimer = null;
|
|
586
650
|
let messageStreamRuntime = null;
|
|
587
651
|
const userProvidedOpenCodePassword = hmrStateRuntime.getUserProvidedOpenCodePassword(hmrState);
|
|
588
652
|
const initialOpenCodeAuthState = hmrStateRuntime.resolveOpenCodeAuthFromState({
|
|
@@ -739,6 +803,7 @@ const openCodeEnvRuntime = createOpenCodeEnvRuntime({
|
|
|
739
803
|
state: openCodeEnvState,
|
|
740
804
|
normalizeDirectoryPath,
|
|
741
805
|
readSettingsFromDiskMigrated,
|
|
806
|
+
providedLoginShellEnvSnapshot,
|
|
742
807
|
});
|
|
743
808
|
|
|
744
809
|
const applyLoginShellEnvSnapshot = (...args) => openCodeEnvRuntime.applyLoginShellEnvSnapshot(...args);
|
|
@@ -800,6 +865,7 @@ const notificationTriggerRuntime = createNotificationTriggerRuntime({
|
|
|
800
865
|
isAnyInteractiveClientVisible,
|
|
801
866
|
buildOpenCodeUrl,
|
|
802
867
|
getOpenCodeAuthHeaders,
|
|
868
|
+
readSessionMetadata: readStoredSessionMetadata,
|
|
803
869
|
});
|
|
804
870
|
|
|
805
871
|
const maybeSendPushForTrigger = (...args) => notificationTriggerRuntime.maybeSendPushForTrigger(...args);
|
|
@@ -810,12 +876,19 @@ const sessionAssistRuntime = createSessionAssistRuntime({
|
|
|
810
876
|
buildOpenCodeUrl,
|
|
811
877
|
getOpenCodeAuthHeaders,
|
|
812
878
|
getSmallModelService: async () => import('./lib/small-model/index.js'),
|
|
879
|
+
persistSessionAssist: (sessionID, directory, assist) =>
|
|
880
|
+
persistSessionMetadataPatch(sessionID, { openchamber: { assist } }, { directory }),
|
|
881
|
+
// Declared further down; only ever called after startup.
|
|
882
|
+
isSessionArchived: (sessionID) => openChamberSessionService.archiveStore.isArchived(sessionID),
|
|
813
883
|
});
|
|
814
884
|
|
|
815
885
|
const sessionGoalRuntime = createSessionGoalRuntime({
|
|
816
886
|
buildOpenCodeUrl,
|
|
817
887
|
getOpenCodeAuthHeaders,
|
|
818
888
|
getSmallModelService: async () => import('./lib/small-model/index.js'),
|
|
889
|
+
readSessionMetadata: readStoredSessionMetadata,
|
|
890
|
+
persistSessionGoal: (sessionID, directory, goal) =>
|
|
891
|
+
persistSessionMetadataPatch(sessionID, { openchamber: { goal } }, { directory }),
|
|
819
892
|
emitGoalNotification: async ({ sessionId, directory, status, goal }) => {
|
|
820
893
|
// The goal settle notification replaces the per-turn ready notifications
|
|
821
894
|
// (suppressed while the goal is active) — so it obeys the same toggle.
|
|
@@ -863,29 +936,18 @@ const sessionKnowledgeRuntime = createSessionKnowledgeRuntime({
|
|
|
863
936
|
// reference here would read it before it exists.
|
|
864
937
|
resolveProjectId: (directory) => resolveMemoryProjectId(directory),
|
|
865
938
|
isAgentMemoryEnabled,
|
|
866
|
-
|
|
867
|
-
|
|
868
|
-
|
|
869
|
-
|
|
870
|
-
const response = await fetch(`${buildOpenCodeUrl(fetchPath, '')}${search ? `?${search}` : ''}`, {
|
|
871
|
-
method,
|
|
872
|
-
headers: {
|
|
873
|
-
Accept: 'application/json',
|
|
874
|
-
...(body ? { 'Content-Type': 'application/json' } : {}),
|
|
875
|
-
...getOpenCodeAuthHeaders(),
|
|
876
|
-
},
|
|
877
|
-
...(body ? { body: JSON.stringify(body) } : {}),
|
|
878
|
-
signal: AbortSignal.timeout(15_000),
|
|
879
|
-
});
|
|
880
|
-
if (!response.ok) throw new Error(`OpenCode ${method} ${fetchPath} failed with ${response.status}`);
|
|
881
|
-
return response.json().catch(() => null);
|
|
882
|
-
},
|
|
939
|
+
readSessionMetadata: readStoredSessionMetadata,
|
|
940
|
+
// Pins and the delivered-signature cursor are read from and written to
|
|
941
|
+
// OpenChamber's own store; nothing here talks to OpenCode any more.
|
|
942
|
+
persistSessionMetadata: (sessionID, directory, patch) => persistSessionMetadataPatch(sessionID, patch, { directory }),
|
|
883
943
|
});
|
|
884
944
|
|
|
885
945
|
const contextObligatoryRuntime = createContextObligatoryRuntime({
|
|
886
946
|
buildOpenCodeUrl,
|
|
887
947
|
getOpenCodeAuthHeaders,
|
|
888
948
|
sessionKnowledgeRuntime,
|
|
949
|
+
readSessionMetadata: readStoredSessionMetadata,
|
|
950
|
+
persistContextCursor: (sessionID, directory, patch) => persistSessionMetadataPatch(sessionID, patch, { directory }),
|
|
889
951
|
});
|
|
890
952
|
|
|
891
953
|
const linearSessionStatusRuntime = createLinearSessionStatusRuntime();
|
|
@@ -897,17 +959,8 @@ const globalMessageStreamHub = createGlobalMessageStreamHub({
|
|
|
897
959
|
deltaCoalesceWindowMs: resolveDeltaCoalesceWindowMs(),
|
|
898
960
|
});
|
|
899
961
|
|
|
900
|
-
//
|
|
901
|
-
//
|
|
902
|
-
const broadcastOpenChamberUiEvent = createGlobalUiEventBroadcaster({
|
|
903
|
-
sseClients: uiOpenChamberEventClients,
|
|
904
|
-
wsClients: uiNotificationWsClients,
|
|
905
|
-
writeSseEvent,
|
|
906
|
-
});
|
|
907
|
-
|
|
908
|
-
// Jev model routing and the permission safety net. Dark unless
|
|
909
|
-
// OPENCHAMBER_ROUTING_ENABLE is set; every failure keeps the user's own model
|
|
910
|
-
// or the auto-accept reply it was asked about.
|
|
962
|
+
// Jev model routing and the permission safety net. Every failure keeps the
|
|
963
|
+
// user's own model or the auto-accept reply it was asked about.
|
|
911
964
|
const routingRuntime = createRoutingRuntime({
|
|
912
965
|
dataDir: OPENCHAMBER_DATA_DIR,
|
|
913
966
|
buildOpenCodeUrl,
|
|
@@ -937,8 +990,10 @@ const messageQueueRuntime = createMessageQueueRuntime({
|
|
|
937
990
|
buildOpenCodeUrl,
|
|
938
991
|
getOpenCodeAuthHeaders,
|
|
939
992
|
sessionKnowledgeRuntime,
|
|
993
|
+
// OpenCode's event SSE proxy cannot carry OpenChamber-owned events. Use the
|
|
994
|
+
// shared control stream for SSE clients and the existing WS fan-out.
|
|
940
995
|
broadcastGlobalUiEvent: broadcastOpenChamberUiEvent,
|
|
941
|
-
|
|
996
|
+
resolveAutoSelection: (send) => routingRuntime.resolveAutoSelection(send),
|
|
942
997
|
onPromptSent: (sessionId) => sessionRuntime.markUserMessageSent(sessionId),
|
|
943
998
|
dataDir: OPENCHAMBER_DATA_DIR,
|
|
944
999
|
});
|
|
@@ -961,23 +1016,41 @@ const openCodeWatcherRuntime = createOpenCodeWatcherRuntime({
|
|
|
961
1016
|
// directory to route its own OpenCode calls to the right instance.
|
|
962
1017
|
console.log('[session-assist] listening for session events');
|
|
963
1018
|
globalMessageStreamHub.subscribeEvent((event) => {
|
|
964
|
-
const raw = event?.payload;
|
|
965
|
-
const payload = raw?.payload && typeof raw.payload === 'object' ? raw.payload : raw;
|
|
966
|
-
if (!payload || typeof payload !== 'object') return;
|
|
967
1019
|
const directory = typeof event?.directory === 'string' && event.directory && event.directory !== 'global'
|
|
968
1020
|
? event.directory
|
|
969
1021
|
: '';
|
|
970
|
-
|
|
971
|
-
|
|
972
|
-
|
|
973
|
-
|
|
1022
|
+
// The hub translates v2 wire events into the server's vocabulary once; these
|
|
1023
|
+
// consumers were written against it and stay unaware of the wire shape.
|
|
1024
|
+
for (const payload of event?.translated?.() ?? []) {
|
|
1025
|
+
// The user cancelled the turn: stop the OpenChamber tool actions that
|
|
1026
|
+
// turn still has running (a browser action, a memory write). OpenCode 2
|
|
1027
|
+
// gives the plugin no abort signal, so this is where the cancel lands.
|
|
1028
|
+
if (payload.type === 'session.idle' && payload.properties?.aborted === true) {
|
|
1029
|
+
agentToolRuntime?.abortSession?.(payload.properties.sessionID);
|
|
1030
|
+
}
|
|
1031
|
+
sessionAssistRuntime.processPayload(payload, directory || payload.properties?.directory || '');
|
|
1032
|
+
sessionGoalRuntime.processPayload(payload, directory || payload.properties?.directory || '');
|
|
1033
|
+
contextObligatoryRuntime.processPayload(payload, directory || payload.properties?.directory || '');
|
|
1034
|
+
linearSessionStatusRuntime.processPayload(payload);
|
|
1035
|
+
}
|
|
974
1036
|
});
|
|
975
1037
|
|
|
1038
|
+
/**
|
|
1039
|
+
* Browser bridges hand us the raw v2 wire payload (they forward it untouched to
|
|
1040
|
+
* the client). The synthetic OpenChamber frames the UI also expects are derived
|
|
1041
|
+
* from the translated event, so the translation happens here.
|
|
1042
|
+
*/
|
|
976
1043
|
const processForwardedEventPayload = (payload, emitSyntheticEvent) => {
|
|
977
1044
|
if (!payload || typeof payload !== 'object' || typeof emitSyntheticEvent !== 'function') {
|
|
978
1045
|
return;
|
|
979
1046
|
}
|
|
980
1047
|
|
|
1048
|
+
for (const translated of translateWireEvent(payload)) {
|
|
1049
|
+
processForwardedServerEvent(translated, emitSyntheticEvent);
|
|
1050
|
+
}
|
|
1051
|
+
};
|
|
1052
|
+
|
|
1053
|
+
const processForwardedServerEvent = (payload, emitSyntheticEvent) => {
|
|
981
1054
|
maybeCacheSessionInfoFromEvent(payload);
|
|
982
1055
|
|
|
983
1056
|
if (payload.type !== 'session.status') {
|
|
@@ -1028,6 +1101,10 @@ const processForwardedEventPayload = (payload, emitSyntheticEvent) => {
|
|
|
1028
1101
|
|
|
1029
1102
|
|
|
1030
1103
|
const serverUtilsRuntime = createServerUtilsRuntime({
|
|
1104
|
+
// Read lazily: the archive store is created with the session service further
|
|
1105
|
+
// down, while the proxy is registered later still.
|
|
1106
|
+
getArchivedSessions: () => openChamberSessionService.archiveStore.getAll(),
|
|
1107
|
+
getStoredSessionMetadata: () => sessionMetadataStore.listUnmigrated(),
|
|
1031
1108
|
fs,
|
|
1032
1109
|
os,
|
|
1033
1110
|
path,
|
|
@@ -1264,25 +1341,21 @@ const openCodeLifecycleRuntime = createOpenCodeLifecycleRuntime({
|
|
|
1264
1341
|
console.warn('Failed to reconcile sessions after OpenCode restart:', error?.message ?? error);
|
|
1265
1342
|
}
|
|
1266
1343
|
},
|
|
1267
|
-
getManagedOpenCodeEnv: async () => {
|
|
1268
|
-
const settings = await readSettingsFromDiskMigrated().catch(() => null);
|
|
1269
|
-
// Each capability is its own tool and its own switch; the plugin is only
|
|
1270
|
-
// injected while at least one of them is on.
|
|
1271
|
-
const includeControl = settings?.agentControlToolEnabled !== false;
|
|
1272
|
-
const includeWeb = settings?.agentWebToolEnabled !== false;
|
|
1273
|
-
const includeMemory = isAgentMemoryFeatureAvailable() && settings?.agentMemoryToolEnabled === true;
|
|
1274
|
-
const managedEnv = includeControl || includeWeb || includeMemory
|
|
1275
|
-
? await (agentToolRuntime?.prepareManagedOpenCodeEnv({ includeControl, includeWeb, includeMemory }) || {})
|
|
1276
|
-
: {};
|
|
1277
|
-
|
|
1278
|
-
if (settings?.optimizeSystemPrompt === true) {
|
|
1279
|
-
const configContent = managedEnv.OPENCODE_CONFIG_CONTENT ?? process.env.OPENCODE_CONFIG_CONTENT;
|
|
1280
|
-
Object.assign(managedEnv, await systemPromptRuntime.prepareManagedOpenCodeEnv(configContent));
|
|
1281
|
-
}
|
|
1282
|
-
return managedEnv;
|
|
1283
|
-
},
|
|
1344
|
+
getManagedOpenCodeEnv: async () => (managedConfigRuntime ? managedConfigRuntime.buildManagedChildEnv() : {}),
|
|
1284
1345
|
});
|
|
1285
1346
|
|
|
1347
|
+
const getOpenCodeCompatibility = async () => {
|
|
1348
|
+
if (isExternalOpenCode || ENV_SKIP_OPENCODE_START) {
|
|
1349
|
+
const base = ENV_CONFIGURED_OPENCODE_HOST?.origin || openCodeBaseUrl || `http://127.0.0.1:${openCodePort || ENV_EFFECTIVE_PORT}`;
|
|
1350
|
+
const version = await readExternalOpenCodeVersion(base, getOpenCodeAuthHeaders()).catch(() => null);
|
|
1351
|
+
return describeOpenCodeCompatibility(version, 'external', false);
|
|
1352
|
+
}
|
|
1353
|
+
const binary = ensureOpencodeCliEnv();
|
|
1354
|
+
const installation = isBundledOpenCodeCliPath(binary) ? 'bundled' : 'managed';
|
|
1355
|
+
const version = await readOpenCodeCliVersion(resolveManagedOpenCodeLaunchSpec(binary)).catch(() => null);
|
|
1356
|
+
return describeOpenCodeCompatibility(version, installation, supportsOpenCodeV2Install());
|
|
1357
|
+
};
|
|
1358
|
+
|
|
1286
1359
|
const getOpenCodeUpgradeCapability = () => {
|
|
1287
1360
|
const activeBinary = lastOpenCodeLaunchDiagnostics?.sourceBinary
|
|
1288
1361
|
|| lastOpenCodeLaunchDiagnostics?.binary
|
|
@@ -1311,6 +1384,8 @@ const scheduledTasksRuntime = createScheduledTasksRuntime({
|
|
|
1311
1384
|
getOpenCodeAuthHeaders,
|
|
1312
1385
|
waitForOpenCodeReady,
|
|
1313
1386
|
sessionKnowledgeRuntime,
|
|
1387
|
+
persistSessionGoal: (sessionID, directory, goal) =>
|
|
1388
|
+
persistSessionMetadataPatch(sessionID, { openchamber: { goal } }, { directory }),
|
|
1314
1389
|
setSessionAutoAccept: (sessionId, enabled, directory) => permissionAutoAcceptRuntime.setSessionPolicy(sessionId, enabled, directory),
|
|
1315
1390
|
emitTaskRunEvent: (event) => {
|
|
1316
1391
|
for (const client of uiOpenChamberEventClients) {
|
|
@@ -1399,7 +1474,13 @@ const openChamberSessionService = createOpenChamberSessionService({
|
|
|
1399
1474
|
waitForOpenCodeReady,
|
|
1400
1475
|
emitSessionCreatedEvent,
|
|
1401
1476
|
sessionKnowledgeRuntime,
|
|
1402
|
-
|
|
1477
|
+
// OpenCode 2.x has no archive route, so the state is OpenChamber's own and
|
|
1478
|
+
// lives beside the instance it describes.
|
|
1479
|
+
dataDir: OPENCHAMBER_DATA_DIR,
|
|
1480
|
+
sessionMetadataStore,
|
|
1481
|
+
persistSessionMetadata: persistSessionMetadataPatch,
|
|
1482
|
+
broadcastGlobalUiEvent: broadcastOpenChamberUiEvent,
|
|
1483
|
+
resolveAutoSelection: (input) => routingRuntime.resolveAutoSelection(input),
|
|
1403
1484
|
});
|
|
1404
1485
|
// Browser actions are published to whichever OpenChamber clients are connected;
|
|
1405
1486
|
// the one owning the browser panel answers. `emitRequest` returns the number of
|
|
@@ -1432,6 +1513,56 @@ const browserControlBroker = createBrowserControlBroker({
|
|
|
1432
1513
|
},
|
|
1433
1514
|
});
|
|
1434
1515
|
|
|
1516
|
+
/**
|
|
1517
|
+
* Tells every client the selected browser provider was dropped back to the
|
|
1518
|
+
* in-app browser, so Settings shows the change and the user hears why.
|
|
1519
|
+
*/
|
|
1520
|
+
const emitBrowserProviderResetEvent = ({ guestId, guestName }) => {
|
|
1521
|
+
for (const client of uiOpenChamberEventClients) {
|
|
1522
|
+
try {
|
|
1523
|
+
writeSseEvent(client, {
|
|
1524
|
+
type: 'openchamber:browser-provider-reset',
|
|
1525
|
+
properties: { guestId, guestName },
|
|
1526
|
+
});
|
|
1527
|
+
} catch {
|
|
1528
|
+
uiOpenChamberEventClients.delete(client);
|
|
1529
|
+
}
|
|
1530
|
+
}
|
|
1531
|
+
};
|
|
1532
|
+
// Every browser action passes through here: the in-app view by default, or an
|
|
1533
|
+
// extension service chosen in Settings → OpenChamber Tools.
|
|
1534
|
+
const browserControlRouter = createBrowserControlRouter({
|
|
1535
|
+
broker: browserControlBroker,
|
|
1536
|
+
readSettings: () => readSettingsFromDiskMigrated(),
|
|
1537
|
+
persistSettings: (changes) => persistSettings(changes),
|
|
1538
|
+
findGuest: (id) => findInstalledGuest(id, extensionsPersistPath(OPENCHAMBER_DATA_DIR)),
|
|
1539
|
+
persistPath: extensionsPersistPath(OPENCHAMBER_DATA_DIR),
|
|
1540
|
+
emitProviderReset: emitBrowserProviderResetEvent,
|
|
1541
|
+
createId: () => `browser-${crypto.randomUUID()}`,
|
|
1542
|
+
surfaceControl: {
|
|
1543
|
+
userControls: (guestId) => guestSurfaceRuntime?.userControls(guestId) ?? false,
|
|
1544
|
+
noteAgentActivity: (guestId) => guestSurfaceRuntime?.noteAgentActivity(guestId),
|
|
1545
|
+
},
|
|
1546
|
+
});
|
|
1547
|
+
|
|
1548
|
+
// "Show this file" reaches every connected client; the ones showing that
|
|
1549
|
+
// project open it. Nothing comes back, so the count of clients reached is the
|
|
1550
|
+
// only signal the agent gets.
|
|
1551
|
+
const fileOpenRequester = createFileOpenRequester({
|
|
1552
|
+
emit: (request) => {
|
|
1553
|
+
let delivered = 0;
|
|
1554
|
+
for (const client of uiOpenChamberEventClients) {
|
|
1555
|
+
try {
|
|
1556
|
+
writeSseEvent(client, { type: 'openchamber:file-open-request', properties: request });
|
|
1557
|
+
delivered += 1;
|
|
1558
|
+
} catch {
|
|
1559
|
+
uiOpenChamberEventClients.delete(client);
|
|
1560
|
+
}
|
|
1561
|
+
}
|
|
1562
|
+
return delivered;
|
|
1563
|
+
},
|
|
1564
|
+
});
|
|
1565
|
+
|
|
1435
1566
|
const openChamberControlService = createOpenChamberControlService({
|
|
1436
1567
|
readSettingsFromDiskMigrated,
|
|
1437
1568
|
sanitizeProjects,
|
|
@@ -1440,7 +1571,8 @@ const openChamberControlService = createOpenChamberControlService({
|
|
|
1440
1571
|
waitForOpenCodeReady,
|
|
1441
1572
|
sessionService: openChamberSessionService,
|
|
1442
1573
|
scheduledTaskService,
|
|
1443
|
-
browserControl:
|
|
1574
|
+
browserControl: browserControlRouter,
|
|
1575
|
+
fileOpen: fileOpenRequester,
|
|
1444
1576
|
agentMemoryActions: createAgentMemoryActions({
|
|
1445
1577
|
agentMemoryRuntime,
|
|
1446
1578
|
createError: (message, status) => new OpenChamberControlError(message, status),
|
|
@@ -1474,6 +1606,11 @@ const bootstrapOpenCodeAtStartup = async (...args) => {
|
|
|
1474
1606
|
void ensureGlobalWatcherStarted().catch((error) => {
|
|
1475
1607
|
console.warn(`Global event watcher startup failed: ${error?.message || error}`);
|
|
1476
1608
|
});
|
|
1609
|
+
// Entries the sweep cannot push now stay in the legacy file and are pushed on
|
|
1610
|
+
// the session's next write or the next start.
|
|
1611
|
+
void waitForOpenCodeReady()
|
|
1612
|
+
.then(() => sessionMetadataStore.migrateLegacy())
|
|
1613
|
+
.catch((error) => console.warn('[openchamber-sessions] session metadata migration failed:', error?.message ?? error));
|
|
1477
1614
|
};
|
|
1478
1615
|
const killProcessOnPort = (...args) => openCodeLifecycleRuntime.killProcessOnPort(...args);
|
|
1479
1616
|
const waitForPortRelease = (...args) => openCodeLifecycleRuntime.waitForPortRelease(...args);
|
|
@@ -1526,11 +1663,19 @@ const gracefulShutdownRuntime = createGracefulShutdownRuntime({
|
|
|
1526
1663
|
},
|
|
1527
1664
|
tunnelAuthController,
|
|
1528
1665
|
scheduledTasksRuntime,
|
|
1666
|
+
beginGuestServiceShutdown,
|
|
1667
|
+
stopAllGuestServices,
|
|
1668
|
+
getGuestSurfaceRuntime: () => guestSurfaceRuntime,
|
|
1669
|
+
getRealtimeProxyRuntime: () => realtimeProxyRuntime,
|
|
1670
|
+
getDictationRuntime: () => dictationRuntime,
|
|
1671
|
+
getRelayService: () => relayServiceInstance,
|
|
1672
|
+
getRelayReconcileTimer: () => relayReconcileTimer,
|
|
1529
1673
|
});
|
|
1530
1674
|
|
|
1531
1675
|
const gracefulShutdown = (...args) => gracefulShutdownRuntime.gracefulShutdown(...args);
|
|
1532
1676
|
|
|
1533
1677
|
async function main(options = {}) {
|
|
1678
|
+
beginGuestServiceHost();
|
|
1534
1679
|
const port = Number.isFinite(options.port) && options.port >= 0 ? Math.trunc(options.port) : DEFAULT_PORT;
|
|
1535
1680
|
const host = typeof options.host === 'string' && options.host.length > 0 ? options.host : undefined;
|
|
1536
1681
|
const effectiveBindHost = host
|
|
@@ -1544,6 +1689,8 @@ async function main(options = {}) {
|
|
|
1544
1689
|
dataDir: OPENCHAMBER_DATA_DIR,
|
|
1545
1690
|
env: process.env,
|
|
1546
1691
|
executeAction: (...args) => openChamberControlService.execute(...args),
|
|
1692
|
+
// A v2 tool call carries no directory, only the session it runs in.
|
|
1693
|
+
resolveSessionDirectory: (sessionID) => openChamberControlService.resolveSessionDirectory(sessionID),
|
|
1547
1694
|
getActivePort: () => {
|
|
1548
1695
|
const address = server?.address?.();
|
|
1549
1696
|
return typeof address === 'object' && address ? address.port : null;
|
|
@@ -1551,10 +1698,14 @@ async function main(options = {}) {
|
|
|
1551
1698
|
// A pipe listener reports a string here, which has no address to bind back to.
|
|
1552
1699
|
getActiveHost: () => server?.address?.()?.address ?? null,
|
|
1553
1700
|
});
|
|
1554
|
-
|
|
1701
|
+
managedConfigRuntime = createManagedConfigRuntime({
|
|
1555
1702
|
fsPromises,
|
|
1556
1703
|
path,
|
|
1557
1704
|
dataDir: OPENCHAMBER_DATA_DIR,
|
|
1705
|
+
env: process.env,
|
|
1706
|
+
agentToolRuntime,
|
|
1707
|
+
readSettings: () => readSettingsFromDiskMigrated(),
|
|
1708
|
+
isAgentMemoryAvailable: isAgentMemoryFeatureAvailable,
|
|
1558
1709
|
});
|
|
1559
1710
|
|
|
1560
1711
|
// Pairing transports advertised to the create-device dialog. LAN reachability is
|
|
@@ -1744,13 +1895,7 @@ async function main(options = {}) {
|
|
|
1744
1895
|
}));
|
|
1745
1896
|
expressApp = app;
|
|
1746
1897
|
server = http.createServer(app);
|
|
1747
|
-
|
|
1748
|
-
|
|
1749
|
-
// The relay service is constructed further below (it depends on the tunnel
|
|
1750
|
-
// runtime's active port). The pairing routes registered here only read the
|
|
1751
|
-
// relay candidate lazily at request time, so a late-bound holder is enough.
|
|
1752
|
-
let relayServiceInstance = null;
|
|
1753
|
-
|
|
1898
|
+
gracefulShutdownRuntime.trackServerConnections(server);
|
|
1754
1899
|
// Same pattern for the tunnel runtime: created after the base routes so
|
|
1755
1900
|
// /api/system/info resolves port + tunnel URL lazily at request time.
|
|
1756
1901
|
let tunnelRuntimeContextHolder = null;
|
|
@@ -1877,7 +2022,7 @@ async function main(options = {}) {
|
|
|
1877
2022
|
isRequestOriginAllowed,
|
|
1878
2023
|
});
|
|
1879
2024
|
|
|
1880
|
-
const tunnelRuntimeContext = tunnelWiringRuntime.initialize(app, port);
|
|
2025
|
+
const tunnelRuntimeContext = tunnelWiringRuntime.initialize(app, port, Boolean(uiPassword?.trim()));
|
|
1881
2026
|
const { tunnelService, startTunnelWithNormalizedRequest } = tunnelRuntimeContext;
|
|
1882
2027
|
tunnelRuntimeContextHolder = tunnelRuntimeContext;
|
|
1883
2028
|
|
|
@@ -1958,6 +2103,10 @@ async function main(options = {}) {
|
|
|
1958
2103
|
createFsSearchRuntime: createFsSearchRuntimeFactory,
|
|
1959
2104
|
openchamberDataDir: OPENCHAMBER_DATA_DIR,
|
|
1960
2105
|
openchamberVersion: OPENCHAMBER_VERSION,
|
|
2106
|
+
onGuestDeactivated: async (event) => {
|
|
2107
|
+
guestSurfaceRuntime?.endForGuest(event.guestId);
|
|
2108
|
+
return browserControlRouter.handleGuestDeactivated(event);
|
|
2109
|
+
},
|
|
1961
2110
|
builtInExtensionsDir: options.builtInExtensionsDir,
|
|
1962
2111
|
openchamberUserConfigRoot: OPENCHAMBER_USER_CONFIG_ROOT,
|
|
1963
2112
|
managedChatsRoot: OPENCHAMBER_CHATS_DIR,
|
|
@@ -1971,6 +2120,19 @@ async function main(options = {}) {
|
|
|
1971
2120
|
refreshOpenCodeAfterConfigChange,
|
|
1972
2121
|
getOpenCodeResolutionSnapshot,
|
|
1973
2122
|
getOpenCodeUpgradeCapability,
|
|
2123
|
+
getOpenCodeCompatibility,
|
|
2124
|
+
installOpenCodeV2: async () => {
|
|
2125
|
+
const binary = await installOpenCodeV2({
|
|
2126
|
+
env: { ...getLoginShellEnvSnapshot(), ...process.env, PATH: buildManagedOpenCodePath() },
|
|
2127
|
+
});
|
|
2128
|
+
await persistSettings({ opencodeBinary: binary });
|
|
2129
|
+
await refreshOpenCodeAfterConfigChange('OpenCode v2 installation');
|
|
2130
|
+
await waitForOpenCodeReady();
|
|
2131
|
+
},
|
|
2132
|
+
upgradeOpenCodeCli: () => runOpenCodeCliUpgrade(
|
|
2133
|
+
resolveManagedOpenCodeLaunchSpec(lastOpenCodeLaunchDiagnostics?.sourceBinary || resolvedOpencodeBinary),
|
|
2134
|
+
{ env: { ...getLoginShellEnvSnapshot(), ...process.env, PATH: buildManagedOpenCodePath() }, cwd: os.homedir() },
|
|
2135
|
+
),
|
|
1974
2136
|
formatSettingsResponse,
|
|
1975
2137
|
readSettingsFromDisk,
|
|
1976
2138
|
readSettingsFromDiskMigrated,
|
|
@@ -2004,6 +2166,17 @@ async function main(options = {}) {
|
|
|
2004
2166
|
routingRuntime,
|
|
2005
2167
|
});
|
|
2006
2168
|
|
|
2169
|
+
// After bootstrap: the upgrade gate needs the real UI auth controller.
|
|
2170
|
+
guestSurfaceRuntime = createGuestSurfaceRuntime({
|
|
2171
|
+
server,
|
|
2172
|
+
uiAuthController,
|
|
2173
|
+
isRequestOriginAllowed,
|
|
2174
|
+
rejectWebSocketUpgrade,
|
|
2175
|
+
persistPath: extensionsPersistPath(OPENCHAMBER_DATA_DIR),
|
|
2176
|
+
findGuest: (id) => findInstalledGuest(id, extensionsPersistPath(OPENCHAMBER_DATA_DIR)),
|
|
2177
|
+
idleStopMs: BROWSER_PROVIDER_IDLE_MS,
|
|
2178
|
+
});
|
|
2179
|
+
|
|
2007
2180
|
const startupPipelineResult = await startupPipelineRuntime.run({
|
|
2008
2181
|
app,
|
|
2009
2182
|
server,
|
|
@@ -2073,7 +2246,7 @@ async function main(options = {}) {
|
|
|
2073
2246
|
// --relay` writes a pending relay session straight to the on-disk store, and
|
|
2074
2247
|
// pending sessions expire without any request hitting us. Poll reconcile so a
|
|
2075
2248
|
// headless instance picks the relay up (or drops it) within a minute.
|
|
2076
|
-
|
|
2249
|
+
relayReconcileTimer = setInterval(() => {
|
|
2077
2250
|
void relayService.reconcile();
|
|
2078
2251
|
}, 60_000);
|
|
2079
2252
|
relayReconcileTimer.unref?.();
|
|
@@ -2091,6 +2264,7 @@ async function main(options = {}) {
|
|
|
2091
2264
|
scheduledTasks: scheduledTasksRuntime.getStatus(),
|
|
2092
2265
|
}),
|
|
2093
2266
|
isReady: () => isOpenCodeReady,
|
|
2267
|
+
getManagedOpenCodePreflight: () => openCodeLifecycleRuntime.getManagedOpenCodePreflight(),
|
|
2094
2268
|
restartOpenCode: () => restartOpenCode(),
|
|
2095
2269
|
getOpenCodeProcessInfo: () => {
|
|
2096
2270
|
const managed = Boolean((openCodeProcess || openCodePort) && !ENV_SKIP_OPENCODE_START && !isExternalOpenCode);
|
|
@@ -2106,26 +2280,7 @@ async function main(options = {}) {
|
|
|
2106
2280
|
port: managed ? openCodePort : null,
|
|
2107
2281
|
};
|
|
2108
2282
|
},
|
|
2109
|
-
stop:
|
|
2110
|
-
realtimeProxyRuntime.stop();
|
|
2111
|
-
clearInterval(relayReconcileTimer);
|
|
2112
|
-
try {
|
|
2113
|
-
relayService.stop();
|
|
2114
|
-
} catch {
|
|
2115
|
-
// best-effort teardown of the relay host client
|
|
2116
|
-
}
|
|
2117
|
-
try {
|
|
2118
|
-
dictationRuntime?.stop?.();
|
|
2119
|
-
} catch {
|
|
2120
|
-
// best-effort shutdown of the dictation worker
|
|
2121
|
-
}
|
|
2122
|
-
// Guest services are child processes; leaving before SIGTERM lands
|
|
2123
|
-
// (and the SIGKILL fallback fires) orphans them on the user's machine.
|
|
2124
|
-
await stopAllGuestServices().catch(() => {
|
|
2125
|
-
// best-effort teardown of guest service processes
|
|
2126
|
-
});
|
|
2127
|
-
return gracefulShutdown({ exitProcess: shutdownOptions.exitProcess ?? false });
|
|
2128
|
-
}
|
|
2283
|
+
stop: (shutdownOptions = {}) => gracefulShutdown({ exitProcess: shutdownOptions.exitProcess ?? false }),
|
|
2129
2284
|
};
|
|
2130
2285
|
}
|
|
2131
2286
|
|