@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
|
@@ -16,7 +16,7 @@ export const createStaticRoutesRuntime = (dependencies) => {
|
|
|
16
16
|
} = dependencies;
|
|
17
17
|
|
|
18
18
|
const resolveDistPath = () => {
|
|
19
|
-
const env = typeof process.env.
|
|
19
|
+
const env = typeof process.env.AIWORKER_DIST_DIR === 'string' ? process.env.AIWORKER_DIST_DIR.trim() : '';
|
|
20
20
|
if (env) {
|
|
21
21
|
return path.resolve(env);
|
|
22
22
|
}
|
|
@@ -61,7 +61,7 @@ export const createStaticRoutesRuntime = (dependencies) => {
|
|
|
61
61
|
|
|
62
62
|
const registerApiOnlyFallbackRoutes = (app) => {
|
|
63
63
|
app.get(/^(?!\/api|\/auth|\/health|\/linear|.*\.(js|css|svg|png|jpg|jpeg|gif|ico|woff|woff2|ttf|eot|map)).*$/, (req, res) => {
|
|
64
|
-
const command = '
|
|
64
|
+
const command = 'aiworker connect-url --help';
|
|
65
65
|
res.status(200).format({
|
|
66
66
|
html: () => {
|
|
67
67
|
res.send(`<!doctype html>
|
|
@@ -69,7 +69,7 @@ export const createStaticRoutesRuntime = (dependencies) => {
|
|
|
69
69
|
<head>
|
|
70
70
|
<meta charset="utf-8">
|
|
71
71
|
<meta name="viewport" content="width=device-width, initial-scale=1">
|
|
72
|
-
<title>
|
|
72
|
+
<title>AiWorker API-only mode</title>
|
|
73
73
|
<style>
|
|
74
74
|
:root {
|
|
75
75
|
color-scheme: dark;
|
|
@@ -171,7 +171,7 @@ export const createStaticRoutesRuntime = (dependencies) => {
|
|
|
171
171
|
</head>
|
|
172
172
|
<body>
|
|
173
173
|
<main>
|
|
174
|
-
<svg class="logo" viewBox="0 0 100 100" fill="none" xmlns="http://www.w3.org/2000/svg" role="img" aria-label="
|
|
174
|
+
<svg class="logo" viewBox="0 0 100 100" fill="none" xmlns="http://www.w3.org/2000/svg" role="img" aria-label="AiWorker logo">
|
|
175
175
|
<path d="M50 50 L8.432 26 L8.432 74 L50 98 Z" fill="currentColor" fill-opacity=".15" stroke="currentColor" stroke-width="2" stroke-linejoin="round"/>
|
|
176
176
|
<path d="M8.432 26 L18.824 32 L18.824 44 L8.432 38 Z" fill="currentColor" fill-opacity=".2"/>
|
|
177
177
|
<path d="M18.824 32 L29.216 38 L29.216 50 L18.824 44 Z" fill="currentColor" fill-opacity=".45"/>
|
|
@@ -212,8 +212,8 @@ export const createStaticRoutesRuntime = (dependencies) => {
|
|
|
212
212
|
<path d="M-8 -4 L8 -4 L8 12 L-8 12 Z" fill="currentColor" fill-opacity=".4"/>
|
|
213
213
|
</g>
|
|
214
214
|
</svg>
|
|
215
|
-
<h1>
|
|
216
|
-
<p>This server is ready. Open it from the
|
|
215
|
+
<h1>AiWorker is running in headless mode</h1>
|
|
216
|
+
<p>This server is ready. Open it from the AiWorker desktop or mobile app to use it.</p>
|
|
217
217
|
<div class="command">
|
|
218
218
|
<code id="connect-command">${command}</code>
|
|
219
219
|
<button type="button" id="copy-command" aria-label="Copy command" title="Copy command">
|
|
@@ -249,10 +249,10 @@ export const createStaticRoutesRuntime = (dependencies) => {
|
|
|
249
249
|
</html>`);
|
|
250
250
|
},
|
|
251
251
|
json: () => {
|
|
252
|
-
res.json({ ok: true, mode: 'api-only', message: '
|
|
252
|
+
res.json({ ok: true, mode: 'api-only', message: 'AiWorker is running in API-only mode' });
|
|
253
253
|
},
|
|
254
254
|
default: () => {
|
|
255
|
-
res.type('text/plain').send('
|
|
255
|
+
res.type('text/plain').send('AiWorker is running in API-only mode');
|
|
256
256
|
},
|
|
257
257
|
});
|
|
258
258
|
});
|
|
@@ -25,9 +25,9 @@ describe('static routes runtime', () => {
|
|
|
25
25
|
const response = await request(app).get('/sessions/abc').set('Accept', 'text/html');
|
|
26
26
|
|
|
27
27
|
expect(response.status).toBe(200);
|
|
28
|
-
expect(response.text).toContain('
|
|
29
|
-
expect(response.text).toContain('Open it from the
|
|
30
|
-
expect(response.text).toContain('
|
|
28
|
+
expect(response.text).toContain('AiWorker is running in headless mode');
|
|
29
|
+
expect(response.text).toContain('Open it from the AiWorker desktop or mobile app');
|
|
30
|
+
expect(response.text).toContain('aiworker connect-url --help');
|
|
31
31
|
expect(response.text).toContain('Copy command');
|
|
32
32
|
});
|
|
33
33
|
|
|
@@ -41,7 +41,7 @@ describe('static routes runtime', () => {
|
|
|
41
41
|
expect(response.body).toEqual({
|
|
42
42
|
ok: true,
|
|
43
43
|
mode: 'api-only',
|
|
44
|
-
message: '
|
|
44
|
+
message: 'AiWorker is running in API-only mode',
|
|
45
45
|
});
|
|
46
46
|
});
|
|
47
47
|
|
|
@@ -53,8 +53,8 @@ describe('static routes runtime', () => {
|
|
|
53
53
|
const auth = await request(app).get('/auth/session');
|
|
54
54
|
const health = await request(app).get('/health');
|
|
55
55
|
|
|
56
|
-
expect(api.body).not.toEqual({ ok: true, mode: 'api-only', message: '
|
|
57
|
-
expect(auth.body).not.toEqual({ ok: true, mode: 'api-only', message: '
|
|
58
|
-
expect(health.body).not.toEqual({ ok: true, mode: 'api-only', message: '
|
|
56
|
+
expect(api.body).not.toEqual({ ok: true, mode: 'api-only', message: 'AiWorker is running in API-only mode' });
|
|
57
|
+
expect(auth.body).not.toEqual({ ok: true, mode: 'api-only', message: 'AiWorker is running in API-only mode' });
|
|
58
|
+
expect(health.body).not.toEqual({ ok: true, mode: 'api-only', message: 'AiWorker is running in API-only mode' });
|
|
59
59
|
});
|
|
60
60
|
});
|
|
@@ -13,7 +13,7 @@ export const resolveOpenCodeUpgradeCapability = ({
|
|
|
13
13
|
if (isWindowsArm64()) {
|
|
14
14
|
return {
|
|
15
15
|
supported: false,
|
|
16
|
-
manager: '
|
|
16
|
+
manager: 'aiworker',
|
|
17
17
|
reason: 'windows-arm64-workaround',
|
|
18
18
|
};
|
|
19
19
|
}
|
|
@@ -37,7 +37,7 @@ export const resolveOpenCodeUpgradeCapability = ({
|
|
|
37
37
|
if (isBundledBinary(activeBinary)) {
|
|
38
38
|
return {
|
|
39
39
|
supported: false,
|
|
40
|
-
manager: '
|
|
40
|
+
manager: 'aiworker',
|
|
41
41
|
reason: 'bundled',
|
|
42
42
|
};
|
|
43
43
|
}
|
|
@@ -2,17 +2,17 @@ import { describe, expect, it, vi } from 'vitest';
|
|
|
2
2
|
import { resolveOpenCodeUpgradeCapability } from './upgrade-capability.js';
|
|
3
3
|
|
|
4
4
|
describe('OpenCode upgrade capability', () => {
|
|
5
|
-
it('assigns bundled binaries to the
|
|
5
|
+
it('assigns bundled binaries to the AiWorker updater', () => {
|
|
6
6
|
const isBundledBinary = vi.fn(() => true);
|
|
7
7
|
|
|
8
8
|
expect(resolveOpenCodeUpgradeCapability({
|
|
9
9
|
isExternal: false,
|
|
10
10
|
hasManagedProcess: true,
|
|
11
|
-
activeBinary: '/Applications/
|
|
11
|
+
activeBinary: '/Applications/AiWorker.app/Contents/Resources/opencode-cli/opencode',
|
|
12
12
|
isBundledBinary,
|
|
13
13
|
})).toEqual({
|
|
14
14
|
supported: false,
|
|
15
|
-
manager: '
|
|
15
|
+
manager: 'aiworker',
|
|
16
16
|
reason: 'bundled',
|
|
17
17
|
});
|
|
18
18
|
});
|
|
@@ -4,30 +4,30 @@ import fs from 'fs';
|
|
|
4
4
|
import os from 'os';
|
|
5
5
|
import path from 'path';
|
|
6
6
|
import { fileURLToPath } from 'url';
|
|
7
|
+
import { fetchUpdateNotes } from './changelog/update-notes.js';
|
|
7
8
|
|
|
8
9
|
const __filename = fileURLToPath(import.meta.url);
|
|
9
10
|
const __dirname = path.dirname(__filename);
|
|
10
11
|
|
|
11
|
-
const PACKAGE_NAME = '@
|
|
12
|
+
const PACKAGE_NAME = '@aiworker/web';
|
|
12
13
|
const PACKAGE_PATH_SEGMENTS = PACKAGE_NAME.split('/');
|
|
13
14
|
const NPM_REGISTRY_URL = `https://registry.npmjs.org/${PACKAGE_NAME}`;
|
|
14
|
-
const
|
|
15
|
-
const GITHUB_RELEASES_URL = 'https://github.com/openchamber/openchamber/releases';
|
|
15
|
+
const GITHUB_RELEASES_URL = 'https://roweb.cn/roweb/openchamber/releases';
|
|
16
16
|
const GITHUB_RELEASES_API_URL = 'https://api.github.com/repos/openchamber/openchamber/releases';
|
|
17
17
|
let cachedDetectedPm = null;
|
|
18
18
|
|
|
19
19
|
function getSpawnSyncBaseOptions() {
|
|
20
20
|
return process.platform === 'win32' ? { windowsHide: true } : {};
|
|
21
21
|
}
|
|
22
|
-
const UPDATE_CHECK_URL = process.env.
|
|
22
|
+
const UPDATE_CHECK_URL = process.env.AIWORKER_UPDATE_API_URL || 'https://api.aiworker.dev/v1/update/check';
|
|
23
23
|
|
|
24
|
-
function
|
|
24
|
+
function getAiWorkerConfigDir() {
|
|
25
25
|
if (process.platform === 'win32') {
|
|
26
26
|
const appData = process.env.APPDATA;
|
|
27
|
-
if (appData) return path.join(appData, '
|
|
27
|
+
if (appData) return path.join(appData, 'aiworker');
|
|
28
28
|
}
|
|
29
29
|
|
|
30
|
-
return path.join(os.homedir(), '.config', '
|
|
30
|
+
return path.join(os.homedir(), '.config', 'aiworker');
|
|
31
31
|
}
|
|
32
32
|
|
|
33
33
|
function sanitizeInstallScope(scope) {
|
|
@@ -36,7 +36,7 @@ function sanitizeInstallScope(scope) {
|
|
|
36
36
|
}
|
|
37
37
|
|
|
38
38
|
function getOrCreateInstallId(scope = 'web') {
|
|
39
|
-
const configDir =
|
|
39
|
+
const configDir = getAiWorkerConfigDir();
|
|
40
40
|
const normalizedScope = sanitizeInstallScope(scope);
|
|
41
41
|
const idPath = path.join(configDir, `install-id-${normalizedScope}`);
|
|
42
42
|
|
|
@@ -113,7 +113,7 @@ async function resolveAndroidApkUrl(version, candidateUrl) {
|
|
|
113
113
|
&& typeof asset.browser_download_url === 'string'
|
|
114
114
|
))
|
|
115
115
|
: [];
|
|
116
|
-
const canonicalAsset = apkAssets.find((asset) => /^
|
|
116
|
+
const canonicalAsset = apkAssets.find((asset) => /^AiWorker-.+-android\.apk$/i.test(asset.name));
|
|
117
117
|
return (canonicalAsset || apkAssets[0])?.browser_download_url;
|
|
118
118
|
} catch {
|
|
119
119
|
return undefined;
|
|
@@ -344,7 +344,7 @@ function getGlobalNodeModulesRoots(pm) {
|
|
|
344
344
|
function getOwnedPackagePathsFromGlobalBins(pm) {
|
|
345
345
|
const packagePaths = [];
|
|
346
346
|
for (const binDir of getGlobalBinDirs(pm)) {
|
|
347
|
-
const binaryName = process.platform === 'win32' ? '
|
|
347
|
+
const binaryName = process.platform === 'win32' ? 'aiworker.cmd' : 'aiworker';
|
|
348
348
|
const binaryPath = path.join(binDir, binaryName);
|
|
349
349
|
if (!fs.existsSync(binaryPath)) continue;
|
|
350
350
|
|
|
@@ -386,7 +386,7 @@ export function detectPackageManagerDetails() {
|
|
|
386
386
|
// dozen spawnSync(pm, ['bin', '-g']) calls with 10s timeouts each; under
|
|
387
387
|
// the in-process server every one blocks the Electron main event loop and
|
|
388
388
|
// manifests as a multi-second UI freeze. Short-circuit here.
|
|
389
|
-
if (process.env.
|
|
389
|
+
if (process.env.AIWORKER_RUNTIME === 'desktop') {
|
|
390
390
|
return {
|
|
391
391
|
packageManager: 'electron',
|
|
392
392
|
reason: 'desktop-runtime',
|
|
@@ -406,7 +406,7 @@ export function detectPackageManagerDetails() {
|
|
|
406
406
|
};
|
|
407
407
|
}
|
|
408
408
|
|
|
409
|
-
const forcedPm = process.env.
|
|
409
|
+
const forcedPm = process.env.AIWORKER_PACKAGE_MANAGER?.trim();
|
|
410
410
|
if (forcedPm && ['npm', 'pnpm', 'yarn', 'bun'].includes(forcedPm)) {
|
|
411
411
|
const forcedPmCommand = resolvePackageManagerCommand(forcedPm);
|
|
412
412
|
if (isCommandAvailable(forcedPmCommand)) {
|
|
@@ -645,7 +645,7 @@ function isPackageInstalledWith(pm) {
|
|
|
645
645
|
});
|
|
646
646
|
|
|
647
647
|
if (result.status !== 0) return false;
|
|
648
|
-
return result.stdout.includes(PACKAGE_NAME) || result.stdout.includes('
|
|
648
|
+
return result.stdout.includes(PACKAGE_NAME) || result.stdout.includes('aiworker');
|
|
649
649
|
} catch {
|
|
650
650
|
return false;
|
|
651
651
|
}
|
|
@@ -737,34 +737,9 @@ function compareVersions(left, right) {
|
|
|
737
737
|
return 0;
|
|
738
738
|
}
|
|
739
739
|
|
|
740
|
-
/**
|
|
741
|
-
* Fetch changelog notes between versions
|
|
742
|
-
*/
|
|
740
|
+
/** Release notes between the installed and the offered version, or undefined. */
|
|
743
741
|
async function fetchChangelogNotes(fromVersion, toVersion) {
|
|
744
|
-
|
|
745
|
-
const response = await fetch(CHANGELOG_URL, {
|
|
746
|
-
signal: AbortSignal.timeout(10000),
|
|
747
|
-
});
|
|
748
|
-
|
|
749
|
-
if (!response.ok) return undefined;
|
|
750
|
-
|
|
751
|
-
const changelog = await response.text();
|
|
752
|
-
const sections = changelog.split(/^## /m).slice(1);
|
|
753
|
-
|
|
754
|
-
const relevantSections = sections.filter((section) => {
|
|
755
|
-
const match = section.match(/^\[(\d+\.\d+\.\d+)\]/);
|
|
756
|
-
if (!match) return false;
|
|
757
|
-
return compareVersions(match[1], fromVersion) > 0 && compareVersions(match[1], toVersion) <= 0;
|
|
758
|
-
});
|
|
759
|
-
|
|
760
|
-
if (relevantSections.length === 0) return undefined;
|
|
761
|
-
|
|
762
|
-
return relevantSections
|
|
763
|
-
.map((s) => '## ' + s.trim())
|
|
764
|
-
.join('\n\n');
|
|
765
|
-
} catch {
|
|
766
|
-
return undefined;
|
|
767
|
-
}
|
|
742
|
+
return (await fetchUpdateNotes(fromVersion, toVersion, compareVersions)) ?? undefined;
|
|
768
743
|
}
|
|
769
744
|
|
|
770
745
|
export async function checkForUpdates(options = {}) {
|
|
@@ -785,7 +760,7 @@ export async function checkForUpdates(options = {}) {
|
|
|
785
760
|
return {
|
|
786
761
|
...remote,
|
|
787
762
|
packageManager: pm,
|
|
788
|
-
updateCommand: '
|
|
763
|
+
updateCommand: 'aiworker update',
|
|
789
764
|
};
|
|
790
765
|
}
|
|
791
766
|
}
|
|
@@ -819,7 +794,7 @@ export async function checkForUpdates(options = {}) {
|
|
|
819
794
|
downloadUrl,
|
|
820
795
|
packageManager: pm,
|
|
821
796
|
// Show our CLI command, not raw package manager command
|
|
822
|
-
updateCommand: '
|
|
797
|
+
updateCommand: 'aiworker update',
|
|
823
798
|
};
|
|
824
799
|
}
|
|
825
800
|
|
|
@@ -55,7 +55,7 @@ describe('checkForUpdates', () => {
|
|
|
55
55
|
|
|
56
56
|
it('returns available=true when both API and npm confirm a newer version', async () => {
|
|
57
57
|
fetchMock
|
|
58
|
-
.when('api.
|
|
58
|
+
.when('api.aiworker.dev', {
|
|
59
59
|
ok: true,
|
|
60
60
|
json: async () => ({
|
|
61
61
|
latestVersion: '1.10.0',
|
|
@@ -85,7 +85,7 @@ describe('checkForUpdates', () => {
|
|
|
85
85
|
|
|
86
86
|
it('returns available=false when API claims update but npm has same version', async () => {
|
|
87
87
|
fetchMock
|
|
88
|
-
.when('api.
|
|
88
|
+
.when('api.aiworker.dev', {
|
|
89
89
|
ok: true,
|
|
90
90
|
json: async () => ({
|
|
91
91
|
latestVersion: '1.10.0',
|
|
@@ -107,7 +107,7 @@ describe('checkForUpdates', () => {
|
|
|
107
107
|
|
|
108
108
|
it('returns available=false when npm only has a prerelease of the current version', async () => {
|
|
109
109
|
fetchMock
|
|
110
|
-
.when('api.
|
|
110
|
+
.when('api.aiworker.dev', Promise.reject(new Error('Network error')))
|
|
111
111
|
.when('registry.npmjs.org', {
|
|
112
112
|
ok: true,
|
|
113
113
|
json: async () => ({
|
|
@@ -122,7 +122,7 @@ describe('checkForUpdates', () => {
|
|
|
122
122
|
|
|
123
123
|
it('accepts electron desktop update claims without npm cross-checking', async () => {
|
|
124
124
|
fetchMock
|
|
125
|
-
.when('api.
|
|
125
|
+
.when('api.aiworker.dev', {
|
|
126
126
|
ok: true,
|
|
127
127
|
json: async () => ({
|
|
128
128
|
latestVersion: '1.10.0',
|
|
@@ -151,12 +151,12 @@ describe('checkForUpdates', () => {
|
|
|
151
151
|
|
|
152
152
|
it('resolves an Android APK asset when the update API returns an AAB', async () => {
|
|
153
153
|
fetchMock
|
|
154
|
-
.when('api.
|
|
154
|
+
.when('api.aiworker.dev', {
|
|
155
155
|
ok: true,
|
|
156
156
|
json: async () => ({
|
|
157
157
|
latestVersion: '1.10.0',
|
|
158
158
|
updateAvailable: true,
|
|
159
|
-
downloadUrl: 'https://
|
|
159
|
+
downloadUrl: 'https://roweb.cn/roweb/openchamber/releases/download/v1.10.0/AiWorker-1.10.0-42-android.aab',
|
|
160
160
|
}),
|
|
161
161
|
})
|
|
162
162
|
.when('api.github.com/repos/openchamber/openchamber/releases/tags/v1.10.0', {
|
|
@@ -164,16 +164,16 @@ describe('checkForUpdates', () => {
|
|
|
164
164
|
json: async () => ({
|
|
165
165
|
assets: [
|
|
166
166
|
{
|
|
167
|
-
name: '
|
|
168
|
-
browser_download_url: 'https://downloads.example/
|
|
167
|
+
name: 'AiWorker-1.10.0-42-android.aab',
|
|
168
|
+
browser_download_url: 'https://downloads.example/AiWorker-1.10.0-42-android.aab',
|
|
169
169
|
},
|
|
170
170
|
{
|
|
171
171
|
name: 'app-release.apk',
|
|
172
172
|
browser_download_url: 'https://downloads.example/app-release.apk',
|
|
173
173
|
},
|
|
174
174
|
{
|
|
175
|
-
name: '
|
|
176
|
-
browser_download_url: 'https://downloads.example/
|
|
175
|
+
name: 'AiWorker-1.10.0-42-android.apk',
|
|
176
|
+
browser_download_url: 'https://downloads.example/AiWorker-1.10.0-42-android.apk',
|
|
177
177
|
},
|
|
178
178
|
],
|
|
179
179
|
}),
|
|
@@ -185,12 +185,12 @@ describe('checkForUpdates', () => {
|
|
|
185
185
|
currentVersion: '1.9.10',
|
|
186
186
|
});
|
|
187
187
|
|
|
188
|
-
expect(result.downloadUrl).toBe('https://downloads.example/
|
|
188
|
+
expect(result.downloadUrl).toBe('https://downloads.example/AiWorker-1.10.0-42-android.apk');
|
|
189
189
|
});
|
|
190
190
|
|
|
191
191
|
it('keeps a direct Android APK URL from the update API', async () => {
|
|
192
|
-
const apkUrl = 'https://
|
|
193
|
-
fetchMock.when('api.
|
|
192
|
+
const apkUrl = 'https://roweb.cn/roweb/openchamber/releases/download/v1.10.0/AiWorker-1.10.0-42-android.apk';
|
|
193
|
+
fetchMock.when('api.aiworker.dev', {
|
|
194
194
|
ok: true,
|
|
195
195
|
json: async () => ({
|
|
196
196
|
latestVersion: '1.10.0',
|
|
@@ -211,7 +211,7 @@ describe('checkForUpdates', () => {
|
|
|
211
211
|
|
|
212
212
|
it('returns available=false when API claims update but npm is behind', async () => {
|
|
213
213
|
fetchMock
|
|
214
|
-
.when('api.
|
|
214
|
+
.when('api.aiworker.dev', {
|
|
215
215
|
ok: true,
|
|
216
216
|
json: async () => ({
|
|
217
217
|
latestVersion: '1.10.0',
|
|
@@ -234,7 +234,7 @@ describe('checkForUpdates', () => {
|
|
|
234
234
|
// --- Scenario: API says no update, npm agrees ---
|
|
235
235
|
|
|
236
236
|
it('returns available=false when API says no update and versions match', async () => {
|
|
237
|
-
fetchMock.when('api.
|
|
237
|
+
fetchMock.when('api.aiworker.dev', {
|
|
238
238
|
ok: true,
|
|
239
239
|
json: async () => ({
|
|
240
240
|
latestVersion: '1.9.10',
|
|
@@ -251,7 +251,7 @@ describe('checkForUpdates', () => {
|
|
|
251
251
|
|
|
252
252
|
it('returns available=true from npm fallback when API is unreachable and npm has newer version', async () => {
|
|
253
253
|
fetchMock
|
|
254
|
-
.when('api.
|
|
254
|
+
.when('api.aiworker.dev', Promise.reject(new Error('Network error')))
|
|
255
255
|
.when('registry.npmjs.org', {
|
|
256
256
|
ok: true,
|
|
257
257
|
json: async () => ({
|
|
@@ -271,7 +271,7 @@ describe('checkForUpdates', () => {
|
|
|
271
271
|
|
|
272
272
|
it('returns available=false from npm fallback when API is unreachable and versions match', async () => {
|
|
273
273
|
fetchMock
|
|
274
|
-
.when('api.
|
|
274
|
+
.when('api.aiworker.dev', Promise.reject(new Error('Network error')))
|
|
275
275
|
.when('registry.npmjs.org', {
|
|
276
276
|
ok: true,
|
|
277
277
|
json: async () => ({
|
|
@@ -288,7 +288,7 @@ describe('checkForUpdates', () => {
|
|
|
288
288
|
|
|
289
289
|
it('returns available=false when API returns non-ok status and versions match on npm', async () => {
|
|
290
290
|
fetchMock
|
|
291
|
-
.when('api.
|
|
291
|
+
.when('api.aiworker.dev', {
|
|
292
292
|
ok: false,
|
|
293
293
|
status: 500,
|
|
294
294
|
json: async () => ({}),
|
|
@@ -309,7 +309,7 @@ describe('checkForUpdates', () => {
|
|
|
309
309
|
|
|
310
310
|
it('returns available=false when both sources are unreachable', async () => {
|
|
311
311
|
fetchMock
|
|
312
|
-
.when('api.
|
|
312
|
+
.when('api.aiworker.dev', Promise.reject(new Error('Network error')))
|
|
313
313
|
.when('registry.npmjs.org', Promise.reject(new Error('Registry unreachable')));
|
|
314
314
|
|
|
315
315
|
const result = await checkForUpdates({ currentVersion: '1.9.10' });
|
|
@@ -63,7 +63,7 @@ export function createPermissionAutoAcceptRuntime({
|
|
|
63
63
|
policy = next;
|
|
64
64
|
loaded = true;
|
|
65
65
|
broadcastGlobalUiEvent?.({
|
|
66
|
-
type: '
|
|
66
|
+
type: 'aiworker:permission-auto-accept.updated',
|
|
67
67
|
properties: snapshot(),
|
|
68
68
|
});
|
|
69
69
|
return snapshot();
|
|
@@ -9,9 +9,10 @@ The managed Chats root (`~/.config/openchamber/chats`) is also one context owner
|
|
|
9
9
|
|
|
10
10
|
| Path | Owner | Contents |
|
|
11
11
|
|---|---|---|
|
|
12
|
-
| `<projectsDir>/<projectId>.json` |
|
|
12
|
+
| `<projectsDir>/<projectId>.json` | `packages/web/server/lib/projects` (`project-setup.js` for the client-owned keys behind `/api/projects/:projectId/config`; `project-config.js` for `version` / `scheduledTasks`), one write lock for both | worktree setup, draft starters, project actions, scheduled tasks |
|
|
13
13
|
| `<projectsDir>/<projectId>/context.json` | **this module, exclusively** | notes, todos, plan manifest |
|
|
14
14
|
| `<projectsDir>/<projectId>/plans/*.md` | **this module, exclusively** | plan bodies |
|
|
15
|
+
| `<repo>/<plansDir>/*.md` | this module (read, edit, delete, move) when the team config names a `plansDir`; the folder is the team's, any tool may write there | shared plan bodies |
|
|
15
16
|
|
|
16
17
|
The split is the point. Both files were previously one, written by the client
|
|
17
18
|
with a whole-file read-modify-write. Adding a server writer to that file would
|
|
@@ -58,6 +59,27 @@ denormalized into the manifest so listing plans costs one read rather than one
|
|
|
58
59
|
read per plan; `readPlan` returns the title parsed from the file, which wins if
|
|
59
60
|
the two ever disagree.
|
|
60
61
|
|
|
62
|
+
## Shared plans
|
|
63
|
+
|
|
64
|
+
Every `.md` file in the repository plans folder is a plan too: `.aiworker/plans`
|
|
65
|
+
by default, or the `plansDir` the team config (`<repo>/.aiworker/project.json`,
|
|
66
|
+
see `packages/web/server/lib/projects`) names instead of it (the custom folder
|
|
67
|
+
replaces the default outright; moving files between the two is the user's job). `readContext` appends them after the personal ones,
|
|
68
|
+
each marked `source: "shared"` (personal ones get `source: "personal"`), and
|
|
69
|
+
reports the folder as `sharedPlansDir`. A shared plan is addressed as
|
|
70
|
+
`shared:<file>` when no manifest entry claims it; its title is parsed from the
|
|
71
|
+
file on every list, and `readPlan` / `updatePlan` / `deletePlan` work on the
|
|
72
|
+
file directly (an update writes the raw document verbatim, so a plan another
|
|
73
|
+
tool wrote keeps its shape). `setPlanPinned` is `404` for such a plan.
|
|
74
|
+
|
|
75
|
+
A plan the user moves there keeps its id: `sharePlan` moves the markdown into
|
|
76
|
+
the folder and keeps the manifest entry with `shared: true` (the flag says
|
|
77
|
+
which folder holds the file), so a session that attached the plan still finds
|
|
78
|
+
it, and the file is listed under that id instead of `shared:<file>`.
|
|
79
|
+
`unsharePlan` moves it back and clears the flag; a plan that only ever lived
|
|
80
|
+
in the team's folder gets a manifest entry (and an id) on the way in. A name
|
|
81
|
+
collision gets a numeric suffix. Sharing is refused only when the checkout cannot be located.
|
|
82
|
+
|
|
61
83
|
## Routes
|
|
62
84
|
|
|
63
85
|
| Method | Route | Notes |
|
|
@@ -72,6 +94,8 @@ the two ever disagree.
|
|
|
72
94
|
| POST | `/api/project-context/:projectId/plans` | `201`; takes `{title, body}`, never a path |
|
|
73
95
|
| PUT | `/api/project-context/:projectId/plans/:planId` | takes the whole `{raw}` document; `404` when the link or its markdown is gone |
|
|
74
96
|
| DELETE | `/api/project-context/:projectId/plans/:planId` | `404` when unknown |
|
|
97
|
+
| POST | `/api/project-context/:projectId/plans/:planId/share` | moves the plan into the shared folder; `400` without one, `404` when unknown |
|
|
98
|
+
| POST | `/api/project-context/:projectId/plans/:planId/unshare` | moves a `shared:` plan back; `404` when unknown |
|
|
75
99
|
|
|
76
100
|
**Body parsing is attached per route.** This server has no global JSON parser:
|
|
77
101
|
`core-routes` parses only an allowlist of `/api` path prefixes so the generic
|
|
@@ -57,6 +57,8 @@ const createApp = (overrides = {}) => {
|
|
|
57
57
|
context: emptyContext,
|
|
58
58
|
}),
|
|
59
59
|
deletePlan: async () => ({ deleted: true, context: emptyContext }),
|
|
60
|
+
sharePlan: async (_projectId, planId) => (planId === 'p1' ? { plan: { id: 'shared:a.md', file: 'a.md', title: 'A', createdAt: 1, pinned: false, source: 'shared' }, context: emptyContext } : null),
|
|
61
|
+
unsharePlan: async (_projectId, planId) => (planId === 'shared:a.md' ? { plan: { id: 'p2', file: 'a.md', title: 'A', createdAt: 1, pinned: false, source: 'personal' }, context: emptyContext } : null),
|
|
60
62
|
...overrides,
|
|
61
63
|
};
|
|
62
64
|
|
|
@@ -212,6 +214,22 @@ describe('project context routes over HTTP', () => {
|
|
|
212
214
|
.expect(400);
|
|
213
215
|
});
|
|
214
216
|
|
|
217
|
+
it('shares and unshares a plan, and answers 404 for an unknown one', async () => {
|
|
218
|
+
const { app } = createApp();
|
|
219
|
+
const shared = await request(app).post('/api/project-context/proj/plans/p1/share');
|
|
220
|
+
expect(shared.status).toBe(200);
|
|
221
|
+
expect(shared.body.plan.id).toBe('shared:a.md');
|
|
222
|
+
const back = await request(app).post('/api/project-context/proj/plans/shared%3Aa.md/unshare');
|
|
223
|
+
expect(back.status).toBe(200);
|
|
224
|
+
expect(back.body.plan.source).toBe('personal');
|
|
225
|
+
expect((await request(app).post('/api/project-context/proj/plans/nope/share')).status).toBe(404);
|
|
226
|
+
});
|
|
227
|
+
|
|
228
|
+
it('answers 400 when sharing without a shared plans folder', async () => {
|
|
229
|
+
const { app } = createApp({ sharePlan: async () => { throw new Error('shared plans folder is required'); } });
|
|
230
|
+
expect((await request(app).post('/api/project-context/proj/plans/p1/share')).status).toBe(400);
|
|
231
|
+
});
|
|
232
|
+
|
|
215
233
|
it('returns 404 for an unknown plan', async () => {
|
|
216
234
|
const { app } = createApp();
|
|
217
235
|
await request(app).get(`${BASE}/plans/nope`).expect(404);
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/**
|
|
2
|
-
*
|
|
2
|
+
* AiWorker project context routes: notes, todos, and plan files.
|
|
3
3
|
*
|
|
4
4
|
* These replace the shared UI's direct `/api/fs/*` access to
|
|
5
5
|
* `~/.config/openchamber/projects/*`. The client no longer resolves the home
|
|
@@ -220,6 +220,21 @@ export const registerProjectContextRoutes = (app, dependencies) => {
|
|
|
220
220
|
}
|
|
221
221
|
});
|
|
222
222
|
|
|
223
|
+
// Moving a plan between the user's folder and the team's shared folder.
|
|
224
|
+
for (const [suffix, method] of [['share', 'sharePlan'], ['unshare', 'unsharePlan']]) {
|
|
225
|
+
app.post(`/api/project-context/:projectId/plans/:planId/${suffix}`, async (req, res) => {
|
|
226
|
+
try {
|
|
227
|
+
const result = await projectContextRuntime[method](req.params.projectId, req.params.planId);
|
|
228
|
+
if (!result) {
|
|
229
|
+
return res.status(404).json({ error: 'Plan not found' });
|
|
230
|
+
}
|
|
231
|
+
return res.json(result);
|
|
232
|
+
} catch (error) {
|
|
233
|
+
return respondWithError(res, error, `Failed to ${suffix} plan`);
|
|
234
|
+
}
|
|
235
|
+
});
|
|
236
|
+
}
|
|
237
|
+
|
|
223
238
|
app.delete('/api/project-context/:projectId/plans/:planId', async (req, res) => {
|
|
224
239
|
try {
|
|
225
240
|
const { deleted, context } = await projectContextRuntime.deletePlan(
|