@aiworker/web 1.22.0 → 1.23.0
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 +4 -4
- package/bin/cli.js +14 -4
- package/bin/cli.test.js +165 -73
- package/bin/lib/cli-api-target.js +2 -2
- package/bin/lib/cli-args.js +119 -119
- package/bin/lib/cli-lifecycle.js +9 -9
- package/bin/lib/cli-network.js +3 -3
- package/bin/lib/cli-paths.js +3 -3
- package/bin/lib/cli-ports.js +2 -2
- package/bin/lib/cli-process.js +4 -4
- package/bin/lib/cli-startup.js +64 -15
- package/bin/lib/cli-tunnel-profiles.js +1 -1
- package/bin/lib/cli-tunnel-utils.js +2 -2
- package/bin/lib/commands-connect-url.js +19 -19
- package/bin/lib/commands-lifecycle.js +27 -27
- package/bin/lib/commands-logs.js +5 -5
- package/bin/lib/commands-models.js +1 -1
- package/bin/lib/commands-projects.js +1 -1
- package/bin/lib/commands-schedule.js +1 -1
- package/bin/lib/commands-serve.js +29 -29
- package/bin/lib/commands-session.js +1 -1
- package/bin/lib/commands-startup.js +45 -10
- package/bin/lib/commands-status.js +1 -1
- package/bin/lib/commands-tunnel.js +40 -40
- package/bin/lib/commands-update.js +1 -1
- package/bin/lib/commands-update.test.js +6 -6
- package/dist/assets/{CodeMirrorCommentWidgets-B3u7UIcE.js → CodeMirrorCommentWidgets-B1Gizi3a.js} +1 -1
- package/dist/assets/DiffView-DXjVsEOw.js +4 -0
- package/dist/assets/DirtyBranchSwitchDialog-aig6zJjg.js +1 -0
- package/dist/assets/FilesView-CJdG0-wk.js +17 -0
- package/dist/assets/GitView-BXsS3jG6.js +6 -0
- package/dist/assets/{JsonTreeView-B0BdZEHG.js → JsonTreeView-D_hpXBnF.js} +1 -1
- package/dist/assets/LinearIssuesView-BoUiLQG1.js +1 -0
- package/dist/assets/MarkdownImageGallery-B_B_a9KS.js +1 -0
- package/dist/assets/MarkdownRendererImpl-xgyyLiBM.js +12 -0
- package/dist/assets/OnboardingScreen-DIp84OWt.js +1 -0
- package/dist/assets/{PatchDiff-DvfqDql7.js → PatchDiff-8p6nLJaU.js} +1 -1
- package/dist/assets/PierreDiffViewer-DjC8nTk9.js +161 -0
- package/dist/assets/PlanView-CJTmOF6I.js +5 -0
- package/dist/assets/SettingsView-DD-JqIJx.js +28 -0
- package/dist/assets/{SettingsWindow-i45U1Cy1.js → SettingsWindow-Cpb4hM6q.js} +1 -1
- package/dist/assets/SymbolsNerdFontMono-Regular-aK5vsLov.woff2 +0 -0
- package/dist/assets/{ToolOutputDialog-BTwyh5OF.js → ToolOutputDialog-DfaKZXNU.js} +6 -6
- package/dist/assets/ToolPartDiffPreview-DtZLzrSK.js +8 -0
- package/dist/assets/{VirtualizedFileDiff-DD8lDVej.js → VirtualizedFileDiff-C8i9HpTB.js} +1 -1
- package/dist/assets/WalkthroughView-DeKMvZlL.js +4 -0
- package/dist/assets/{computeVirtualFileMetrics-BMIRgMHv.js → computeVirtualFileMetrics-BBI7ZwrC.js} +2 -2
- package/dist/assets/contextPanelEmbeddedChat-BdA6bdky.js +1 -0
- package/dist/assets/de-DCrsQ5zS.js +10 -0
- package/dist/assets/es-Dwv4YfH6.js +16 -0
- package/dist/assets/fr-BCWg4Cnx.js +14 -0
- package/dist/assets/ghostty-vt-DdA0Zryv.wasm +0 -0
- package/dist/assets/index-B68h5S5B.css +1 -0
- package/dist/assets/index-DVwMarHI.js +39 -0
- package/dist/assets/{index-CODwDsU_.js → index-jXSK5RrB.js} +1 -1
- package/dist/assets/{isDiffPlainText-BqayB8d3.js → isDiffPlainText-B_x_rVon.js} +1 -1
- package/dist/assets/{isFilePlainText-QfoiKJNY.js → isFilePlainText-DW_xMer1.js} +1 -1
- package/dist/assets/ja-Bruw3RYC.js +16 -0
- package/dist/assets/ko-idhXGF8j.js +16 -0
- package/dist/assets/main-BkyaQhJX.js +930 -0
- package/dist/assets/{main-C5DVOxc6.js → main-CzdPuL0s.js} +2 -2
- package/dist/assets/markdownCore-Cn4Tyejo.js +5 -0
- package/dist/assets/{miniChat-DUJ4irZc.js → miniChat-CCkqKOLp.js} +2 -2
- package/dist/assets/{mobile-CcaxB0n4.js → mobile-mvxTo055.js} +2 -2
- package/dist/assets/patchFileDiff-Csk4iNUi.js +13 -0
- package/dist/assets/pl-CGZWUqZJ.js +16 -0
- package/dist/assets/pt-BR-B8V7u7tA.js +16 -0
- package/dist/assets/renderElectronMiniChatApp-BxoyujA5.js +2 -0
- package/dist/assets/renderMobileApp-B48CsP4r.js +25 -0
- package/dist/assets/runtimeEndpointReset-Bg5gx18H.js +17 -0
- package/dist/assets/scheduledTasksApi-BW0Etzwz.js +1 -0
- package/dist/assets/{shikiHighlight-DYOWuY65.js → shikiHighlight-CRl0SUC9.js} +1 -1
- package/dist/assets/surface-oMvhsog3.js +1 -0
- package/dist/assets/tr-BK_KiO2V.js +7 -0
- package/dist/assets/uk-CG74xV8N.js +16 -0
- package/dist/assets/useAppFontEffects-CPKeOpUo.js +7284 -0
- package/dist/assets/useGitComparison-DH220WmO.js +1 -0
- package/dist/assets/useInlineCommentController-BiWz4AVb.js +2 -0
- package/dist/assets/useRootScrollLock-BS4-kr7P.js +1 -0
- package/dist/assets/{vendor-base-ui-BeMD8X_w.js → vendor-base-ui-DdV8vhHn.js} +1 -1
- package/dist/assets/{vendor-codemirror-language-data-DFZik9R2.js → vendor-codemirror-language-data-Bg4AEeCr.js} +2 -2
- package/dist/assets/vendor-zod-BPAANqvH.js +39 -0
- package/dist/assets/{web-components-Bhg83tjf.js → web-components-z7hfnS8n.js} +1 -1
- package/dist/assets/zh-CN-T4AXofZI.js +16 -0
- package/dist/assets/zh-TW-Dte40sxp.js +16 -0
- package/dist/index.html +21 -59
- package/dist/mini-chat.html +7 -7
- package/dist/mobile.html +5 -5
- package/package.json +3 -4
- package/server/index.d.ts +15 -0
- package/server/index.js +158 -89
- package/server/lib/agent-memory/actions.js +2 -2
- package/server/lib/agent-memory/feature-flag.js +1 -1
- package/server/lib/agent-memory/feature-flag.test.js +8 -8
- package/server/lib/agent-memory/routes.js +2 -2
- package/server/lib/agent-tool/runtime.js +37 -54
- package/server/lib/agent-tool/runtime.test.js +59 -59
- package/server/lib/browser-control/broker.js +3 -3
- package/server/lib/browser-control/broker.test.js +1 -1
- package/server/lib/changelog/update-notes.js +82 -0
- package/server/lib/changelog/update-notes.test.js +59 -0
- package/server/lib/client-auth/remote-clients.test.js +5 -5
- package/server/lib/context-obligatory/runtime.js +7 -7
- package/server/lib/context-obligatory/runtime.test.js +5 -5
- package/server/lib/data-dir-migration.js +40 -0
- package/server/lib/data-dir-migration.test.js +59 -0
- package/server/lib/dev-servers/parse.js +2 -2
- package/server/lib/dev-servers/parse.test.js +2 -2
- package/server/lib/dev-servers/routes.js +1 -1
- package/server/lib/dev-tunnel/DOCUMENTATION.md +13 -4
- package/server/lib/dev-tunnel/client.js +1 -1
- package/server/lib/dev-tunnel/runtime.js +5 -5
- package/server/lib/dev-tunnel/tunnel.test.js +21 -1
- package/server/lib/dictation/local/model-catalog.js +1 -1
- package/server/lib/dictation/local/worker-process.js +2 -2
- package/server/lib/event-stream/directory-ws-bridge.js +1 -1
- package/server/lib/event-stream/global-ws-bridge.js +1 -1
- package/server/lib/event-stream/protocol.test.js +4 -4
- package/server/lib/event-stream/runtime.test.js +18 -18
- package/server/lib/fs/DOCUMENTATION.md +5 -0
- package/server/lib/fs/routes.js +68 -26
- package/server/lib/fs/routes.test.js +208 -22
- package/server/lib/git/DOCUMENTATION.md +32 -6
- package/server/lib/git/identity-storage.js +1 -1
- package/server/lib/git/issue-2746-longpaths.test.js +4 -4
- package/server/lib/git/routes.js +41 -5
- package/server/lib/git/service.js +300 -224
- package/server/lib/git/service.test.js +596 -28
- package/server/lib/github/auth.js +8 -8
- package/server/lib/github/pr-status.js +1 -1
- package/server/lib/github/routes.js +2 -2
- package/server/lib/inherited-env.js +17 -10
- package/server/lib/inherited-env.test.js +10 -11
- package/server/lib/linear/auth.js +8 -8
- package/server/lib/linear/auth.test.js +24 -24
- package/server/lib/linear/issues.test.js +6 -6
- package/server/lib/linear/mapping.test.js +4 -4
- package/server/lib/linear/oauth.js +2 -2
- package/server/lib/linear/oauth.test.js +14 -14
- package/server/lib/linear/routes.js +5 -5
- package/server/lib/linear/routes.test.js +16 -16
- package/server/lib/linear/status-runtime.test.js +9 -9
- package/server/lib/linear/status.js +1 -1
- package/server/lib/linear/status.test.js +15 -15
- package/server/lib/linear/teams.test.js +4 -4
- package/server/lib/magic-prompts/routes.js +2 -2
- package/server/lib/mcp-reconnect/DOCUMENTATION.md +55 -0
- package/server/lib/mcp-reconnect/runtime.js +122 -0
- package/server/lib/mcp-reconnect/runtime.test.js +140 -0
- package/server/lib/message-queue/DOCUMENTATION.md +161 -0
- package/server/lib/message-queue/runtime.js +870 -0
- package/server/lib/message-queue/runtime.test.js +482 -0
- package/server/lib/network-defaults.js +23 -0
- package/server/lib/network-defaults.test.js +52 -0
- package/server/lib/notifications/apns-runtime.js +17 -17
- package/server/lib/notifications/apns-runtime.test.js +11 -11
- package/server/lib/notifications/emitter-runtime.js +1 -1
- package/server/lib/notifications/emitter-runtime.test.js +1 -1
- package/server/lib/notifications/push-runtime.js +7 -7
- package/server/lib/notifications/routes.js +1 -1
- package/server/lib/notifications/runtime.js +1 -1
- package/server/lib/openchamber-control/action-resolution.test.js +10 -10
- package/server/lib/openchamber-control/actions.js +24 -24
- package/server/lib/openchamber-control/error.js +4 -4
- package/server/lib/openchamber-control/routes.js +2 -2
- package/server/lib/openchamber-control/routes.test.js +5 -5
- package/server/lib/openchamber-control/screenshots.js +1 -1
- package/server/lib/openchamber-control/screenshots.test.js +1 -1
- package/server/lib/openchamber-control/service.js +50 -50
- package/server/lib/openchamber-control/service.test.js +5 -5
- package/server/lib/openchamber-sessions/routes.js +124 -22
- package/server/lib/openchamber-sessions/routes.test.js +99 -11
- package/server/lib/opencode/DOCUMENTATION.md +30 -6
- package/server/lib/opencode/auth.js +1 -1
- package/server/lib/opencode/bootstrap-runtime.js +8 -6
- package/server/lib/opencode/cli-options.js +8 -8
- package/server/lib/opencode/config-paths.test.js +116 -0
- package/server/lib/opencode/core-routes.js +8 -7
- package/server/lib/opencode/core-routes.test.js +11 -11
- package/server/lib/opencode/env-config.js +5 -5
- package/server/lib/opencode/env-config.test.js +7 -7
- package/server/lib/opencode/env-runtime.js +10 -10
- package/server/lib/opencode/env-runtime.test.js +18 -18
- package/server/lib/opencode/feature-routes-runtime.js +19 -12
- package/server/lib/opencode/hmr-state-runtime.js +2 -2
- package/server/lib/opencode/hmr-state-runtime.test.js +1 -1
- package/server/lib/opencode/input-history-scope.js +14 -0
- package/server/lib/opencode/lifecycle.js +8 -8
- package/server/lib/opencode/lifecycle.test.js +4 -4
- package/server/lib/opencode/managed-plugin-config.js +35 -0
- package/server/lib/opencode/managed-process-registry.js +3 -3
- package/server/lib/opencode/mcp-oauth-callback.test.js +2 -2
- package/server/lib/opencode/openchamber-routes.js +79 -19
- package/server/lib/opencode/openchamber-routes.test.js +139 -12
- package/server/lib/opencode/plugins.js +2 -2
- package/server/lib/opencode/plugins.test.js +1 -1
- package/server/lib/opencode/project-icon-routes.js +2 -2
- package/server/lib/opencode/project-icon-routes.test.js +1 -1
- package/server/lib/opencode/providers.js +44 -2
- package/server/lib/opencode/providers.test.js +131 -4
- package/server/lib/opencode/proxy.js +2 -2
- package/server/lib/opencode/pwa-manifest-routes.js +1 -1
- package/server/lib/opencode/restart-session-recovery.test.js +1 -1
- package/server/lib/opencode/routes-upgrade.test.js +4 -4
- package/server/lib/opencode/routes.js +19 -17
- package/server/lib/opencode/server-startup-runtime.js +6 -6
- package/server/lib/opencode/session-runtime.js +3 -3
- package/server/lib/opencode/session-runtime.test.js +6 -6
- package/server/lib/opencode/settings-files.js +214 -0
- package/server/lib/opencode/settings-helpers.js +116 -44
- package/server/lib/opencode/settings-helpers.test.js +354 -12
- package/server/lib/opencode/settings-registry.json +747 -0
- package/server/lib/opencode/settings-runtime.js +141 -20
- package/server/lib/opencode/settings-runtime.test.js +191 -4
- package/server/lib/opencode/shared.js +5 -2
- package/server/lib/opencode/shared.test.js +7 -7
- package/server/lib/opencode/shutdown-runtime.js +2 -0
- package/server/lib/opencode/skill-routes.js +2 -1
- package/server/lib/opencode/snippets.js +1 -2
- package/server/lib/opencode/startup-performance.js +1 -1
- package/server/lib/opencode/startup-performance.test.js +6 -6
- package/server/lib/opencode/static-routes-runtime.js +8 -8
- package/server/lib/opencode/static-routes-runtime.test.js +7 -7
- package/server/lib/opencode/upgrade-capability.js +2 -2
- package/server/lib/opencode/upgrade-capability.test.js +3 -3
- package/server/lib/package-manager.js +17 -42
- package/server/lib/package-manager.test.js +19 -19
- package/server/lib/permission-auto-accept/runtime.js +1 -1
- package/server/lib/project-context/DOCUMENTATION.md +25 -1
- package/server/lib/project-context/routes.http.test.js +18 -0
- package/server/lib/project-context/routes.js +16 -1
- package/server/lib/project-context/runtime.js +248 -23
- package/server/lib/project-context/runtime.test.js +106 -3
- package/server/lib/projects/DOCUMENTATION.md +76 -0
- package/server/lib/projects/project-config.js +144 -11
- package/server/lib/projects/project-id.js +17 -0
- package/server/lib/projects/project-setup.js +409 -0
- package/server/lib/projects/project-setup.test.js +557 -0
- package/server/lib/projects/routes.js +59 -0
- package/server/lib/quota/DOCUMENTATION.md +40 -2
- package/server/lib/quota/credentials/providers.js +4 -0
- package/server/lib/quota/credentials/store.js +4 -4
- package/server/lib/quota/credentials/store.test.js +8 -8
- package/server/lib/quota/index.js +1 -0
- package/server/lib/quota/providers/cline-pass.js +125 -0
- package/server/lib/quota/providers/cline-pass.test.js +103 -0
- package/server/lib/quota/providers/exe-dev.js +75 -0
- package/server/lib/quota/providers/exe-dev.test.js +47 -0
- package/server/lib/quota/providers/hyper.js +118 -0
- package/server/lib/quota/providers/hyper.test.js +126 -0
- package/server/lib/quota/providers/index.js +22 -0
- package/server/lib/quota/providers/neuralwatt.js +3 -6
- package/server/lib/quota/providers/neuralwatt.test.js +7 -7
- package/server/lib/quota/providers/ollama-cloud.js +32 -1
- package/server/lib/quota/providers/ollama-cloud.test.js +33 -1
- package/server/lib/quota/providers/opencode-go.js +3 -2
- package/server/lib/quota/providers/opencode-go.test.js +35 -6
- package/server/lib/quota/providers/openrouter.js +119 -24
- package/server/lib/quota/providers/openrouter.test.js +330 -0
- package/server/lib/quota/providers/xai.js +1 -1
- package/server/lib/quota/routes.js +2 -0
- package/server/lib/quota/utils/auth.js +1 -1
- package/server/lib/relay/DOCUMENTATION.md +56 -1
- package/server/lib/relay/cross-compat.test.js +26 -0
- package/server/lib/relay/downstream-scheduler.js +154 -0
- package/server/lib/relay/downstream-scheduler.test.js +162 -0
- package/server/lib/relay/e2ee.js +10 -8
- package/server/lib/relay/flow-control.test.js +177 -0
- package/server/lib/relay/host-client.js +38 -9
- package/server/lib/relay/host-client.test.js +9 -1
- package/server/lib/relay/host-lock.js +1 -1
- package/server/lib/relay/service.js +5 -5
- package/server/lib/relay/tunnel-codec.js +9 -0
- package/server/lib/relay/tunnel-host.js +69 -18
- package/server/lib/relay/tunnel-host.test.js +9 -1
- package/server/lib/scheduled-tasks/issue-2710-double-execution.test.js +2 -2
- package/server/lib/scheduled-tasks/routes.js +5 -5
- package/server/lib/scheduled-tasks/service.js +25 -25
- package/server/lib/scheduled-tasks/service.test.js +1 -1
- package/server/lib/security/bind-host.js +4 -4
- package/server/lib/security/bind-host.test.js +1 -1
- package/server/lib/security/request-security.js +11 -5
- package/server/lib/security/request-security.test.js +14 -14
- package/server/lib/session-assist/runtime.js +15 -18
- package/server/lib/session-folders/routes.js +2 -2
- package/server/lib/session-folders/routes.test.js +8 -8
- package/server/lib/session-goal/DOCUMENTATION.md +20 -7
- package/server/lib/session-goal/create.js +4 -2
- package/server/lib/session-goal/create.test.js +1 -1
- package/server/lib/session-goal/objectives.js +4 -4
- package/server/lib/session-goal/routes.js +1 -1
- package/server/lib/session-goal/runtime.js +91 -30
- package/server/lib/session-goal/runtime.test.js +428 -2
- package/server/lib/session-knowledge/runtime.js +11 -11
- package/server/lib/session-knowledge/runtime.test.js +5 -5
- package/server/lib/skills-catalog/DOCUMENTATION.md +1 -1
- package/server/lib/skills-catalog/cache.test.js +2 -2
- package/server/lib/skills-catalog/disk-cache.js +5 -5
- package/server/lib/skills-catalog/github-meta.test.js +2 -2
- package/server/lib/skills-catalog/install.js +3 -2
- package/server/lib/small-model/DOCUMENTATION.md +7 -2
- package/server/lib/small-model/call.js +18 -7
- package/server/lib/small-model/call.test.js +58 -6
- package/server/lib/small-model/index.js +12 -16
- package/server/lib/small-model/index.test.js +1 -1
- package/server/lib/small-model/resolve.js +1 -1
- package/server/lib/small-model/resolve.test.js +1 -1
- package/server/lib/small-model/routes.js +2 -1
- package/server/lib/small-model/runtime-providers.js +15 -7
- package/server/lib/small-model/runtime-providers.test.js +7 -1
- package/server/lib/system-prompt/runtime.js +3 -22
- package/server/lib/system-prompt/runtime.test.js +3 -3
- package/server/lib/terminal/DOCUMENTATION.md +14 -10
- package/server/lib/terminal/runtime.js +190 -31
- package/server/lib/terminal/runtime.test.js +572 -38
- package/server/lib/terminal/shells.js +20 -3
- package/server/lib/terminal/shells.test.js +33 -2
- package/server/lib/tts/base-url.js +3 -3
- package/server/lib/tts/routes.test.js +20 -20
- package/server/lib/ui-auth/ui-auth.js +12 -9
- package/server/lib/ui-auth/ui-auth.test.js +19 -3
- package/server/lib/ui-auth/ui-passkeys.js +7 -7
- package/server/lib/walkthrough/DOCUMENTATION.md +33 -14
- package/server/lib/walkthrough/index.js +1 -0
- package/server/lib/walkthrough/jobs.test.js +1 -1
- package/server/lib/walkthrough/language.test.js +1 -1
- package/server/lib/walkthrough/model-settings.js +11 -15
- package/server/lib/walkthrough/model-settings.test.js +1 -1
- package/server/lib/walkthrough/prompt.js +3 -1
- package/server/lib/walkthrough/pull-request.test.js +5 -5
- package/server/lib/walkthrough/reproduce-2607.test.js +2 -2
- package/server/lib/walkthrough/routes.test.js +26 -5
- package/server/lib/walkthrough/sources.js +23 -2
- package/server/lib/walkthrough/store.js +3 -3
- package/server/lib/walkthrough/store.test.js +1 -1
- package/server/opencode-proxy.test.js +2 -2
- package/server/proxy-headers.js +1 -1
- package/server/sse-routes.test.js +4 -4
- package/README.md.bak +0 -250
- package/bin/lib/DOCUMENTATION.md.bak +0 -163
- package/dist/assets/CommitSection-SGBCAW0w.js +0 -1
- package/dist/assets/DiffView-DluiRSla.js +0 -4
- package/dist/assets/FilesView-Bdq8ppva.js +0 -17
- package/dist/assets/GitView-Znn7VJcP.js +0 -6
- package/dist/assets/LinearIssuesView-jP-hXyac.js +0 -1
- package/dist/assets/MarkdownImageGallery-ClOvuZxC.js +0 -1
- package/dist/assets/MarkdownRendererImpl-Dt9mjTRN.js +0 -12
- package/dist/assets/OnboardingScreen-D2DG7K6b.js +0 -1
- package/dist/assets/PierreDiffViewer-B7m3f0d7.js +0 -157
- package/dist/assets/PlanView-B0F3BtPZ.js +0 -5
- package/dist/assets/SettingsView-BBW-S-gh.js +0 -28
- package/dist/assets/ToolPartDiffPreview-CUNe28U1.js +0 -8
- package/dist/assets/WalkthroughView-egQgxel3.js +0 -4
- package/dist/assets/contextPanelEmbeddedChat-C3fjDbdg.js +0 -1
- package/dist/assets/de-C1P6X5Rs.js +0 -9
- package/dist/assets/es-CDgaF1_t.js +0 -15
- package/dist/assets/fr-Bgxqvvz_.js +0 -13
- package/dist/assets/index-C57jT0Sa.css +0 -1
- package/dist/assets/index-DW_E3rnL.js +0 -7
- package/dist/assets/ja-BDRrEcNP.js +0 -15
- package/dist/assets/ko-Ba8sQV79.js +0 -15
- package/dist/assets/main-Bv5Pkngh.js +0 -928
- package/dist/assets/markdownCore-CZwzz5gw.js +0 -3
- package/dist/assets/patchFileDiff-yNfWXN4E.js +0 -10
- package/dist/assets/pl-Dioz29BI.js +0 -15
- package/dist/assets/pt-BR-DIs6ElwV.js +0 -15
- package/dist/assets/renderElectronMiniChatApp-BcKLHXKe.js +0 -2
- package/dist/assets/renderMobileApp-D9yQJy0L.js +0 -25
- package/dist/assets/runtimeEndpointReset-CjhvxLH0.js +0 -16
- package/dist/assets/scheduledTasksApi-DLW0mkQK.js +0 -1
- package/dist/assets/tr-DFnMlPxY.js +0 -6
- package/dist/assets/uk-ZrCNjM7Y.js +0 -15
- package/dist/assets/useAppFontEffects-CjrntdL0.js +0 -7310
- package/dist/assets/useInlineCommentController-CDEuSlPH.js +0 -2
- package/dist/assets/useRootScrollLock-BHYPkrLv.js +0 -1
- package/dist/assets/vendor-ghostty-web-CrxinGGH.js +0 -13
- package/dist/assets/vendor-zod-BLfBSgBh.js +0 -39
- package/dist/assets/zh-CN-iv_AV4EC.js +0 -15
- package/dist/assets/zh-TW-CzEUk38j.js +0 -15
- package/server/index.d.ts.bak +0 -39
- package/server/lib/agent-tool/DOCUMENTATION.md.bak +0 -119
- package/server/lib/browser-control/DOCUMENTATION.md.bak +0 -50
- package/server/lib/context-obligatory/DOCUMENTATION.md.bak +0 -19
- package/server/lib/dev-tunnel/DOCUMENTATION.md.bak +0 -57
- package/server/lib/dictation/DOCUMENTATION.md.bak +0 -100
- package/server/lib/event-stream/DOCUMENTATION.md.bak +0 -62
- package/server/lib/fs/DOCUMENTATION.md.bak +0 -47
- package/server/lib/git/DOCUMENTATION.md.bak +0 -193
- package/server/lib/github/DOCUMENTATION.md.bak +0 -183
- package/server/lib/linear/DOCUMENTATION.md.bak +0 -97
- package/server/lib/linear/OAUTH-BROKER-HANDOFF.md.bak +0 -91
- package/server/lib/markdown-image-grants/DOCUMENTATION.md.bak +0 -40
- package/server/lib/notifications/APNS.md.bak +0 -135
- package/server/lib/notifications/DOCUMENTATION.md.bak +0 -138
- package/server/lib/openchamber-control/DOCUMENTATION.md.bak +0 -64
- package/server/lib/opencode/DOCUMENTATION.md.bak +0 -431
- package/server/lib/opencode/managed-process-registry.d.ts.bak +0 -13
- package/server/lib/opencode/provider-env-aliases.d.ts.bak +0 -3
- package/server/lib/permission-auto-accept/DOCUMENTATION.md.bak +0 -34
- package/server/lib/project-context/DOCUMENTATION.md.bak +0 -160
- package/server/lib/quota/DOCUMENTATION.md.bak +0 -123
- package/server/lib/relay/DOCUMENTATION.md.bak +0 -100
- package/server/lib/scheduled-tasks/DOCUMENTATION.md.bak +0 -182
- package/server/lib/session-assist/DOCUMENTATION.md.bak +0 -66
- package/server/lib/session-goal/DOCUMENTATION.md.bak +0 -213
- package/server/lib/session-knowledge/DOCUMENTATION.md.bak +0 -89
- package/server/lib/skills-catalog/DOCUMENTATION.md.bak +0 -151
- package/server/lib/small-model/DOCUMENTATION.md.bak +0 -212
- package/server/lib/system-prompt/DOCUMENTATION.md.bak +0 -36
- package/server/lib/terminal/DOCUMENTATION.md.bak +0 -50
- package/server/lib/text/DOCUMENTATION.md.bak +0 -35
- package/server/lib/tts/DOCUMENTATION.md.bak +0 -147
- package/server/lib/tunnels/DOCUMENTATION.md.bak +0 -21
- package/server/lib/ui-auth/DOCUMENTATION.md.bak +0 -44
- package/server/lib/walkthrough/DOCUMENTATION.md.bak +0 -411
|
@@ -1,135 +0,0 @@
|
|
|
1
|
-
# APNs remote push — signed relay mode
|
|
2
|
-
|
|
3
|
-
Native iOS background push (notifications even when the app is **suspended or killed**) is
|
|
4
|
-
delivered via APNs through a **central relay**, so no user configures an Apple key. Each server
|
|
5
|
-
signs its relay requests with an auto-generated keypair, and tokens are bound to the server that
|
|
6
|
-
registered them — so a leaked device token alone can't be used to push.
|
|
7
|
-
|
|
8
|
-
## How it works
|
|
9
|
-
|
|
10
|
-
1. The app registers its APNs device token with **its own server** (`POST /api/push/apns-token`,
|
|
11
|
-
`useNativePushRegistration`). PWA/desktop never register — only the native Capacitor app.
|
|
12
|
-
2. The server **binds the token on the relay**: it POSTs `{ token, publicKeyJwk, ts, sig }` to
|
|
13
|
-
`POST /v1/push/register-token`, signed with its auto-generated ECDSA P-256 key
|
|
14
|
-
(`getOrCreateRelayKeypair`, persisted in settings like the VAPID keys). The relay records
|
|
15
|
-
`token → serverId` where `serverId = SHA-256(publicKey)`.
|
|
16
|
-
3. On a trigger (ready/error/question/permission), the server composes **generic, content-free**
|
|
17
|
-
text — a fixed scenario title ("Agent response is ready" / "Agent needs your input" / "Agent
|
|
18
|
-
needs permission" / "Agent hit an error") + the **session name** as the body, no model/project/
|
|
19
|
-
message content — plus a **`badge`** count (see below) — and POSTs `{ tokens, title, body,
|
|
20
|
-
badge, env, data:{sessionId}, publicKeyJwk, ts, sig }` to `POST /v1/push/send`
|
|
21
|
-
(`apns-runtime.js` → `sendViaRelay`). It does **not** gate on UI visibility (see below).
|
|
22
|
-
4. The **relay** (`openchamber-website/apps/api`, Cloudflare Worker) verifies the signature +
|
|
23
|
-
`ts` freshness, derives `serverId`, and only delivers to tokens bound to that server. It holds
|
|
24
|
-
the single project APNs `.p8` key, signs an ES256 JWT with `crypto.subtle`, and sends each
|
|
25
|
-
token to APNs over HTTP/2, returning per-token results; the server drops tokens flagged `drop`
|
|
26
|
-
(410 / BadDeviceToken). The relay stores no secret — only `token → serverId` hashes.
|
|
27
|
-
5. Tapping a push deep-links to its session via the forwarded `sessionId`.
|
|
28
|
-
|
|
29
|
-
## Foreground suppression
|
|
30
|
-
|
|
31
|
-
APNs is **not** gated on UI visibility. A backgrounded WKWebView can't reliably report "hidden"
|
|
32
|
-
before iOS suspends it, so a server-side visibility gate dropped background push for short
|
|
33
|
-
responses. Instead the server always sends, and **iOS** suppresses the foreground banner
|
|
34
|
-
(`PushNotifications.presentationOptions: []` in `capacitor.config`) — so there is no notification
|
|
35
|
-
while the app is active, with no race. APNs is the native app's **only** channel; local
|
|
36
|
-
notifications were removed (a WKWebView can't tell foreground from background — `document.hasFocus()`
|
|
37
|
-
is unreliable — so they leaked while the app was open). Cloudflare is touched only when a native
|
|
38
|
-
app with notifications on has a registered token and a trigger fires.
|
|
39
|
-
|
|
40
|
-
## App-icon badge
|
|
41
|
-
|
|
42
|
-
Each push carries an **absolute** `aps.badge` = the number of **distinct collapse-ids (`tag`)
|
|
43
|
-
pushed since the app was last foregrounded**. It mirrors the lock-screen banner stack.
|
|
44
|
-
|
|
45
|
-
The count is a `Set<tag>` (`pendingPushTags`) in the trigger runtime (`runtime.js`):
|
|
46
|
-
`toApnsGenericPayload` adds the push `tag` and returns the set size as the badge. We key by **`tag`,
|
|
47
|
-
not sessionId**, because the tag *is* the banner identity — iOS uses it as `apns-collapse-id`, so
|
|
48
|
-
same-tag pushes replace one banner while different tags are distinct banners. One session can raise
|
|
49
|
-
several banners (`ready-<id>`, `question-<id>`, `permission-<requestKey>` are different tags), so
|
|
50
|
-
counting sessionIds both over- and under-counts the stack; counting tags matches it.
|
|
51
|
-
|
|
52
|
-
It is deliberately **not** derived from the live attention snapshot (`needsAttention`/`isViewed`):
|
|
53
|
-
that machinery drives in-app indicators on *connected* clients, where a backgrounded client stays
|
|
54
|
-
"viewing" and `needsAttention` is set by a separate `session.status` event that races the push
|
|
55
|
-
trigger. The set self-clears via `clearPendingPushBadge` on any signal that the user is engaging
|
|
56
|
-
with the app: the visibility beacon (`updateUiVisibility` wrapper, `visible:true`), **plus** opening
|
|
57
|
-
a session (`POST /api/sessions/:id/view`) and sending a message (`POST /api/sessions/:id/
|
|
58
|
-
message-sent`). The latter two need no auth and fire reliably on the native app when it foregrounds,
|
|
59
|
-
so they are the dependable reset — the visibility beacon alone proved unreliable in WKWebView. This
|
|
60
|
-
mirrors the device zeroing its icon badge on `sceneDidBecomeActive` (`AppDelegate.swift`), keeping
|
|
61
|
-
server and device in sync.
|
|
62
|
-
|
|
63
|
-
The value flows `runtime.js` (`toApnsGenericPayload`) → `apns-runtime.js` (`sendViaRelay` body /
|
|
64
|
-
direct-mode `aps.badge`) → relay (`pushSendSchema.badge` → `aps.badge`). It is **not** signed (like
|
|
65
|
-
`body`/`data`); the relay still only delivers to bound tokens. The set is server-global, so every
|
|
66
|
-
device token of a server sees the same badge.
|
|
67
|
-
|
|
68
|
-
## Modes
|
|
69
|
-
|
|
70
|
-
- **Relay (default):** server has no Apple key; `AIWORKER_PUSH_RELAY_URL` defaults to
|
|
71
|
-
`https://api.aiworker.dev/v1/push/send` (register URL is derived as `…/register-token`).
|
|
72
|
-
- **Direct (fallback):** set `AIWORKER_PUSH_RELAY_DISABLED=true` + `AIWORKER_APNS_KEY_ID/
|
|
73
|
-
TEAM_ID/P8` to sign+send from the server itself (HTTP/2 + ES256 JWT); no relay binding needed.
|
|
74
|
-
|
|
75
|
-
## Config
|
|
76
|
-
|
|
77
|
-
Server (`apns-runtime.js`):
|
|
78
|
-
- `AIWORKER_PUSH_RELAY_URL` (default the public relay), `AIWORKER_APNS_ENVIRONMENT`
|
|
79
|
-
(optional override forcing every send to `sandbox` or `production`; normally unset — each
|
|
80
|
-
token is delivered to the environment it registered with: the iOS shell reads the
|
|
81
|
-
`aps-environment` entitlement from the embedded provisioning profile and reports it at
|
|
82
|
-
registration, so Xcode dev builds go to sandbox and TestFlight/App Store to production).
|
|
83
|
-
The signing keypair is auto-generated — nothing to set.
|
|
84
|
-
- Direct fallback: `AIWORKER_APNS_KEY_ID`, `AIWORKER_APNS_TEAM_ID`, `AIWORKER_APNS_P8`
|
|
85
|
-
(or `_P8_PATH`), `AIWORKER_APNS_BUNDLE_ID`, `AIWORKER_PUSH_RELAY_DISABLED=true`.
|
|
86
|
-
|
|
87
|
-
Relay (Cloudflare Worker secrets via `wrangler secret put` / GitHub Actions): `APNS_P8`,
|
|
88
|
-
`APNS_KEY_ID`, `APNS_TEAM_ID`, optional `APNS_BUNDLE_ID` / `APNS_DEFAULT_ENV`. The `push_tokens`
|
|
89
|
-
binding table is created by `migrations/0002_push_tokens.sql` (applied on deploy).
|
|
90
|
-
|
|
91
|
-
## Apple setup (one-time)
|
|
92
|
-
|
|
93
|
-
1. Apple **Keys** (not Certificates) → create an **APNs Auth Key** (`.p8`) → Key ID + Team ID;
|
|
94
|
-
enable **Push Notifications** on App ID `com.aiworker.app`.
|
|
95
|
-
2. In the **openchamber-website** repo → Actions secrets: `APNS_P8` (PEM), `APNS_KEY_ID`,
|
|
96
|
-
`APNS_TEAM_ID`. Push to `main` → relay deploys, secrets sync, D1 migrations apply.
|
|
97
|
-
3. Xcode: confirm the Push Notifications capability; Clean Build Folder; run on device.
|
|
98
|
-
|
|
99
|
-
## Security posture
|
|
100
|
-
|
|
101
|
-
- The device token is a per-install secret, but no longer the *only* defence: every relay request
|
|
102
|
-
is signed by the server's private key, and the relay only delivers to a token from its bound
|
|
103
|
-
`serverId`. A leaked token alone is useless — an attacker has neither the private key nor a
|
|
104
|
-
matching binding.
|
|
105
|
-
- `serverId` self-certifies (`SHA-256(publicKey)`), so the relay holds no secret; a D1 leak
|
|
106
|
-
exposes only `token → serverId` hashes. The signed `ts` (±5 min window) blocks replay.
|
|
107
|
-
- Residual: trust-on-first-bind (whoever registers a token first owns it) — acceptable, since
|
|
108
|
-
registering already requires possessing the token. Cloudflare rate limiting is defence-in-depth.
|
|
109
|
-
|
|
110
|
-
## Data confidentiality (what the relay / Apple can see)
|
|
111
|
-
|
|
112
|
-
The push payload is **not** application-encrypted, so there is no decryption step. The text is
|
|
113
|
-
sent in plaintext, protected only by **TLS in transit** (HTTPS to the relay, TLS from the relay
|
|
114
|
-
to APNs). The request **signature is authentication, not encryption** — the relay *verifies* it
|
|
115
|
-
(valid / invalid), it does not hide anything.
|
|
116
|
-
|
|
117
|
-
Who can read the alert text:
|
|
118
|
-
|
|
119
|
-
- **Network hops:** nothing (TLS).
|
|
120
|
-
- **The relay (Cloudflare):** the generic title + body (session name), the device token, and
|
|
121
|
-
`sessionId`. It stores only `token → serverId` hashes (no text, no payload).
|
|
122
|
-
- **Apple APNs:** the alert text too — APNs always reads the alert payload of an `alert` push.
|
|
123
|
-
- **The device:** displays it.
|
|
124
|
-
|
|
125
|
-
This is acceptable **because the text is deliberately content-free**: a fixed scenario title +
|
|
126
|
-
the session name only — no model, project, or message content (`runtime.js` →
|
|
127
|
-
`toApnsGenericPayload`). The session name is the single semi-personal field that crosses the
|
|
128
|
-
relay/Apple. To hide even that from Apple would require an end-to-end **encrypted payload**
|
|
129
|
-
(`mutable-content` + a Notification Service Extension that decrypts on-device with a key never
|
|
130
|
-
sent to the relay) — not implemented, and unnecessary for generic text.
|
|
131
|
-
|
|
132
|
-
## Android (FCM) note
|
|
133
|
-
|
|
134
|
-
The Android equivalent is **FCM** (not implemented): the same relay would forward to FCM with a
|
|
135
|
-
server key, and the client would register an FCM token (same store/routes + signing).
|
|
@@ -1,138 +0,0 @@
|
|
|
1
|
-
# Notifications Module Documentation
|
|
2
|
-
|
|
3
|
-
## Purpose
|
|
4
|
-
This module provides notification message preparation utilities for the web server runtime, including text truncation and plain-text normalization for system notifications.
|
|
5
|
-
|
|
6
|
-
## Entrypoints and structure
|
|
7
|
-
- `packages/web/server/lib/notifications/index.js`: public entrypoint imported by `packages/web/server/index.js`.
|
|
8
|
-
- `packages/web/server/lib/notifications/routes.js`: route registration for push, visibility, and session status/attention endpoints.
|
|
9
|
-
- `packages/web/server/lib/notifications/push-runtime.js`: push subscription persistence, VAPID initialization, and UI visibility runtime.
|
|
10
|
-
- `packages/web/server/lib/notifications/apns-runtime.js`: native iOS APNs device-token persistence + delivery. Two modes: **relay** (default — sign + POST tokens + generic text to the central Cloudflare relay `https://api.aiworker.dev/v1/push/send`, which holds the single project APNs key) and **direct** (fallback — sign ES256 JWT with Node crypto + HTTP/2, when `AIWORKER_PUSH_RELAY_DISABLED=true`). Each server has an auto-generated ECDSA P-256 keypair (`getOrCreateRelayKeypair`, persisted in settings); it binds tokens on the relay (`/v1/push/register-token`) and signs every relay request, so the relay only delivers to tokens bound to that server. APNs is the native app's sole notification channel (no local notifications) and is NOT gated on UI visibility — iOS suppresses the foreground banner instead. Mobile push carries only generic text (scenario title + session name) — see `APNS.md`.
|
|
11
|
-
- `packages/web/server/lib/notifications/emitter-runtime.js`: desktop/stdout + UI SSE notification emission runtime.
|
|
12
|
-
- `packages/web/server/lib/notifications/runtime.js`: trigger runtime for OpenCode event-driven notification fanout.
|
|
13
|
-
- `packages/web/server/lib/notifications/template-runtime.js`: notification template variables and session text/title enrichment runtime. Zen-model helpers are retained as compatibility stubs only.
|
|
14
|
-
- `packages/web/server/lib/notifications/message.js`: helper implementation module.
|
|
15
|
-
- `packages/web/server/lib/notifications/message.test.js`: unit tests for notification message helpers.
|
|
16
|
-
|
|
17
|
-
## Public exports
|
|
18
|
-
|
|
19
|
-
### Notifications API (re-exported from message.js)
|
|
20
|
-
- `truncateNotificationText(text, maxLength)`: Truncates text to specified max length, appending `...` if truncated.
|
|
21
|
-
- `prepareNotificationLastMessage({ message, settings })`: Prepares the last message for notification display by normalizing and truncating text.
|
|
22
|
-
|
|
23
|
-
### Route registration API (routes.js)
|
|
24
|
-
- `registerNotificationRoutes(app, dependencies)`: Registers notification-owned endpoints:
|
|
25
|
-
- `GET /api/push/vapid-public-key`
|
|
26
|
-
- `POST /api/push/subscribe`
|
|
27
|
-
- `DELETE /api/push/subscribe`
|
|
28
|
-
- `POST /api/push/apns-token` (native iOS APNs device-token registration)
|
|
29
|
-
- `DELETE /api/push/apns-token`
|
|
30
|
-
- `POST /api/push/visibility`
|
|
31
|
-
- `GET /api/push/visibility`
|
|
32
|
-
- `GET /api/notifications/stream`
|
|
33
|
-
- `GET /api/session-activity`
|
|
34
|
-
- `GET /api/sessions/snapshot`
|
|
35
|
-
- `GET /api/sessions/status`
|
|
36
|
-
- `GET /api/sessions/:id/status`
|
|
37
|
-
- `GET /api/sessions/attention`
|
|
38
|
-
- `GET /api/sessions/:id/attention`
|
|
39
|
-
- `POST /api/sessions/:id/view`
|
|
40
|
-
- `POST /api/sessions/:id/unview`
|
|
41
|
-
- `POST /api/sessions/:id/message-sent`
|
|
42
|
-
|
|
43
|
-
### Trigger runtime API (runtime.js)
|
|
44
|
-
- `createNotificationTriggerRuntime(dependencies)`: creates runtime-owned debounced trigger handling for OpenCode events.
|
|
45
|
-
- Returned API:
|
|
46
|
-
- `maybeSendPushForTrigger(payload)`
|
|
47
|
-
- Owns:
|
|
48
|
-
- completion/error/question/permission trigger routing; permission suppression consults the authoritative permission-auto-accept runtime
|
|
49
|
-
- session parent cache for subtask suppression
|
|
50
|
-
- template resolution and fallback behavior
|
|
51
|
-
- native notification fanout and web push payload fanout
|
|
52
|
-
- push suppression while any fresh UI visibility heartbeat reports a focused client
|
|
53
|
-
|
|
54
|
-
### Push runtime API (push-runtime.js)
|
|
55
|
-
- `createPushRuntime(dependencies)`: creates runtime for web push and UI visibility state.
|
|
56
|
-
- Returned API:
|
|
57
|
-
- `getOrCreateVapidKeys()`
|
|
58
|
-
- `ensurePushInitialized()`
|
|
59
|
-
- `setPushInitialized(value)`
|
|
60
|
-
- `addOrUpdatePushSubscription(uiSessionToken, subscription, userAgent)`
|
|
61
|
-
- `removePushSubscription(uiSessionToken, endpoint)`
|
|
62
|
-
- `sendPushToAllUiSessions(payload, options?)`
|
|
63
|
-
- `updateUiVisibility(token, visible)`
|
|
64
|
-
- `isAnyUiVisible()`
|
|
65
|
-
- `isUiVisible(token)`
|
|
66
|
-
|
|
67
|
-
### APNs runtime API (apns-runtime.js)
|
|
68
|
-
- `createApnsRuntime(dependencies)`: creates runtime for native iOS APNs push and device-token state. Dependencies: `fsPromises`, `path`, `crypto`, `http2`, `APNS_TOKENS_FILE_PATH`, `readSettingsFromDiskMigrated`, `writeSettingsToDisk` (persists the auto-generated relay signing keypair).
|
|
69
|
-
- Returned API:
|
|
70
|
-
- `addOrUpdateApnsToken(uiSessionToken, deviceToken, userAgent, platform, environment)` — also binds a newly-seen token on the relay (signed `/v1/push/register-token`). `environment` is the APNs environment the token was minted for (`sandbox` for Xcode/dev-signed installs, `production` otherwise — reported by the client at registration); delivery groups tokens by it.
|
|
71
|
-
- `removeApnsToken(uiSessionToken, deviceToken)`
|
|
72
|
-
- `removeApnsTokenFromAllSessions(deviceToken)`
|
|
73
|
-
- `sendApnsToAllUiSessions(payload)` — signs + sends to all registered tokens (no UI-visibility gate; iOS suppresses the foreground banner). No-ops with a single warning when APNs is unconfigured. Drops tokens on `410` / `BadDeviceToken` / `Unregistered`.
|
|
74
|
-
- `resolveApnsConfig()`
|
|
75
|
-
- Configuration (env first, then `settings.apnsConfig`): `AIWORKER_APNS_KEY_ID`, `AIWORKER_APNS_TEAM_ID`, `AIWORKER_APNS_P8` (PEM contents; literal `\n` accepted) or `AIWORKER_APNS_P8_PATH`, `AIWORKER_APNS_BUNDLE_ID` (default `com.aiworker.app`), `AIWORKER_APNS_ENVIRONMENT` (optional override forcing every send to `sandbox` or `production`; when unset, each token is delivered to the environment it registered with, defaulting to `production` for tokens without one).
|
|
76
|
-
|
|
77
|
-
### Emitter runtime API (emitter-runtime.js)
|
|
78
|
-
- `createNotificationEmitterRuntime(dependencies)`: creates runtime for unified notification emission channels.
|
|
79
|
-
- Returned API:
|
|
80
|
-
- `writeSseEvent(res, payload)`
|
|
81
|
-
- `emitDesktopNotification(payload)`
|
|
82
|
-
- `broadcastUiNotification(payload)`
|
|
83
|
-
|
|
84
|
-
### Template runtime API (template-runtime.js)
|
|
85
|
-
- `createNotificationTemplateRuntime(dependencies)`: creates shared notification/template runtime. Model-backed summarization was retired after the Zen provider became unavailable.
|
|
86
|
-
- Returned API:
|
|
87
|
-
- `resolveNotificationTemplate(template, variables)`
|
|
88
|
-
- `shouldApplyResolvedTemplateMessage(template, resolved, variables)`
|
|
89
|
-
- `fetchFreeZenModels()` compatibility stub returning `[]`
|
|
90
|
-
- `resolveZenModel(override)` compatibility stub preserving stored values without validation
|
|
91
|
-
- `validateZenModelAtStartup()` compatibility no-op
|
|
92
|
-
- `summarizeText(text, targetLength, zenModel)` compatibility stub returning local fallback text
|
|
93
|
-
- `extractLastMessageText(payload, maxLength?)`
|
|
94
|
-
- `fetchLastAssistantMessageText(sessionId, messageId, maxLength?)`
|
|
95
|
-
- `maybeCacheSessionInfoFromEvent(payload)`
|
|
96
|
-
- `buildTemplateVariables(payload, sessionId)`
|
|
97
|
-
- `getCachedZenModels()`
|
|
98
|
-
|
|
99
|
-
## Constants
|
|
100
|
-
|
|
101
|
-
### Default values
|
|
102
|
-
- `DEFAULT_NOTIFICATION_MESSAGE_MAX_LENGTH`: 250 (default max length for notification text).
|
|
103
|
-
- `NOTIFICATION_SSE_HEARTBEAT_INTERVAL_MS`: 20000 (notification SSE comment heartbeat interval).
|
|
104
|
-
|
|
105
|
-
## Settings object format
|
|
106
|
-
|
|
107
|
-
The `settings` parameter for `prepareNotificationLastMessage` supports `maxLastMessageLength` (number), the maximum length for the final notification text (default: 250). Legacy summarization settings may still exist in persisted settings but are ignored.
|
|
108
|
-
|
|
109
|
-
## Response contracts
|
|
110
|
-
|
|
111
|
-
### `truncateNotificationText`
|
|
112
|
-
- Returns empty string for non-string input.
|
|
113
|
-
- Returns original text if under max length.
|
|
114
|
-
- Returns `${text.slice(0, maxLength)}...` for truncated text.
|
|
115
|
-
|
|
116
|
-
### `prepareNotificationLastMessage`
|
|
117
|
-
- Returns empty string for empty/null message.
|
|
118
|
-
- Returns truncated original message. Model-backed notification summarization is retired.
|
|
119
|
-
- Normalizes markdown-like formatting to plain text before truncation.
|
|
120
|
-
- Always applies `maxLastMessageLength` truncation to final result.
|
|
121
|
-
|
|
122
|
-
## Notes for contributors
|
|
123
|
-
|
|
124
|
-
### Adding new notification helpers
|
|
125
|
-
1. Add new helper functions to `packages/web/server/lib/notifications/message.js`.
|
|
126
|
-
2. Export functions that are intended for public use.
|
|
127
|
-
3. Follow existing patterns for input validation (e.g., type checking for strings).
|
|
128
|
-
4. Use `resolvePositiveNumber` for numeric parameters with fallbacks to maintain safe defaults.
|
|
129
|
-
5. Add corresponding unit tests in `packages/web/server/lib/notifications/message.test.js`.
|
|
130
|
-
|
|
131
|
-
### Error handling
|
|
132
|
-
- `prepareNotificationLastMessage` does not call model summarization.
|
|
133
|
-
- Invalid numeric parameters default to safe fallback values.
|
|
134
|
-
- Non-string inputs are handled gracefully (return empty string).
|
|
135
|
-
|
|
136
|
-
### Testing
|
|
137
|
-
- Run `bun run type-check`, `bun run lint`, and `bun run build` before finalizing changes.
|
|
138
|
-
- Unit tests should cover truncation behavior and edge cases (empty strings, invalid inputs).
|
|
@@ -1,64 +0,0 @@
|
|
|
1
|
-
# AiWorker Control Service
|
|
2
|
-
|
|
3
|
-
## Purpose
|
|
4
|
-
|
|
5
|
-
This module owns the typed control contract shared by the AiWorker CLI and
|
|
6
|
-
the managed OpenCode `aiworker` tool. Both adapters delegate to
|
|
7
|
-
`createAiWorkerControlService()`; neither adapter may call or spawn the
|
|
8
|
-
other.
|
|
9
|
-
|
|
10
|
-
## Boundaries
|
|
11
|
-
|
|
12
|
-
- `service.js` validates and executes the fixed project, model, session, and
|
|
13
|
-
scheduled-task action allowlist. `actions.js` marks CLI-only actions with
|
|
14
|
-
`agentExposed: false` (currently `schedule.status`); the agent tool consumes
|
|
15
|
-
the filtered `AIWORKER_AGENT_TOOL_*` exports. `schedule.toggle` requires
|
|
16
|
-
the `disabled` boolean and replaces separate enable/disable actions;
|
|
17
|
-
`schedule.list` also returns scheduler status as `scheduler`.
|
|
18
|
-
- `routes.js` is the authenticated CLI HTTP adapter. It forwards one action,
|
|
19
|
-
preserves service status and partial-result details, and propagates request
|
|
20
|
-
cancellation.
|
|
21
|
-
- `../agent-tool/runtime.js` is the managed-tool adapter. It wraps service
|
|
22
|
-
results in the versioned native-tool envelope and uses a separate ephemeral
|
|
23
|
-
loopback credential.
|
|
24
|
-
- `../openchamber-sessions/routes.js` and `../scheduled-tasks/service.js` own
|
|
25
|
-
their domain operations and are composed into this service.
|
|
26
|
-
|
|
27
|
-
## Invariants
|
|
28
|
-
|
|
29
|
-
- Session status and messages come from official directory-scoped OpenCode
|
|
30
|
-
APIs. Message output includes only ordered `text` parts.
|
|
31
|
-
- Wait never treats an initial idle response as completion after dispatch. It
|
|
32
|
-
requires observed activity or a newly completed assistant message.
|
|
33
|
-
- Timeout and cancellation are failures, never authoritative idle results.
|
|
34
|
-
- Validation that protects side effects runs before session creation or
|
|
35
|
-
dispatch. An explicitly requested model, agent, or variant is checked against
|
|
36
|
-
the directory's own OpenCode agent and provider lists before any session,
|
|
37
|
-
worktree, or goal is created, because `prompt_async` accepts an unusable
|
|
38
|
-
selection and then fails only on the event stream. A failed or empty lookup
|
|
39
|
-
never turns a valid selection into a rejection.
|
|
40
|
-
- `promptDispatched` reports an observed dispatch, never an accepted request.
|
|
41
|
-
After `prompt_async` the service confirms a new user message reached the
|
|
42
|
-
session; when it does not, the result reports `promptDispatched: false` with
|
|
43
|
-
`promptError` instead of claiming success.
|
|
44
|
-
- Send and fork dispatches without an explicit model/agent/variant reuse the
|
|
45
|
-
target session's last user-message selection before falling back to the
|
|
46
|
-
configured defaults; only session creation resolves defaults directly.
|
|
47
|
-
- Usage errors name the missing or conflicting input so CLI and agent-tool
|
|
48
|
-
callers can correct an invalid request without an upfront usage manual.
|
|
49
|
-
- Explicit `projectId` or `directory` scope takes precedence over the managed
|
|
50
|
-
tool's current-session directory fallback; the fallback never creates a
|
|
51
|
-
conflicting second scope.
|
|
52
|
-
- One failed directory status lookup produces `unknown` for only that
|
|
53
|
-
directory and does not erase other session results.
|
|
54
|
-
- Destructive session/worktree deletion and project-path registration are not
|
|
55
|
-
part of the action contract.
|
|
56
|
-
- `browser.capture` writes its image on the server, into
|
|
57
|
-
`.aiworker/screenshots/` under the scoped project directory, and returns
|
|
58
|
-
the project-relative path rather than the image bytes. The client that took
|
|
59
|
-
the picture may be on a different machine than the repository, and a path is
|
|
60
|
-
what an answer, a commit, or a review can use; base64 in a tool result cannot
|
|
61
|
-
be any of those. The agent's label is reduced to a filename fragment, never
|
|
62
|
-
used as a path. The result also states how to present the image, because chat
|
|
63
|
-
renders the image paths written in a finished answer below that message —
|
|
64
|
-
saving the file is not what shows it to anyone.
|