@weavecode/weave 0.1.5 → 0.1.6
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/node_modules/@modelcontextprotocol/sdk/node_modules/express/node_modules/encodeurl/README.md +14 -0
- package/node_modules/@modelcontextprotocol/sdk/node_modules/express/node_modules/encodeurl/index.js +5 -10
- package/node_modules/@modelcontextprotocol/sdk/node_modules/express/node_modules/encodeurl/package.json +10 -6
- package/node_modules/@modelcontextprotocol/sdk/node_modules/express/node_modules/qs/CHANGELOG.md +42 -0
- package/node_modules/@modelcontextprotocol/sdk/node_modules/express/node_modules/qs/README.md +38 -10
- package/node_modules/@modelcontextprotocol/sdk/node_modules/express/node_modules/qs/dist/qs.js +18 -18
- package/node_modules/@modelcontextprotocol/sdk/node_modules/express/node_modules/qs/lib/parse.js +16 -4
- package/node_modules/@modelcontextprotocol/sdk/node_modules/express/node_modules/qs/lib/utils.js +13 -2
- package/node_modules/@modelcontextprotocol/sdk/node_modules/express/node_modules/qs/package.json +1 -1
- package/node_modules/@modelcontextprotocol/sdk/node_modules/express-rate-limit/dist/index.cjs +6 -2
- package/node_modules/@modelcontextprotocol/sdk/node_modules/express-rate-limit/dist/index.mjs +6 -2
- package/node_modules/@modelcontextprotocol/sdk/node_modules/express-rate-limit/package.json +10 -10
- package/node_modules/@modelcontextprotocol/sdk/node_modules/jose/dist/types/jwt/decrypt.d.ts +3 -0
- package/node_modules/@modelcontextprotocol/sdk/node_modules/jose/dist/types/jwt/unsecured.d.ts +2 -0
- package/node_modules/@modelcontextprotocol/sdk/node_modules/jose/dist/types/jwt/verify.d.ts +3 -0
- package/node_modules/@modelcontextprotocol/sdk/node_modules/jose/dist/types/types.d.ts +8 -0
- package/node_modules/@modelcontextprotocol/sdk/node_modules/jose/dist/types/util/decode_jwt.d.ts +1 -0
- package/node_modules/@modelcontextprotocol/sdk/node_modules/jose/dist/webapi/jwks/remote.js +1 -1
- package/node_modules/@modelcontextprotocol/sdk/node_modules/jose/package.json +1 -1
- package/node_modules/@weavecode/cli/dist/cli.js +4 -4
- package/node_modules/@weavecode/cli/dist/commands/daemon.d.ts +2 -0
- package/node_modules/@weavecode/cli/dist/commands/daemon.js +2 -2
- package/node_modules/@weavecode/cli/dist/commands/dashboard.js +2 -2
- package/node_modules/@weavecode/cli/dist/commands/doctor.js +1 -1
- package/node_modules/@weavecode/cli/dist/commands/init.js +1 -1
- package/node_modules/@weavecode/cli/dist/commands/msg.js +2 -2
- package/node_modules/@weavecode/cli/dist/commands/status.js +2 -2
- package/node_modules/@weavecode/cli/dist/i18n/dict/en.js +4 -4
- package/node_modules/@weavecode/cli/dist/i18n/dict/zh.d.ts +5 -1
- package/node_modules/@weavecode/cli/dist/i18n/dict/zh.js +4 -4
- package/node_modules/@weavecode/cli/dist/statusline/ansi.js +1 -1
- package/node_modules/@weavecode/cli/package.json +5 -5
- package/node_modules/@weavecode/core/dist/harness.d.ts +14 -0
- package/node_modules/@weavecode/core/dist/harness.js +1 -1
- package/node_modules/@weavecode/core/dist/index.d.ts +1 -1
- package/node_modules/@weavecode/core/dist/index.js +1 -1
- package/node_modules/@weavecode/core/package.json +1 -1
- package/node_modules/@weavecode/harness/dist/claude/assets.js +1 -1
- package/node_modules/@weavecode/harness/dist/claude/commands.d.ts +3 -0
- package/node_modules/@weavecode/harness/dist/claude/commands.js +2 -3
- package/node_modules/@weavecode/harness/dist/claude/index.d.ts +1 -0
- package/node_modules/@weavecode/harness/dist/claude/index.js +1 -1
- package/node_modules/@weavecode/harness/dist/claude/narration.d.ts +0 -11
- package/node_modules/@weavecode/harness/dist/claude/narration.js +1 -1
- package/node_modules/@weavecode/harness/dist/claude/questions.js +2 -2
- package/node_modules/@weavecode/harness/dist/claude/rewind.d.ts +8 -0
- package/node_modules/@weavecode/harness/dist/claude/rewind.js +1 -0
- package/node_modules/@weavecode/harness/dist/claude/statusline/generator.js +31 -10
- package/node_modules/@weavecode/harness/dist/claude/transcript-cursor.d.ts +26 -0
- package/node_modules/@weavecode/harness/dist/claude/transcript-cursor.js +2 -0
- package/node_modules/@weavecode/harness/dist/codex/commands.js +4 -4
- package/node_modules/@weavecode/harness/dist/driver.d.ts +49 -1
- package/node_modules/@weavecode/harness/dist/driver.js +1 -1
- package/node_modules/@weavecode/harness/dist/zcode/assets.js +1 -1
- package/node_modules/@weavecode/harness/dist/zcode/capture.js +3 -3
- package/node_modules/@weavecode/harness/dist/zcode/mcp.js +2 -2
- package/node_modules/@weavecode/harness/package.json +2 -2
- package/node_modules/@weavecode/server/dist/config/dotted.js +1 -1
- package/node_modules/@weavecode/server/dist/config/profiles.d.ts +19 -13
- package/node_modules/@weavecode/server/dist/config/profiles.js +2 -2
- package/node_modules/@weavecode/server/dist/daemon/ai-config.js +2 -2
- package/node_modules/@weavecode/server/dist/daemon/ai-context.js +6 -6
- package/node_modules/@weavecode/server/dist/daemon/ai-routes.js +4 -4
- package/node_modules/@weavecode/server/dist/daemon/api-log.js +3 -3
- package/node_modules/@weavecode/server/dist/daemon/auth-routes.js +1 -1
- package/node_modules/@weavecode/server/dist/daemon/auto-start.js +6 -6
- package/node_modules/@weavecode/server/dist/daemon/capture-routes.js +1 -1
- package/node_modules/@weavecode/server/dist/daemon/config-routes.js +1 -1
- package/node_modules/@weavecode/server/dist/daemon/cron.js +1 -1
- package/node_modules/@weavecode/server/dist/daemon/dashboard-auth.js +2 -2
- package/node_modules/@weavecode/server/dist/daemon/dashboard-pusher.js +1 -1
- package/node_modules/@weavecode/server/dist/daemon/data-bus.js +1 -1
- package/node_modules/@weavecode/server/dist/daemon/decision-config.js +2 -2
- package/node_modules/@weavecode/server/dist/daemon/dev-entry.js +1 -1
- package/node_modules/@weavecode/server/dist/daemon/entry.js +7 -1
- package/node_modules/@weavecode/server/dist/daemon/fs-browser.js +1 -1
- package/node_modules/@weavecode/server/dist/daemon/hook-pipeline.js +1 -1
- package/node_modules/@weavecode/server/dist/daemon/hooks-routes.js +1 -1
- package/node_modules/@weavecode/server/dist/daemon/http.js +1 -1
- package/node_modules/@weavecode/server/dist/daemon/liveness.js +1 -1
- package/node_modules/@weavecode/server/dist/daemon/mcp-orchestration.js +1 -1
- package/node_modules/@weavecode/server/dist/daemon/narration-watcher.js +2 -2
- package/node_modules/@weavecode/server/dist/daemon/opener/backend-ghostty.js +1 -1
- package/node_modules/@weavecode/server/dist/daemon/opener/backend-iterm.js +1 -1
- package/node_modules/@weavecode/server/dist/daemon/opener/backend-konsole.js +2 -2
- package/node_modules/@weavecode/server/dist/daemon/opener/backend-terminal-app.js +1 -1
- package/node_modules/@weavecode/server/dist/daemon/opener/backend-wezterm.js +1 -1
- package/node_modules/@weavecode/server/dist/daemon/opener/backend-wt.js +1 -1
- package/node_modules/@weavecode/server/dist/daemon/opener/backend.js +1 -1
- package/node_modules/@weavecode/server/dist/daemon/opener/pty-terminals.js +4 -4
- package/node_modules/@weavecode/server/dist/daemon/opener/shared.js +1 -1
- package/node_modules/@weavecode/server/dist/daemon/opener/wezterm-mux.js +1 -1
- package/node_modules/@weavecode/server/dist/daemon/opener/wt.js +3 -3
- package/node_modules/@weavecode/server/dist/daemon/opener.d.ts +2 -0
- package/node_modules/@weavecode/server/dist/daemon/opener.js +1 -1
- package/node_modules/@weavecode/server/dist/daemon/port.js +1 -1
- package/node_modules/@weavecode/server/dist/daemon/project-files.js +2 -2
- package/node_modules/@weavecode/server/dist/daemon/project-harnesses.js +2 -2
- package/node_modules/@weavecode/server/dist/daemon/project-updates-refresher.js +1 -1
- package/node_modules/@weavecode/server/dist/daemon/prompt-images.js +1 -1
- package/node_modules/@weavecode/server/dist/daemon/routes/hooks-admin.js +1 -1
- package/node_modules/@weavecode/server/dist/daemon/routes/market.js +1 -1
- package/node_modules/@weavecode/server/dist/daemon/routes/orchestration.js +1 -1
- package/node_modules/@weavecode/server/dist/daemon/routes/path-refs.js +1 -1
- package/node_modules/@weavecode/server/dist/daemon/routes/project-files.js +1 -1
- package/node_modules/@weavecode/server/dist/daemon/routes/projects.js +1 -1
- package/node_modules/@weavecode/server/dist/daemon/routes/search.js +1 -1
- package/node_modules/@weavecode/server/dist/daemon/routes/session-control.js +1 -1
- package/node_modules/@weavecode/server/dist/daemon/routes/session-insights.js +1 -1
- package/node_modules/@weavecode/server/dist/daemon/routes/settings-statusline.js +1 -1
- package/node_modules/@weavecode/server/dist/daemon/routes/uploads.js +1 -1
- package/node_modules/@weavecode/server/dist/daemon/routes/visualizations.d.ts +3 -0
- package/node_modules/@weavecode/server/dist/daemon/routes/visualizations.js +1 -0
- package/node_modules/@weavecode/server/dist/daemon/routes/watches.js +1 -1
- package/node_modules/@weavecode/server/dist/daemon/server.js +8 -8
- package/node_modules/@weavecode/server/dist/daemon/session-open.js +1 -1
- package/node_modules/@weavecode/server/dist/daemon/session-probe.d.ts +5 -4
- package/node_modules/@weavecode/server/dist/daemon/session-probe.js +1 -1
- package/node_modules/@weavecode/server/dist/daemon/settings.js +2 -2
- package/node_modules/@weavecode/server/dist/daemon/snapshot-refresher.js +1 -1
- package/node_modules/@weavecode/server/dist/daemon/sse-hub.js +1 -1
- package/node_modules/@weavecode/server/dist/daemon/start.js +1 -1
- package/node_modules/@weavecode/server/dist/daemon/state.js +2 -2
- package/node_modules/@weavecode/server/dist/daemon/static.js +1 -1
- package/node_modules/@weavecode/server/dist/daemon/terminal-topology-refresher.js +1 -1
- package/node_modules/@weavecode/server/dist/daemon/tls.js +1 -1
- package/node_modules/@weavecode/server/dist/daemon/toolkit-routes.js +1 -1
- package/node_modules/@weavecode/server/dist/daemon/upload-sessions.js +1 -1
- package/node_modules/@weavecode/server/dist/db/db.js +6 -2
- package/node_modules/@weavecode/server/dist/db/layout.js +1 -1
- package/node_modules/@weavecode/server/dist/hooks/answer-keys.js +1 -1
- package/node_modules/@weavecode/server/dist/hooks/bus.d.ts +3 -1
- package/node_modules/@weavecode/server/dist/hooks/bus.js +1 -1
- package/node_modules/@weavecode/server/dist/hooks/dashboard-rate.js +1 -1
- package/node_modules/@weavecode/server/dist/hooks/decision-judge.js +1 -1
- package/node_modules/@weavecode/server/dist/hooks/delivery/ack-gate.d.ts +12 -6
- package/node_modules/@weavecode/server/dist/hooks/delivery/ack-gate.js +1 -1
- package/node_modules/@weavecode/server/dist/hooks/delivery/channels.d.ts +3 -3
- package/node_modules/@weavecode/server/dist/hooks/delivery/channels.js +1 -1
- package/node_modules/@weavecode/server/dist/hooks/delivery/keys.d.ts +19 -9
- package/node_modules/@weavecode/server/dist/hooks/delivery/keys.js +1 -1
- package/node_modules/@weavecode/server/dist/hooks/delivery/queue.js +1 -1
- package/node_modules/@weavecode/server/dist/hooks/delivery/relay.d.ts +2 -2
- package/node_modules/@weavecode/server/dist/hooks/delivery/relay.js +1 -1
- package/node_modules/@weavecode/server/dist/hooks/delivery/send.js +2 -2
- package/node_modules/@weavecode/server/dist/hooks/delivery/views.d.ts +3 -1
- package/node_modules/@weavecode/server/dist/hooks/delivery/views.js +1 -1
- package/node_modules/@weavecode/server/dist/hooks/dispatcher.js +6 -6
- package/node_modules/@weavecode/server/dist/hooks/edge-extract.js +1 -1
- package/node_modules/@weavecode/server/dist/hooks/handlers/webhook.js +1 -1
- package/node_modules/@weavecode/server/dist/hooks/headless-runner.js +2 -2
- package/node_modules/@weavecode/server/dist/hooks/inbox-socket.js +2 -2
- package/node_modules/@weavecode/server/dist/hooks/inbox-worker.js +3 -3
- package/node_modules/@weavecode/server/dist/hooks/match.js +1 -1
- package/node_modules/@weavecode/server/dist/hooks/message-deliverer.d.ts +45 -38
- package/node_modules/@weavecode/server/dist/hooks/message-deliverer.js +5 -3
- package/node_modules/@weavecode/server/dist/hooks/mirror.js +4 -4
- package/node_modules/@weavecode/server/dist/hooks/orchestration-engine.js +7 -7
- package/node_modules/@weavecode/server/dist/hooks/orchestration-graph.js +1 -1
- package/node_modules/@weavecode/server/dist/hooks/plugin-installer.js +3 -3
- package/node_modules/@weavecode/server/dist/hooks/plugin-loader.js +1 -1
- package/node_modules/@weavecode/server/dist/hooks/plugin-project-state.js +1 -1
- package/node_modules/@weavecode/server/dist/hooks/prompt-flusher.js +1 -1
- package/node_modules/@weavecode/server/dist/hooks/promptbox.js +8 -8
- package/node_modules/@weavecode/server/dist/hooks/push-notify.js +2 -2
- package/node_modules/@weavecode/server/dist/hooks/question-tracker.js +1 -1
- package/node_modules/@weavecode/server/dist/hooks/registry.js +1 -1
- package/node_modules/@weavecode/server/dist/hooks/resume-runner.js +1 -1
- package/node_modules/@weavecode/server/dist/hooks/session-purge.js +1 -1
- package/node_modules/@weavecode/server/dist/hooks/side-questions.js +1 -1
- package/node_modules/@weavecode/server/dist/hooks/synthetic-sessions.js +1 -1
- package/node_modules/@weavecode/server/dist/hooks/toolkit-scan.js +1 -1
- package/node_modules/@weavecode/server/dist/hooks/toolkit.js +5 -5
- package/node_modules/@weavecode/server/dist/hooks/watch-engine.js +1 -1
- package/node_modules/@weavecode/server/dist/install/apply-update.js +1 -1
- package/node_modules/@weavecode/server/dist/install/capabilities.js +1 -1
- package/node_modules/@weavecode/server/dist/install/codex-toml.js +1 -1
- package/node_modules/@weavecode/server/dist/install/file-assets.js +1 -1
- package/node_modules/@weavecode/server/dist/install/fingerprint.js +1 -1
- package/node_modules/@weavecode/server/dist/install/global-config.js +1 -1
- package/node_modules/@weavecode/server/dist/install/global-file-assets.js +1 -1
- package/node_modules/@weavecode/server/dist/install/init-files.js +2 -2
- package/node_modules/@weavecode/server/dist/install/install-ledger.js +1 -1
- package/node_modules/@weavecode/server/dist/install/installer.js +1 -1
- package/node_modules/@weavecode/server/dist/install/library-index.js +1 -1
- package/node_modules/@weavecode/server/dist/install/mcp-rows.js +1 -1
- package/node_modules/@weavecode/server/dist/install/plugin-install.js +1 -1
- package/node_modules/@weavecode/server/dist/install/plugin-rows.js +1 -1
- package/node_modules/@weavecode/server/dist/install/plugin-templates.js +1 -1
- package/node_modules/@weavecode/server/dist/install/project-config.js +1 -1
- package/node_modules/@weavecode/server/dist/install/reader.js +1 -1
- package/node_modules/@weavecode/server/dist/install/scan-cache.js +1 -1
- package/node_modules/@weavecode/server/dist/install/scanner.js +1 -1
- package/node_modules/@weavecode/server/dist/install/settings-mcp.js +2 -2
- package/node_modules/@weavecode/server/dist/install/updates.js +1 -1
- package/node_modules/@weavecode/server/dist/market/builtin.js +1 -1
- package/node_modules/@weavecode/server/dist/market/identity.js +1 -1
- package/node_modules/@weavecode/server/dist/market/import.js +2 -2
- package/node_modules/@weavecode/server/dist/market/refresh.js +1 -1
- package/node_modules/@weavecode/server/dist/market/resolve.js +1 -1
- package/node_modules/@weavecode/server/dist/market/updates.js +1 -1
- package/node_modules/@weavecode/server/dist/registry.js +2 -2
- package/node_modules/@weavecode/server/dist/repositories/hook-dispatches.js +5 -5
- package/node_modules/@weavecode/server/dist/repositories/hook-events.d.ts +1 -1
- package/node_modules/@weavecode/server/dist/repositories/hook-events.js +5 -5
- package/node_modules/@weavecode/server/dist/repositories/hook-rules.js +4 -4
- package/node_modules/@weavecode/server/dist/repositories/libraries.js +1 -1
- package/node_modules/@weavecode/server/dist/repositories/orchestrations.js +7 -7
- package/node_modules/@weavecode/server/dist/repositories/plugin-states.js +1 -1
- package/node_modules/@weavecode/server/dist/repositories/projects.js +2 -2
- package/node_modules/@weavecode/server/dist/repositories/push-subscriptions.js +2 -2
- package/node_modules/@weavecode/server/dist/repositories/session-watches.js +4 -4
- package/node_modules/@weavecode/server/dist/repositories/sessions.d.ts +11 -1
- package/node_modules/@weavecode/server/dist/repositories/sessions.js +4 -2
- package/node_modules/@weavecode/server/dist/repositories/uploads.d.ts +14 -4
- package/node_modules/@weavecode/server/dist/repositories/uploads.js +11 -11
- package/node_modules/@weavecode/server/dist/statusline/cache-sweeper.js +1 -1
- package/node_modules/@weavecode/server/dist/statusline/generator.js +1 -1
- package/node_modules/@weavecode/server/dist/statusline/manager.js +3 -3
- package/node_modules/@weavecode/server/dist/surfaces.d.ts +3 -1
- package/node_modules/@weavecode/server/dist/surfaces.js +1 -1
- package/node_modules/@weavecode/server/dist/watch/cache.js +1 -1
- package/node_modules/@weavecode/server/dist/watch/classifier.js +1 -1
- package/node_modules/@weavecode/server/dist/watch/plugin-mods.js +1 -1
- package/node_modules/@weavecode/server/dist/watch/sync-scheduler.js +1 -1
- package/node_modules/@weavecode/server/dist/watch/watch-service.js +1 -1
- package/node_modules/@weavecode/server/package.json +4 -4
- package/node_modules/@weavecode/server/web/dist/assets/{abnfDiagram-WEYOIA3C-C-f9WfD3.js → abnfDiagram-WEYOIA3C-CbIFQh0R.js} +1 -1
- package/node_modules/@weavecode/server/web/dist/assets/{arc-D62qulAD.js → arc-DH8-rYAa.js} +1 -1
- package/node_modules/@weavecode/server/web/dist/assets/{architectureDiagram-ZHVYKT53-B6ZJRpcL.js → architectureDiagram-ZHVYKT53-qnv6S0sc.js} +1 -1
- package/node_modules/@weavecode/server/web/dist/assets/{blockDiagram-RJAE7QA3-DOtDFeiT.js → blockDiagram-RJAE7QA3-pT5eO-cB.js} +1 -1
- package/node_modules/@weavecode/server/web/dist/assets/{c4Diagram-XDPPPE54-DWn3ng8X.js → c4Diagram-XDPPPE54-DHDBDMb1.js} +1 -1
- package/node_modules/@weavecode/server/web/dist/assets/channel-BHPeeuzN.js +1 -0
- package/node_modules/@weavecode/server/web/dist/assets/{chunk-2E7WHVMD-B5IIc9cn.js → chunk-2E7WHVMD-CT951PH5.js} +1 -1
- package/node_modules/@weavecode/server/web/dist/assets/{chunk-2Q5K7J3B-BUU9Zvt8.js → chunk-2Q5K7J3B-E5AD7_ZY.js} +1 -1
- package/node_modules/@weavecode/server/web/dist/assets/{chunk-4EMNKR2T-CqEGIghP.js → chunk-4EMNKR2T-DWz9qkcy.js} +1 -1
- package/node_modules/@weavecode/server/web/dist/assets/{chunk-55XCU76K-D36o_E2b.js → chunk-55XCU76K-D-SgWD8w.js} +1 -1
- package/node_modules/@weavecode/server/web/dist/assets/{chunk-5VM5RSS4-sxws8ERh.js → chunk-5VM5RSS4-ci6YzbO5.js} +1 -1
- package/node_modules/@weavecode/server/web/dist/assets/{chunk-JWPE2WC7-CJo_rEEb.js → chunk-JWPE2WC7-CY4mr2f4.js} +1 -1
- package/node_modules/@weavecode/server/web/dist/assets/{chunk-VQ5W62QI-9UlLCpsb.js → chunk-VQ5W62QI-CON8zyg8.js} +1 -1
- package/node_modules/@weavecode/server/web/dist/assets/{chunk-XXDRQBXY-CX9CPbWb.js → chunk-XXDRQBXY-DXXXZ4pW.js} +1 -1
- package/node_modules/@weavecode/server/web/dist/assets/{chunk-ZCHMQSOR-DwEfdZcF.js → chunk-ZCHMQSOR-CukvPvkM.js} +2 -2
- package/node_modules/@weavecode/server/web/dist/assets/{classDiagram-v2-4MYWR3UA-CFCmIyt8.js → classDiagram-v2-4MYWR3UA-GiWZ9xtF.js} +1 -1
- package/node_modules/@weavecode/server/web/dist/assets/{cose-bilkent-JH36ORCC-qWXeXJTn.js → cose-bilkent-JH36ORCC-D7aJ-akq.js} +1 -1
- package/node_modules/@weavecode/server/web/dist/assets/{cynefin-EF2NZ3EQ-CXabWQxz.js → cynefin-EF2NZ3EQ-9B__MaRM.js} +1 -1
- package/node_modules/@weavecode/server/web/dist/assets/{cynefinDiagram-WF24UDRP-Bzpj8Qbj.js → cynefinDiagram-WF24UDRP-B2ujZh2k.js} +1 -1
- package/node_modules/@weavecode/server/web/dist/assets/{dagre-NK4GIZVX-CXsL8t30.js → dagre-NK4GIZVX-nHaB6IWf.js} +1 -1
- package/node_modules/@weavecode/server/web/dist/assets/{diagram-CBK3MWTC-xfR-zlAD.js → diagram-CBK3MWTC-xKfjDvgr.js} +1 -1
- package/node_modules/@weavecode/server/web/dist/assets/{diagram-I5XIIV2D-BjMqEsXr.js → diagram-I5XIIV2D-BHT2-5mY.js} +1 -1
- package/node_modules/@weavecode/server/web/dist/assets/{diagram-ODIL2UCW-QZpf8KhT.js → diagram-ODIL2UCW-CckywF4W.js} +1 -1
- package/node_modules/@weavecode/server/web/dist/assets/{diagram-PFBEJUXE-Cw1ESWft.js → diagram-PFBEJUXE-Dpjlc7Wh.js} +1 -1
- package/node_modules/@weavecode/server/web/dist/assets/{diagram-RJA3I4VV-CAy2RYYZ.js → diagram-RJA3I4VV-M6WznOaW.js} +1 -1
- package/node_modules/@weavecode/server/web/dist/assets/{diagram-TYUNFSNR-B09WciWt.js → diagram-TYUNFSNR-DgRJ3zL1.js} +1 -1
- package/node_modules/@weavecode/server/web/dist/assets/{ebnfDiagram-V4P3TTPT-DuLmHG0U.js → ebnfDiagram-V4P3TTPT-BzzVN__a.js} +1 -1
- package/node_modules/@weavecode/server/web/dist/assets/{elk-QONTBCTQ--zzx0EVP.js → elk-QONTBCTQ-Ch6Gs9G9.js} +1 -1
- package/node_modules/@weavecode/server/web/dist/assets/{erDiagram-KYQIGQAA-BPDjG5vB.js → erDiagram-KYQIGQAA-COxT-Pxb.js} +1 -1
- package/node_modules/@weavecode/server/web/dist/assets/{flowDiagram-IUGLLWBU-DtE2M9a_.js → flowDiagram-IUGLLWBU-CJVWnTBa.js} +1 -1
- package/node_modules/@weavecode/server/web/dist/assets/{ganttDiagram-R7GPNTJY-B-4AaWVa.js → ganttDiagram-R7GPNTJY-BkRpWPUl.js} +1 -1
- package/node_modules/@weavecode/server/web/dist/assets/{gitGraphDiagram-PDYL7XHY-CYj5FGYx.js → gitGraphDiagram-PDYL7XHY-Ba8BJcvZ.js} +1 -1
- package/node_modules/@weavecode/server/web/dist/assets/index-CtifxEiF.css +11 -0
- package/node_modules/@weavecode/server/web/dist/assets/index-FwH9INgS.js +1090 -0
- package/node_modules/@weavecode/server/web/dist/assets/{infoDiagram-MVDRKAX5-DHYSDj-3.js → infoDiagram-MVDRKAX5-HTQ5FUNK.js} +1 -1
- package/node_modules/@weavecode/server/web/dist/assets/{ishikawaDiagram-HPEHV2GE-CumAEBoU.js → ishikawaDiagram-HPEHV2GE-BNjEDIZy.js} +1 -1
- package/node_modules/@weavecode/server/web/dist/assets/{journeyDiagram-BOSHW7O7-ES3O3X05.js → journeyDiagram-BOSHW7O7-Cao6h91a.js} +1 -1
- package/node_modules/@weavecode/server/web/dist/assets/{kanban-definition-FNSA4HC5-BMIrf0d9.js → kanban-definition-FNSA4HC5-CXIx2CHQ.js} +1 -1
- package/node_modules/@weavecode/server/web/dist/assets/{linear-DEZ5FO1r.js → linear-65WmlvQb.js} +1 -1
- package/node_modules/@weavecode/server/web/dist/assets/{mermaid.core-D7gm2szA.js → mermaid.core-D39fi_iR.js} +4 -4
- package/node_modules/@weavecode/server/web/dist/assets/{mindmap-definition-6OY57UG3-BBQP8lyN.js → mindmap-definition-6OY57UG3-DHqpz_AK.js} +1 -1
- package/node_modules/@weavecode/server/web/dist/assets/{pegDiagram-ECIUJNBX-DzkKsqmg.js → pegDiagram-ECIUJNBX-Cpy1nsER.js} +1 -1
- package/node_modules/@weavecode/server/web/dist/assets/{pieDiagram-GNMPY74T-zR3q7Qs1.js → pieDiagram-GNMPY74T-B1IyNqzr.js} +1 -1
- package/node_modules/@weavecode/server/web/dist/assets/{quadrantDiagram-D57K4MC3-B4xuIsMW.js → quadrantDiagram-D57K4MC3-zSM6o7mB.js} +1 -1
- package/node_modules/@weavecode/server/web/dist/assets/{railroadDiagram-Y72NRBL7-D2I52m9D.js → railroadDiagram-Y72NRBL7-oM4XJIwA.js} +1 -1
- package/node_modules/@weavecode/server/web/dist/assets/{requirementDiagram-EQYSW5RA-aJ1KfKj2.js → requirementDiagram-EQYSW5RA-CbCLBjHf.js} +1 -1
- package/node_modules/@weavecode/server/web/dist/assets/{sankeyDiagram-SY24JHO5-CEq16Ecf.js → sankeyDiagram-SY24JHO5-BucVk6EP.js} +1 -1
- package/node_modules/@weavecode/server/web/dist/assets/{sequenceDiagram-BLEHNHQU-Bc66KG9f.js → sequenceDiagram-BLEHNHQU-Dg8CYEnT.js} +1 -1
- package/node_modules/@weavecode/server/web/dist/assets/{sizeCapture-INFHLROL-Ddizw_UG.js → sizeCapture-INFHLROL-C51zb7Oc.js} +1 -1
- package/node_modules/@weavecode/server/web/dist/assets/{stateDiagram-v2-A6IESKWZ-C1eVtEX9.js → stateDiagram-v2-A6IESKWZ-BvK2l3is.js} +1 -1
- package/node_modules/@weavecode/server/web/dist/assets/{swimlanes-B3ENRKFQ-CCd_KlpZ.js → swimlanes-B3ENRKFQ-Ds7QOfXW.js} +1 -1
- package/node_modules/@weavecode/server/web/dist/assets/swimlanesDiagram-AYQRV4AK-ByBF02UJ.js +8 -0
- package/node_modules/@weavecode/server/web/dist/assets/{timeline-definition-JXYKGLGB-DqpBhIII.js → timeline-definition-JXYKGLGB-CadU4Qq4.js} +1 -1
- package/node_modules/@weavecode/server/web/dist/assets/{usecaseDiagram-WPOLBNNX-bX_jNjSt.js → usecaseDiagram-WPOLBNNX-BYuZwTDZ.js} +1 -1
- package/node_modules/@weavecode/server/web/dist/assets/{vennDiagram-Q3Y3IDCW-D07CUHl3.js → vennDiagram-Q3Y3IDCW-C7zgxe07.js} +1 -1
- package/node_modules/@weavecode/server/web/dist/assets/{wardleyDiagram-IVAIDKWA-CZ5ovcWa.js → wardleyDiagram-IVAIDKWA-DA4Otf4s.js} +1 -1
- package/node_modules/@weavecode/server/web/dist/assets/{xychartDiagram-4URNHDU4-CBTh52hU.js → xychartDiagram-4URNHDU4-Bs5YGwMU.js} +1 -1
- package/node_modules/@weavecode/server/web/dist/index.html +2 -2
- package/node_modules/@weavecode/server/web/dist/sw.js +14 -12
- package/node_modules/@weavecode/templates/package.json +2 -2
- package/package.json +6 -6
- package/node_modules/@weavecode/server/web/dist/assets/channel-CjSr3Zfg.js +0 -1
- package/node_modules/@weavecode/server/web/dist/assets/index-BGdTLG4q.js +0 -1031
- package/node_modules/@weavecode/server/web/dist/assets/index-CEpJpR7P.css +0 -11
- package/node_modules/@weavecode/server/web/dist/assets/swimlanesDiagram-AYQRV4AK-yIifcHaR.js +0 -8
|
@@ -1 +1 @@
|
|
|
1
|
-
import{readBody as m,sendJson as
|
|
1
|
+
import{readBody as m,sendJson as r}from"../http.js";import{DEFAULT_AI_SETTINGS as b,DEFAULT_DECISION_SETTINGS as E,readDaemonSettings as u,writeDaemonSettings as T,terminalPresetsFor as K}from"../settings.js";import{readAiKey as N,writeAiKey as G}from"../ai-config.js";import{readDecisionKey as I,writeDecisionKey as U}from"../decision-config.js";import{accessUrls as j}from"../tls.js";import{applyLaunchOnLogin as A}from"../auto-start.js";import{WEAVE_VERSION as O}from"../../version.js";import{readProjectConfig as h,writeProjectConfig as v}from"../../install/project-config.js";import{readStatuslineConfig as y,readStatuslineScript as C,readStatuslineFacts as D,applyStatuslineConfig as g,readGlobalStatuslineConfig as S,writeGlobalStatuslineConfig as J}from"../../statusline/manager.js";import{DEFAULT_STATUSLINE_CONFIG as F}from"../../statusline/config.js";import{listBrowseRoots as B,listDirectoryChildren as L}from"../fs-browser.js";import{projectFileNamespaces as _}from"../../hooks/toolkit.js";import{listGlobalFileAssets as k}from"../../install/global-file-assets.js";function w(i,e,s){const n=i.ai??b,l=i.decision??E,p=N(e),d=I(s);return{...i,ai:{baseUrl:n.baseUrl,model:n.model,apiKey:p,apiKeySet:p!==null},decision:{baseUrl:l.baseUrl,model:l.model,apiKey:d,apiKeySet:d!==null}}}function P(i){if(!i)return;const{apiKey:e,...s}=i;return s}export async function handleSettingsRoutes(i,e,s,n,l){if(n==="/settings"){if(i.method==="GET")return r(e,200,{settings:w(await u(),s.aiKeyPath,s.decisionKeyPath),presets:K(process.platform),platform:process.platform,urls:j(s.port,s.tlsPort??0),version:O,repoUrl:"https://github.com/zijing66/weave"}),!0;if(i.method==="PUT"){let t;try{t=JSON.parse(await m(i))}catch{return r(e,400,{error:"Invalid JSON body"}),!0}const a=t.ai?.apiKey;a!==void 0&&G(typeof a=="string"?a:null,s.aiKeyPath);const o=t.decision?.apiKey;o!==void 0&&U(typeof o=="string"?o:null,s.decisionKeyPath);const c=await u(),f=await T({...c,...t,ai:t.ai?P(t.ai):c.ai,decision:t.decision?P(t.decision):c.decision});return s.hookEvents?.resetPrune(),(s.autoStart??A)(f.startup?.launchOnLogin??!1),s.dataBus?.emit({key:"settings"}),r(e,200,w(f,s.aiKeyPath,s.decisionKeyPath)),!0}}if(n==="/fs/roots"&&i.method==="GET"){const t=s.libraries?s.libraries.list().map(o=>o.path):[],a=await B(t);return r(e,200,{roots:a}),!0}if(n==="/fs/children"&&i.method==="GET"){const t=l.searchParams.get("path");if(!t)return r(e,400,{error:'Missing "path" query parameter'}),!0;try{const a=await L(t);r(e,200,{children:a})}catch(a){r(e,400,{error:`Cannot list directory: ${String(a)}`})}return!0}const p=n.match(/^\/projects\/(\d+)\/config$/);if(p){const t=s.projects.getById(Number(p[1]));if(!t)return r(e,404,{error:"Project not found"}),!0;if(i.method==="GET")return r(e,200,await h(t.path)),!0;if(i.method==="PUT"){let a;try{a=JSON.parse(await m(i))}catch{return r(e,400,{error:"Invalid JSON body"}),!0}const o=await h(t.path),c={lastSyncAt:a.lastSyncAt??o.lastSyncAt};return await v(t.path,c),r(e,200,c),!0}}if(n==="/statusline/global"){if(i.method==="GET")return r(e,200,{config:await S()}),!0;if(i.method==="PUT"){let t;try{t=JSON.parse(await m(i))}catch{return r(e,400,{error:"Invalid JSON body"}),!0}try{await J(t);for(const a of s.projects.list()){const o=await y(a.path);o.source==="global"&&await g(a.path,o)}s.dataBus?.emit({key:"statusline"}),r(e,200,{ok:!0})}catch(a){r(e,400,{error:a instanceof Error?a.message:"Global statusline update failed"})}return!0}}if(n==="/statusline/default"&&i.method==="GET")return r(e,200,{config:F}),!0;const d=n.match(/^\/projects\/(\d+)\/statusline$/);if(d){const t=s.projects.getById(Number(d[1]));if(!t)return r(e,404,{error:"Project not found"}),!0;if(i.method==="GET"){const[a,o,c]=await Promise.all([y(t.path),C(t.path),S()]);return r(e,200,{config:a,script:o,globalConfig:c,facts:D(t.path)}),!0}if(i.method==="PUT"){let a;try{a=JSON.parse(await m(i))}catch{return r(e,400,{error:"Invalid JSON body"}),!0}try{await g(t.path,a),s.dataBus?.emit({key:"statusline",projectPath:t.path}),r(e,200,{ok:!0})}catch(o){r(e,400,{error:o instanceof Error?o.message:"Statusline update failed"})}return!0}}if(n==="/assets"&&i.method==="GET"){const t=l.searchParams.get("path");if(!t)return r(e,400,{error:'Missing "path" query parameter'}),!0;if(!s.watch)return r(e,503,{error:"Watch service unavailable"}),!0;const a=await _(t),o=s.watch.getAssets(t).map(c=>{const f=a.get(c.relPath);return f?{...c,namespace:f}:c});return r(e,200,{projectPath:t,assets:o}),!0}return n==="/global-file-assets"&&i.method==="GET"?(r(e,200,{assets:await k()}),!0):!1}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{createReadStream as
|
|
1
|
+
import{createReadStream as w}from"node:fs";import{z as u}from"zod";import{readJson as c,readRawBody as E,sendJson as a}from"../http.js";import{isImageMediaType as I,maxUploadBytes as b}from"../../repositories/uploads.js";import{defaultUploadSessions as S}from"../upload-sessions.js";const z=u.object({name:u.string().min(1).max(200),mediaType:u.string().min(1).max(100),data:u.string().min(1),projectId:u.number().int().positive().optional()}),B=u.object({name:u.string().min(1).max(200),mediaType:u.string().min(1).max(100),size:u.number().int().positive(),projectId:u.number().int().positive().optional()});function j(o,e){return(I(e)?o?.images:o?.files)??null}const x=16*1024*1024;function f(o,e){return{id:e.id,name:e.name,mediaType:e.mediaType,size:e.size,path:o.uploads.pathOf(e)}}function g(o,e,t){if(!o.projects.getById(e))return null;const d=o.projects.getMeta(e);return j(d?.storage,t)}export async function handleUploadRoutes(o,e,t,d,h){const l=t.uploadSessions??S;if(d==="/uploads/begin"&&o.method==="POST"){if(!t.uploads)return a(e,503,{error:"Upload subsystem unavailable"}),!0;let r;try{r=B.parse(await c(o))}catch(n){return a(e,400,{error:n instanceof Error?n.message:"Invalid body"}),!0}if(r.size>b(r.mediaType))return a(e,413,{error:"File too large"}),!0;const s=r.projectId?g(t,r.projectId,r.mediaType):null,i=await l.begin({...r,dir:s});return a(e,201,{uploadId:i.id,received:0,size:i.size}),!0}const m=d.match(/^\/uploads\/([0-9a-f-]{36})\/finish$/);if(m&&o.method==="POST"){if(!t.uploads)return a(e,503,{error:"Upload subsystem unavailable"}),!0;const r=await l.finish(m[1]);if(!r)return a(e,409,{error:"Upload incomplete"}),!0;const s=await t.uploads.adoptFromFile(r);return await l.abort(m[1]),a(e,201,{upload:f(t,s)}),!0}const y=d.match(/^\/uploads\/([0-9a-f-]{36})$/);if(y){const r=y[1];if(o.method==="GET"){const s=await l.get(r);return s?(a(e,200,{received:s.received,size:s.size,name:s.name,mediaType:s.mediaType}),!0):(a(e,404,{error:"Upload not found"}),!0)}if(o.method==="PUT"){const s=Number(h.searchParams.get("offset")??"");if(!Number.isInteger(s)||s<0)return a(e,400,{error:"Invalid offset"}),!0;const i=await E(o,x).catch(()=>null);if(!i)return a(e,413,{error:"Chunk too large"}),!0;const n=await l.append(r,s,i);return n.kind==="missing"?(a(e,404,{error:"Upload not found"}),!0):n.kind==="conflict"?(a(e,409,{received:n.received}),!0):n.kind==="overflow"?(a(e,413,{received:n.received,error:"Exceeds declared size"}),!0):(a(e,200,{received:n.received}),!0)}if(o.method==="DELETE")return await l.abort(r),a(e,200,{ok:!0}),!0}if(d==="/uploads"&&o.method==="POST"){if(!t.uploads)return a(e,503,{error:"Upload subsystem unavailable"}),!0;let r;try{r=z.parse(await c(o))}catch(n){return a(e,400,{error:n instanceof Error?n.message:"Invalid body"}),!0}const s=Buffer.from(r.data,"base64");if(s.length===0)return a(e,400,{error:"Empty upload"}),!0;if(s.length>b(r.mediaType))return a(e,413,{error:"File too large"}),!0;const i=t.uploads.save({name:r.name,mediaType:r.mediaType,bytes:s,dir:r.projectId?g(t,r.projectId,r.mediaType):null});return a(e,201,{upload:f(t,i)}),!0}const p=d.match(/^\/sessions\/([^/]+)\/uploads$/);if(p&&o.method==="GET"){if(!t.uploads)return a(e,503,{error:"Upload subsystem unavailable"}),!0;const r=t.uploads.uploadsBySession(decodeURIComponent(p[1]));return a(e,200,{uploads:(r??[]).map(s=>({...f(t,s),createdAt:s.createdAt})),totalBytes:(r??[]).reduce((s,i)=>s+i.size,0)}),!0}if(p&&o.method==="DELETE"){if(!t.uploads)return a(e,503,{error:"Upload subsystem unavailable"}),!0;const r=t.uploads.uploadsBySession(decodeURIComponent(p[1]));if(!r)return a(e,200,{removed:0,freedBytes:0}),!0;const s=r.reduce((n,U)=>n+U.size,0),i=t.uploads.removeMany(r.map(n=>n.id));return t.dataBus?.emit({key:"sessions"}),a(e,200,{removed:i,freedBytes:s}),!0}if(d==="/uploads/unreferenced"&&o.method==="GET")return t.uploads?(a(e,200,t.uploads.unreferencedStats()),!0):(a(e,503,{error:"Upload subsystem unavailable"}),!0);if(d==="/uploads/overview"&&o.method==="GET")return t.uploads?(a(e,200,t.uploads.overview()),!0):(a(e,503,{error:"Upload subsystem unavailable"}),!0);const T=u.object({ids:u.array(u.string().regex(/^[a-f0-9]{64}$/)).min(1).max(500)});if(d==="/uploads/remove"&&o.method==="POST"){if(!t.uploads)return a(e,503,{error:"Upload subsystem unavailable"}),!0;let r;try{r=T.parse(await c(o))}catch(i){return a(e,400,{error:i instanceof Error?i.message:"Invalid body"}),!0}const s=t.uploads.removeMany(r.ids);return t.dataBus?.emit({key:"sessions"}),a(e,200,{removed:s}),!0}if(d==="/uploads/usage"&&o.method==="GET")return t.uploads?(a(e,200,{sessions:t.uploads.usageBySession()}),!0):(a(e,503,{error:"Upload subsystem unavailable"}),!0);if(d==="/uploads/unreferenced"&&o.method==="POST"){if(!t.uploads)return a(e,503,{error:"Upload subsystem unavailable"}),!0;let r={done:0,total:0};const s=t.uploads.cleanupUnreferenced((i,n)=>{r={done:i,total:n}});return t.dataBus?.emit({key:"sessions"}),a(e,200,{removed:s,...r}),!0}const v=d.match(/^\/images\/([a-f0-9]{64})$/);if(v&&o.method==="GET"){if(!t.uploads)return a(e,503,{error:"Upload subsystem unavailable"}),!0;const r=t.uploads.fileStatOf(v[1]);if(!r)return a(e,404,{error:"Image not found"}),!0;e.writeHead(200,{"content-type":r.row.mediaType,"content-length":String(r.size),"cache-control":"private, max-age=31536000, immutable"});const s=w(r.file);return s.on("error",()=>{typeof e.destroy=="function"&&e.destroy()}),s.pipe(e),!0}return!1}
|
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
import type { IncomingMessage, ServerResponse } from 'node:http';
|
|
2
|
+
import type { WeaveServerDeps } from '../server.js';
|
|
3
|
+
export declare function handleVisualizationRoutes(req: IncomingMessage, res: ServerResponse, deps: WeaveServerDeps, pathname: string, url: URL): Promise<boolean>;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import t from"node:path";import d from"node:os";import{promises as l}from"node:fs";import{HARNESS_DIRS as u,VISUALIZATION_PROTOCOL as g}from"@weavecode/core";import{sendJson as e}from"../http.js";import{isInsideDir as F}from"../../market/resolve.js";function j(s){const r=d.homedir(),o=[t.join(r,u.codex.userDir,"visualizations"),t.join(r,u.claude.userDir),t.join(r,u.codex.userDir,"plugins")];for(const a of s.projects.list())o.push(a.path);return o}export async function handleVisualizationRoutes(s,r,o,a,c){if(a!=="/visualizations/fragment"||s.method!=="GET")return!1;const n=c.searchParams.get("path")??"",i=t.resolve(n);if(!n||!t.isAbsolute(n))return e(r,400,{error:'Missing or relative "path" query parameter'}),!0;const f=j(o);if(!f.some(h=>F(i,h)))return e(r,403,{error:`Fragment path is outside the allowed roots: ${f.join(", ")}`}),!0;if(t.extname(i).toLowerCase()!==".html")return e(r,403,{error:"Only .html fragments are served"}),!0;let m;try{m=await l.stat(i)}catch{return e(r,404,{error:"Fragment file not found"}),!0}if(!m.isFile())return e(r,404,{error:"Fragment path is not a file"}),!0;if(m.size>g.maxFragmentBytes)return e(r,413,{error:"Fragment exceeds the 1 MB size limit"}),!0;const p=await l.readFile(i,"utf8");return e(r,200,{html:p}),!0}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{z as o}from"zod";import{isHarness as
|
|
1
|
+
import{z as o}from"zod";import{isHarness as I}from"@weavecode/core";import{readJson as m,sendJson as e}from"../http.js";import{messagingSurfaceFor as v}from"../../surfaces.js";import{DEFAULT_WATCH_ON as E}from"../../repositories/session-watches.js";const k=o.object({watcherSessionId:o.string().min(1).nullable().optional(),notify:o.string().min(1).max(2e4).nullable().optional(),on:o.array(o.enum(["idle","turnEnd","messageFailed"])).min(1).optional(),times:o.number().int().min(1).max(100).nullable().optional()}),W=o.object({watchId:o.number().int().positive()}),T=o.object({endpoint:o.string().url(),keys:o.object({p256dh:o.string().min(1),auth:o.string().min(1)})}),B=o.object({endpoint:o.string().url()});function P(i,s){return i.queuedPrompt!==null||i.prompt!==null||s}export async function handleWatchRoutes(i,s,t,d){const f=d.match(/^\/sessions\/([^/]+)\/watch$/);if(f){const n=decodeURIComponent(f[1]);if(i.method==="POST"){if(!t.sessionWatches||!t.hookSessions||!t.hookEvents)return e(s,503,{error:"Messaging subsystem unavailable"}),!0;let r;try{r=k.parse(await m(i))}catch(u){return e(s,400,{error:u instanceof Error?u.message:"Invalid body"}),!0}if(!t.hookSessions.getBySessionId(n))return e(s,404,{error:"Session not found"}),!0;const c=t.hookEvents.listBySession(n,1),a=c[c.length-1]?.source;if(!I(a))return e(s,400,{error:"Session has no hook events to determine its harness"}),!0;const h=v(a),l=r.on??[...E];if((l.includes("idle")||l.includes("turnEnd"))&&h.idleSignals.length===0)return e(s,409,{error:h.unsupportedReasons?.watch??`Harness "${a}" does not support idle watching`}),!0;if(l.includes("messageFailed")&&!(P(h,t.messageDeliverer?.hasTerminalChannel()??!1)||h.inject!==null||h.headless!==null))return e(s,409,{error:h.unsupportedReasons?.prompt??`Harness "${a}" supports no messaging channel`}),!0;if(r.watcherSessionId){if(!t.hookSessions.getBySessionId(r.watcherSessionId))return e(s,404,{error:"Watcher session not found"}),!0;const u=t.hookEvents.listBySession(r.watcherSessionId,1),g=u[u.length-1]?.source;if(!I(g))return e(s,400,{error:"Watcher session has no hook events to determine its harness"}),!0;const w=v(g);if(!w.inject)return e(s,409,{error:w.unsupportedReasons?.inject??`Harness "${g}" cannot receive watch notifications`}),!0}const b=r.times===void 0?1:r.times,y=(r.watcherSessionId??null)===null?t.sessionWatches.listPendingByTarget(n).find(u=>u.watcherSessionId===null):void 0,S=y?t.sessionWatches.updateById(y.id,{onEvents:l,remaining:b}):void 0,p=S??t.sessionWatches.insert({watcherSessionId:r.watcherSessionId??null,targetSessionId:n,notify:r.notify??null,onEvents:l,times:b});return t.watchEngine?.created(p),e(s,S?200:201,{ok:!0,watchId:p.id,watch:p}),!0}if(i.method==="DELETE"){if(!t.sessionWatches)return e(s,503,{error:"Messaging subsystem unavailable"}),!0;let r;try{r=W.parse(await m(i))}catch(a){return e(s,400,{error:a instanceof Error?a.message:"Invalid body"}),!0}const c=t.sessionWatches.getById(r.watchId);return!c||c.targetSessionId!==n||c.firedAt!==null?(e(s,404,{error:"Watch not found"}),!0):(t.sessionWatches.deleteById(r.watchId),e(s,200,{ok:!0,watchId:r.watchId}),!0)}}if(d==="/messaging/watches"&&i.method==="GET")return t.sessionWatches?(e(s,200,{watches:t.sessionWatches.listPending()}),!0):(e(s,503,{error:"Messaging subsystem unavailable"}),!0);if(d==="/messaging/push/key"&&i.method==="GET")return t.pushNotifier?(e(s,200,{publicKey:t.pushNotifier.publicKey()}),!0):(e(s,503,{error:"Push subsystem unavailable"}),!0);if(d==="/messaging/push/subscribe"&&i.method==="POST"){if(!t.pushSubscriptions)return e(s,503,{error:"Push subsystem unavailable"}),!0;try{const n=T.parse(await m(i)),r=t.pushSubscriptions.upsert({endpoint:n.endpoint,p256dh:n.keys.p256dh,auth:n.keys.auth,userAgent:i.headers["user-agent"]??null});e(s,201,{ok:!0,subscription:r})}catch(n){e(s,400,{error:n instanceof Error?n.message:"Invalid body"})}return!0}if(d==="/messaging/push/unsubscribe"&&i.method==="POST"){if(!t.pushSubscriptions)return e(s,503,{error:"Push subsystem unavailable"}),!0;try{const n=B.parse(await m(i));t.pushSubscriptions.deleteByEndpoint(n.endpoint),e(s,200,{ok:!0})}catch(n){e(s,400,{error:n instanceof Error?n.message:"Invalid body"})}return!0}return!1}
|
|
@@ -1,13 +1,13 @@
|
|
|
1
|
-
import y from"node:http";import{WEAVE_VERSION as S}from"../version.js";import{isHarness as R}from"@weavecode/core";import h from"node:fs";import
|
|
1
|
+
import y from"node:http";import{WEAVE_VERSION as S}from"../version.js";import{isHarness as R}from"@weavecode/core";import h from"node:fs";import l from"node:path";import{SseHub as E}from"./sse-hub.js";import{importPromptImagesOnce as H,needsImageImport as N}from"./prompt-images.js";import{sendJson as m}from"./http.js";import{FingerprintCache as P}from"../install/fingerprint.js";import{ApiLogger as j}from"./api-log.js";import{handleHooksRoutes as k}from"./hooks-routes.js";import{handleMcpRequest as x}from"./mcp-orchestration.js";import{handleToolkitRoutes as W}from"./toolkit-routes.js";import{handleCaptureRoutes as O}from"./capture-routes.js";import{handleConfigRoutes as T}from"./config-routes.js";import{handleMarketRoutes as A}from"./routes/market.js";import{handleProjectRoutes as I}from"./routes/projects.js";import{handleSettingsRoutes as M}from"./routes/settings-statusline.js";import{handleSearchRoutes as C}from"./routes/search.js";import{handleProjectFileRoutes as D}from"./routes/project-files.js";import{DAEMON_HOST as J}from"./port.js";import{handleAuthRoutes as $}from"./auth-routes.js";import{handleAiRoutes as B}from"./ai-routes.js";export const DAEMON_VERSION=S;export function weaveRequestHandler(e){const r=e.fingerprintCache??new P,t=e.apiLog??new j,o=e.sseHub??new E(e),a={...e,fingerprintCache:r,apiLog:t,sseHub:o};return(n,i)=>{t.begin(n,i),F(n,i,a)}}export function createWeaveServer(e){return y.createServer(weaveRequestHandler(e))}async function F(e,r,t){const o=new URL(e.url??"/",`http://${J}`);let a=o.pathname;if(a.startsWith("/api/")?a=a.slice(4):a==="/api"&&(a="/"),a==="/health"&&e.method==="GET"){m(r,200,{service:"weave-daemon",version:DAEMON_VERSION,pid:process.pid,port:t.port,uptimeMs:Math.round(process.uptime()*1e3)});return}if(await $(e,r,t,a)||await B(e,r,t,a))return;if(t.auth&&!G(e,a,t)&&!t.auth.isAuthenticated(e.headers)){m(r,401,{error:"Unauthorized"});return}if(a==="/mcp"){await x(e,r,{port:t.port,token:t.auth?.getLocalToken()??null});return}if(a==="/api-logs"&&e.method==="GET"){if(!t.apiLog){m(r,503,{error:"API log unavailable"});return}const i=o.searchParams.get("status"),c=o.searchParams.get("limit"),s=await t.apiLog.query({from:o.searchParams.get("from")??void 0,to:o.searchParams.get("to")??void 0,path:o.searchParams.get("path")??void 0,method:o.searchParams.get("method")??void 0,status:i==null?void 0:Number(i),limit:c==null?void 0:Number(c)});m(r,200,s);return}if(await k(e,r,t,a,o)||await W(e,r,t,a,o)||await O(e,r,t,a)||await T(e,r,t,a,o))return;const n=a.match(/^\/projects\/(\d+)\/hooks$/);if(n&&e.method==="GET"){if(!t.hookEvents){m(r,503,{error:"Hook ingestion unavailable"});return}const i=Number(n[1]),c=K(o.searchParams.get("limit")),s=o.searchParams.get("sessionId"),f=o.searchParams.get("beforeId"),u=f?Number(f):void 0,b=(o.searchParams.get("types")??"").split(",").map(p=>p.trim()).filter(Boolean);if(s){const p=t.hookEvents.listBySession(s,c??300,u,b);let v=t.uploads?.imagesBySession(s);if(N(p,v)){const d=t.projects.getMeta(i);await H({hookEvents:t.hookEvents,uploads:t.uploads,sessionProbe:t.sessionProbe,uploadDir:d?.storage?.images??null},s,U(p))&&(v=t.uploads?.imagesBySession(s))}m(r,200,{events:p.map(d=>{const w=v?.get(d.id);return w?.length?{...d,images:w.map(g=>({id:g.id,name:g.name,mediaType:g.mediaType,size:g.size}))}:d})});return}m(r,200,{events:t.hookEvents.listByProject(i,c)});return}if(!await A(e,r,t,a,o)&&!await M(e,r,t,a,o)&&!await C(e,r,t,a,o)&&!await D(e,r,t,a,o)){if(a==="/events"&&e.method==="GET"){z(e,r,t,o);return}if(!await I(e,r,t,a)){if(e.method==="GET"&&t.staticDir){_(r,a,t.staticDir);return}m(r,404,{error:"Not found"})}}}const L=25e3;function z(e,r,t,o){const a=t.sseHub;if(!a||!t.watch&&!t.hookBus&&!t.dataBus){r.statusCode=503,r.setHeader("content-type","application/json"),r.end(JSON.stringify({error:"Event stream unavailable"}));return}const n=e.headers["last-event-id"],i=(Array.isArray(n)?n[0]:n)??o.searchParams.get("since")??null,c=a.replay(i);r.writeHead(200,{"content-type":"text/event-stream","cache-control":"no-cache",connection:"keep-alive","x-accel-buffering":"no"}),r.write(`: connected
|
|
2
2
|
|
|
3
|
-
`);const
|
|
3
|
+
`);const s=setInterval(()=>{r.writableEnded||r.write(`data: ${JSON.stringify({type:"ping"})}
|
|
4
4
|
|
|
5
|
-
`)},
|
|
5
|
+
`)},L);s.unref?.(),c.gap&&r.write(`data: ${JSON.stringify({type:"resync"})}
|
|
6
6
|
|
|
7
|
-
`);for(const
|
|
8
|
-
data: ${
|
|
7
|
+
`);for(const u of c.frames)r.write(`id: ${u.id}
|
|
8
|
+
data: ${u.data}
|
|
9
9
|
|
|
10
|
-
`);const
|
|
11
|
-
data: ${
|
|
10
|
+
`);const f=a.subscribe(u=>{r.write(`id: ${u.id}
|
|
11
|
+
data: ${u.data}
|
|
12
12
|
|
|
13
|
-
`)});
|
|
13
|
+
`)});t.inflightRefresher?.refreshNow(),t.terminalRefresher?.onSubscriberJoin(),t.updatesRefresher?.onSubscriberJoin(),e.on("close",()=>{clearInterval(s),f()})}function G(e,r,t){if(r==="/health"||r.startsWith("/webhooks/orchestrate/"))return!0;if(e.method!=="GET")return!1;if((e.headers.accept??"").includes("text/html"))return!0;if(!t.staticDir)return!1;const o=l.normalize(r).replace(/^([/\\]\.\.[/\\])+/,""),a=l.join(t.staticDir,o);return a.startsWith(t.staticDir)&&h.existsSync(a)&&h.statSync(a).isFile()}function V(e,r){e.setHeader("cache-control",r.startsWith("/assets/")?"public, max-age=31536000, immutable":"no-cache")}function _(e,r,t){const o=l.normalize(r).replace(/^([/\\]\.\.[/\\])+/,""),a=l.join(t,o);if(!a.startsWith(t)){e.statusCode=403,e.setHeader("content-type","application/json"),e.end(JSON.stringify({error:"Forbidden"}));return}h.stat(a,(n,i)=>{if(!n&&i.isFile()){e.setHeader("content-type",q(a)),V(e,r),e.setHeader("content-length",String(i.size)),h.createReadStream(a).pipe(e);return}h.readFile(l.join(t,"index.html"),(c,s)=>{if(c){e.statusCode=404,e.setHeader("content-type","application/json"),e.end(JSON.stringify({error:"Not found"}));return}e.setHeader("content-type","text/html"),e.setHeader("cache-control","no-cache"),e.end(s)})})}function q(e){return e.endsWith(".js")?"text/javascript":e.endsWith(".css")?"text/css":e.endsWith(".html")?"text/html":e.endsWith(".svg")?"image/svg+xml":e.endsWith(".json")?"application/json":"application/octet-stream"}function U(e){for(let r=e.length-1;r>=0;r--){const t=e[r].source;if(R(t))return t}return null}function K(e){const r=Number(e??"100");return!Number.isFinite(r)||r<=0?100:Math.min(Math.floor(r),500)}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{stat as
|
|
1
|
+
import{stat as k}from"node:fs/promises";import{isHarness as w}from"@weavecode/core";import{readDaemonSettings as g}from"./settings.js";import{defaultProjectOpener as S,terminalBackendFor as v}from"./opener.js";import{messagingSurfaceFor as y}from"../surfaces.js";const p=8e3,T=11e3,E=14e3;export function transcriptState(e,r){return e!==!1?e:r===!0?!1:null}function h(e,r,s,t){!t||y(r).paneEnvSource!=="launch"||e.messageDeliverer?.notePaneEnv(s,t.env)}export function scheduleBootstrapInjection(e,r,s){const t=e.terminal;t&&(async()=>{await new Promise(n=>setTimeout(n,p));const i=await t.locatePane?.(r.env).catch(()=>null)??null;if(!i)return;const o=async()=>{try{await t.sendText(i,s)}catch{return}};await o(),setTimeout(()=>{t.sendKeys(i,"\r").catch(()=>{})},T-p),setTimeout(()=>{o()},E-p)})()}export async function openSessionTerminal(e,r,s){if(!e.hookSessions)return{ok:!1,status:503,error:"Hooks subsystem unavailable"};const t=e.hookSessions.getBySessionId(r);if(!t)return{ok:!1,status:404,error:"Session not found"};if(!e.hookEvents)return{ok:!1,status:503,error:"Hook ingestion unavailable"};const i=e.hookEvents.listBySession(r,1),o=i[i.length-1]?.source;if(!w(o))return{ok:!1,status:400,error:"Session has no hook events to determine its harness"};const n=e.harnesses?.get(o)?.resume;if(!n?.supported||!n.openArgs)return{ok:!1,status:501,error:`Harness "${o}" does not support interactive resume`};if(!t.projectId)return{ok:!1,status:400,error:"Session is not bound to a project"};const u=e.projects?.getById(t.projectId);if(!u)return{ok:!1,status:404,error:"Project not found"};const f=e.sessionProbe?.transcriptPresent(r)??null;if(transcriptState(f,e.hookSessions.hasRunOf(r))===!1)return{ok:!1,status:409,error:"Session transcript is missing \u2014 nothing to resume"};const l=e.opener??S;try{if(!(await k(u.path)).isDirectory())throw new Error(`Not a directory: ${u.path}`);const a=await g(),m=[n.bin,...n.launchArgs??[],...n.openArgs(r)];if(s){if(!v(a.terminal).enumerable)throw new Error(`Terminal preset "${a.terminal.preset}" cannot attach to a chosen pane \u2014 pick wezterm, wt or Terminal.app in settings`);const c=l.runInTerminalAt;if(!c)throw new Error("Targeted attach is unavailable");const d=await c(u.path,m,s,a.terminal);h(e,o,r,d)}else{const c=await l.runInTerminal(u.path,m,a.terminal);h(e,o,r,c)}return setTimeout(()=>{e.terminalRefresher?.refreshNow()},600),{ok:!0,sessionId:r,command:m.join(" "),cwd:u.path,...s?{target:s}:{}}}catch(a){return{ok:!1,status:400,error:a instanceof Error?a.message:"Open failed"}}}
|
|
@@ -96,11 +96,12 @@ export declare class SessionProbe {
|
|
|
96
96
|
*/
|
|
97
97
|
transcriptPresent(sessionId: string): boolean | null;
|
|
98
98
|
/**
|
|
99
|
-
* 单会话的中断时刻(ms
|
|
100
|
-
*
|
|
101
|
-
* 未知路径/读不到/没标记一律 null
|
|
99
|
+
* 单会话的中断时刻(ms):转录最后一条中断标记**晚于**最后一条主回合事件才算
|
|
100
|
+
* ——之后任何主回合事件(用户又发了一条、工具收尾)都会把它盖过去,故是自愈的;
|
|
101
|
+
* 未知路径/读不到/没标记一律 null(不猜)。基准由调用方给(`lastMainEventAtOf`
|
|
102
|
+
* ,排除 SubagentStop——后台子代理收尾与主回合无关,中断后异步到达不该盖掉它)。
|
|
102
103
|
*/
|
|
103
|
-
interruptedAt(sessionId: string,
|
|
104
|
+
interruptedAt(sessionId: string, lastMainEventAt: string): number | null;
|
|
104
105
|
/** 最近一轮真跑过的模型(转录 `message.model`);未知/读不到一律 null(不猜)。 */
|
|
105
106
|
currentModel(sessionId: string): string | null;
|
|
106
107
|
/**
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{closeSync as
|
|
1
|
+
import{closeSync as h,openSync as u,readSync as f,statSync as a}from"node:fs";import{bareModelName as i,codexInterruptMarkerAt as d,currentContextTokensAt as p,currentEffortAt as m,currentModelAt as k,currentModeAt as w,interruptMarkerAt as M,switchedModelOf as O}from"@weavecode/harness";import{HARNESS_SESSION_CONTROL as S,isHarness as x}from"@weavecode/core";const b=64*1024,y={model:null,mode:null,effort:null,contextTokens:null};export function readTail(l,t=b){try{const e=a(l).size,s=Math.max(0,e-t),n=u(l,"r");try{const r=Buffer.alloc(e-s);return f(n,r,0,r.length,s),r.toString("utf8")}finally{h(n)}}catch{return null}}export function dbTranscriptPathResolver(l){return t=>{try{const e=JSON.parse(l.listBySession(t,1)[0]?.payload??"");return typeof e.transcriptPath=="string"&&e.transcriptPath?e.transcriptPath:null}catch{return null}}}export function dbModelFactResolver(l,t){return e=>{const s=t(e),n=s&&x(s)?S[s].modelFactEvents:[];if(n.length===0)return null;const r=l.listBySession(e,1,void 0,n),o=r[r.length-1];if(!o)return null;try{const c=JSON.parse(o.payload).raw;return O(o.eventType,c)}catch{return null}}}function T(l){const t=M(l),e=d(l);return t===null?e:e===null?t:Math.max(t,e)}export class SessionProbe{fallbackPath;fallbackSwitch;constructor(t,e){this.fallbackPath=t,this.fallbackSwitch=e}paths=new Map;marks=new Map;known=new Map;switched=new Map;probed=new Set;efforts=new Map;modes=new Map;noteTranscript(t,e){e&&this.paths.set(t,e)}pathOf(t){const e=this.paths.get(t);if(e)return e;const s=this.fallbackPath?.(t)??null;return s&&this.paths.set(t,s),s}transcriptPathOf(t){return this.pathOf(t)}forget(t){this.paths.delete(t),this.known.delete(t),this.switched.delete(t),this.probed.delete(t),this.efforts.delete(t),this.modes.delete(t)}noteEffort(t,e){this.efforts.set(t,e)}currentEffort(t){return this.efforts.get(t)??this.latched(t).effort}currentContextTokens(t){return this.latched(t).contextTokens}noteModel(t,e){const s=this.pathOf(t);this.switched.set(t,{stale:s?this.factsOf(s).model:null,model:e})}sessionStarted(t,e){this.known.delete(t),this.switched.delete(t),this.probed.delete(t),e&&this.noteModel(t,e)}transcriptPresent(t){const e=this.pathOf(t);return e?this.factsOf(e).size>0:null}interruptedAt(t,e){const s=this.pathOf(t);if(!s)return null;const n=this.factsOf(s).markerAt;if(n===null)return null;const r=Date.parse(e);return Number.isFinite(r)&&n>r?n:null}currentModel(t){return this.latched(t).model}noteMode(t,e){this.modes.set(t,e)}currentMode(t){return this.modes.get(t)??this.latched(t).mode}latched(t){const e=this.pathOf(t),s=e?this.factsOf(e):y,n=this.known.get(t),r={model:this.switchedModel(t,s.model)??n?.model??null,mode:s.mode??n?.mode??null,effort:s.effort??n?.effort??null,contextTokens:s.contextTokens??n?.contextTokens??null};return(!n||n.model!==r.model||n.mode!==r.mode||n.effort!==r.effort||n.contextTokens!==r.contextTokens)&&this.known.set(t,r),r}switchedModel(t,e){const s=this.switchOf(t,e);return s&&e===s.stale?s.model:e}switchOf(t,e){const s=this.switched.get(t);if(s||!e||this.probed.has(t))return s;this.probed.add(t);const n=this.fallbackSwitch?.(t);if(!n||n.from===null||i(n.from)!==i(e))return;const r={stale:e,model:n.to};return this.switched.set(t,r),r}factsOf(t){let e;try{e=a(t).size}catch{return{size:-1,markerAt:null,model:null,mode:null,effort:null,contextTokens:null}}const s=this.marks.get(t);if(s&&s.size===e)return s;const n=readTail(t),r={size:e,markerAt:n===null?null:T(n),model:n===null?null:k(n),mode:n===null?null:w(n),effort:n===null?null:m(n),contextTokens:n===null?null:p(n)};return this.marks.set(t,r),r}}
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import{openDatabase as
|
|
2
|
-
ON CONFLICT(key) DO UPDATE SET value = excluded.value`);e.exec("BEGIN");try{for(const[r,
|
|
1
|
+
import{openDatabase as b}from"../db/db.js";import{getDbPath as f}from"../db/paths.js";import{DEFAULT_BIND_HOST as p}from"./port.js";export const SUPPORTED_LOCALES=["zh-CN","en"],DEFAULT_LOCALE="zh-CN",DEFAULT_TERMINAL_SETTINGS={preset:"auto",customCommand:""},DEFAULT_HOOKS_SETTINGS={enabled:!0},DEFAULT_EVENT_RETENTION_DAYS=90,DEFAULT_EVENTS_SETTINGS={retentionDays:DEFAULT_EVENT_RETENTION_DAYS},DEFAULT_SESSION_IDLE_DAYS=90,DEFAULT_SESSIONS_SETTINGS={idleDays:DEFAULT_SESSION_IDLE_DAYS},DEFAULT_STARTUP_SETTINGS={launchOnLogin:!1},DEFAULT_SERVER_SETTINGS={bindHost:p,tlsPort:6443},DEFAULT_AI_SETTINGS={baseUrl:"",model:""},DEFAULT_DECISION_SETTINGS={baseUrl:"",model:""},DEFAULT_HTML_EXPORT_SETTINGS={activeId:null,profiles:[]},DEFAULT_DAEMON_SETTINGS={terminal:DEFAULT_TERMINAL_SETTINGS,locale:DEFAULT_LOCALE,hooks:DEFAULT_HOOKS_SETTINGS,decision:DEFAULT_DECISION_SETTINGS,events:DEFAULT_EVENTS_SETTINGS,sessions:DEFAULT_SESSIONS_SETTINGS,startup:DEFAULT_STARTUP_SETTINGS,server:DEFAULT_SERVER_SETTINGS,ai:DEFAULT_AI_SETTINGS,htmlExport:DEFAULT_HTML_EXPORT_SETTINGS};export function resolveLocale(e){return SUPPORTED_LOCALES.includes(e)?e:DEFAULT_LOCALE}export const ALL_TERMINAL_PRESETS=["auto","wt","powershell","cmd","terminal","iterm","gnome","konsole","wezterm","ghostty","custom"];const L={auto:"\u81EA\u52A8\uFF08\u63A2\u6D4B\u53EF\u7528\u7EC8\u7AEF\uFF09",wt:"Windows Terminal",powershell:"PowerShell",cmd:"\u547D\u4EE4\u63D0\u793A\u7B26 (cmd)",terminal:"Terminal.app",iterm:"iTerm2",gnome:"gnome-terminal",konsole:"Konsole",wezterm:"WezTerm",ghostty:"Ghostty",custom:"\u81EA\u5B9A\u4E49\u547D\u4EE4"};export function terminalPresetsFor(e){return(e==="win32"?["auto","wt","wezterm","powershell","cmd","custom"]:e==="darwin"?["auto","terminal","iterm","wezterm","ghostty","custom"]:["auto","gnome","konsole","wezterm","ghostty","custom"]).map(n=>({id:n,label:L[n]}))}function v(e){return Number.isInteger(e)&&e>=0&&e<=65535?e:DEFAULT_SERVER_SETTINGS.tlsPort}const U=50,I=2e5;function A(e){const n=e??{},o=new Set,r=[];for(const a of Array.isArray(n.profiles)?n.profiles:[]){const s=a??{};if(!(typeof s.id!="string"||s.id===""||o.has(s.id))&&!(typeof s.name!="string"||typeof s.head!="string")&&(o.add(s.id),r.push({id:s.id,name:s.name.trim()||`profile-${r.length+1}`,head:s.head.slice(0,I)}),r.length>=U))break}return{activeId:typeof n.activeId=="string"&&o.has(n.activeId)?n.activeId:null,profiles:r}}function h(e){const n=e??{},o=n.terminal??{},r=n.hooks??{},a=n.events??{},s=n.sessions??{},E=n.startup??{},l=n.server??{},u=n.ai??{},m=n.decision??{},D=A(n.htmlExport),y=Number.isInteger(a.retentionDays)&&a.retentionDays>=1?a.retentionDays:DEFAULT_EVENTS_SETTINGS.retentionDays,S=Number.isInteger(s.idleDays)&&s.idleDays>=1?s.idleDays:DEFAULT_SESSIONS_SETTINGS.idleDays;return{terminal:{preset:ALL_TERMINAL_PRESETS.includes(o.preset)?o.preset:DEFAULT_TERMINAL_SETTINGS.preset,customCommand:typeof o.customCommand=="string"?o.customCommand:""},locale:resolveLocale(n.locale),hooks:{enabled:typeof r.enabled=="boolean"?r.enabled:DEFAULT_HOOKS_SETTINGS.enabled},events:{retentionDays:y},sessions:{idleDays:S},startup:{launchOnLogin:typeof E.launchOnLogin=="boolean"?E.launchOnLogin:DEFAULT_STARTUP_SETTINGS.launchOnLogin},server:{bindHost:typeof l.bindHost=="string"&&l.bindHost.trim()!==""?l.bindHost.trim():DEFAULT_SERVER_SETTINGS.bindHost,tlsPort:v(l.tlsPort)},ai:{baseUrl:typeof u.baseUrl=="string"?u.baseUrl.trim():"",model:typeof u.model=="string"?u.model.trim():""},decision:{baseUrl:typeof m.baseUrl=="string"?m.baseUrl.trim():"",model:typeof m.model=="string"?m.model.trim():""},htmlExport:D}}const t={terminalPreset:"terminal.preset",terminalCustomCommand:"terminal.customCommand",locale:"locale",hooksEnabled:"hooks.enabled",eventRetentionDays:"events.retentionDays",sessionIdleDays:"sessions.idleDays",startupLaunchOnLogin:"startup.launchOnLogin",serverBindHost:"server.bindHost",serverTlsPort:"server.tlsPort",aiBaseUrl:"ai.baseUrl",aiModel:"ai.model",decisionBaseUrl:"decision.baseUrl",decisionModel:"decision.model",htmlExport:"htmlExport"};let i=null,d=null;export function setDaemonSettingsDb(e){i=e,d=null}function g(e){if(i)return e(i);const n=b(f());try{return e(n)}finally{n.close()}}function N(e){const n=e.prepare("SELECT key, value FROM settings").all();return new Map(n.map(o=>[o.key,o.value]))}function O(e){return h({terminal:{preset:e.get(t.terminalPreset),customCommand:e.get(t.terminalCustomCommand)},locale:e.get(t.locale),...e.has(t.hooksEnabled)?{hooks:{enabled:e.get(t.hooksEnabled)==="true"}}:{},...e.has(t.eventRetentionDays)?{events:{retentionDays:Number(e.get(t.eventRetentionDays))}}:{},...e.has(t.sessionIdleDays)?{sessions:{idleDays:Number(e.get(t.sessionIdleDays))}}:{},...e.has(t.startupLaunchOnLogin)?{startup:{launchOnLogin:e.get(t.startupLaunchOnLogin)==="true"}}:{},...e.has(t.serverBindHost)||e.has(t.serverTlsPort)?{server:{...e.has(t.serverBindHost)?{bindHost:e.get(t.serverBindHost)}:{},...e.has(t.serverTlsPort)?{tlsPort:Number(e.get(t.serverTlsPort))}:{}}}:{},...e.has(t.aiBaseUrl)||e.has(t.aiModel)?{ai:{baseUrl:e.get(t.aiBaseUrl)??"",model:e.get(t.aiModel)??""}}:{},...e.has(t.decisionBaseUrl)||e.has(t.decisionModel)?{decision:{baseUrl:e.get(t.decisionBaseUrl)??"",model:e.get(t.decisionModel)??""}}:{},...T(e.get(t.htmlExport))!=null?{htmlExport:T(e.get(t.htmlExport))}:{}})}function T(e){if(!e)return null;try{const n=JSON.parse(e);return n!=null&&typeof n=="object"?n:null}catch{return null}}function _(e){return[[t.terminalPreset,e.terminal.preset],[t.terminalCustomCommand,e.terminal.customCommand],[t.locale,e.locale],[t.hooksEnabled,String(e.hooks.enabled)],[t.eventRetentionDays,String(e.events?.retentionDays??DEFAULT_EVENT_RETENTION_DAYS)],[t.sessionIdleDays,String(e.sessions?.idleDays??DEFAULT_SESSION_IDLE_DAYS)],[t.startupLaunchOnLogin,String(e.startup?.launchOnLogin??!1)],[t.serverBindHost,e.server?.bindHost??p],[t.serverTlsPort,String(e.server?.tlsPort??DEFAULT_SERVER_SETTINGS.tlsPort)],[t.aiBaseUrl,e.ai?.baseUrl??""],[t.aiModel,e.ai?.model??""],[t.decisionBaseUrl,e.decision?.baseUrl??""],[t.decisionModel,e.decision?.model??""],[t.htmlExport,JSON.stringify(e.htmlExport??DEFAULT_HTML_EXPORT_SETTINGS)]]}function P(e,n){const o=e.prepare(`INSERT INTO settings (key, value) VALUES (?, ?)
|
|
2
|
+
ON CONFLICT(key) DO UPDATE SET value = excluded.value`);e.exec("BEGIN");try{for(const[r,a]of n)o.run(r,a);e.exec("COMMIT")}catch(r){throw e.exec("ROLLBACK"),r}}function c(){try{return g(e=>O(N(e)))}catch{return DEFAULT_DAEMON_SETTINGS}}export async function readDaemonSettings(){return c()}export function readDaemonSettingsSync(){return c()}export function readHooksEnabled(){const e=d;if(e&&e.db===i)return e.value;const n=c().hooks.enabled;return d={db:i,value:n},n}export async function writeDaemonSettings(e){const n=h(e);return g(o=>P(o,_(n))),d=null,n}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
export class SnapshotRefresher{snapshot;bus;options;timer;lastFingerprint=null;constructor(t,i
|
|
1
|
+
export class SnapshotRefresher{snapshot;bus;options;timer;lastFingerprint=null;constructor(t,s,i){this.snapshot=t,this.bus=s,this.options=i}start(){this.timer||(this.timer=setInterval(()=>this.tick(),this.options.intervalMs??15e3))}stop(){this.timer&&(clearInterval(this.timer),this.timer=void 0)}tick(){if(!(this.options.shouldRun&&!this.options.shouldRun()))try{const t=this.snapshot(),s=JSON.stringify(t);if(s===this.lastFingerprint)return;this.lastFingerprint=s,this.bus.emit(this.options.invalidateOnly?{key:this.options.key}:{key:this.options.key,payload:t})}catch{}}}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{randomBytes as
|
|
1
|
+
import{randomBytes as a}from"node:crypto";const u=1e3,c=6e4;export class SseHub{sources;epoch=a(4).toString("hex");seq=0;buffer=[];subs=new Set;detach=null;graceTimer=null;brokenAt=0;constructor(s){this.sources=s}subscribe(s){return this.subs.add(s),this.attach(),()=>{this.subs.delete(s),this.subs.size===0&&this.scheduleDetach()}}push(s){const r=++this.seq,i=JSON.stringify(s);this.buffer.push({seq:r,data:i}),this.buffer.length>u&&this.buffer.shift();const e={id:this.frameId(r),data:i};for(const t of this.subs)t(e)}replay(s){if(!s)return{frames:[],gap:!1};const[r,i]=s.split("-"),e=Number(i);if(r!==this.epoch||!Number.isInteger(e)||e<0)return{frames:[],gap:!0};const t=this.buffer[0]?.seq;return e<=this.brokenAt||t!==void 0&&e<t-1?{frames:[],gap:!0}:{frames:this.buffer.filter(h=>h.seq>e).map(h=>({id:this.frameId(h.seq),data:h.data})),gap:!1}}frameId(s){return`${this.epoch}-${s}`}attach(){if(this.graceTimer!==null&&(clearTimeout(this.graceTimer),this.graceTimer=null),this.detach)return;this.sources.onAttach?.();const s=[],{watch:r,hookBus:i,dataBus:e}=this.sources;r&&(s.push(r.subscribe(t=>this.push({type:"asset",...t}))),s.push(r.subscribeProjects(t=>this.push({type:"project",...t})))),i&&s.push(i.subscribe(t=>this.push({type:"hook",...t}))),e&&s.push(e.subscribe(t=>this.push({type:t.payload===void 0?"invalidate":"push",...t}))),this.detach=()=>{for(const t of s)t()}}scheduleDetach(){this.graceTimer!==null||!this.detach||(this.graceTimer=setTimeout(()=>{this.graceTimer=null,this.brokenAt=this.seq,this.detach?.(),this.detach=null},c),this.graceTimer.unref?.())}}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import we from"node:http";import{openDatabase as ge}from"../db/db.js";import{ProjectRepository as Se}from"../repositories/projects.js";import{HookEventRepository as Re}from"../repositories/hook-events.js";import{LibraryRepository as ve}from"../repositories/libraries.js";import{HookRuleRepository as ae}from"../repositories/hook-rules.js";import{HookDispatchRepository as be}from"../repositories/hook-dispatches.js";import{PluginStateRepository as T}from"../repositories/plugin-states.js";import{SessionRepository as ye}from"../repositories/sessions.js";import{createRuntimeRegistry as ke}from"@weavecode/harness";import{TERMINAL_LOCATOR_ENV_KEYS as De,isHarness as j}from"@weavecode/core";import{messagingSurfaceFor as Pe,narrationSurfaceFor as Te}from"../surfaces.js";import{syntheticSessionIds as Ee}from"../hooks/synthetic-sessions.js";import{createEdgeExtract as Ce}from"../hooks/edge-extract.js";import{startSessionSweeper as Oe}from"../hooks/session-sweeper.js";import{startStatuslineCacheSweeper as Ie}from"../statusline/cache-sweeper.js";import{readStatuslineFacts as He}from"../statusline/manager.js";import{wireHookFilePipeline as Ae}from"./hook-pipeline.js";import{ensureBuiltinMarket as Be,builtinMarketDir as _e}from"../market/builtin.js";import{HookRuleRegistry as Fe}from"../hooks/registry.js";import{HookDispatcher as Le}from"../hooks/dispatcher.js";import{HookEventBus as Me}from"../hooks/bus.js";import{ResumeRunner as Ne}from"../hooks/resume-runner.js";import{HeadlessRunner as Ue}from"../hooks/headless-runner.js";import{MessageDeliverer as We}from"../hooks/message-deliverer.js";import{QuestionTracker as xe}from"../hooks/question-tracker.js";import{SideQuestionRepository as Qe}from"../repositories/side-questions.js";import{claimSideAnswer as qe}from"../hooks/side-questions.js";import{DashboardRateCache as je}from"../hooks/dashboard-rate.js";import{startDashboardPusher as Ke}from"./dashboard-pusher.js";import{startPromptFlusher as $e}from"../hooks/prompt-flusher.js";import{SessionWatchRepository as Ge}from"../repositories/session-watches.js";import{PushSubscriptionRepository as Je}from"../repositories/push-subscriptions.js";import{UploadRepository as Ve}from"../repositories/uploads.js";import{defaultUploadSessions as Ye}from"./upload-sessions.js";import{PushNotifier as ze}from"../hooks/push-notify.js";import{OrchestrationRepository as Xe,OrchestrationRunRepository as Ze}from"../repositories/orchestrations.js";import{WatchEngine as es}from"../hooks/watch-engine.js";import{OrchestrationEngine as ss,createForkConditionJudge as ts}from"../hooks/orchestration-engine.js";import{createDecisionConditionJudge as os}from"../hooks/decision-judge.js";import{readDecisionKey as rs}from"./decision-config.js";import{openSessionTerminal as ns}from"./session-open.js";import{loadAllPlugins as is}from"../hooks/plugin-loader.js";import{ToolkitService as as}from"../hooks/toolkit.js";import{WatchService as ls}from"../watch/watch-service.js";import{SyncScheduler as cs}from"../watch/sync-scheduler.js";import{FingerprintCache as ps}from"../install/fingerprint.js";import{detectProjectUpdateCounts as ms}from"../install/updates.js";import{weaveRequestHandler as us}from"./server.js";import{startTlsServer as fs}from"./tls.js";import{DataBus as ds}from"./data-bus.js";import{TerminalTopologyRefresher as hs}from"./terminal-topology-refresher.js";import{SnapshotRefresher as K}from"./snapshot-refresher.js";import{SessionProbe as ws,dbModelFactResolver as gs,dbTranscriptPathResolver as Ss}from"./session-probe.js";import{NarrationWatcher as Rs}from"./narration-watcher.js";import{InflightCountsRefresher as vs}from"./inflight-counts-refresher.js";import{ProjectUpdatesRefresher as bs}from"./project-updates-refresher.js";import{pidAliveOf as ys}from"./claude-liveness.js";import{combinedLivenessOf as v}from"./liveness.js";import{promptTerminalChannel as le,readTerminalCounts as ks}from"./opener.js";import{DEFAULT_BIND_HOST as Ds}from"./port.js";import{readDaemonState as Ps,writeDaemonState as Ts}from"./state.js";import{ensureDataLayout as Es}from"../db/layout.js";import{pruneFileIndexes as Cs}from"./project-files.js";import{pruneInstallTmp as Os}from"../hooks/plugin-installer.js";import{readDaemonSettingsSync as b,setDaemonSettingsDb as Is,DEFAULT_SERVER_SETTINGS as Hs}from"./settings.js";import{AuthService as As}from"./dashboard-auth.js";import{syncLaunchOnLogin as Bs}from"./auto-start.js";import{resolveStaticDir as _s}from"./static.js";delete process.env.CLAUDE_CODE_CHILD_SESSION;for(const u of De)delete process.env[u];export function startDaemon(){Es();const u=Ps();u||(console.error("Daemon state not found. Run `weave daemon start` first."),process.exit(1));const t=ge();Is(t);const E=b().server?.bindHost??Ds,C=b().server?.tlsPort??Hs.tlsPort,O=new As;O.initialPassword&&console.log(`[weave] initial dashboard password: ${O.initialPassword}`);const r=new Se(t);Cs(r.list().map(e=>e.id)),Os();const a=new Re(t),p=new ve(t),d=ke(),ce=d.byCapability("events").flatMap(e=>e.events??[]),y=new Fe(new ae(t)),k=new be(t),o=new ye(t),n=new Me,I={getHandler:()=>{},getConfig:()=>({})};let f;const H={list:()=>f?.list()??[],setPluginEnabled:(e,s)=>f?.setPluginEnabled(e,s)??!1,reloadAll:async()=>{await f?.reloadAll()},rescan:async()=>{await f?.rescanRoots(r.list(),p)}},pe=new as({projects:r,states:new T(t),plugins:H,libraries:p}),A={run:null},$=new Le({registry:y,dispatches:k,bus:n,projects:r,sessions:o,plugins:I,pluginStates:new T(t),classify:e=>A.run?A.run(e):Promise.resolve(null),sessionTitleOf:async e=>{const s=a.listBySession(e,1).at(-1)?.source;return j(s)?d.get(s)?.titles?.sessionTitleOf(e)??null:null}});Be({libraries:p}).then(e=>(e.error?console.error(`[weave] builtin market unavailable: ${e.error}`):e.changed&&console.log(`[weave] builtin market ${e.form==="link"?"linked":"copied"} -> ${_e(p.dataRoot)}`),is({rules:new ae(t),registry:y,states:new T(t),bus:n,libraries:p},r.list()))).then(({loader:e})=>{f=e,I.getHandler=(s,i)=>e.getHandler(s,i),I.getConfig=s=>e.getConfig(s),e.watchRoots()});const D=new Ue,me=new Ne({dispatches:k,sessions:o,projects:r,bus:n,resumeSpec:d.get("claude")?.resume,headless:D}),c=new We({sessions:o,projects:r,hookEvents:a,bus:n,headless:D,terminal:le(()=>b().terminal),blockedByQuestion:e=>h.get(e)!=null,livenessOf:v,sideAnswerStore:{answerById:(e,s,i)=>{M.answerById(e,s,i)}}});$e(c);const B=new Ge(t),_=new es({watches:B,deliverer:c,sessions:o,bus:n,livenessOf:v}),G=new Je(t),F=new Ve(t),ue=new ze({subscriptions:G,sessions:o,bus:n}),L=new Xe(t),J=new Ze(t),m=new ws(Ss(a),gs(a,e=>o.getBySessionId(e)?.harness??null)),V=new Rs(n,e=>Te(j(e)?e:"claude"),e=>m.transcriptPathOf(e),e=>o.livenessRowOf(e)?.harness??null);V.start();const h=new xe({sessions:o,hookEvents:a,onPending:e=>{n.emit({kind:"question.pending",sessionId:e.sessionId,harness:e.harness,count:e.questions.length,at:e.at})},interruptedAt:e=>{const s=o.getBySessionId(e);return s?m.interruptedAt(e,s.lastSeenAt):null}});h.seedFromDb();const M=new Qe(t),Y=new je,N=Ke({rate:Y,events:a,sessions:o,projects:r,bus:n}),z={repo:M,bus:n,settle:e=>{c.interrupt(e.sessionId)}},U=new ls(r);U.start();const W=new ps,l=new ds,X=new bs(()=>ms(r.list(),p.list(),W),l,n,()=>l.hasSubscribers()),Z=new cs(r,p,{cache:W,plugins:H,onSynced:()=>{X.refreshNow(!0)}});Z.start();const w=new hs(async()=>({counts:await ks(r.list()),terminals:await c.sessionTerminals()}),l,{shouldRun:()=>l.hasSubscribers(),graceMs:1e4});w.start();const x=new K(()=>{const e=v(),s={};for(const i of o.listWithCounts()){const R=ys(i,e);R!==null&&(s[i.sessionId]=R)}return{alive:s}},l,{key:"sessionLiveness",shouldRun:()=>l.hasSubscribers()});x.start();const Q=new K(()=>{const e={};for(const s of o.listWithCounts()){if(s.turnOpen!==!0)continue;const i=m.interruptedAt(s.sessionId,s.lastSeenAt);i!==null&&(e[s.sessionId]=i)}return{interrupted:e}},l,{key:"sessionInterrupt",intervalMs:5e3,shouldRun:()=>l.hasSubscribers()});Q.start(),new K(()=>{const e={};for(const s of r.list())e[s.id]=He(s.path);return e},l,{key:"statusline",intervalMs:5e3,shouldRun:()=>l.hasSubscribers(),invalidateOnly:!0}).start();const fe=new vs(()=>c.listInflightCounts(),l,n);let ee=null;const g=Ce({sessions:o,projects:r,harnessOf:e=>{const s=a.listBySession(e,1),i=s[s.length-1]?.source;return j(i)?i:null},surfaceFor:Pe,headless:D,onSyntheticChange:()=>ee?.pushSyntheticSessions(Ee())});A.run=e=>g.run(e);const de=os({config:async()=>{const e=b().decision;if(!e?.baseUrl||!e.model)return null;const s=rs();return s?{baseUrl:e.baseUrl,model:e.model,apiKey:s}:null},fallback:ts({supports:e=>g.supports(e),extract:e=>g.run(e)})}),S=new ss({orchestrations:L,runs:J,deliverer:c,sessions:o,bus:n,supportsExtract:e=>g.supports(e),extract:e=>g.run(e),conditionJudge:de,deferWhenUserPresent:!0,ensureOpen:async e=>{const s=a.listBySession(e,1).at(-1)?.id??0,i=await ns({hookSessions:o,hookEvents:a,projects:r,harnesses:d,sessionProbe:m,terminalRefresher:w},e);if(!i.ok)return i;let R=!1;for(let ie=0;ie<60;ie++){if(a.listBySession(e,20).some(P=>P.id>s&&P.eventType==="SessionStart"))return{ok:!0,ack:"session-start"};v().get(e)===!0&&(R=!0),await new Promise(P=>setTimeout(P,250))}return R?{ok:!0,ack:"registry"}:{ok:!1,error:"session did not report ready within 15s"}}});S.rearm();const se=setInterval(()=>S.cronTick(),3e4);se.unref(),Oe({sessions:o,events:a,dispatches:k,deliverer:c,watches:B,orchestrations:L,watchEngine:_,orchestrationEngine:S,questions:h,sideQuestions:M,probe:m,uploads:F,uploadSessions:Ye,livenessOf:v}),Ie();const q=Ae({projects:r,rules:y,sessions:o,bus:n,dispatcher:$,watchEngine:_,orchestrationEngine:S,messagePipe:c,questionTracker:h,sideQuestions:{onEvent:e=>{qe(z,e)}},sessionProbe:m,uploads:F,dashboardRate:Y,terminalTopologyKick:()=>{w.refreshNow()}});ee=q;const he=_s(),te=us({projects:r,port:u.port,tlsPort:C,watch:U,hookEvents:a,adapters:ce,harnesses:d,libraries:p,fingerprintCache:W,staticDir:he,hookRegistry:y,hookDispatches:k,hookSessions:o,hookBus:n,dataBus:l,terminalRefresher:w,interruptRefresher:Q,livenessRefresher:x,sessionProbe:m,inflightRefresher:fe,updatesRefresher:X,hookDispatcher:$,hookRunner:me,messageDeliverer:c,terminal:le(()=>b().terminal),uploads:F,questionTracker:h,sideQuestions:z,sessionWatches:B,watchEngine:_,orchestrations:L,orchestrationRuns:J,orchestrationEngine:S,pushSubscriptions:G,pushNotifier:ue,onAttach:N.attach,dashboardRefresh:N.attach,hookPlugins:H,hookMirror:q.mirror,pluginStates:new T(t),toolkit:pe,auth:O}),oe=we.createServer(te);let re=null;fs({port:C,bindHost:E,handler:te}).then(e=>{re=e});const ne=()=>{f?.stopWatching(),w.stop(),x.stop(),Q.stop(),Z.stop(),U.stop(),D.killAll(),clearInterval(se),V.stop(),N.stop(),q.stop(),oe.close(),re?.server.close(),process.exit(0)};process.on("SIGTERM",ne),process.on("SIGINT",ne),oe.listen(u.port,E,()=>{Ts({...u,pid:process.pid,host:E,tlsPort:C}),Bs()})}
|
|
1
|
+
import ws from"node:http";import{openDatabase as gs}from"../db/db.js";import{ProjectRepository as Ss}from"../repositories/projects.js";import{HookEventRepository as bs}from"../repositories/hook-events.js";import{LibraryRepository as ys}from"../repositories/libraries.js";import{HookRuleRepository as as}from"../repositories/hook-rules.js";import{HookDispatchRepository as vs}from"../repositories/hook-dispatches.js";import{PluginStateRepository as P}from"../repositories/plugin-states.js";import{SessionRepository as Rs}from"../repositories/sessions.js";import{createRuntimeRegistry as ks}from"@weavecode/harness";import{TERMINAL_LOCATOR_ENV_KEYS as Es,isHarness as Q}from"@weavecode/core";import{messagingSurfaceFor as Ds,narrationSurfaceFor as Ts}from"../surfaces.js";import{syntheticSessionIds as Ps}from"../hooks/synthetic-sessions.js";import{createEdgeExtract as Is}from"../hooks/edge-extract.js";import{startSessionSweeper as Os}from"../hooks/session-sweeper.js";import{startStatuslineCacheSweeper as Cs}from"../statusline/cache-sweeper.js";import{readStatuslineFacts as As}from"../statusline/manager.js";import{wireHookFilePipeline as Hs}from"./hook-pipeline.js";import{ensureBuiltinMarket as Bs,builtinMarketDir as Fs}from"../market/builtin.js";import{HookRuleRegistry as Ms}from"../hooks/registry.js";import{HookDispatcher as js}from"../hooks/dispatcher.js";import{HookEventBus as Ls}from"../hooks/bus.js";import{ResumeRunner as Ns}from"../hooks/resume-runner.js";import{HeadlessRunner as Us}from"../hooks/headless-runner.js";import{MessageDeliverer as _s}from"../hooks/message-deliverer.js";import{QuestionTracker as xs}from"../hooks/question-tracker.js";import{SideQuestionRepository as Ws}from"../repositories/side-questions.js";import{claimSideAnswer as $s}from"../hooks/side-questions.js";import{DashboardRateCache as qs}from"../hooks/dashboard-rate.js";import{startDashboardPusher as Qs}from"./dashboard-pusher.js";import{startPromptFlusher as Ks}from"../hooks/prompt-flusher.js";import{SessionWatchRepository as Gs}from"../repositories/session-watches.js";import{PushSubscriptionRepository as Js}from"../repositories/push-subscriptions.js";import{UploadRepository as Vs}from"../repositories/uploads.js";import{defaultUploadSessions as Ys}from"./upload-sessions.js";import{PushNotifier as zs}from"../hooks/push-notify.js";import{OrchestrationRepository as Xs,OrchestrationRunRepository as Zs}from"../repositories/orchestrations.js";import{WatchEngine as se}from"../hooks/watch-engine.js";import{OrchestrationEngine as ee,createForkConditionJudge as re}from"../hooks/orchestration-engine.js";import{createDecisionConditionJudge as oe}from"../hooks/decision-judge.js";import{readDecisionKey as te}from"./decision-config.js";import{openSessionTerminal as ne}from"./session-open.js";import{loadAllPlugins as ie}from"../hooks/plugin-loader.js";import{ToolkitService as ae}from"../hooks/toolkit.js";import{WatchService as le}from"../watch/watch-service.js";import{SyncScheduler as pe}from"../watch/sync-scheduler.js";import{FingerprintCache as me}from"../install/fingerprint.js";import{detectProjectUpdateCounts as ce}from"../install/updates.js";import{weaveRequestHandler as ue}from"./server.js";import{startTlsServer as fe}from"./tls.js";import{DataBus as de}from"./data-bus.js";import{TerminalTopologyRefresher as he}from"./terminal-topology-refresher.js";import{SnapshotRefresher as K}from"./snapshot-refresher.js";import{SessionProbe as we,dbModelFactResolver as ge,dbTranscriptPathResolver as Se}from"./session-probe.js";import{NarrationWatcher as be}from"./narration-watcher.js";import{InflightCountsRefresher as ye}from"./inflight-counts-refresher.js";import{ProjectUpdatesRefresher as ve}from"./project-updates-refresher.js";import{pidAliveOf as Re}from"./claude-liveness.js";import{combinedLivenessOf as y}from"./liveness.js";import{promptTerminalChannel as ls,readTerminalCounts as ke}from"./opener.js";import{DEFAULT_BIND_HOST as Ee}from"./port.js";import{readDaemonState as De,writeDaemonState as Te}from"./state.js";import{ensureDataLayout as Pe}from"../db/layout.js";import{pruneFileIndexes as Ie}from"./project-files.js";import{pruneInstallTmp as Oe}from"../hooks/plugin-installer.js";import{readDaemonSettingsSync as v,setDaemonSettingsDb as Ce,DEFAULT_SERVER_SETTINGS as Ae}from"./settings.js";import{AuthService as He}from"./dashboard-auth.js";import{syncLaunchOnLogin as Be}from"./auto-start.js";import{resolveStaticDir as Fe}from"./static.js";delete process.env.CLAUDE_CODE_CHILD_SESSION;for(const c of Es)delete process.env[c];export function startDaemon(){Pe();const c=De();c||(console.error("Daemon state not found. Run `weave daemon start` first."),process.exit(1));const o=gs();Ce(o);const R=v().server?.bindHost??Ee,I=v().server?.tlsPort??Ae.tlsPort,O=new He;O.initialPassword&&console.log(`[weave] initial dashboard password: ${O.initialPassword}`);const t=new Ss(o);Ie(t.list().map(s=>s.id)),Oe();const a=new bs(o),m=new ys(o),d=ks(),ps=d.byCapability("events").flatMap(s=>s.events??[]),k=new Ms(new as(o)),E=new vs(o),r=new Rs(o),n=new Ls,C={getHandler:()=>{},getConfig:()=>({})};let f;const A={list:()=>f?.list()??[],setPluginEnabled:(s,e)=>f?.setPluginEnabled(s,e)??!1,reloadAll:async()=>{await f?.reloadAll()},rescan:async()=>{await f?.rescanRoots(t.list(),m)}},ms=new ae({projects:t,states:new P(o),plugins:A,libraries:m}),H={run:null},G=new js({registry:k,dispatches:E,bus:n,projects:t,sessions:r,plugins:C,pluginStates:new P(o),classify:s=>H.run?H.run(s):Promise.resolve(null),sessionTitleOf:async s=>{const e=a.listBySession(s,1).at(-1)?.source;return Q(e)?d.get(e)?.titles?.sessionTitleOf(s)??null:null}});Bs({libraries:m}).then(s=>(s.error?console.error(`[weave] builtin market unavailable: ${s.error}`):s.changed&&console.log(`[weave] builtin market ${s.form==="link"?"linked":"copied"} -> ${Fs(m.dataRoot)}`),ie({rules:new as(o),registry:k,states:new P(o),bus:n,libraries:m},t.list()))).then(({loader:s})=>{f=s,C.getHandler=(e,i)=>s.getHandler(e,i),C.getConfig=e=>s.getConfig(e),s.watchRoots()}).catch(s=>{console.error("[weave] plugin load failed:",s instanceof Error?s.message:s)});const D=new Us,cs=new Ns({dispatches:E,sessions:r,projects:t,bus:n,resumeSpec:d.get("claude")?.resume,headless:D}),p=new _s({sessions:r,projects:t,hookEvents:a,bus:n,headless:D,terminal:ls(()=>v().terminal),blockedByQuestion:s=>h.get(s)!=null,livenessOf:y,sideAnswerStore:{answerById:(s,e,i)=>{L.answerById(s,e,i)}}});Ks(p);const B=new Gs(o),F=new se({watches:B,deliverer:p,sessions:r,bus:n,livenessOf:y}),J=new Js(o),M=new Vs(o),us=new zs({subscriptions:J,sessions:r,bus:n}),j=new Xs(o),V=new Zs(o),u=new we(Se(a),ge(a,s=>r.getBySessionId(s)?.harness??null)),Y=new be(n,s=>Ts(Q(s)?s:"claude"),s=>u.transcriptPathOf(s),s=>r.livenessRowOf(s)?.harness??null);Y.start();const h=new xs({sessions:r,hookEvents:a,onPending:s=>{n.emit({kind:"question.pending",sessionId:s.sessionId,harness:s.harness,count:s.questions.length,at:s.at})},interruptedAt:s=>{const e=r.getBySessionId(s);return e?u.interruptedAt(s,r.lastMainEventAtOf(s)??e.lastSeenAt):null}});h.seedFromDb();const L=new Ws(o),z=new qs,N=Qs({rate:z,events:a,sessions:r,projects:t,bus:n}),X={repo:L,bus:n,settle:s=>{p.interrupt(s.sessionId)}},U=new le(t);U.start();const _=new me,l=new de,Z=new ve(()=>ce(t.list(),m.list(),_),l,n,()=>l.hasSubscribers()),ss=new pe(t,m,{cache:_,plugins:A,onSynced:()=>{Z.refreshNow(!0)}});ss.start();const w=new he(async()=>({counts:await ke(t.list()),terminals:await p.sessionTerminals()}),l,{shouldRun:()=>l.hasSubscribers(),graceMs:1e4});w.start();const x=new K(()=>{const s=y(),e={};for(const i of r.listWithCounts()){const b=Re(i,s);b!==null&&(e[i.sessionId]=b)}return{alive:e}},l,{key:"sessionLiveness",shouldRun:()=>l.hasSubscribers()});x.start();const W=new K(()=>{const s={};for(const e of r.listWithCounts()){if(e.turnOpen!==!0)continue;const i=u.interruptedAt(e.sessionId,r.lastMainEventAtOf(e.sessionId)??e.lastSeenAt);i!==null&&(s[e.sessionId]=i)}return{interrupted:s}},l,{key:"sessionInterrupt",intervalMs:5e3,shouldRun:()=>l.hasSubscribers()});W.start(),new K(()=>{const s={};for(const e of t.list())s[e.id]=As(e.path);return s},l,{key:"statusline",intervalMs:5e3,shouldRun:()=>l.hasSubscribers(),invalidateOnly:!0}).start();const fs=new ye(()=>p.listInflightCounts(),l,n);let es=null;const g=Is({sessions:r,projects:t,harnessOf:s=>{const e=a.listBySession(s,1),i=e[e.length-1]?.source;return Q(i)?i:null},surfaceFor:Ds,headless:D,onSyntheticChange:()=>es?.pushSyntheticSessions(Ps())});H.run=s=>g.run(s);const ds=oe({config:async()=>{const s=v().decision;if(!s?.baseUrl||!s.model)return null;const e=te();return e?{baseUrl:s.baseUrl,model:s.model,apiKey:e}:null},fallback:re({supports:s=>g.supports(s),extract:s=>g.run(s)})}),S=new ee({orchestrations:j,runs:V,deliverer:p,sessions:r,bus:n,supportsExtract:s=>g.supports(s),extract:s=>g.run(s),conditionJudge:ds,deferWhenUserPresent:!0,ensureOpen:async s=>{const e=a.listBySession(s,1).at(-1)?.id??0,i=await ne({hookSessions:r,hookEvents:a,projects:t,harnesses:d,sessionProbe:u,terminalRefresher:w},s);if(!i.ok)return i;let b=!1;for(let is=0;is<60;is++){if(a.listBySession(s,20).some(T=>T.id>e&&T.eventType==="SessionStart"))return{ok:!0,ack:"session-start"};y().get(s)===!0&&(b=!0),await new Promise(T=>setTimeout(T,250))}return b?{ok:!0,ack:"registry"}:{ok:!1,error:"session did not report ready within 15s"}}});S.rearm();const rs=setInterval(()=>S.cronTick(),3e4);rs.unref(),Os({sessions:r,events:a,dispatches:E,deliverer:p,watches:B,orchestrations:j,watchEngine:F,orchestrationEngine:S,questions:h,sideQuestions:L,probe:u,uploads:M,uploadSessions:Ys,livenessOf:y}),Cs();const $=Hs({projects:t,rules:k,sessions:r,bus:n,dispatcher:G,watchEngine:F,orchestrationEngine:S,messagePipe:p,questionTracker:h,sideQuestions:{onEvent:s=>{$s(X,s)}},sessionProbe:u,uploads:M,dashboardRate:z,terminalTopologyKick:()=>{w.refreshNow()}});es=$;const hs=Fe(),os=ue({projects:t,port:c.port,tlsPort:I,watch:U,hookEvents:a,adapters:ps,harnesses:d,libraries:m,fingerprintCache:_,staticDir:hs,hookRegistry:k,hookDispatches:E,hookSessions:r,hookBus:n,dataBus:l,terminalRefresher:w,interruptRefresher:W,livenessRefresher:x,sessionProbe:u,inflightRefresher:fs,updatesRefresher:Z,hookDispatcher:G,hookRunner:cs,messageDeliverer:p,terminal:ls(()=>v().terminal),uploads:M,questionTracker:h,sideQuestions:X,sessionWatches:B,watchEngine:F,orchestrations:j,orchestrationRuns:V,orchestrationEngine:S,pushSubscriptions:J,pushNotifier:us,onAttach:N.attach,dashboardRefresh:N.attach,hookPlugins:A,hookMirror:$.mirror,pluginStates:new P(o),toolkit:ms,auth:O}),q=ws.createServer(os);let ts=null;fe({port:I,bindHost:R,handler:os}).then(s=>{ts=s});const ns=()=>{f?.stopWatching(),w.stop(),x.stop(),W.stop(),ss.stop(),U.stop(),D.killAll(),clearInterval(rs),Y.stop(),N.stop(),q.close(),ts?.server.close();const s=setTimeout(()=>process.exit(0),3e3);$.stop().catch(()=>{}).finally(()=>{clearTimeout(s),process.exit(0)})};process.on("SIGTERM",ns),process.on("SIGINT",ns),q.listen(c.port,R,()=>{Te({...c,pid:process.pid,host:R,tlsPort:I}),Be()}),q.on("error",s=>{throw console.error(`[weave] daemon listen failed on ${R}:${c.port}: ${s.message}`),s})}
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import{existsSync as n,mkdirSync as
|
|
2
|
-
`,"utf-8")}export function clearDaemonState(){const t=r();n(t)&&
|
|
1
|
+
import{existsSync as n,mkdirSync as a,readFileSync as o,rmSync as i,writeFileSync as c}from"node:fs";import m from"node:path";import{getDaemonStatePath as r}from"../db/paths.js";export function readDaemonState(){const t=r();if(!n(t))return null;try{return JSON.parse(o(t,"utf-8"))}catch{return null}}export function writeDaemonState(t){const e=r();a(m.dirname(e),{recursive:!0}),c(e,JSON.stringify(t,null,2)+`
|
|
2
|
+
`,"utf-8")}export function clearDaemonState(){const t=r();n(t)&&i(t)}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{existsSync as
|
|
1
|
+
import{existsSync as i}from"node:fs";import{fileURLToPath as e}from"node:url";import o from"node:path";export function resolveStaticDir(){const t=o.dirname(e(import.meta.url)),r=o.resolve(t,"../../web/dist");return i(r)?r:void 0}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
export class TerminalTopologyRefresher{snapshot;bus;options;timer;running=!1;last=null;lastFingerprint=null;startedAt=0;constructor(t,i,s={}){this.snapshot=t,this.bus=i,this.options=s}get lastSnapshot(){return this.last}start(){this.timer||(this.startedAt=Date.now(),this.timer=setInterval(()=>{this.tick()},this.options.intervalMs??3e4))}stop(){this.timer&&(clearInterval(this.timer),this.timer=void 0)}async refreshNow(){await this.run(!0,!0)}onSubscriberJoin(){this.last!==null&&(this.lastFingerprint=JSON.stringify(this.last),this.bus.emit({key:"terminalTopology",payload:this.last})),this.tick()}async tick(t=!1){await this.run(t,!1)}async run(t,i){if(this.running)return;const s=this.options.shouldRun;if(!(!t&&s&&!s())&&!(!i&&Date.now()-this.startedAt<(this.options.graceMs??0))){this.running=!0;try{const r=await this.snapshot(),
|
|
1
|
+
export class TerminalTopologyRefresher{snapshot;bus;options;timer;running=!1;last=null;lastFingerprint=null;startedAt=0;constructor(t,i,s={}){this.snapshot=t,this.bus=i,this.options=s}get lastSnapshot(){return this.last}start(){this.timer||(this.startedAt=Date.now(),this.timer=setInterval(()=>{this.tick()},this.options.intervalMs??3e4))}stop(){this.timer&&(clearInterval(this.timer),this.timer=void 0)}async refreshNow(){await this.run(!0,!0)}onSubscriberJoin(){this.last!==null&&(this.lastFingerprint=JSON.stringify(this.last),this.bus.emit({key:"terminalTopology",payload:this.last})),this.tick()}async tick(t=!1){await this.run(t,!1)}async run(t,i){if(this.running)return;const s=this.options.shouldRun;if(!(!t&&s&&!s())&&!(!i&&Date.now()-this.startedAt<(this.options.graceMs??0))){this.running=!0;try{const r=await this.snapshot(),a={...this.last?.terminals};for(const[h,o]of Object.entries(r.terminals))o!==void 0&&(a[h]=o);const n={counts:r.counts,terminals:a};this.last=n;const e=JSON.stringify(n);if(e===this.lastFingerprint)return;this.lastFingerprint=e,this.bus.emit({key:"terminalTopology",payload:n})}catch{}finally{this.running=!1}}}}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import
|
|
1
|
+
import v from"node:https";import m from"node:os";import u from"node:path";import{existsSync as f,mkdirSync as w,readFileSync as l,writeFileSync as h}from"node:fs";import{X509Certificate as S,createPrivateKey as k}from"node:crypto";import{generate as $}from"selfsigned";import{getCertsDir as D}from"../db/paths.js";export function daemonCertsDir(){return D()}export function lanIps(){const e=new Set;for(const t of Object.values(m.networkInterfaces()))for(const r of t??[])r.family==="IPv4"&&!r.internal&&e.add(r.address);return[...e].sort()}export function accessUrls(e,t){const r=[{url:`http://localhost:${e}`,protocol:"http",scope:"local"}];t>0&&r.push({url:`https://localhost:${t}`,protocol:"https",scope:"local"});for(const o of lanIps())r.push({url:`http://${o}:${e}`,protocol:"http",scope:"lan"}),t>0&&r.push({url:`https://${o}:${t}`,protocol:"https",scope:"lan"});return r}function x(e){const t=e.subjectAltName??"",r=new Set;for(const o of t.split(",")){const n=o.trim().match(/^IP Address:(.+)$/);n&&r.add(n[1])}return r}export async function ensureDaemonCert(e=daemonCertsDir(),t={}){const r=t.ips??["127.0.0.1",...lanIps()],o=t.hostname??m.hostname(),n=t.now??new Date,s=u.join(e,"host.key"),a=u.join(e,"host.crt");if(f(s)&&f(a))try{const i=l(s,"utf-8"),p=new S(l(a,"utf-8")),y=r.every(d=>x(p).has(d));if(p.checkPrivateKey(k(i))&&Date.parse(p.validTo)>n.getTime()+7*864e5&&y)return{key:i,cert:l(a,"utf-8")}}catch{}const c=await $([{name:"commonName",value:"weave-daemon"}],{keySize:2048,notAfterDate:new Date(n.getTime()+825*864e5),extensions:[{name:"subjectAltName",altNames:[{type:2,value:"localhost"},{type:2,value:o},...r.map(i=>({type:7,ip:i}))]}]});return w(e,{recursive:!0}),h(s,c.private,{mode:384}),h(a,c.cert),{key:c.private,cert:c.cert}}export async function startTlsServer(e){if(e.port<=0)return null;try{const{key:t,cert:r}=await ensureDaemonCert(e.certDir),o=v.createServer({key:t,cert:r},e.handler);return await new Promise((n,s)=>{o.once("error",s),o.listen(e.port,e.bindHost,()=>{o.off("error",s),n()})}),{server:o,port:e.port}}catch(t){return console.warn(`[weave] https listener disabled (port ${e.port}): ${t instanceof Error?t.message:String(t)}`),null}}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{sendJson as e}from"./http.js";import{ToolkitError as h}from"../hooks/toolkit.js";export async function handleToolkitRoutes(
|
|
1
|
+
import{sendJson as e}from"./http.js";import{ToolkitError as h}from"../hooks/toolkit.js";export async function handleToolkitRoutes(n,o,r,a,f){if(!a.includes("/toolkit"))return!1;if(!r.toolkit)return e(o,503,{error:"Toolkit unavailable"}),!0;const l=t=>{if(t instanceof h){e(o,t.code==="not-found"?404:400,{error:t.message,code:t.code});return}e(o,400,{error:t instanceof Error?t.message:"Toolkit operation failed"})},u=a.match(/^\/projects\/(\d+)\/toolkit$/);if(u){if(n.method!=="GET")return e(o,405,{error:"Method not allowed"}),!0;try{e(o,200,await r.toolkit.list(Number(u[1])))}catch(t){l(t)}return!0}const i=a.match(/^\/projects\/(\d+)\/toolkit\/([^/]+)\/(enable|disable|uninstall)$/);if(i){if(n.method!=="POST")return e(o,405,{error:"Method not allowed"}),!0;const t=Number(i[1]),s=decodeURIComponent(i[2]),m=i[3],c=f.searchParams.get("source");try{const d=m==="enable"?await r.toolkit.enable(t,s,c??void 0):m==="disable"?await r.toolkit.disable(t,s,c??void 0):await r.toolkit.uninstall(t,s,c??void 0);r.dataBus?.emit({key:"toolkit"}),e(o,200,d)}catch(d){l(d)}return!0}const k=a.match(/^\/projects\/(\d+)\/toolkit\/legacy-copies\/cleanup$/);if(k){if(n.method!=="POST")return e(o,405,{error:"Method not allowed"}),!0;try{const t=await r.toolkit.cleanupLegacyCopies(Number(k[1]));r.dataBus?.emit({key:"toolkit"}),e(o,200,t)}catch(t){l(t)}return!0}return!1}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{randomUUID as
|
|
1
|
+
import{randomUUID as p}from"node:crypto";import{open as o,mkdir as u,readFile as f,readdir as w,rm as c,stat as m,writeFile as l}from"node:fs/promises";import n from"node:path";import{getTmpDir as y}from"../db/paths.js";export const UPLOAD_SESSION_MAX_AGE_MS=1440*6e4;const d=/^[0-9a-f-]{36}$/;export class UploadSessions{dir;handles=new Map;constructor(e=n.join(y(),"uploads")){this.dir=e}part(e){return n.join(this.dir,`${e}.part`)}meta(e){return n.join(this.dir,`${e}.json`)}async begin(e){await u(this.dir,{recursive:!0});const t=p();await l(this.meta(t),JSON.stringify({name:e.name,mediaType:e.mediaType,size:e.size,received:0,dir:e.dir??null}),"utf8");const a=await o(this.part(t),"w");return await a.truncate(e.size),this.handles.set(t,a),{id:t,...e,received:0}}async get(e){if(!d.test(e))return null;try{const t=JSON.parse(await f(this.meta(e),"utf8"));if(typeof t.name!="string"||typeof t.mediaType!="string"||typeof t.size!="number")return null;const a=typeof t.received=="number"?t.received:(await m(this.part(e))).size;return{id:e,name:t.name,mediaType:t.mediaType,size:t.size,received:a,dir:typeof t.dir=="string"?t.dir:null}}catch{return null}}async append(e,t,a){const i=await this.get(e);if(!i)return{kind:"missing"};if(t!==i.received)return{kind:"conflict",received:i.received};if(i.received+a.length>i.size)return{kind:"overflow",received:i.received};let r=this.handles.get(e);r||(r=await o(this.part(e),"r+"),this.handles.set(e,r));const s=i.received+a.length;return await r.write(a,0,a.length,t),await r.truncate(s),await l(this.meta(e),JSON.stringify({name:i.name,mediaType:i.mediaType,size:i.size,received:s,dir:i.dir??null}),"utf8"),{kind:"ok",received:s}}async finish(e){const t=await this.get(e);return!t||t.received!==t.size?null:{name:t.name,mediaType:t.mediaType,file:this.part(e),size:t.size,dir:t.dir}}async abort(e){d.test(e)&&(await this.handles.get(e)?.close().catch(()=>{}),this.handles.delete(e),await c(this.part(e),{force:!0}),await c(this.meta(e),{force:!0}))}async sweep(e=UPLOAD_SESSION_MAX_AGE_MS,t=Date.now()){let a;try{a=await w(this.dir)}catch{return 0}let i=0;for(const r of a){if(!r.endsWith(".json"))continue;const s=r.slice(0,-5);if(d.test(s))try{const h=await m(this.meta(s));if(t-h.mtimeMs<e)continue;await this.abort(s),i++}catch{}}return i}}export const defaultUploadSessions=new UploadSessions;
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import{mkdirSync as
|
|
1
|
+
import{mkdirSync as t}from"node:fs";import N from"node:path";import{DatabaseSync as i}from"node:sqlite";import{getDbPath as o}from"./paths.js";import{projectKey as A}from"../repositories/projects.js";const n=`
|
|
2
2
|
CREATE TABLE IF NOT EXISTS projects (
|
|
3
3
|
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
4
4
|
path TEXT NOT NULL UNIQUE,
|
|
@@ -23,6 +23,10 @@ CREATE TABLE IF NOT EXISTS hook_events (
|
|
|
23
23
|
);
|
|
24
24
|
CREATE INDEX IF NOT EXISTS idx_hook_events_project ON hook_events(project_id, created_at);
|
|
25
25
|
CREATE INDEX IF NOT EXISTS idx_hook_events_session ON hook_events(session_id);
|
|
26
|
+
-- \u4F1A\u8BDD\u5217\u8868\uFF08listWithCounts\uFF09\u7684\u90A3\u51E0\u4E2A\u76F8\u5173\u5B50\u67E5\u8BE2\uFF1AMAX(id) WHERE session_id=? AND
|
|
27
|
+
-- event_type IN (\u2026)\u3002\u53EA\u6709 (session_id) \u65F6\u6BCF\u4E2A\u5B50\u67E5\u8BE2\u90FD\u8981\u626B\u8BE5\u4F1A\u8BDD\u5168\u90E8\u4E8B\u4EF6\uFF08\u6700\u5927\u7684
|
|
28
|
+
-- \u4F1A\u8BDD\u51E0\u4E07\u6761\uFF09\uFF0C\u5B9E\u6D4B 63 \u4E2A\u4F1A\u8BDD 3.9s\uFF1B\u5E26\u4E0A event_type \u540E\u6BCF\u4E2A\u7C7B\u578B\u4E00\u6B21\u5B9A\u4F4D\uFF0C2.6ms\u3002
|
|
29
|
+
CREATE INDEX IF NOT EXISTS idx_hook_events_session_type ON hook_events(session_id, event_type, id);
|
|
26
30
|
-- \u5168\u5C40\u641C\u7D22\uFF08GET /search\uFF09\u7684\u804A\u5929\u8BB0\u5F55\u8DEF\uFF1Aevent_type \u5148\u6536\u7A84\u5230\u5BF9\u8BDD\u7C7B\uFF08\u7EA6\u5360 2%\uFF09\uFF0C
|
|
27
31
|
-- \u518D\u5BF9 payload \u505A json_extract + LIKE\u2014\u2014\u6CA1\u6709\u8FD9\u628A\u7D22\u5F15\u5C31\u662F 20 \u4E07\u884C\u5168\u8868\u626B\u3002
|
|
28
32
|
CREATE INDEX IF NOT EXISTS idx_hook_events_type ON hook_events(event_type);
|
|
@@ -200,4 +204,4 @@ CREATE TABLE IF NOT EXISTS event_images (
|
|
|
200
204
|
upload_id TEXT NOT NULL,
|
|
201
205
|
PRIMARY KEY (event_id, upload_id)
|
|
202
206
|
);
|
|
203
|
-
`;export function openDatabase(
|
|
207
|
+
`;export function openDatabase(E=o()){E!==":memory:"&&t(N.dirname(E),{recursive:!0});const u=new i(E);return u.exec("PRAGMA busy_timeout = 5000"),u.exec("PRAGMA journal_mode = WAL"),u.exec("PRAGMA foreign_keys = ON"),_(u),u.exec(n),u.exec("DROP TABLE IF EXISTS session_messages"),d(u),r(u),a(u),L(u),D(u),u}function a(E){const u=E.prepare("SELECT id, path FROM projects ORDER BY id").all(),F=new Set(u.map(e=>e.path)),s=E.prepare("UPDATE projects SET path = ? WHERE id = ?");for(const e of u){const T=A(e.path);T===e.path||F.has(T)||(F.delete(e.path),F.add(T),s.run(T,e.id))}}function L(E){const u=new Set(E.prepare("PRAGMA table_info(session_watches)").all().map(F=>String(F.name)));u.size!==0&&(u.has("on_events")||E.exec("ALTER TABLE session_watches ADD COLUMN on_events TEXT"),u.has("remaining")||(E.exec("ALTER TABLE session_watches ADD COLUMN remaining INTEGER"),E.exec("UPDATE session_watches SET remaining = 1")))}function r(E){const u=new Set(E.prepare("PRAGMA table_info(projects)").all().map(F=>String(F.name)));u.size!==0&&(u.has("sort_order")||E.exec("ALTER TABLE projects ADD COLUMN sort_order INTEGER"),u.has("archived_at")||E.exec("ALTER TABLE projects ADD COLUMN archived_at TEXT"))}function D(E){const u=new Set(E.prepare("PRAGMA table_info(uploads)").all().map(F=>String(F.name)));u.size!==0&&(u.has("dir")||E.exec("ALTER TABLE uploads ADD COLUMN dir TEXT"))}function _(E){const u=E.prepare("PRAGMA table_info(orchestrations)").all();u.length===0||u.some(F=>F.name==="enabled")||E.exec("DROP TABLE orchestrations")}function d(E){const u=new Set(E.prepare("PRAGMA table_info(hook_rules)").all().map(F=>String(F.name)));u.size!==0&&(u.has("origin")||E.exec("ALTER TABLE hook_rules ADD COLUMN origin TEXT NOT NULL DEFAULT 'user'"),u.has("plugin_id")||E.exec("ALTER TABLE hook_rules ADD COLUMN plugin_id TEXT"),E.exec("CREATE INDEX IF NOT EXISTS idx_hook_rules_plugin ON hook_rules(plugin_id)"))}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{existsSync as u,lstatSync as g,mkdirSync as
|
|
1
|
+
import{existsSync as u,lstatSync as g,mkdirSync as p,readFileSync as S,readdirSync as f,renameSync as m,rmSync as b,symlinkSync as w}from"node:fs";import e from"node:path";import{dataRoots as y,getDataDir as l}from"./paths.js";const h={data:["market","uploads","plugins"],local:["auth.json","ai.json","push.json","initial-password","certs","weave-autostart.vbs"],cache:["logs","statusline","hooks","tmp","daemon.json"]},D="weave.db",j=["hooks","statusline"];export function liveDaemonPid(o=l()){const t=y(o);for(const i of[e.join(t.cache,"daemon.json"),e.join(o,"daemon.json")])try{const s=Number(JSON.parse(S(i,"utf-8")).pid);if(s>0&&x(s))return s}catch{}return null}function x(o){try{return process.kill(o,0),!0}catch{return!1}}function L(o){try{return g(o).isSymbolicLink()}catch{return!1}}function k(o,t){p(t,{recursive:!0});for(const i of f(o,{withFileTypes:!0})){const s=e.join(o,i.name),a=e.join(t,i.name);i.isDirectory()?k(s,a):u(a)||m(s,a)}b(o,{recursive:!0,force:!0})}export function ensureDataLayout(o=l()){const t=migrateDataLayout(o);return t.moved.length>0&&console.log(`[weave] data layout: moved ${t.moved.join(", ")}`),t.kept.length>0&&console.log(`[weave] data layout: kept ${t.kept.join(", ")} (target exists)`),t}export function migrateDataLayout(o=l()){const t={moved:[],kept:[],bridged:[],busyPid:null},i=liveDaemonPid(o);if(i!==null)return t.busyPid=i,t;let s;try{s=f(o)}catch{return t}const a=Object.keys(h),d=y(o);for(const n of s){if(L(e.join(o,n)))continue;const c=a.find(v=>h[v].includes(n))??(n.startsWith(D)?"data":null);if(!c)continue;const r=d[c];if(u(e.join(r,n))&&j.includes(n)){try{k(e.join(o,n),e.join(r,n)),t.moved.push(n)}catch{t.kept.push(n)}continue}if(u(e.join(r,n))){t.kept.push(n);continue}try{p(r,{recursive:!0}),m(e.join(o,n),e.join(r,n)),t.moved.push(n)}catch{t.kept.push(n)}}for(const n of j){const c=e.join(o,n),r=e.join(d.cache,n);if(!(!u(r)||u(c)))try{w(r,c,process.platform==="win32"?"junction":"dir"),t.bridged.push(n)}catch{}}return t}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
const
|
|
1
|
+
const l=" ";export function composeAnswerAtoms(i,p){if(i.every(o=>o.options.length===0))return{ok:!1,error:"Question face has no answerable options"};const u=new Map(p.map(o=>[o.questionKey,o]));for(const o of u.keys())if(!i.some(s=>s.key===o))return{ok:!1,error:`Unknown question: ${o}`};const n=[];for(const o of i){const s=u.get(o.key),t=(s?.options??[]).map(e=>o.options[e]);if(t.some(e=>!e))return{ok:!1,error:`Invalid option index: ${o.key}`};if(o.submit&&t.length!==1)return{ok:!1,error:"Submit choice required to finish the call"};const c=t.filter(e=>!e.input);if(!o.multiSelect&&c.length>1)return{ok:!1,error:`Single-select question got ${c.length} options: ${o.key}`};const f=s?.text?.trim()??"",r=t.find(e=>e.input);if(r&&!f)return{ok:!1,error:`Text required for this option: ${o.key}`};for(const e of t)n.push(...e.keys);if(r)n.push(...r.textFocus??[],f,...r.textTail??["\r"]);else for(const e of t)n.push(...e.commit??[]);if(o.submit||t.some(e=>e.chat))break;!r&&(o.multiSelect||t.length===0)&&n.push(" ")}return{ok:!0,atoms:n}}
|
|
@@ -81,11 +81,13 @@ export type HookBusMessage = {
|
|
|
81
81
|
sessionId: string;
|
|
82
82
|
at: string;
|
|
83
83
|
}
|
|
84
|
-
/** 投递回执:目标会话自己的 UserPromptSubmit 与在途条目匹配上了(真到达)。
|
|
84
|
+
/** 投递回执:目标会话自己的 UserPromptSubmit 与在途条目匹配上了(真到达)。
|
|
85
|
+
* eventId = 命中的那条开轮事件(精确配对键;内建命令没有这一轮,不带)。 */
|
|
85
86
|
| {
|
|
86
87
|
kind: 'message.acknowledged';
|
|
87
88
|
messageId: string;
|
|
88
89
|
sessionId: string;
|
|
90
|
+
eventId?: number;
|
|
89
91
|
at: string;
|
|
90
92
|
}
|
|
91
93
|
/** 队列暂停闸置位:未回执超窗(unacked)或投递失败(failed)——该会话后续队列
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{EventEmitter as
|
|
1
|
+
import{EventEmitter as t}from"node:events";export class HookEventBus{emitter=new t;constructor(){this.emitter.setMaxListeners(100)}emit(e){this.emitter.emit("change",e)}subscribe(e){return this.emitter.on("change",e),()=>this.emitter.off("change",e)}}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
export const RATE_BUCKET_MS=1e4,RATE_RETAIN_MS=864e5;const h=6e4;export class DashboardRateCache{buckets=new Map;seeded=!1;lastPrune=0;events=0;today=0;dayKey="";get isSeeded(){return this.seeded}record(
|
|
1
|
+
export const RATE_BUCKET_MS=1e4,RATE_RETAIN_MS=864e5;const h=6e4;export class DashboardRateCache{buckets=new Map;seeded=!1;lastPrune=0;events=0;today=0;dayKey="";get isSeeded(){return this.seeded}record(e=Date.now()){const t=Math.floor(e/1e4)*1e4;this.buckets.set(t,(this.buckets.get(t)??0)+1),this.events+=1;const s=new Date(e).toDateString();s!==this.dayKey&&(this.dayKey=s,this.today!==0&&(this.today=0)),this.today+=1,this.prune(e)}get totals(){return{events:this.events,today:this.today}}seedTotals(e,t){this.events=Math.max(this.events,e),this.today=Math.max(this.today,t),this.dayKey=new Date().toDateString()}recentBuckets(e,t=Date.now()){const s=Math.floor(t/1e4)*1e4-(e-1)*1e4;return Array.from({length:e},(o,n)=>{const a=s+n*1e4;return{at:new Date(a).toISOString().slice(0,19),n:this.buckets.get(a)??0}})}seed(e){const t=new Map;for(const{at:s,n:o}of e){const n=Date.parse(`${s}Z`);if(!Number.isFinite(n))continue;const a=Math.floor(n/1e4)*1e4;t.set(a,(t.get(a)??0)+o)}for(const[s,o]of t)this.buckets.set(s,Math.max(this.buckets.get(s)??0,o));this.seeded=!0}bucketsFor(e,t){return Array.from({length:t},(s,o)=>this.buckets.get(e+o*1e4)??0)}prune(e){if(e-this.lastPrune<6e4)return;this.lastPrune=e;const t=e-864e5;for(const s of this.buckets.keys())s<t&&this.buckets.delete(s)}}
|