@vantran-se/openchamber-web 1.24.3 → 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-BjJHrzmU.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-CDOJy5Ay.js → GitView-BWa7e5vw.js} +4 -4
- package/dist/assets/{GuestAttachDialog-D3S0Rjic.js → GuestAttachDialog-DdOuyZzp.js} +1 -1
- package/dist/assets/GuestSurfacePane-DDfzid3U.js +1 -0
- package/dist/assets/{JsonTreeView-D0C9nU7K.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-DnEhjXcC.js → PatchDiff-DS-IMU1j.js} +1 -1
- package/dist/assets/{PierreDiffViewer-DyxZVVVR.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-0pyr_mHY.js → VirtualizedFileDiff-C763hNCR.js} +4 -4
- package/dist/assets/{WalkthroughView-yNj4nOP5.js → WalkthroughView-lap5btCF.js} +2 -2
- package/dist/assets/appThemeRegistry-u4zw1l0B.js +1 -0
- package/dist/assets/{commitAndPush-DvJKa3Ks.js → commitAndPush-CwGJfJG-.js} +1 -1
- package/dist/assets/{computeVirtualFileMetrics-DxTBMuu-.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-D7FkBMP6.js → isDiffPlainText-D47a6hMP.js} +1 -1
- package/dist/assets/{isFilePlainText-CL2vsrIZ.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-Dh7WEsdM.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-Bsba8KFp.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-8_3csmr6.js → shikiHighlight-DNm2Z_Jc.js} +1 -1
- package/dist/assets/{textMateThemeFromAppTheme-CHo2fCgW.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-DkQ_gqpn.js → useInlineCommentController-CuUuakrt.js} +2 -2
- package/dist/assets/useRootScrollLock-CQIsyERq.js +2 -0
- package/dist/assets/{vendor-codemirror-language-data-CdzUmUyZ.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-B8IcVQAA.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-COVQhWGd.js +0 -4
- package/dist/assets/FilesView-B1V5JxFX.js +0 -13
- package/dist/assets/LinearIssuesView-D7FKg1XJ.js +0 -1
- package/dist/assets/MarkdownImageGallery-BrFjAVEf.js +0 -1
- package/dist/assets/MarkdownRendererImpl-DWepTafh.js +0 -12
- package/dist/assets/OnboardingScreen-Dyxxiqdt.js +0 -1
- package/dist/assets/PlanView-LW2z_EAP.js +0 -5
- package/dist/assets/PluginPane-B4tKno2h.js +0 -3
- package/dist/assets/SettingsView-DEaMulN9.js +0 -29
- package/dist/assets/SettingsWindow-FLDJXOgQ.js +0 -1
- package/dist/assets/SubmoduleDiffSummary-CvVwD-Vi.js +0 -1
- package/dist/assets/ToolOutputDialog-BiP0x2Rw.js +0 -15
- package/dist/assets/ToolPartDiffPreview-CkR4msKP.js +0 -8
- package/dist/assets/appThemeRegistry-BuUKhbYQ.js +0 -1
- package/dist/assets/de-DgxgFyGG.js +0 -10
- package/dist/assets/es-BFsZj5F_.js +0 -16
- package/dist/assets/fr-jdZ5KKQi.js +0 -14
- package/dist/assets/index-CKHjPKbq.js +0 -1
- package/dist/assets/index-Cbci4i1W.js +0 -40
- package/dist/assets/index-DqaMWNrC.css +0 -1
- package/dist/assets/ja-C5kKrhO4.js +0 -16
- package/dist/assets/ko-DXDTT_0O.js +0 -16
- package/dist/assets/main-CZALtVek.js +0 -896
- package/dist/assets/main-CgXMBNvG.js +0 -2
- package/dist/assets/miniChat-CwTmDixi.js +0 -2
- package/dist/assets/mobile-CLf2vCtO.js +0 -2
- package/dist/assets/pl-D-7x4Y8Q.js +0 -16
- package/dist/assets/pt-BR-CSBZrHa8.js +0 -16
- package/dist/assets/renderElectronMiniChatApp-C5gAFBk0.js +0 -2
- package/dist/assets/renderMobileApp-V4hYd32H.js +0 -25
- package/dist/assets/runtimeEndpointReset-DhlHCn-2.js +0 -25
- package/dist/assets/scheduledTasksApi-DzjbLd8P.js +0 -1
- package/dist/assets/tr-Dr-oJ22L.js +0 -7
- package/dist/assets/uk-9Nx83UcI.js +0 -16
- package/dist/assets/useAppFontEffects-khZXpFL_.js +0 -7333
- package/dist/assets/useRootScrollLock-DdvHf9Pt.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-Bxy_Hj3r.js +0 -16
- package/dist/assets/zh-TW-0BB4gpHM.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
|
@@ -20,6 +20,8 @@ import path from 'path';
|
|
|
20
20
|
|
|
21
21
|
import { GOAL_OBJECTIVE_CHAR_LIMIT, readObjective } from './objectives.js';
|
|
22
22
|
import { readMergedSettingsSync } from '../opencode/settings-files.js';
|
|
23
|
+
import { createSessionActivityProbe } from '../opencode/session-activity.js';
|
|
24
|
+
import { unwrapOpenCodeResponse } from '../opencode/response-envelope.js';
|
|
23
25
|
|
|
24
26
|
const OPENCHAMBER_SETTINGS_FILE = path.join(
|
|
25
27
|
process.env.OPENCHAMBER_DATA_DIR
|
|
@@ -158,24 +160,29 @@ const extractSessionStatus = (payload) => {
|
|
|
158
160
|
return { sessionId, type, directory };
|
|
159
161
|
};
|
|
160
162
|
|
|
161
|
-
|
|
163
|
+
/**
|
|
164
|
+
* A user abort no longer lands as an assistant message carrying
|
|
165
|
+
* `MessageAbortedError`: v2 reports `session.execution.interrupted`, which the
|
|
166
|
+
* translator turns into `session.idle` with `aborted: true`.
|
|
167
|
+
*/
|
|
162
168
|
const extractAbortedAssistant = (payload) => {
|
|
163
|
-
if (!payload || payload.type !== '
|
|
164
|
-
const
|
|
165
|
-
if (!
|
|
166
|
-
if (
|
|
167
|
-
|
|
168
|
-
return { sessionId: info.sessionID };
|
|
169
|
+
if (!payload || payload.type !== 'session.idle') return null;
|
|
170
|
+
const properties = payload.properties;
|
|
171
|
+
if (!properties || typeof properties !== 'object' || properties.aborted !== true) return null;
|
|
172
|
+
if (typeof properties.sessionID !== 'string' || !properties.sessionID) return null;
|
|
173
|
+
return { sessionId: properties.sessionID };
|
|
169
174
|
};
|
|
170
175
|
|
|
171
176
|
const extractSessionUpdate = (payload) => {
|
|
172
177
|
if (!payload || payload.type !== 'session.updated') return null;
|
|
173
178
|
const info = payload.properties?.info;
|
|
174
179
|
if (!info || typeof info !== 'object' || typeof info.id !== 'string' || !info.id) return null;
|
|
180
|
+
// No goal here any more: the record OpenCode publishes carries only what
|
|
181
|
+
// OpenCode owns, and the goal lives in OpenChamber's own metadata store. A
|
|
182
|
+
// new or resumed goal reaches this runtime through `notifyGoalChanged`.
|
|
175
183
|
return {
|
|
176
184
|
sessionId: info.id,
|
|
177
185
|
directory: typeof info.directory === 'string' ? info.directory : '',
|
|
178
|
-
goal: parseGoalMetadata(info),
|
|
179
186
|
parentID: typeof info.parentID === 'string' ? info.parentID : '',
|
|
180
187
|
};
|
|
181
188
|
};
|
|
@@ -216,6 +223,67 @@ const parseGoalMetadata = (session) => {
|
|
|
216
223
|
};
|
|
217
224
|
};
|
|
218
225
|
|
|
226
|
+
/**
|
|
227
|
+
* The loop reads the v1 view of a message — `{ info, parts }` with
|
|
228
|
+
* `info.role`, `info.summary`, `info.time`, `info.tokens`, `info.error`,
|
|
229
|
+
* `info.finish`, `info.providerID` / `modelID` / `agent` / `variant` — and v2
|
|
230
|
+
* records are flat: `type` instead of `role`, `content[]` instead of `parts`,
|
|
231
|
+
* `model.{providerID,id}`, and a compaction turn is its own `compaction` type
|
|
232
|
+
* rather than an assistant message flagged `summary`. This is the only place
|
|
233
|
+
* that knows both shapes. Roles the loop does not reason about (system,
|
|
234
|
+
* skill, shell, switches, idle) are dropped; a `synthetic` message folds into
|
|
235
|
+
* the user role so a trailing context item still reads as "user just sent".
|
|
236
|
+
*/
|
|
237
|
+
const toLoopMessage = (message) => {
|
|
238
|
+
const id = String(message?.id ?? '');
|
|
239
|
+
if (!id) return null;
|
|
240
|
+
const time = message.time && !Array.isArray(message.time) ? { ...message.time } : {};
|
|
241
|
+
const base = { id, sessionID: message.sessionID, time };
|
|
242
|
+
switch (message.type) {
|
|
243
|
+
case 'user':
|
|
244
|
+
case 'synthetic':
|
|
245
|
+
return {
|
|
246
|
+
info: { ...base, role: 'user' },
|
|
247
|
+
parts: message.text ? [{ type: 'text', text: String(message.text) }] : [],
|
|
248
|
+
};
|
|
249
|
+
case 'assistant': {
|
|
250
|
+
const model = message.model ?? {};
|
|
251
|
+
// v1 errors carried `name`; v2's structured error calls it `type`.
|
|
252
|
+
const error = message.error ? { name: message.error.type, ...message.error } : undefined;
|
|
253
|
+
return {
|
|
254
|
+
info: {
|
|
255
|
+
...base,
|
|
256
|
+
role: 'assistant',
|
|
257
|
+
summary: false,
|
|
258
|
+
agent: message.agent,
|
|
259
|
+
providerID: model.providerID,
|
|
260
|
+
modelID: model.id,
|
|
261
|
+
variant: model.variant,
|
|
262
|
+
finish: message.finish,
|
|
263
|
+
tokens: message.tokens,
|
|
264
|
+
error,
|
|
265
|
+
},
|
|
266
|
+
parts: (Array.isArray(message.content) ? message.content : [])
|
|
267
|
+
.filter((part) => part?.type === 'text' && part.text)
|
|
268
|
+
.map((part) => ({ type: 'text', text: String(part.text) })),
|
|
269
|
+
};
|
|
270
|
+
}
|
|
271
|
+
case 'compaction': {
|
|
272
|
+
// A finished compaction plays the part of v1's `summary: true` assistant
|
|
273
|
+
// turn: it closes a token segment and is never audited or continued
|
|
274
|
+
// from. Its model must not be inherited either (v1: "the compaction
|
|
275
|
+
// summary carries the summarize model").
|
|
276
|
+
if (message.status !== 'completed') return null;
|
|
277
|
+
return {
|
|
278
|
+
info: { ...base, role: 'assistant', summary: true, tokens: message.tokens, finish: 'stop' },
|
|
279
|
+
parts: message.summary ? [{ type: 'text', text: String(message.summary) }] : [],
|
|
280
|
+
};
|
|
281
|
+
}
|
|
282
|
+
default:
|
|
283
|
+
return null;
|
|
284
|
+
}
|
|
285
|
+
};
|
|
286
|
+
|
|
219
287
|
const messagePartsToText = (message) => {
|
|
220
288
|
const parts = Array.isArray(message?.parts) ? message.parts : [];
|
|
221
289
|
return parts
|
|
@@ -299,6 +367,8 @@ export const createSessionGoalRuntime = ({
|
|
|
299
367
|
idleQuietMs = IDLE_QUIET_MS,
|
|
300
368
|
kickoffQuietMs = KICKOFF_QUIET_MS,
|
|
301
369
|
maxAutoTurns = MAX_AUTO_TURNS,
|
|
370
|
+
persistSessionGoal = null,
|
|
371
|
+
readSessionMetadata = null,
|
|
302
372
|
}) => {
|
|
303
373
|
const timers = new Map();
|
|
304
374
|
const inflight = new Set();
|
|
@@ -331,53 +401,45 @@ export const createSessionGoalRuntime = ({
|
|
|
331
401
|
if (!response.ok) {
|
|
332
402
|
throw new Error(`OpenCode ${method} ${fetchPath} failed with ${response.status}`);
|
|
333
403
|
}
|
|
334
|
-
return response.json().catch(() => null);
|
|
404
|
+
return unwrapOpenCodeResponse(await response.json().catch(() => null));
|
|
335
405
|
};
|
|
336
406
|
|
|
337
407
|
const fetchRecentMessages = async (sessionId, directory) => {
|
|
338
|
-
|
|
408
|
+
// v2 pages messages as `{ data, cursor }`, newest first.
|
|
409
|
+
const page = await openCodeFetch(`/api/session/${encodeURIComponent(sessionId)}/message`, {
|
|
339
410
|
directory,
|
|
340
411
|
query: { limit: String(MESSAGE_FETCH_LIMIT) },
|
|
341
412
|
}).catch(() => null);
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
const fetchSessionStatuses = async (directory) => {
|
|
346
|
-
const statuses = await openCodeFetch('/session/status', { directory }).catch(() => null);
|
|
347
|
-
return statuses && typeof statuses === 'object' && !Array.isArray(statuses) ? statuses : null;
|
|
413
|
+
const messages = page && typeof page === 'object' ? page.data : null;
|
|
414
|
+
if (!Array.isArray(messages)) return null;
|
|
415
|
+
return messages.map(toLoopMessage).filter(Boolean).reverse();
|
|
348
416
|
};
|
|
349
417
|
|
|
350
|
-
const
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
};
|
|
418
|
+
const activityProbe = createSessionActivityProbe({
|
|
419
|
+
buildOpenCodeUrl,
|
|
420
|
+
getOpenCodeAuthHeaders,
|
|
421
|
+
timeoutMs: FETCH_TIMEOUT_MS,
|
|
422
|
+
});
|
|
355
423
|
|
|
356
|
-
|
|
424
|
+
// v2 reports only that a session is running.
|
|
425
|
+
const isWorkingStatus = (status) => Boolean(status);
|
|
357
426
|
|
|
358
427
|
// Merge-write the goal payload from a FRESH session read so concurrent
|
|
359
428
|
// metadata writes (assist payloads, dismissals, UI goal edits) survive.
|
|
360
429
|
// Returns the written goal, or null when the stored goal no longer matches
|
|
361
430
|
// the expected id (user replaced/cleared it while we worked).
|
|
431
|
+
/**
|
|
432
|
+
* The goal lives in OpenChamber's own metadata store: OpenCode 2.x accepts
|
|
433
|
+
* session metadata only at create time. Re-read before every write so a
|
|
434
|
+
* concurrent edit (the user pausing from the UI) is not overwritten.
|
|
435
|
+
*/
|
|
436
|
+
const readGoal = async (sessionId) => parseGoalMetadata({ metadata: await readSessionMetadata(sessionId) });
|
|
437
|
+
|
|
362
438
|
const writeGoal = async (sessionId, directory, expectedGoalId, mutate) => {
|
|
363
|
-
const
|
|
364
|
-
const currentGoal = parseGoalMetadata(session);
|
|
439
|
+
const currentGoal = await readGoal(sessionId);
|
|
365
440
|
if (!currentGoal || currentGoal.id !== expectedGoalId) return null;
|
|
366
441
|
const nextGoal = { ...currentGoal, ...mutate(currentGoal), updatedAt: Date.now() };
|
|
367
|
-
|
|
368
|
-
const currentNamespace = currentMetadata.openchamber && typeof currentMetadata.openchamber === 'object'
|
|
369
|
-
? currentMetadata.openchamber
|
|
370
|
-
: {};
|
|
371
|
-
await openCodeFetch(`/session/${encodeURIComponent(sessionId)}`, {
|
|
372
|
-
directory,
|
|
373
|
-
method: 'PATCH',
|
|
374
|
-
body: {
|
|
375
|
-
metadata: {
|
|
376
|
-
...currentMetadata,
|
|
377
|
-
openchamber: { ...currentNamespace, goal: nextGoal },
|
|
378
|
-
},
|
|
379
|
-
},
|
|
380
|
-
});
|
|
442
|
+
await persistSessionGoal(sessionId, directory, nextGoal);
|
|
381
443
|
return nextGoal;
|
|
382
444
|
};
|
|
383
445
|
|
|
@@ -469,32 +531,21 @@ export const createSessionGoalRuntime = ({
|
|
|
469
531
|
}
|
|
470
532
|
};
|
|
471
533
|
|
|
472
|
-
|
|
473
|
-
|
|
474
|
-
|
|
475
|
-
|
|
476
|
-
|
|
477
|
-
}
|
|
478
|
-
const agent = typeof lastAssistantInfo?.agent === 'string' && lastAssistantInfo.agent
|
|
479
|
-
? lastAssistantInfo.agent
|
|
480
|
-
: (typeof lastAssistantInfo?.mode === 'string' ? lastAssistantInfo.mode : '');
|
|
481
|
-
const variant = typeof lastAssistantInfo?.variant === 'string' ? lastAssistantInfo.variant : '';
|
|
482
|
-
await openCodeFetch(`/session/${encodeURIComponent(sessionId)}/prompt_async`, {
|
|
534
|
+
// v2 keeps the model and agent on the session itself, so a plain prompt
|
|
535
|
+
// runs on whatever the session was already using. v1 had to repeat the
|
|
536
|
+
// selection on every request; there is nothing to repeat here.
|
|
537
|
+
const sendContinuation = async ({ sessionId, directory, goal }) => {
|
|
538
|
+
await openCodeFetch(`/api/session/${encodeURIComponent(sessionId)}/prompt`, {
|
|
483
539
|
directory,
|
|
484
540
|
method: 'POST',
|
|
485
|
-
body: {
|
|
486
|
-
model: { providerID, modelID },
|
|
487
|
-
...(agent ? { agent } : {}),
|
|
488
|
-
...(variant ? { variant } : {}),
|
|
489
|
-
parts: [{ type: 'text', text: buildContinuationPrompt(goal) }],
|
|
490
|
-
},
|
|
541
|
+
body: { text: buildContinuationPrompt(goal) },
|
|
491
542
|
});
|
|
492
543
|
};
|
|
493
544
|
|
|
494
545
|
const tick = async (sessionId, directory) => {
|
|
495
546
|
if (!isEnabled()) return;
|
|
496
547
|
|
|
497
|
-
const session = await openCodeFetch(`/session/${encodeURIComponent(sessionId)}`, { directory })
|
|
548
|
+
const session = await openCodeFetch(`/api/session/${encodeURIComponent(sessionId)}`, { directory })
|
|
498
549
|
.catch((error) => {
|
|
499
550
|
console.warn(`[session-goal] session fetch failed: ${error?.message || error}`);
|
|
500
551
|
return null;
|
|
@@ -503,7 +554,7 @@ export const createSessionGoalRuntime = ({
|
|
|
503
554
|
// Sub-agent/task sessions never carry user goals — skip them.
|
|
504
555
|
if (typeof session.parentID === 'string' && session.parentID) return;
|
|
505
556
|
|
|
506
|
-
const goal =
|
|
557
|
+
const goal = await readGoal(sessionId);
|
|
507
558
|
if (!goal || goal.status !== 'active') return;
|
|
508
559
|
|
|
509
560
|
// File-backed objectives: the metadata carries only a flag; the objective
|
|
@@ -530,19 +581,19 @@ export const createSessionGoalRuntime = ({
|
|
|
530
581
|
// its next idle event will arm a fresh tick. If a child is still working,
|
|
531
582
|
// OpenCode will inject its result into the parent and produce the same
|
|
532
583
|
// busy→idle cycle, so do not poll or audit the interim parent reply.
|
|
533
|
-
const statuses = await
|
|
584
|
+
const statuses = await activityProbe.fetchActiveSessionStatuses();
|
|
534
585
|
if (!statuses) {
|
|
535
586
|
armTimer(sessionId, directory, idleQuietMs);
|
|
536
587
|
return;
|
|
537
588
|
}
|
|
538
589
|
if (isWorkingStatus(statuses[sessionId])) return;
|
|
539
590
|
|
|
540
|
-
const
|
|
541
|
-
if (
|
|
591
|
+
const childrenWorking = await activityProbe.hasWorkingChildren(sessionId, statuses);
|
|
592
|
+
if (childrenWorking === null) {
|
|
542
593
|
armTimer(sessionId, directory, idleQuietMs);
|
|
543
594
|
return;
|
|
544
595
|
}
|
|
545
|
-
if (
|
|
596
|
+
if (childrenWorking) return;
|
|
546
597
|
|
|
547
598
|
const messages = await fetchRecentMessages(sessionId, directory);
|
|
548
599
|
if (!messages) return;
|
|
@@ -797,7 +848,7 @@ export const createSessionGoalRuntime = ({
|
|
|
797
848
|
}
|
|
798
849
|
|
|
799
850
|
console.log(`[session-goal] continuing ${sessionId} (turn ${written.turnsUsed}/${maxAutoTurns}, tokens ${written.tokensUsed}${written.tokenBudget ? `/${written.tokenBudget}` : ''})`);
|
|
800
|
-
await sendContinuation({ sessionId, directory, goal: { ...written, objective: effectiveObjective }
|
|
851
|
+
await sendContinuation({ sessionId, directory, goal: { ...written, objective: effectiveObjective } });
|
|
801
852
|
};
|
|
802
853
|
|
|
803
854
|
const armTimer = (sessionId, directory, quietMs) => {
|
|
@@ -823,9 +874,7 @@ export const createSessionGoalRuntime = ({
|
|
|
823
874
|
// "stop". Messages the user sends afterwards leave the paused goal alone;
|
|
824
875
|
// Resume re-arms the loop (and kicks off immediately on an idle session).
|
|
825
876
|
const pauseAfterAbort = async (sessionId, directory) => {
|
|
826
|
-
const
|
|
827
|
-
.catch(() => null);
|
|
828
|
-
const goal = parseGoalMetadata(session);
|
|
877
|
+
const goal = await readGoal(sessionId);
|
|
829
878
|
if (!goal || goal.status !== 'active') return;
|
|
830
879
|
await writeGoal(sessionId, directory, goal.id, () => ({
|
|
831
880
|
status: 'paused',
|
|
@@ -834,8 +883,44 @@ export const createSessionGoalRuntime = ({
|
|
|
834
883
|
console.log(`[session-goal] ${sessionId} paused after user abort`);
|
|
835
884
|
};
|
|
836
885
|
|
|
886
|
+
const isWired = () => typeof persistSessionGoal === 'function' && typeof readSessionMetadata === 'function';
|
|
887
|
+
|
|
888
|
+
/**
|
|
889
|
+
* A goal is created, edited or resumed through OpenChamber's own metadata
|
|
890
|
+
* route, not through an OpenCode event, so the write tells this runtime
|
|
891
|
+
* directly. That is also the authoritative moment: the store already holds it.
|
|
892
|
+
*/
|
|
893
|
+
const notifyGoalChanged = async (sessionId, directory, metadata) => {
|
|
894
|
+
if (stopped || !isWired()) return;
|
|
895
|
+
const goal = parseGoalMetadata({ metadata });
|
|
896
|
+
if (!goal || goal.status !== 'active') {
|
|
897
|
+
clearTimer(sessionId);
|
|
898
|
+
return;
|
|
899
|
+
}
|
|
900
|
+
if (goal.turnsUsed !== 0 && goal.statusReason !== 'resumed') return;
|
|
901
|
+
if (timers.has(sessionId) || inflight.has(sessionId)) return;
|
|
902
|
+
|
|
903
|
+
// A patch from the UI names no directory, and the loop needs one to scope
|
|
904
|
+
// its own OpenCode calls. The session record is authoritative for it.
|
|
905
|
+
let resolved = directory;
|
|
906
|
+
if (!resolved) {
|
|
907
|
+
const session = await openCodeFetch(`/api/session/${encodeURIComponent(sessionId)}`).catch(() => null);
|
|
908
|
+
resolved = typeof session?.location?.directory === 'string' ? session.location.directory : '';
|
|
909
|
+
}
|
|
910
|
+
if (stopped || timers.has(sessionId) || inflight.has(sessionId)) return;
|
|
911
|
+
armTimer(sessionId, resolved, goal.statusReason === 'resumed' ? RESUME_KICKOFF_MS : kickoffQuietMs);
|
|
912
|
+
};
|
|
913
|
+
|
|
914
|
+
let parkedNoticeLogged = false;
|
|
837
915
|
const processPayload = (payload, directoryHint = '') => {
|
|
838
916
|
if (stopped) return;
|
|
917
|
+
if (!isWired()) {
|
|
918
|
+
if (!parkedNoticeLogged) {
|
|
919
|
+
parkedNoticeLogged = true;
|
|
920
|
+
console.log('[session-goal] parked: no session metadata store is wired, so goal progress cannot be saved');
|
|
921
|
+
}
|
|
922
|
+
return;
|
|
923
|
+
}
|
|
839
924
|
|
|
840
925
|
const aborted = extractAbortedAssistant(payload);
|
|
841
926
|
if (aborted) {
|
|
@@ -868,17 +953,19 @@ export const createSessionGoalRuntime = ({
|
|
|
868
953
|
// transition, only session.updated. Arm a short timer; the tick's
|
|
869
954
|
// quiescence check keeps this safe if the session is actually busy.
|
|
870
955
|
const update = extractSessionUpdate(payload);
|
|
871
|
-
if (
|
|
872
|
-
update
|
|
873
|
-
|
|
874
|
-
|
|
875
|
-
|
|
876
|
-
|
|
877
|
-
|
|
878
|
-
|
|
879
|
-
|
|
880
|
-
|
|
881
|
-
|
|
956
|
+
if (update && !update.parentID && !timers.has(update.sessionId) && !inflight.has(update.sessionId)) {
|
|
957
|
+
void readGoal(update.sessionId)
|
|
958
|
+
.then((goal) => {
|
|
959
|
+
if (stopped || !goal || goal.status !== 'active') return;
|
|
960
|
+
if (goal.turnsUsed !== 0 && goal.statusReason !== 'resumed') return;
|
|
961
|
+
if (timers.has(update.sessionId) || inflight.has(update.sessionId)) return;
|
|
962
|
+
armTimer(
|
|
963
|
+
update.sessionId,
|
|
964
|
+
update.directory || directoryHint,
|
|
965
|
+
goal.statusReason === 'resumed' ? RESUME_KICKOFF_MS : kickoffQuietMs,
|
|
966
|
+
);
|
|
967
|
+
})
|
|
968
|
+
.catch(() => undefined);
|
|
882
969
|
}
|
|
883
970
|
};
|
|
884
971
|
|
|
@@ -890,5 +977,5 @@ export const createSessionGoalRuntime = ({
|
|
|
890
977
|
timers.clear();
|
|
891
978
|
};
|
|
892
979
|
|
|
893
|
-
return { processPayload, stop };
|
|
980
|
+
return { processPayload, notifyGoalChanged, stop };
|
|
894
981
|
};
|