@weavecode/weave 0.1.4 → 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.
Files changed (362) hide show
  1. package/node_modules/@modelcontextprotocol/sdk/node_modules/express/node_modules/encodeurl/README.md +14 -0
  2. package/node_modules/@modelcontextprotocol/sdk/node_modules/express/node_modules/encodeurl/index.js +5 -10
  3. package/node_modules/@modelcontextprotocol/sdk/node_modules/express/node_modules/encodeurl/package.json +10 -6
  4. package/node_modules/@modelcontextprotocol/sdk/node_modules/express/node_modules/qs/CHANGELOG.md +42 -0
  5. package/node_modules/@modelcontextprotocol/sdk/node_modules/express/node_modules/qs/README.md +38 -10
  6. package/node_modules/@modelcontextprotocol/sdk/node_modules/express/node_modules/qs/dist/qs.js +18 -18
  7. package/node_modules/@modelcontextprotocol/sdk/node_modules/express/node_modules/qs/lib/parse.js +16 -4
  8. package/node_modules/@modelcontextprotocol/sdk/node_modules/express/node_modules/qs/lib/utils.js +13 -2
  9. package/node_modules/@modelcontextprotocol/sdk/node_modules/express/node_modules/qs/package.json +1 -1
  10. package/node_modules/@modelcontextprotocol/sdk/node_modules/express-rate-limit/dist/index.cjs +6 -2
  11. package/node_modules/@modelcontextprotocol/sdk/node_modules/express-rate-limit/dist/index.mjs +6 -2
  12. package/node_modules/@modelcontextprotocol/sdk/node_modules/express-rate-limit/package.json +10 -10
  13. package/node_modules/@modelcontextprotocol/sdk/node_modules/jose/dist/types/jwt/decrypt.d.ts +3 -0
  14. package/node_modules/@modelcontextprotocol/sdk/node_modules/jose/dist/types/jwt/unsecured.d.ts +2 -0
  15. package/node_modules/@modelcontextprotocol/sdk/node_modules/jose/dist/types/jwt/verify.d.ts +3 -0
  16. package/node_modules/@modelcontextprotocol/sdk/node_modules/jose/dist/types/types.d.ts +8 -0
  17. package/node_modules/@modelcontextprotocol/sdk/node_modules/jose/dist/types/util/decode_jwt.d.ts +1 -0
  18. package/node_modules/@modelcontextprotocol/sdk/node_modules/jose/dist/webapi/jwks/remote.js +1 -1
  19. package/node_modules/@modelcontextprotocol/sdk/node_modules/jose/package.json +1 -1
  20. package/node_modules/@weavecode/cli/dist/cli.js +4 -4
  21. package/node_modules/@weavecode/cli/dist/commands/chpass.js +1 -1
  22. package/node_modules/@weavecode/cli/dist/commands/daemon-auth.js +1 -1
  23. package/node_modules/@weavecode/cli/dist/commands/daemon.d.ts +2 -0
  24. package/node_modules/@weavecode/cli/dist/commands/daemon.js +2 -2
  25. package/node_modules/@weavecode/cli/dist/commands/dashboard.js +2 -2
  26. package/node_modules/@weavecode/cli/dist/commands/doctor.js +1 -1
  27. package/node_modules/@weavecode/cli/dist/commands/init.js +1 -1
  28. package/node_modules/@weavecode/cli/dist/commands/msg.js +2 -2
  29. package/node_modules/@weavecode/cli/dist/commands/scan.js +1 -1
  30. package/node_modules/@weavecode/cli/dist/commands/status.js +2 -2
  31. package/node_modules/@weavecode/cli/dist/commands/uninstall.js +1 -1
  32. package/node_modules/@weavecode/cli/dist/i18n/dict/en.js +4 -4
  33. package/node_modules/@weavecode/cli/dist/i18n/dict/zh.d.ts +5 -1
  34. package/node_modules/@weavecode/cli/dist/i18n/dict/zh.js +5 -5
  35. package/node_modules/@weavecode/cli/dist/i18n/index.js +1 -1
  36. package/node_modules/@weavecode/cli/dist/i18n/t.js +1 -1
  37. package/node_modules/@weavecode/cli/dist/init/claudemd-gen.js +3 -3
  38. package/node_modules/@weavecode/cli/dist/init/executor.js +3 -3
  39. package/node_modules/@weavecode/cli/dist/init/git-commit.js +2 -2
  40. package/node_modules/@weavecode/cli/dist/init/harnesses/claude.js +7 -7
  41. package/node_modules/@weavecode/cli/dist/init/harnesses/codex.js +1 -1
  42. package/node_modules/@weavecode/cli/dist/init/instruction-link.js +1 -1
  43. package/node_modules/@weavecode/cli/dist/init/plugin-templates.js +1 -1
  44. package/node_modules/@weavecode/cli/dist/init/prompt.js +4 -4
  45. package/node_modules/@weavecode/cli/dist/init/provision.js +1 -1
  46. package/node_modules/@weavecode/cli/dist/init/uninstall.js +6 -6
  47. package/node_modules/@weavecode/cli/dist/init/wiring.js +1 -1
  48. package/node_modules/@weavecode/cli/dist/parser.js +1 -1
  49. package/node_modules/@weavecode/cli/dist/statusline/ansi.js +1 -1
  50. package/node_modules/@weavecode/cli/dist/statusline/mock-input.js +1 -1
  51. package/node_modules/@weavecode/cli/dist/statusline/preview.js +2 -2
  52. package/node_modules/@weavecode/cli/package.json +5 -5
  53. package/node_modules/@weavecode/core/dist/harness-checks.js +1 -1
  54. package/node_modules/@weavecode/core/dist/harness.d.ts +14 -0
  55. package/node_modules/@weavecode/core/dist/harness.js +1 -1
  56. package/node_modules/@weavecode/core/dist/index.d.ts +1 -1
  57. package/node_modules/@weavecode/core/dist/index.js +1 -1
  58. package/node_modules/@weavecode/core/dist/platform.js +1 -1
  59. package/node_modules/@weavecode/core/dist/types.js +1 -1
  60. package/node_modules/@weavecode/core/dist/utils/fs.js +1 -1
  61. package/node_modules/@weavecode/core/dist/utils/logger.js +1 -1
  62. package/node_modules/@weavecode/core/package.json +1 -1
  63. package/node_modules/@weavecode/harness/dist/claude/assets.js +4 -4
  64. package/node_modules/@weavecode/harness/dist/claude/capture.js +9 -9
  65. package/node_modules/@weavecode/harness/dist/claude/commands.d.ts +3 -0
  66. package/node_modules/@weavecode/harness/dist/claude/commands.js +2 -3
  67. package/node_modules/@weavecode/harness/dist/claude/config.js +2 -2
  68. package/node_modules/@weavecode/harness/dist/claude/detect.js +1 -1
  69. package/node_modules/@weavecode/harness/dist/claude/edits.js +1 -1
  70. package/node_modules/@weavecode/harness/dist/claude/event-source.js +1 -1
  71. package/node_modules/@weavecode/harness/dist/claude/images.js +2 -2
  72. package/node_modules/@weavecode/harness/dist/claude/index.d.ts +1 -0
  73. package/node_modules/@weavecode/harness/dist/claude/index.js +1 -1
  74. package/node_modules/@weavecode/harness/dist/claude/liveness.js +1 -1
  75. package/node_modules/@weavecode/harness/dist/claude/mcp-gen.js +1 -1
  76. package/node_modules/@weavecode/harness/dist/claude/messaging.js +2 -2
  77. package/node_modules/@weavecode/harness/dist/claude/model-aliases.js +1 -1
  78. package/node_modules/@weavecode/harness/dist/claude/narration.d.ts +0 -11
  79. package/node_modules/@weavecode/harness/dist/claude/narration.js +1 -1
  80. package/node_modules/@weavecode/harness/dist/claude/peers.js +1 -1
  81. package/node_modules/@weavecode/harness/dist/claude/plan.js +1 -1
  82. package/node_modules/@weavecode/harness/dist/claude/plugins.js +4 -4
  83. package/node_modules/@weavecode/harness/dist/claude/prompt-inbox.js +1 -1
  84. package/node_modules/@weavecode/harness/dist/claude/prompt.js +3 -3
  85. package/node_modules/@weavecode/harness/dist/claude/questions.js +2 -2
  86. package/node_modules/@weavecode/harness/dist/claude/resume.js +1 -1
  87. package/node_modules/@weavecode/harness/dist/claude/rewind.d.ts +8 -0
  88. package/node_modules/@weavecode/harness/dist/claude/rewind.js +1 -0
  89. package/node_modules/@weavecode/harness/dist/claude/settings-gen.js +1 -1
  90. package/node_modules/@weavecode/harness/dist/claude/side-question.js +2 -2
  91. package/node_modules/@weavecode/harness/dist/claude/statusline/generator.js +39 -18
  92. package/node_modules/@weavecode/harness/dist/claude/statusline/git-cache.js +1 -1
  93. package/node_modules/@weavecode/harness/dist/claude/statusline/surface.js +2 -2
  94. package/node_modules/@weavecode/harness/dist/claude/transcript-cursor.d.ts +26 -0
  95. package/node_modules/@weavecode/harness/dist/claude/transcript-cursor.js +2 -0
  96. package/node_modules/@weavecode/harness/dist/claude/transcript.js +7 -7
  97. package/node_modules/@weavecode/harness/dist/codex/assets.js +1 -1
  98. package/node_modules/@weavecode/harness/dist/codex/capture.js +2 -2
  99. package/node_modules/@weavecode/harness/dist/codex/commands.js +4 -4
  100. package/node_modules/@weavecode/harness/dist/codex/config.js +2 -2
  101. package/node_modules/@weavecode/harness/dist/codex/detect.js +1 -1
  102. package/node_modules/@weavecode/harness/dist/codex/event-source.js +2 -2
  103. package/node_modules/@weavecode/harness/dist/codex/images.js +1 -1
  104. package/node_modules/@weavecode/harness/dist/codex/index.js +1 -1
  105. package/node_modules/@weavecode/harness/dist/codex/liveness.js +1 -1
  106. package/node_modules/@weavecode/harness/dist/codex/mcp.js +1 -1
  107. package/node_modules/@weavecode/harness/dist/codex/messaging.js +2 -2
  108. package/node_modules/@weavecode/harness/dist/codex/narration.js +1 -1
  109. package/node_modules/@weavecode/harness/dist/codex/plugin-state.js +1 -1
  110. package/node_modules/@weavecode/harness/dist/codex/plugins.js +3 -3
  111. package/node_modules/@weavecode/harness/dist/codex/provision.js +1 -1
  112. package/node_modules/@weavecode/harness/dist/codex/questions.js +2 -2
  113. package/node_modules/@weavecode/harness/dist/codex/rollout.js +5 -5
  114. package/node_modules/@weavecode/harness/dist/codex/side-question.js +4 -4
  115. package/node_modules/@weavecode/harness/dist/codex/titles.js +4 -4
  116. package/node_modules/@weavecode/harness/dist/codex/toml.js +13 -13
  117. package/node_modules/@weavecode/harness/dist/codex/transcript.js +2 -2
  118. package/node_modules/@weavecode/harness/dist/driver.d.ts +49 -1
  119. package/node_modules/@weavecode/harness/dist/driver.js +1 -1
  120. package/node_modules/@weavecode/harness/dist/init/generated.js +2 -2
  121. package/node_modules/@weavecode/harness/dist/init/pipeline.js +1 -1
  122. package/node_modules/@weavecode/harness/dist/registry-wiring.js +1 -1
  123. package/node_modules/@weavecode/harness/dist/shared/install-link.js +1 -1
  124. package/node_modules/@weavecode/harness/dist/shared/json-cap.js +1 -1
  125. package/node_modules/@weavecode/harness/package.json +2 -2
  126. package/node_modules/@weavecode/server/dist/config/dotted.js +1 -1
  127. package/node_modules/@weavecode/server/dist/config/profiles.d.ts +19 -13
  128. package/node_modules/@weavecode/server/dist/config/profiles.js +2 -2
  129. package/node_modules/@weavecode/server/dist/daemon/ai-config.js +2 -2
  130. package/node_modules/@weavecode/server/dist/daemon/ai-context.js +6 -6
  131. package/node_modules/@weavecode/server/dist/daemon/ai-routes.js +4 -4
  132. package/node_modules/@weavecode/server/dist/daemon/api-log.js +3 -3
  133. package/node_modules/@weavecode/server/dist/daemon/auth-routes.js +1 -1
  134. package/node_modules/@weavecode/server/dist/daemon/auto-start.js +6 -6
  135. package/node_modules/@weavecode/server/dist/daemon/capture-routes.js +1 -1
  136. package/node_modules/@weavecode/server/dist/daemon/config-routes.js +1 -1
  137. package/node_modules/@weavecode/server/dist/daemon/cron.js +1 -1
  138. package/node_modules/@weavecode/server/dist/daemon/dashboard-auth.js +2 -2
  139. package/node_modules/@weavecode/server/dist/daemon/dashboard-pusher.js +1 -1
  140. package/node_modules/@weavecode/server/dist/daemon/data-bus.js +1 -1
  141. package/node_modules/@weavecode/server/dist/daemon/decision-config.js +2 -2
  142. package/node_modules/@weavecode/server/dist/daemon/dev-entry.js +1 -1
  143. package/node_modules/@weavecode/server/dist/daemon/entry.js +7 -1
  144. package/node_modules/@weavecode/server/dist/daemon/fs-browser.js +1 -1
  145. package/node_modules/@weavecode/server/dist/daemon/hook-pipeline.js +1 -1
  146. package/node_modules/@weavecode/server/dist/daemon/hooks-routes.js +1 -1
  147. package/node_modules/@weavecode/server/dist/daemon/http.js +1 -1
  148. package/node_modules/@weavecode/server/dist/daemon/liveness.js +1 -1
  149. package/node_modules/@weavecode/server/dist/daemon/mcp-orchestration.js +1 -1
  150. package/node_modules/@weavecode/server/dist/daemon/narration-watcher.js +2 -2
  151. package/node_modules/@weavecode/server/dist/daemon/opener/backend-ghostty.js +1 -1
  152. package/node_modules/@weavecode/server/dist/daemon/opener/backend-iterm.js +1 -1
  153. package/node_modules/@weavecode/server/dist/daemon/opener/backend-konsole.js +2 -2
  154. package/node_modules/@weavecode/server/dist/daemon/opener/backend-terminal-app.js +1 -1
  155. package/node_modules/@weavecode/server/dist/daemon/opener/backend-wezterm.js +1 -1
  156. package/node_modules/@weavecode/server/dist/daemon/opener/backend-wt.js +1 -1
  157. package/node_modules/@weavecode/server/dist/daemon/opener/backend.js +1 -1
  158. package/node_modules/@weavecode/server/dist/daemon/opener/launch.js +1 -1
  159. package/node_modules/@weavecode/server/dist/daemon/opener/pty-terminals.js +4 -4
  160. package/node_modules/@weavecode/server/dist/daemon/opener/shared.js +1 -1
  161. package/node_modules/@weavecode/server/dist/daemon/opener/wezterm-mux.js +1 -1
  162. package/node_modules/@weavecode/server/dist/daemon/opener/wt.js +3 -3
  163. package/node_modules/@weavecode/server/dist/daemon/opener.d.ts +2 -0
  164. package/node_modules/@weavecode/server/dist/daemon/opener.js +1 -1
  165. package/node_modules/@weavecode/server/dist/daemon/port.js +1 -1
  166. package/node_modules/@weavecode/server/dist/daemon/project-files.d.ts +12 -6
  167. package/node_modules/@weavecode/server/dist/daemon/project-files.js +2 -2
  168. package/node_modules/@weavecode/server/dist/daemon/project-harnesses.js +2 -2
  169. package/node_modules/@weavecode/server/dist/daemon/project-updates-refresher.js +1 -1
  170. package/node_modules/@weavecode/server/dist/daemon/prompt-images.js +1 -1
  171. package/node_modules/@weavecode/server/dist/daemon/routes/hooks-admin.js +1 -1
  172. package/node_modules/@weavecode/server/dist/daemon/routes/market.js +1 -1
  173. package/node_modules/@weavecode/server/dist/daemon/routes/orchestration.js +1 -1
  174. package/node_modules/@weavecode/server/dist/daemon/routes/path-refs.js +1 -1
  175. package/node_modules/@weavecode/server/dist/daemon/routes/project-files.js +1 -1
  176. package/node_modules/@weavecode/server/dist/daemon/routes/projects.js +1 -1
  177. package/node_modules/@weavecode/server/dist/daemon/routes/search.js +1 -1
  178. package/node_modules/@weavecode/server/dist/daemon/routes/session-control.js +1 -1
  179. package/node_modules/@weavecode/server/dist/daemon/routes/session-insights.js +1 -1
  180. package/node_modules/@weavecode/server/dist/daemon/routes/settings-statusline.js +1 -1
  181. package/node_modules/@weavecode/server/dist/daemon/routes/uploads.js +1 -1
  182. package/node_modules/@weavecode/server/dist/daemon/routes/visualizations.d.ts +3 -0
  183. package/node_modules/@weavecode/server/dist/daemon/routes/visualizations.js +1 -0
  184. package/node_modules/@weavecode/server/dist/daemon/routes/watches.js +1 -1
  185. package/node_modules/@weavecode/server/dist/daemon/server.js +8 -8
  186. package/node_modules/@weavecode/server/dist/daemon/session-open.js +1 -1
  187. package/node_modules/@weavecode/server/dist/daemon/session-probe.d.ts +5 -4
  188. package/node_modules/@weavecode/server/dist/daemon/session-probe.js +1 -1
  189. package/node_modules/@weavecode/server/dist/daemon/settings.js +2 -2
  190. package/node_modules/@weavecode/server/dist/daemon/snapshot-refresher.js +1 -1
  191. package/node_modules/@weavecode/server/dist/daemon/sse-hub.js +1 -1
  192. package/node_modules/@weavecode/server/dist/daemon/start.js +1 -1
  193. package/node_modules/@weavecode/server/dist/daemon/state.js +2 -2
  194. package/node_modules/@weavecode/server/dist/daemon/static.js +1 -1
  195. package/node_modules/@weavecode/server/dist/daemon/terminal-topology-refresher.js +1 -1
  196. package/node_modules/@weavecode/server/dist/daemon/tls.js +1 -1
  197. package/node_modules/@weavecode/server/dist/daemon/toolkit-routes.js +1 -1
  198. package/node_modules/@weavecode/server/dist/daemon/upload-sessions.js +1 -1
  199. package/node_modules/@weavecode/server/dist/db/db.js +6 -2
  200. package/node_modules/@weavecode/server/dist/db/layout.js +1 -1
  201. package/node_modules/@weavecode/server/dist/hooks/answer-keys.js +1 -1
  202. package/node_modules/@weavecode/server/dist/hooks/bus.d.ts +3 -1
  203. package/node_modules/@weavecode/server/dist/hooks/bus.js +1 -1
  204. package/node_modules/@weavecode/server/dist/hooks/dashboard-rate.js +1 -1
  205. package/node_modules/@weavecode/server/dist/hooks/decision-judge.js +1 -1
  206. package/node_modules/@weavecode/server/dist/hooks/delivery/ack-gate.d.ts +12 -6
  207. package/node_modules/@weavecode/server/dist/hooks/delivery/ack-gate.js +1 -1
  208. package/node_modules/@weavecode/server/dist/hooks/delivery/channels.d.ts +3 -3
  209. package/node_modules/@weavecode/server/dist/hooks/delivery/channels.js +1 -1
  210. package/node_modules/@weavecode/server/dist/hooks/delivery/keys.d.ts +19 -9
  211. package/node_modules/@weavecode/server/dist/hooks/delivery/keys.js +1 -1
  212. package/node_modules/@weavecode/server/dist/hooks/delivery/queue.js +1 -1
  213. package/node_modules/@weavecode/server/dist/hooks/delivery/relay.d.ts +2 -2
  214. package/node_modules/@weavecode/server/dist/hooks/delivery/relay.js +1 -1
  215. package/node_modules/@weavecode/server/dist/hooks/delivery/send.js +2 -2
  216. package/node_modules/@weavecode/server/dist/hooks/delivery/views.d.ts +3 -1
  217. package/node_modules/@weavecode/server/dist/hooks/delivery/views.js +1 -1
  218. package/node_modules/@weavecode/server/dist/hooks/dispatcher.js +6 -6
  219. package/node_modules/@weavecode/server/dist/hooks/edge-extract.js +1 -1
  220. package/node_modules/@weavecode/server/dist/hooks/handlers/webhook.js +1 -1
  221. package/node_modules/@weavecode/server/dist/hooks/headless-runner.js +2 -2
  222. package/node_modules/@weavecode/server/dist/hooks/inbox-socket.js +2 -2
  223. package/node_modules/@weavecode/server/dist/hooks/inbox-worker.js +3 -3
  224. package/node_modules/@weavecode/server/dist/hooks/match.js +1 -1
  225. package/node_modules/@weavecode/server/dist/hooks/message-deliverer.d.ts +45 -38
  226. package/node_modules/@weavecode/server/dist/hooks/message-deliverer.js +5 -3
  227. package/node_modules/@weavecode/server/dist/hooks/mirror.js +4 -4
  228. package/node_modules/@weavecode/server/dist/hooks/orchestration-engine.js +7 -7
  229. package/node_modules/@weavecode/server/dist/hooks/orchestration-graph.js +1 -1
  230. package/node_modules/@weavecode/server/dist/hooks/plugin-installer.js +3 -3
  231. package/node_modules/@weavecode/server/dist/hooks/plugin-loader.js +1 -1
  232. package/node_modules/@weavecode/server/dist/hooks/plugin-project-state.js +1 -1
  233. package/node_modules/@weavecode/server/dist/hooks/prompt-flusher.js +1 -1
  234. package/node_modules/@weavecode/server/dist/hooks/promptbox.js +8 -8
  235. package/node_modules/@weavecode/server/dist/hooks/push-notify.js +2 -2
  236. package/node_modules/@weavecode/server/dist/hooks/question-tracker.js +1 -1
  237. package/node_modules/@weavecode/server/dist/hooks/registry.js +1 -1
  238. package/node_modules/@weavecode/server/dist/hooks/resume-runner.js +1 -1
  239. package/node_modules/@weavecode/server/dist/hooks/session-purge.js +1 -1
  240. package/node_modules/@weavecode/server/dist/hooks/side-questions.js +1 -1
  241. package/node_modules/@weavecode/server/dist/hooks/synthetic-sessions.js +1 -1
  242. package/node_modules/@weavecode/server/dist/hooks/toolkit-scan.js +1 -1
  243. package/node_modules/@weavecode/server/dist/hooks/toolkit.js +5 -5
  244. package/node_modules/@weavecode/server/dist/hooks/watch-engine.js +1 -1
  245. package/node_modules/@weavecode/server/dist/install/apply-update.js +1 -1
  246. package/node_modules/@weavecode/server/dist/install/capabilities.js +1 -1
  247. package/node_modules/@weavecode/server/dist/install/codex-toml.js +1 -1
  248. package/node_modules/@weavecode/server/dist/install/file-assets.js +1 -1
  249. package/node_modules/@weavecode/server/dist/install/fingerprint.js +1 -1
  250. package/node_modules/@weavecode/server/dist/install/global-config.js +1 -1
  251. package/node_modules/@weavecode/server/dist/install/global-file-assets.js +1 -1
  252. package/node_modules/@weavecode/server/dist/install/init-files.js +2 -2
  253. package/node_modules/@weavecode/server/dist/install/install-ledger.js +1 -1
  254. package/node_modules/@weavecode/server/dist/install/installer.js +1 -1
  255. package/node_modules/@weavecode/server/dist/install/library-index.js +1 -1
  256. package/node_modules/@weavecode/server/dist/install/mcp-rows.js +1 -1
  257. package/node_modules/@weavecode/server/dist/install/plugin-install.js +1 -1
  258. package/node_modules/@weavecode/server/dist/install/plugin-rows.js +1 -1
  259. package/node_modules/@weavecode/server/dist/install/plugin-templates.js +1 -1
  260. package/node_modules/@weavecode/server/dist/install/project-config.js +1 -1
  261. package/node_modules/@weavecode/server/dist/install/reader.js +1 -1
  262. package/node_modules/@weavecode/server/dist/install/scan-cache.js +1 -1
  263. package/node_modules/@weavecode/server/dist/install/scanner.js +1 -1
  264. package/node_modules/@weavecode/server/dist/install/settings-mcp.js +2 -2
  265. package/node_modules/@weavecode/server/dist/install/updates.js +1 -1
  266. package/node_modules/@weavecode/server/dist/market/builtin.js +1 -1
  267. package/node_modules/@weavecode/server/dist/market/identity.js +1 -1
  268. package/node_modules/@weavecode/server/dist/market/import.js +2 -2
  269. package/node_modules/@weavecode/server/dist/market/refresh.js +1 -1
  270. package/node_modules/@weavecode/server/dist/market/resolve.js +1 -1
  271. package/node_modules/@weavecode/server/dist/market/updates.js +1 -1
  272. package/node_modules/@weavecode/server/dist/registry.js +2 -2
  273. package/node_modules/@weavecode/server/dist/repositories/hook-dispatches.js +5 -5
  274. package/node_modules/@weavecode/server/dist/repositories/hook-events.d.ts +1 -1
  275. package/node_modules/@weavecode/server/dist/repositories/hook-events.js +5 -5
  276. package/node_modules/@weavecode/server/dist/repositories/hook-rules.js +4 -4
  277. package/node_modules/@weavecode/server/dist/repositories/libraries.js +1 -1
  278. package/node_modules/@weavecode/server/dist/repositories/orchestrations.js +7 -7
  279. package/node_modules/@weavecode/server/dist/repositories/plugin-states.js +1 -1
  280. package/node_modules/@weavecode/server/dist/repositories/projects.js +2 -2
  281. package/node_modules/@weavecode/server/dist/repositories/push-subscriptions.js +2 -2
  282. package/node_modules/@weavecode/server/dist/repositories/session-watches.js +4 -4
  283. package/node_modules/@weavecode/server/dist/repositories/sessions.d.ts +11 -1
  284. package/node_modules/@weavecode/server/dist/repositories/sessions.js +4 -2
  285. package/node_modules/@weavecode/server/dist/repositories/uploads.d.ts +14 -4
  286. package/node_modules/@weavecode/server/dist/repositories/uploads.js +11 -11
  287. package/node_modules/@weavecode/server/dist/statusline/cache-sweeper.js +1 -1
  288. package/node_modules/@weavecode/server/dist/statusline/generator.js +1 -1
  289. package/node_modules/@weavecode/server/dist/statusline/manager.js +3 -3
  290. package/node_modules/@weavecode/server/dist/surfaces.d.ts +3 -1
  291. package/node_modules/@weavecode/server/dist/surfaces.js +1 -1
  292. package/node_modules/@weavecode/server/dist/watch/cache.js +1 -1
  293. package/node_modules/@weavecode/server/dist/watch/classifier.js +1 -1
  294. package/node_modules/@weavecode/server/dist/watch/plugin-mods.js +1 -1
  295. package/node_modules/@weavecode/server/dist/watch/sync-scheduler.js +1 -1
  296. package/node_modules/@weavecode/server/dist/watch/watch-service.js +1 -1
  297. package/node_modules/@weavecode/server/package.json +4 -4
  298. package/node_modules/@weavecode/server/web/dist/assets/{abnfDiagram-WEYOIA3C-DA-K085F.js → abnfDiagram-WEYOIA3C-CbIFQh0R.js} +1 -1
  299. package/node_modules/@weavecode/server/web/dist/assets/{arc-BI1jnmdZ.js → arc-DH8-rYAa.js} +1 -1
  300. package/node_modules/@weavecode/server/web/dist/assets/{architectureDiagram-ZHVYKT53-DbdBgric.js → architectureDiagram-ZHVYKT53-qnv6S0sc.js} +1 -1
  301. package/node_modules/@weavecode/server/web/dist/assets/{blockDiagram-RJAE7QA3-BPRBmzb-.js → blockDiagram-RJAE7QA3-pT5eO-cB.js} +1 -1
  302. package/node_modules/@weavecode/server/web/dist/assets/{c4Diagram-XDPPPE54-C4D5sRs1.js → c4Diagram-XDPPPE54-DHDBDMb1.js} +1 -1
  303. package/node_modules/@weavecode/server/web/dist/assets/channel-BHPeeuzN.js +1 -0
  304. package/node_modules/@weavecode/server/web/dist/assets/{chunk-2E7WHVMD-9ZSKiNU3.js → chunk-2E7WHVMD-CT951PH5.js} +1 -1
  305. package/node_modules/@weavecode/server/web/dist/assets/{chunk-2Q5K7J3B-i0AOjw_8.js → chunk-2Q5K7J3B-E5AD7_ZY.js} +1 -1
  306. package/node_modules/@weavecode/server/web/dist/assets/{chunk-4EMNKR2T-DTpLfX1H.js → chunk-4EMNKR2T-DWz9qkcy.js} +1 -1
  307. package/node_modules/@weavecode/server/web/dist/assets/{chunk-55XCU76K-COQYRD4q.js → chunk-55XCU76K-D-SgWD8w.js} +1 -1
  308. package/node_modules/@weavecode/server/web/dist/assets/{chunk-5VM5RSS4-VsftEbvo.js → chunk-5VM5RSS4-ci6YzbO5.js} +1 -1
  309. package/node_modules/@weavecode/server/web/dist/assets/{chunk-JWPE2WC7-DonektJN.js → chunk-JWPE2WC7-CY4mr2f4.js} +1 -1
  310. package/node_modules/@weavecode/server/web/dist/assets/{chunk-VQ5W62QI-CaKUwuul.js → chunk-VQ5W62QI-CON8zyg8.js} +1 -1
  311. package/node_modules/@weavecode/server/web/dist/assets/{chunk-XXDRQBXY-DXH3D_MT.js → chunk-XXDRQBXY-DXXXZ4pW.js} +1 -1
  312. package/node_modules/@weavecode/server/web/dist/assets/{chunk-ZCHMQSOR-COwyAuGn.js → chunk-ZCHMQSOR-CukvPvkM.js} +2 -2
  313. package/node_modules/@weavecode/server/web/dist/assets/{classDiagram-v2-4MYWR3UA-DEvMZ6mX.js → classDiagram-v2-4MYWR3UA-GiWZ9xtF.js} +1 -1
  314. package/node_modules/@weavecode/server/web/dist/assets/{cose-bilkent-JH36ORCC-6JBJHfH6.js → cose-bilkent-JH36ORCC-D7aJ-akq.js} +1 -1
  315. package/node_modules/@weavecode/server/web/dist/assets/{cynefin-EF2NZ3EQ-C4GM4sjT.js → cynefin-EF2NZ3EQ-9B__MaRM.js} +1 -1
  316. package/node_modules/@weavecode/server/web/dist/assets/{cynefinDiagram-WF24UDRP-Cqgi0MBP.js → cynefinDiagram-WF24UDRP-B2ujZh2k.js} +1 -1
  317. package/node_modules/@weavecode/server/web/dist/assets/{dagre-NK4GIZVX-CljrnkCY.js → dagre-NK4GIZVX-nHaB6IWf.js} +1 -1
  318. package/node_modules/@weavecode/server/web/dist/assets/{diagram-CBK3MWTC-C3PyOj5J.js → diagram-CBK3MWTC-xKfjDvgr.js} +1 -1
  319. package/node_modules/@weavecode/server/web/dist/assets/{diagram-I5XIIV2D-I5brQlaZ.js → diagram-I5XIIV2D-BHT2-5mY.js} +1 -1
  320. package/node_modules/@weavecode/server/web/dist/assets/{diagram-ODIL2UCW-BX9uFNbU.js → diagram-ODIL2UCW-CckywF4W.js} +1 -1
  321. package/node_modules/@weavecode/server/web/dist/assets/{diagram-PFBEJUXE-y7D-VmqJ.js → diagram-PFBEJUXE-Dpjlc7Wh.js} +1 -1
  322. package/node_modules/@weavecode/server/web/dist/assets/{diagram-RJA3I4VV-DLUL8W42.js → diagram-RJA3I4VV-M6WznOaW.js} +1 -1
  323. package/node_modules/@weavecode/server/web/dist/assets/{diagram-TYUNFSNR-DLCC3ILi.js → diagram-TYUNFSNR-DgRJ3zL1.js} +1 -1
  324. package/node_modules/@weavecode/server/web/dist/assets/{ebnfDiagram-V4P3TTPT-D7vALia7.js → ebnfDiagram-V4P3TTPT-BzzVN__a.js} +1 -1
  325. package/node_modules/@weavecode/server/web/dist/assets/{elk-QONTBCTQ-Ct2_hatz.js → elk-QONTBCTQ-Ch6Gs9G9.js} +1 -1
  326. package/node_modules/@weavecode/server/web/dist/assets/{erDiagram-KYQIGQAA-DxLai58T.js → erDiagram-KYQIGQAA-COxT-Pxb.js} +1 -1
  327. package/node_modules/@weavecode/server/web/dist/assets/{flowDiagram-IUGLLWBU-AWn2IHrF.js → flowDiagram-IUGLLWBU-CJVWnTBa.js} +1 -1
  328. package/node_modules/@weavecode/server/web/dist/assets/{ganttDiagram-R7GPNTJY-DmRHd4Wz.js → ganttDiagram-R7GPNTJY-BkRpWPUl.js} +1 -1
  329. package/node_modules/@weavecode/server/web/dist/assets/{gitGraphDiagram-PDYL7XHY-Ccj-t3zg.js → gitGraphDiagram-PDYL7XHY-Ba8BJcvZ.js} +1 -1
  330. package/node_modules/@weavecode/server/web/dist/assets/index-CtifxEiF.css +11 -0
  331. package/node_modules/@weavecode/server/web/dist/assets/index-FwH9INgS.js +1090 -0
  332. package/node_modules/@weavecode/server/web/dist/assets/{infoDiagram-MVDRKAX5-BHquFlQa.js → infoDiagram-MVDRKAX5-HTQ5FUNK.js} +1 -1
  333. package/node_modules/@weavecode/server/web/dist/assets/{ishikawaDiagram-HPEHV2GE-CVogEbdm.js → ishikawaDiagram-HPEHV2GE-BNjEDIZy.js} +1 -1
  334. package/node_modules/@weavecode/server/web/dist/assets/{journeyDiagram-BOSHW7O7-DC9XG9oh.js → journeyDiagram-BOSHW7O7-Cao6h91a.js} +1 -1
  335. package/node_modules/@weavecode/server/web/dist/assets/{kanban-definition-FNSA4HC5-C_eu7DC_.js → kanban-definition-FNSA4HC5-CXIx2CHQ.js} +1 -1
  336. package/node_modules/@weavecode/server/web/dist/assets/{linear-keTbWHJ-.js → linear-65WmlvQb.js} +1 -1
  337. package/node_modules/@weavecode/server/web/dist/assets/{mermaid.core-4sbg0MnY.js → mermaid.core-D39fi_iR.js} +4 -4
  338. package/node_modules/@weavecode/server/web/dist/assets/{mindmap-definition-6OY57UG3-kMQS0S2l.js → mindmap-definition-6OY57UG3-DHqpz_AK.js} +1 -1
  339. package/node_modules/@weavecode/server/web/dist/assets/{pegDiagram-ECIUJNBX-DcUFoEwP.js → pegDiagram-ECIUJNBX-Cpy1nsER.js} +1 -1
  340. package/node_modules/@weavecode/server/web/dist/assets/{pieDiagram-GNMPY74T-BQJ7WDCx.js → pieDiagram-GNMPY74T-B1IyNqzr.js} +1 -1
  341. package/node_modules/@weavecode/server/web/dist/assets/{quadrantDiagram-D57K4MC3-C7Oi1-sq.js → quadrantDiagram-D57K4MC3-zSM6o7mB.js} +1 -1
  342. package/node_modules/@weavecode/server/web/dist/assets/{railroadDiagram-Y72NRBL7-CEF2QbOF.js → railroadDiagram-Y72NRBL7-oM4XJIwA.js} +1 -1
  343. package/node_modules/@weavecode/server/web/dist/assets/{requirementDiagram-EQYSW5RA-CTjjFS7X.js → requirementDiagram-EQYSW5RA-CbCLBjHf.js} +1 -1
  344. package/node_modules/@weavecode/server/web/dist/assets/{sankeyDiagram-SY24JHO5-j0S5kubS.js → sankeyDiagram-SY24JHO5-BucVk6EP.js} +1 -1
  345. package/node_modules/@weavecode/server/web/dist/assets/{sequenceDiagram-BLEHNHQU-B76EsZp4.js → sequenceDiagram-BLEHNHQU-Dg8CYEnT.js} +1 -1
  346. package/node_modules/@weavecode/server/web/dist/assets/{sizeCapture-INFHLROL-r0DZuqAy.js → sizeCapture-INFHLROL-C51zb7Oc.js} +1 -1
  347. package/node_modules/@weavecode/server/web/dist/assets/{stateDiagram-v2-A6IESKWZ-B4DR9LHz.js → stateDiagram-v2-A6IESKWZ-BvK2l3is.js} +1 -1
  348. package/node_modules/@weavecode/server/web/dist/assets/{swimlanes-B3ENRKFQ-Dbcl85ro.js → swimlanes-B3ENRKFQ-Ds7QOfXW.js} +1 -1
  349. package/node_modules/@weavecode/server/web/dist/assets/swimlanesDiagram-AYQRV4AK-ByBF02UJ.js +8 -0
  350. package/node_modules/@weavecode/server/web/dist/assets/{timeline-definition-JXYKGLGB-BlBXXRNf.js → timeline-definition-JXYKGLGB-CadU4Qq4.js} +1 -1
  351. package/node_modules/@weavecode/server/web/dist/assets/{usecaseDiagram-WPOLBNNX-Ck1M0dpc.js → usecaseDiagram-WPOLBNNX-BYuZwTDZ.js} +1 -1
  352. package/node_modules/@weavecode/server/web/dist/assets/{vennDiagram-Q3Y3IDCW-N8B-ohWk.js → vennDiagram-Q3Y3IDCW-C7zgxe07.js} +1 -1
  353. package/node_modules/@weavecode/server/web/dist/assets/{wardleyDiagram-IVAIDKWA-DX-AMXq_.js → wardleyDiagram-IVAIDKWA-DA4Otf4s.js} +1 -1
  354. package/node_modules/@weavecode/server/web/dist/assets/{xychartDiagram-4URNHDU4-4fgL48Yl.js → xychartDiagram-4URNHDU4-Bs5YGwMU.js} +1 -1
  355. package/node_modules/@weavecode/server/web/dist/index.html +2 -2
  356. package/node_modules/@weavecode/server/web/dist/sw.js +14 -12
  357. package/node_modules/@weavecode/templates/package.json +2 -2
  358. package/package.json +6 -6
  359. package/node_modules/@weavecode/server/web/dist/assets/channel-DcCJrvon.js +0 -1
  360. package/node_modules/@weavecode/server/web/dist/assets/index-BSxzia7U.js +0 -1031
  361. package/node_modules/@weavecode/server/web/dist/assets/index-CEpJpR7P.css +0 -11
  362. package/node_modules/@weavecode/server/web/dist/assets/swimlanesDiagram-AYQRV4AK-CZ_6SSBd.js +0 -8
@@ -1,2 +1,2 @@
1
- import s from"node:fs/promises";import f from"node:path";import{randomUUID as I}from"node:crypto";const h=20;function l(t,n){return f.join(t,n)}function S(t,n){return f.join(l(t,n),"profiles.json")}function w(t,n,e,a){return f.join(l(t,n),`${e}-${a}.json`)}function m(t,n){return f.join(l(t,n),"backups")}function $(t,n,e,a){return f.join(m(t,n),`${e}-${a}.json`)}async function y(t){try{const n=JSON.parse(await s.readFile(t,"utf8"));return typeof n=="object"&&n!==null&&!Array.isArray(n)?n:null}catch{return null}}async function x(t,n){await s.mkdir(f.dirname(t),{recursive:!0});const e=`${t}.${process.pid}.${Date.now()}.tmp`;await s.writeFile(e,`${JSON.stringify(n,null,2)}
2
- `,"utf8"),await s.rename(e,t)}async function j(t,n){return await y(S(t,n))??{}}function g(){return{activeId:null,profiles:[]}}function v(t,n){return t[n]??g()}export async function listProfiles(t,n,e){return v(await j(t,n),e)}async function p(t,n,e,a){const r=await j(t,n),c=v(r,e);return a(c),r[e]=c,await x(S(t,n),r),c}function d(){return new Date().toISOString()}export async function writeSnapshot(t,n,e,a,r){await x(w(t,n,e,a),r)}export async function readSnapshot(t,n,e,a){return y(w(t,n,e,a))}export async function createProfile(t,n,e,a,r){const c={id:I().slice(0,8),name:a,createdAt:d(),updatedAt:d()};return await writeSnapshot(t,n,e,c.id,r),await p(t,n,e,i=>{i.profiles.push(c)}),c}export async function saveProfile(t,n,e,a,r){await writeSnapshot(t,n,e,a,r),await p(t,n,e,c=>{const i=c.profiles.find(o=>o.id===a);i&&(i.updatedAt=d())})}export async function renameProfile(t,n,e,a,r){await p(t,n,e,c=>{const i=c.profiles.find(o=>o.id===a);i&&(i.name=r,i.updatedAt=d())})}export async function removeProfile(t,n,e,a){await p(t,n,e,r=>{r.profiles=r.profiles.filter(c=>c.id!==a),r.activeId===a&&(r.activeId=null)}),await s.rm(w(t,n,e,a),{force:!0})}export async function setActive(t,n,e,a){await p(t,n,e,r=>{r.activeId=a})}export const LASTSEEN_ID="_lastseen";export async function baselineSnapshot(t,n,e,a){if(a.activeId){const r=await readSnapshot(t,n,e,a.activeId);if(r)return r}return readSnapshot(t,n,e,LASTSEEN_ID)}export async function syncBaseline(t,n,e,a,r){a.activeId&&await saveProfile(t,n,e,a.activeId,r),await writeSnapshot(t,n,e,LASTSEEN_ID,r)}function A(t){const n=e=>String(e).padStart(2,"0");return`${t.getFullYear()}-${n(t.getMonth()+1)}-${n(t.getDate())}-${n(t.getHours())}${n(t.getMinutes())}${n(t.getSeconds())}`}export async function pushBackup(t,n,e,a){const r=A(new Date),c=new Set((await s.readdir(m(t,n)).catch(()=>[])).filter(u=>u.startsWith(`${e}-${r}`)));let i=r;for(let u=2;c.has(`${e}-${i}.json`);u++)i=`${r}-${u}`;await x($(t,n,e,i),a);const o=(await listBackups(t,n,e)).slice(h);for(const u of o)await s.rm($(t,n,e,u),{force:!0})}export async function listBackups(t,n,e){const a=`${e}-`,r=i=>{const o=/^(\d{4}-\d{2}-\d{2}-\d{6})(?:-(\d+))?$/.exec(i);return o?+`${o[1].replace(/-/g,"")}${o[2]??"1"}`:0};return(await s.readdir(m(t,n)).catch(()=>[])).filter(i=>i.startsWith(a)&&i.endsWith(".json")).map(i=>i.slice(a.length,-5)).sort((i,o)=>r(i)-r(o)).reverse()}export async function readBackup(t,n,e,a){return/^[A-Za-z0-9-]+$/.test(a)?y($(t,n,e,a)):null}
1
+ import c from"node:fs/promises";import u from"node:path";import{randomUUID as S}from"node:crypto";export function profileKeyOf(t,n){return(t==="project"||t==="projectLocal")&&n!==null?`${t}@p${n}`:t}const g=20;function d(t,n){return u.join(t,n)}function h(t,n){return u.join(d(t,n),"profiles.json")}function w(t,n,e,a){return u.join(d(t,n),`${e}-${a}.json`)}function $(t,n){return u.join(d(t,n),"backups")}function y(t,n,e,a){return u.join($(t,n),`${e}-${a}.json`)}async function m(t){try{const n=JSON.parse(await c.readFile(t,"utf8"));return typeof n=="object"&&n!==null&&!Array.isArray(n)?n:null}catch{return null}}async function x(t,n){await c.mkdir(u.dirname(t),{recursive:!0});const e=`${t}.${process.pid}.${Date.now()}.tmp`;await c.writeFile(e,`${JSON.stringify(n,null,2)}
2
+ `,"utf8"),await c.rename(e,t)}async function j(t,n){return await m(h(t,n))??{}}function I(){return{activeId:null,profiles:[]}}function v(t,n){return t[n]??I()}export async function listProfiles(t,n,e){return v(await j(t,n),e)}async function l(t,n,e,a){const i=await j(t,n),r=v(i,e);return a(r),i[e]=r,await x(h(t,n),i),r}function p(){return new Date().toISOString()}export async function writeSnapshot(t,n,e,a,i){await x(w(t,n,e,a),i)}export async function readSnapshot(t,n,e,a){return m(w(t,n,e,a))}export async function createProfile(t,n,e,a,i){const r={id:S().slice(0,8),name:a,createdAt:p(),updatedAt:p()};return await writeSnapshot(t,n,e,r.id,i),await l(t,n,e,o=>{o.profiles.push(r)}),r}export async function saveProfile(t,n,e,a,i){await writeSnapshot(t,n,e,a,i),await l(t,n,e,r=>{const o=r.profiles.find(f=>f.id===a);o&&(o.updatedAt=p())})}export async function renameProfile(t,n,e,a,i){await l(t,n,e,r=>{const o=r.profiles.find(f=>f.id===a);o&&(o.name=i,o.updatedAt=p())})}export async function removeProfile(t,n,e,a){await l(t,n,e,i=>{i.profiles=i.profiles.filter(r=>r.id!==a),i.activeId===a&&(i.activeId=null)}),await c.rm(w(t,n,e,a),{force:!0})}export async function setActive(t,n,e,a){await l(t,n,e,i=>{i.activeId=a})}export const LASTSEEN_ID="_lastseen";export async function baselineSnapshot(t,n,e,a){if(a.activeId){const i=await readSnapshot(t,n,e,a.activeId);if(i)return i}return readSnapshot(t,n,e,LASTSEEN_ID)}export async function syncBaseline(t,n,e,a,i){a.activeId&&await saveProfile(t,n,e,a.activeId,i),await writeSnapshot(t,n,e,LASTSEEN_ID,i)}function A(t){const n=e=>String(e).padStart(2,"0");return`${t.getFullYear()}-${n(t.getMonth()+1)}-${n(t.getDate())}-${n(t.getHours())}${n(t.getMinutes())}${n(t.getSeconds())}`}export async function pushBackup(t,n,e,a){const i=A(new Date),r=new Set((await c.readdir($(t,n)).catch(()=>[])).filter(s=>s.startsWith(`${e}-${i}`)));let o=i;for(let s=2;r.has(`${e}-${o}.json`);s++)o=`${i}-${s}`;await x(y(t,n,e,o),a);const f=(await listBackups(t,n,e)).slice(g);for(const s of f)await c.rm(y(t,n,e,s),{force:!0})}export async function listBackups(t,n,e){const a=`${e}-`,i=r=>{const o=/^(\d{4}-\d{2}-\d{2}-\d{6})(?:-(\d+))?$/.exec(r);return o?+`${o[1].replace(/-/g,"")}${o[2]??"1"}`:0};return(await c.readdir($(t,n)).catch(()=>[])).filter(r=>r.startsWith(a)&&r.endsWith(".json")).map(r=>r.slice(a.length,-5)).sort((r,o)=>i(r)-i(o)).reverse()}export async function readBackup(t,n,e,a){return/^[A-Za-z0-9-]+$/.test(a)?m(y(t,n,e,a)):null}
@@ -1,2 +1,2 @@
1
- import{chmodSync as o,existsSync as c,mkdirSync as i,readFileSync as u,renameSync as y,rmSync as m,writeFileSync as p}from"node:fs";import a from"node:path";import{getAiKeyPath as n}from"../db/paths.js";export function readAiKey(t=n()){if(!c(t))return null;try{const r=JSON.parse(u(t,"utf8"));return typeof r.apiKey=="string"&&r.apiKey!==""?r.apiKey:null}catch{return null}}export function writeAiKey(t,r=n()){if(t===null||t===""){m(r,{force:!0});return}i(a.dirname(r),{recursive:!0});const e=`${r}.tmp`;p(e,`${JSON.stringify({apiKey:t},null,2)}
2
- `,{encoding:"utf8",mode:384}),y(e,r);try{o(r,384)}catch{}}export function hasAiKey(t=n()){return readAiKey(t)!==null}
1
+ import{chmodSync as t,existsSync as a,mkdirSync as c,readFileSync as o,renameSync as y,rmSync as u,writeFileSync as s}from"node:fs";import l from"node:path";import{getAiKeyPath as r}from"../db/paths.js";export function readAiKey(n=r()){if(!a(n))return null;try{const e=JSON.parse(o(n,"utf8"));return typeof e.apiKey=="string"&&e.apiKey!==""?e.apiKey:null}catch{return null}}export function writeAiKey(n,e=r()){if(n===null||n===""){u(e,{force:!0});return}c(l.dirname(e),{recursive:!0});const i=`${e}.tmp`;s(i,`${JSON.stringify({apiKey:n},null,2)}
2
+ `,{encoding:"utf8",mode:384}),y(i,e);try{t(e,384)}catch{}}export function hasAiKey(n=r()){return readAiKey(n)!==null}
@@ -1,10 +1,10 @@
1
- import{existsSync as d,readdirSync as h,readFileSync as S}from"node:fs";import i from"node:path";import{builtinMarketDir as b}from"../market/builtin.js";const p=6e4,w=40,y=6;export function findDocsDir(r){let e=i.resolve(r);for(let n=0;n<y;n++){const s=i.join(e,"docs");if(d(i.join(s,"FEATURES.md")))return s;const c=i.dirname(e);if(c===e)break;e=c}return null}export function collectSkillFiles(r,e=w){const n=[],s=(c,a)=>{if(n.length>=e||a>6)return;let u;try{u=h(c,{withFileTypes:!0})}catch{return}for(const l of u){if(n.length>=e)return;const t=i.join(c,l.name);l.isDirectory()?s(t,a+1):l.name==="SKILL.md"&&n.push(t)}};return s(r,0),n.sort()}function m(r){try{return S(r,"utf8")}catch{return null}}export function buildSystemPrompt(r){const e=[],n=findDocsDir(r.cwd??process.cwd());if(n)for(const t of["ARCHITECTURE.md","FEATURES.md"]){const o=i.join(n,t);if(!d(o))continue;const f=m(o);f&&e.push({label:`docs/${t}`,text:f})}const s=b(r.dataRoot);for(const t of collectSkillFiles(s)){const o=m(t);o&&e.push({label:i.relative(s,t).split(i.sep).join("/"),text:o})}const c=["\u4F60\u662F weave \u63A7\u5236\u53F0\u5185\u7F6E\u7684 AI \u52A9\u624B\uFF0C**\u53EA\u8D1F\u8D23 weave \u672C\u8EAB**\uFF1A\u5B83\u7684\u529F\u80FD\u3001\u7528\u6CD5\u3001\u914D\u7F6E\u3001\u67B6\u6784\u3001","\u5185\u7F6E\u6280\u80FD\uFF0C\u4EE5\u53CA\u57FA\u4E8E\u4E0B\u9762\u6CE8\u5165\u8D44\u6599\u7684\u6392\u969C\u3002","","\u56DE\u7B54\u8303\u56F4\uFF08\u8D8A\u754C\u7684\u60C5\u51B5\u4E00\u5F8B\u793C\u8C8C\u62D2\u7B54\uFF1A\u7528\u4E00\u53E5\u8BDD\u8BF4\u660E\u4F60\u53EA\u804A weave\uFF0C\u7136\u540E\u628A\u8BDD\u9898\u5F15\u56DE weave\uFF09\uFF1A","- \u53EF\u4EE5\u7B54\uFF1Aweave \u7684\u80FD\u529B\u4E0E\u64CD\u4F5C\uFF08\u547D\u4EE4\u3001\u8BBE\u7F6E\u9879\u3001\u6587\u4EF6\u843D\u70B9\u3001\u63D2\u4EF6/\u6280\u80FD/\u5E02\u573A\u3001hooks\u3001\u4F1A\u8BDD\u4E0E\u4EFB\u52A1\u3001\u8BA4\u8BC1\u7B49\uFF09\uFF0C"," \u4EE5\u53CA\u6CE8\u5165\u8D44\u6599\u91CC\u80FD\u67E5\u5230\u7684\u4E8B\u5B9E\uFF1B","- \u4E0D\u8981\u7B54\uFF1A\u4E0E weave \u65E0\u5173\u7684\u901A\u7528\u7F16\u7A0B\u3001\u5199\u4F5C\u3001\u7FFB\u8BD1\u3001\u95F2\u804A\uFF0C\u5176\u5B83\u4EA7\u54C1\u6216\u670D\u52A1\uFF0C\u4EE5\u53CA\u4EFB\u4F55\u6709\u5BB3\u6216\u8D8A\u754C\u7684\u8BF7\u6C42\uFF1B","- \u8D44\u6599\u672A\u8986\u76D6\u65F6\u660E\u786E\u8BF4\u300C\u4E0D\u786E\u5B9A\u300D\uFF0C\u4E0D\u8981\u7F16\u9020 weave \u7684\u884C\u4E3A\u3001\u547D\u4EE4\u6216\u53C2\u6570\uFF1B","- \u4E0D\u7C98\u8D34\u5927\u6BB5\u6CE8\u5165\u8D44\u6599\u539F\u6587\uFF08\u7528\u6237\u70B9\u540D\u8981\u67D0\u4E00\u6BB5\u65F6\u9664\u5916\uFF09\uFF1B","- \u53EA\u505A\u53EA\u8BFB\u95EE\u7B54\uFF1A\u4E0D\u58F0\u79F0\u5DF2\u6267\u884C\u4EFB\u4F55\u64CD\u4F5C\uFF0C\u4E5F\u4E0D\u627F\u8BFA\u4EE3\u66FF\u7528\u6237\u53BB\u6539\u6587\u4EF6\u6216\u8DD1\u547D\u4EE4\u3002","","\u56DE\u7B54\u4F7F\u7528\u4E0E\u63D0\u95EE\u76F8\u540C\u7684\u8BED\u8A00\uFF1B\u6D89\u53CA\u64CD\u4F5C\u65F6\u7ED9\u51FA\u786E\u5207\u547D\u4EE4\u4E0E\u8DEF\u5F84\u3002"].join(`
2
- `),a=[];let u=c.length;const l=[];for(const t of e){const o=`
1
+ import{existsSync as C,readdirSync as i,readFileSync as a}from"node:fs";import D from"node:path";import{builtinMarketDir as f}from"../market/builtin.js";const l=6e4,p=40,d=6;export function findDocsDir(e){let F=D.resolve(e);for(let E=0;E<d;E++){const o=D.join(F,"docs");if(C(D.join(o,"FEATURES.md")))return o;const n=D.dirname(F);if(n===F)break;F=n}return null}export function collectSkillFiles(e,F=p){const E=[],o=(n,s)=>{if(E.length>=F||s>6)return;let r;try{r=i(n,{withFileTypes:!0})}catch{return}for(const B of r){if(E.length>=F)return;const u=D.join(n,B.name);B.isDirectory()?o(u,s+1):B.name==="SKILL.md"&&E.push(u)}};return o(e,0),E.sort()}function c(e){try{return a(e,"utf8")}catch{return null}}export function buildSystemPrompt(e){const F=[],E=findDocsDir(e.cwd??process.cwd());if(E)for(const u of["ARCHITECTURE.md","FEATURES.md"]){const t=D.join(E,u);if(!C(t))continue;const A=c(t);A&&F.push({label:`docs/${u}`,text:A})}const o=f(e.dataRoot);for(const u of collectSkillFiles(o)){const t=c(u);t&&F.push({label:D.relative(o,u).split(D.sep).join("/"),text:t})}const n=["\u4F60\u662F weave \u63A7\u5236\u53F0\u5185\u7F6E\u7684 AI \u52A9\u624B\uFF0C**\u53EA\u8D1F\u8D23 weave \u672C\u8EAB**\uFF1A\u5B83\u7684\u529F\u80FD\u3001\u7528\u6CD5\u3001\u914D\u7F6E\u3001\u67B6\u6784\u3001","\u5185\u7F6E\u6280\u80FD\uFF0C\u4EE5\u53CA\u57FA\u4E8E\u4E0B\u9762\u6CE8\u5165\u8D44\u6599\u7684\u6392\u969C\u3002","","\u56DE\u7B54\u8303\u56F4\uFF08\u8D8A\u754C\u7684\u60C5\u51B5\u4E00\u5F8B\u793C\u8C8C\u62D2\u7B54\uFF1A\u7528\u4E00\u53E5\u8BDD\u8BF4\u660E\u4F60\u53EA\u804A weave\uFF0C\u7136\u540E\u628A\u8BDD\u9898\u5F15\u56DE weave\uFF09\uFF1A","- \u53EF\u4EE5\u7B54\uFF1Aweave \u7684\u80FD\u529B\u4E0E\u64CD\u4F5C\uFF08\u547D\u4EE4\u3001\u8BBE\u7F6E\u9879\u3001\u6587\u4EF6\u843D\u70B9\u3001\u63D2\u4EF6/\u6280\u80FD/\u5E02\u573A\u3001hooks\u3001\u4F1A\u8BDD\u4E0E\u4EFB\u52A1\u3001\u8BA4\u8BC1\u7B49\uFF09\uFF0C"," \u4EE5\u53CA\u6CE8\u5165\u8D44\u6599\u91CC\u80FD\u67E5\u5230\u7684\u4E8B\u5B9E\uFF1B","- \u4E0D\u8981\u7B54\uFF1A\u4E0E weave \u65E0\u5173\u7684\u901A\u7528\u7F16\u7A0B\u3001\u5199\u4F5C\u3001\u7FFB\u8BD1\u3001\u95F2\u804A\uFF0C\u5176\u5B83\u4EA7\u54C1\u6216\u670D\u52A1\uFF0C\u4EE5\u53CA\u4EFB\u4F55\u6709\u5BB3\u6216\u8D8A\u754C\u7684\u8BF7\u6C42\uFF1B","- \u8D44\u6599\u672A\u8986\u76D6\u65F6\u660E\u786E\u8BF4\u300C\u4E0D\u786E\u5B9A\u300D\uFF0C\u4E0D\u8981\u7F16\u9020 weave \u7684\u884C\u4E3A\u3001\u547D\u4EE4\u6216\u53C2\u6570\uFF1B","- \u4E0D\u7C98\u8D34\u5927\u6BB5\u6CE8\u5165\u8D44\u6599\u539F\u6587\uFF08\u7528\u6237\u70B9\u540D\u8981\u67D0\u4E00\u6BB5\u65F6\u9664\u5916\uFF09\uFF1B","- \u53EA\u505A\u53EA\u8BFB\u95EE\u7B54\uFF1A\u4E0D\u58F0\u79F0\u5DF2\u6267\u884C\u4EFB\u4F55\u64CD\u4F5C\uFF0C\u4E5F\u4E0D\u627F\u8BFA\u4EE3\u66FF\u7528\u6237\u53BB\u6539\u6587\u4EF6\u6216\u8DD1\u547D\u4EE4\u3002","","\u56DE\u7B54\u4F7F\u7528\u4E0E\u63D0\u95EE\u76F8\u540C\u7684\u8BED\u8A00\uFF1B\u6D89\u53CA\u64CD\u4F5C\u65F6\u7ED9\u51FA\u786E\u5207\u547D\u4EE4\u4E0E\u8DEF\u5F84\u3002"].join(`
2
+ `),s=[];let r=n.length;const B=[];for(const u of F){const t=`
3
3
 
4
- ## \u6CE8\u5165\u8D44\u6599\uFF1A${t.label}
4
+ ## \u6CE8\u5165\u8D44\u6599\uFF1A${u.label}
5
5
 
6
- ${t.text}`;if(u+o.length>p){const f=p-u;f>500&&(a.push(`
6
+ ${u.text}`;if(r+t.length>l){const A=l-r;A>500&&(s.push(`
7
7
 
8
- ## \u6CE8\u5165\u8D44\u6599\uFF1A${t.label}\uFF08\u6309\u9884\u7B97\u622A\u65AD\uFF09
8
+ ## \u6CE8\u5165\u8D44\u6599\uFF1A${u.label}\uFF08\u6309\u9884\u7B97\u622A\u65AD\uFF09
9
9
 
10
- ${t.text.slice(0,f)}`),l.push(`${t.label}(\u622A\u65AD)`));break}u+=o.length,a.push(o),l.push(t.label)}return{prompt:c+a.join(""),labels:l,docsFound:n!==null}}
10
+ ${u.text.slice(0,A)}`),B.push(`${u.label}(\u622A\u65AD)`));break}r+=t.length,s.push(t),B.push(u.label)}return{prompt:n+s.join(""),labels:B,docsFound:E!==null}}
@@ -1,6 +1,6 @@
1
- import{getDataRoot as I}from"../db/paths.js";import{DEFAULT_AI_SETTINGS as v,readDaemonSettings as N}from"./settings.js";import{hasAiKey as J,readAiKey as O}from"./ai-config.js";import{buildSystemPrompt as P,findDocsDir as R}from"./ai-context.js";import{readJson as k,sendJson as f}from"./http.js";const j=12e4,z=15e3,C=500,G=40,L=2e4;export function normalizeMessages(r){if(!Array.isArray(r)||r.length===0||r.length>G)return null;const e=[];for(const t of r){const o=t;if(o?.role!=="user"&&o?.role!=="assistant")return null;const a=o.content;if(typeof a!="string"||a===""||a.length>L)return null;e.push({role:o.role,content:a})}return e}export function aiConfigured(r,e,t){return r!==""&&e!==""&&t}export async function handleAiRoutes(r,e,t,o){if(o!=="/ai"&&!o.startsWith("/ai/"))return!1;const n=(await N()).ai??v,p=J(t.aiKeyPath);if(o==="/ai/status"&&r.method==="GET")return f(e,200,{configured:aiConfigured(n.baseUrl,n.model,p),baseUrl:n.baseUrl,model:n.model,apiKeySet:p,docsFound:R(process.cwd())!==null}),!0;if(o==="/ai/models"&&r.method==="POST"){let i;try{i=await k(r)}catch{return f(e,400,{error:"Invalid JSON body"}),!0}const u=typeof i.baseUrl=="string"&&i.baseUrl.trim()!==""?i.baseUrl.trim():n.baseUrl,m=typeof i.apiKey=="string"&&i.apiKey!==""?i.apiKey:O(t.aiKeyPath);if(u===""||m===null)return f(e,409,{error:"AI assistant is not configured"}),!0;const l=await B(u,m);return l.ok?(f(e,200,{models:l.models}),!0):(f(e,502,{error:l.error}),!0)}if(o==="/ai/chat"&&r.method==="POST"){const i=O(t.aiKeyPath);if(!aiConfigured(n.baseUrl,n.model,p)||i===null)return f(e,409,{error:"AI assistant is not configured"}),!0;let u;try{u=await k(r)}catch{return f(e,400,{error:"Invalid JSON body"}),!0}const m=normalizeMessages(u.messages);if(!m)return f(e,400,{error:"Invalid messages"}),!0;const l=P({dataRoot:t.libraries?.dataRoot??I()});return await X({req:r,res:e,baseUrl:n.baseUrl,model:n.model,apiKey:i,messages:m,system:l.prompt}),!0}return f(e,404,{error:"Not found"}),!0}function A(r){const t=r?.choices?.[0],o=t?.delta?.content??t?.message?.content;return typeof o=="string"&&o!==""?o:null}export const STREAM_MEMO_TTL_MS=1440*60*1e3;const S=new Map;export function streamMemoKey(r,e){return`${r}#${e}`}export function streamSupported(r,e=Date.now()){const t=S.get(r);return!t||e-t.checkedAt>STREAM_MEMO_TTL_MS?!0:t.streaming}export function rememberStreamSupport(r,e,t=Date.now()){const o=S.get(r);o!==void 0&&o.streaming!==e&&console.log(`[weave] ai gateway ${e?"supports":"rejects"} streaming: ${r}`),S.set(r,{streaming:e,checkedAt:t})}export function resetStreamMemory(){S.clear()}async function B(r,e){try{const t=await fetch(`${r.replace(/\/+$/,"")}/models`,{headers:{authorization:`Bearer ${e}`},signal:AbortSignal.timeout(z)});if(!t.ok){const n=await t.text().catch(()=>"");return{ok:!1,error:`upstream ${t.status}${n?`: ${n.slice(0,200)}`:""}`}}const o=await t.json().catch(()=>null),a=[...new Set((o?.data??[]).map(n=>n?.id).filter(n=>typeof n=="string"&&n!==""))].sort();return a.length===0?{ok:!1,error:"upstream returned no models"}:{ok:!0,models:a.slice(0,C)}}catch(t){return{ok:!1,error:t instanceof Error?t.message:String(t)}}}async function E(r){try{const e=await fetch(r.url,{method:"POST",headers:{"content-type":"application/json",authorization:`Bearer ${r.apiKey}`},body:JSON.stringify({model:r.model,stream:!1,messages:r.messages}),signal:r.signal});if(!e.ok){const o=await e.text().catch(()=>"");return{ok:!1,error:`upstream ${e.status}${o?`: ${o.slice(0,300)}`:""}`}}const t=A(await e.json().catch(()=>null));return t===null?{ok:!1,error:"upstream returned no content"}:{ok:!0,content:t}}catch(e){return{ok:!1,error:e instanceof Error?e.message:String(e)}}}async function X(r){const{req:e,res:t,baseUrl:o,model:a,apiKey:n,messages:p,system:i}=r,u=`${o.replace(/\/+$/,"")}/chat/completions`,m=[{role:"system",content:i},...p],l=new AbortController,_=setTimeout(()=>l.abort(),j);e.on("close",()=>l.abort()),t.writeHead(200,{"content-type":"text/event-stream","cache-control":"no-cache",connection:"keep-alive","x-accel-buffering":"no"});let b=!1;const d=s=>{if(!b)try{t.write(`data: ${JSON.stringify(s)}
1
+ import{getDataRoot as J}from"../db/paths.js";import{DEFAULT_AI_SETTINGS as M,readDaemonSettings as P}from"./settings.js";import{hasAiKey as I,readAiKey as T}from"./ai-config.js";import{buildSystemPrompt as j,findDocsDir as R}from"./ai-context.js";import{readJson as O,sendJson as u}from"./http.js";const _=12e4,z=15e3,B=500,C=40,G=2e4;export function normalizeMessages(r){if(!Array.isArray(r)||r.length===0||r.length>C)return null;const t=[];for(const e of r){const n=e;if(n?.role!=="user"&&n?.role!=="assistant")return null;const o=n.content;if(typeof o!="string"||o===""||o.length>G)return null;t.push({role:n.role,content:o})}return t}export function aiConfigured(r,t,e){return r!==""&&t!==""&&e}export async function handleAiRoutes(r,t,e,n){if(n!=="/ai"&&!n.startsWith("/ai/"))return!1;const o=(await P()).ai??M,a=I(e.aiKeyPath);if(n==="/ai/status"&&r.method==="GET")return u(t,200,{configured:aiConfigured(o.baseUrl,o.model,a),baseUrl:o.baseUrl,model:o.model,apiKeySet:a,docsFound:R(process.cwd())!==null}),!0;if(n==="/ai/models"&&r.method==="POST"){let i;try{i=await O(r)}catch{return u(t,400,{error:"Invalid JSON body"}),!0}const d=typeof i.baseUrl=="string"&&i.baseUrl.trim()!==""?i.baseUrl.trim():o.baseUrl,l=typeof i.apiKey=="string"&&i.apiKey!==""?i.apiKey:T(e.aiKeyPath);if(d===""||l===null)return u(t,409,{error:"AI assistant is not configured"}),!0;const m=await L(d,l);return m.ok?(u(t,200,{models:m.models}),!0):(u(t,502,{error:m.error}),!0)}if(n==="/ai/chat"&&r.method==="POST"){const i=T(e.aiKeyPath);if(!aiConfigured(o.baseUrl,o.model,a)||i===null)return u(t,409,{error:"AI assistant is not configured"}),!0;let d;try{d=await O(r)}catch{return u(t,400,{error:"Invalid JSON body"}),!0}const l=normalizeMessages(d.messages);if(!l)return u(t,400,{error:"Invalid messages"}),!0;const m=j({dataRoot:e.libraries?.dataRoot??J()});return await q({req:r,res:t,baseUrl:o.baseUrl,model:o.model,apiKey:i,messages:l,system:m.prompt}),!0}return u(t,404,{error:"Not found"}),!0}function $(r){const t=r?.choices?.[0],e=t?.delta?.content??t?.message?.content;return typeof e=="string"&&e!==""?e:null}export const STREAM_MEMO_TTL_MS=1440*60*1e3;const w=new Map;export function streamMemoKey(r,t){return`${r}#${t}`}export function streamSupported(r,t=Date.now()){const e=w.get(r);return!e||t-e.checkedAt>STREAM_MEMO_TTL_MS?!0:e.streaming}export function rememberStreamSupport(r,t,e=Date.now()){const n=w.get(r);n!==void 0&&n.streaming!==t&&console.log(`[weave] ai gateway ${t?"supports":"rejects"} streaming: ${r}`),w.set(r,{streaming:t,checkedAt:e})}export function resetStreamMemory(){w.clear()}async function L(r,t){try{const e=await fetch(`${r.replace(/\/+$/,"")}/models`,{headers:{authorization:`Bearer ${t}`},signal:AbortSignal.timeout(z)});if(!e.ok){const a=await e.text().catch(()=>"");return{ok:!1,error:`upstream ${e.status}${a?`: ${a.slice(0,200)}`:""}`}}const n=await e.json().catch(()=>null),o=[...new Set((n?.data??[]).map(a=>a?.id).filter(a=>typeof a=="string"&&a!==""))].sort();return o.length===0?{ok:!1,error:"upstream returned no models"}:{ok:!0,models:o.slice(0,B)}}catch(e){return{ok:!1,error:e instanceof Error?e.message:String(e)}}}async function U(r){try{const t=await fetch(r.url,{method:"POST",headers:{"content-type":"application/json",authorization:`Bearer ${r.apiKey}`},body:JSON.stringify({model:r.model,stream:!1,messages:r.messages}),signal:r.signal});if(!t.ok){const n=await t.text().catch(()=>"");return{ok:!1,error:`upstream ${t.status}${n?`: ${n.slice(0,300)}`:""}`}}const e=$(await t.json().catch(()=>null));return e===null?{ok:!1,error:"upstream returned no content"}:{ok:!0,content:e}}catch(t){return{ok:!1,error:t instanceof Error?t.message:String(t)}}}async function q(r){const{req:t,res:e,baseUrl:n,model:o,apiKey:a,messages:i,system:d}=r,l=`${n.replace(/\/+$/,"")}/chat/completions`,m=[{role:"system",content:d},...i],g=new AbortController,v=setTimeout(()=>g.abort(),_);t.on("close",()=>g.abort()),e.writeHead(200,{"content-type":"text/event-stream","cache-control":"no-cache",connection:"keep-alive","x-accel-buffering":"no"});let b=!1;const f=s=>{if(!b)try{e.write(`data: ${JSON.stringify(s)}
2
2
 
3
- `)}catch{}},K=()=>{if(!b){b=!0;try{t.write(`data: {"done":true}
3
+ `)}catch{}},D=()=>{if(!b){b=!0;try{e.write(`data: {"done":true}
4
4
 
5
- `),t.end()}catch{}}},g=streamMemoKey(u,a),M={url:u,apiKey:n,model:a,messages:m,signal:l.signal};try{if(!streamSupported(g)){const c=await E(M);c.ok?d({delta:c.content}):d({error:c.error});return}const s=await fetch(u,{method:"POST",headers:{"content-type":"application/json",authorization:`Bearer ${n}`},body:JSON.stringify({model:a,stream:!0,messages:m}),signal:l.signal});if(!s.ok||!s.body){const c=await s.text().catch(()=>""),h=await E(M);h.ok?(rememberStreamSupport(g,!1),d({delta:h.content})):d({error:`upstream ${s.status}${c?`: ${c.slice(0,300)}`:""}`});return}if(!(s.headers.get("content-type")??"").includes("text/event-stream")){const c=A(await s.json().catch(()=>null));rememberStreamSupport(g,!1),d(c===null?{error:"upstream returned no content"}:{delta:c});return}rememberStreamSupport(g,!0);const U=s.body.getReader(),D=new TextDecoder;let y="";for(;;){const{done:c,value:h}=await U.read();if(c)break;y+=D.decode(h,{stream:!0});let w;for(;(w=y.indexOf(`
6
- `))>=0;){const $=y.slice(0,w).trim();if(y=y.slice(w+1),!$.startsWith("data:"))continue;const T=$.slice(5).trim();if(T==="[DONE]")return;try{const x=A(JSON.parse(T));x!==null&&d({delta:x})}catch{}}}}catch(s){d({error:s instanceof Error?s.message:String(s)})}finally{clearTimeout(_),K()}}
5
+ `),e.end()}catch{}}},y=streamMemoKey(l,o),k={url:l,apiKey:a,model:o,messages:m,signal:g.signal};try{if(!streamSupported(y)){const c=await U(k);c.ok?f({delta:c.content}):f({error:c.error});return}const s=await fetch(l,{method:"POST",headers:{"content-type":"application/json",authorization:`Bearer ${a}`},body:JSON.stringify({model:o,stream:!0,messages:m}),signal:g.signal});if(!s.ok||!s.body){const c=await s.text().catch(()=>""),h=await U(k);h.ok?(rememberStreamSupport(y,!1),f({delta:h.content})):f({error:`upstream ${s.status}${c?`: ${c.slice(0,300)}`:""}`});return}if(!(s.headers.get("content-type")??"").includes("text/event-stream")){const c=$(await s.json().catch(()=>null));rememberStreamSupport(y,!1),f(c===null?{error:"upstream returned no content"}:{delta:c});return}rememberStreamSupport(y,!0);const E=s.body.getReader(),N=new TextDecoder;let p="";for(;;){const{done:c,value:h}=await E.read();if(c)break;p+=N.decode(h,{stream:!0});let S;for(;(S=p.indexOf(`
6
+ `))>=0;){const x=p.slice(0,S).trim();if(p=p.slice(S+1),!x.startsWith("data:"))continue;const A=x.slice(5).trim();if(A==="[DONE]")return;try{const K=$(JSON.parse(A));K!==null&&f({delta:K})}catch{}}}}catch(s){f({error:s instanceof Error?s.message:String(s)})}finally{clearTimeout(v),D()}}
@@ -1,3 +1,3 @@
1
- import{appendFile as F,mkdir as L,readdir as T,readFile as N,rm as j}from"node:fs/promises";import g from"node:path";import{getApiLogsDir as x}from"../db/paths.js";const w=8*1024,C=2e3,b=50,D=6;export const MAX_LOG_FILES=24;const I=200,O=1e3,H=new Set(["password","apikey","token","secret","authorization","cookie","x-weave-local"]);function y(n,t=0){if(typeof n=="string")return n.length>C?`[truncated ${n.length} chars]`:n;if(Array.isArray(n)){if(t>=D)return"[depth-limited]";const e=n.slice(0,b).map(i=>y(i,t+1));return n.length>b&&e.push(`[truncated ${n.length-b} items]`),e}if(n&&typeof n=="object"){if(t>=D)return"[depth-limited]";const e={};for(const[i,a]of Object.entries(n))e[i]=H.has(i.toLowerCase())?"[redacted]":y(a,t+1);return e}return n}function M(n,t){if(t>w)return`[truncated body ${t} bytes]`;try{return y(JSON.parse(n))}catch{return y(n)}}export function maskPath(n){return n.replace(/^(\/webhooks\/orchestrate\/)[^?]+/,"$1[redacted]")}export function logFileFor(n,t){const e=a=>String(a).padStart(2,"0"),i=`${t.getFullYear()}-${e(t.getMonth()+1)}-${e(t.getDate())}T${e(t.getHours())}`;return g.join(n,`api-${i}.jsonl`)}function _(n){const t=g.basename(n).match(/^api-(\d{4}-\d{2}-\d{2}T\d{2})\.jsonl$/);return t?t[1]:null}const $=new WeakMap;export function noteRequestBody(n,t){$.get(n)?.(t)}export class ApiLogger{dir;chain=Promise.resolve();constructor(t={}){this.dir=t.dir??x()}begin(t,e){const i=Date.now(),a=[];let u=0,c=0,d="",h=0,l=!1;$.set(t,r=>{d=r,h=Buffer.byteLength(r,"utf8")});const f=r=>{const o=Buffer.isBuffer(r)?r:Buffer.from(typeof r=="string"?r:String(r??""),"utf8");if(c+=o.length,u<w){const s=o.subarray(0,w-u);a.push(s),u+=s.length}},m=e.write.bind(e),E=e.end.bind(e);let A="";const B=e.writeHead.bind(e);e.writeHead=((...r)=>{const o=r[1];if(o&&typeof o=="object"&&!Array.isArray(o)){const s=o,p=s["content-type"]??s["Content-Type"];typeof p=="string"&&(A=p)}return B(...r)}),e.write=((r,...o)=>(f(r),m(r,...o))),e.end=((r,...o)=>(typeof r!="function"&&r!=null&&f(r),E(r,...o)));const S=()=>{if(l)return;l=!0;const o=(String(e.getHeader("content-type")??"")||A).includes("event-stream"),s={ts:new Date(i).toISOString(),method:t.method??"GET",path:maskPath(t.url??"/"),status:e.statusCode,durationMs:Date.now()-i,ip:(t.socket?.remoteAddress??"").replace(/^::ffff:/,""),resBytes:c},p=t.headers["user-agent"];typeof p=="string"&&p&&(s.ua=p.slice(0,120)),h&&(s.req=M(d,h)),o?s.stream=!0:c&&(s.res=M(Buffer.concat(a).toString("utf8"),c)),e.writableEnded||(s.aborted=!0),this.write(logFileFor(this.dir,new Date(i)),`${JSON.stringify(s)}
2
- `)};e.on("finish",S),e.on("close",S)}write(t,e){this.chain=this.chain.then(async()=>{try{await L(this.dir,{recursive:!0}),await F(t,e,"utf8"),await this.purge()}catch{}})}async purge(){const t=(await T(this.dir)).filter(e=>_(e)!=null);if(!(t.length<=MAX_LOG_FILES)){t.sort();for(const e of t.slice(0,t.length-MAX_LOG_FILES))await j(g.join(this.dir,e),{force:!0})}}onIdle(){return this.chain}async query(t){const e=(await T(this.dir).catch(()=>[])).filter(d=>_(d)!=null).sort().reverse(),i=Math.min(Math.max(t.limit??I,1),O),a=t.from?Date.parse(t.from):NaN,u=t.to?Date.parse(t.to):NaN,c=[];for(const d of e){if(c.length>=i)break;const h=await N(g.join(this.dir,d),"utf8").catch(()=>"");for(const l of h.split(`
3
- `).reverse()){if(!l.trim())continue;let f;try{f=JSON.parse(l)}catch{continue}const m=Date.parse(f.ts);if(!(Number.isFinite(a)&&m<a)&&!(Number.isFinite(u)&&m>u)&&!(t.status!=null&&f.status!==t.status)&&!(t.method&&f.method.toUpperCase()!==t.method.toUpperCase())&&!(t.path&&!f.path.includes(t.path))&&(c.push(f),c.length>=i))break}}return{entries:c,files:e.length}}}
1
+ import{appendFile as B,mkdir as L,readdir as k,readFile as M,rm as O}from"node:fs/promises";import g from"node:path";import{getApiLogsDir as v}from"../db/paths.js";const y=8*1024,C=2e3,w=50,D=6;export const MAX_LOG_FILES=24;const H=200,T=1e3,E=new Set(["password","apikey","token","secret","authorization","cookie","x-weave-local"]);function m(r,t=0){if(typeof r=="string")return r.length>C?`[truncated ${r.length} chars]`:r;if(Array.isArray(r)){if(t>=D)return"[depth-limited]";const e=r.slice(0,w).map(n=>m(n,t+1));return r.length>w&&e.push(`[truncated ${r.length-w} items]`),e}if(r&&typeof r=="object"){if(t>=D)return"[depth-limited]";const e={};for(const[n,o]of Object.entries(r))e[n]=E.has(n.toLowerCase())?"[redacted]":m(o,t+1);return e}return r}function N(r,t){if(t>y)return`[truncated body ${t} bytes]`;try{return m(JSON.parse(r))}catch{return m(r)}}export function maskPath(r){return r.replace(/^(\/webhooks\/orchestrate\/)[^?]+/,"$1[redacted]")}export function logFileFor(r,t){const e=o=>String(o).padStart(2,"0"),n=`${t.getFullYear()}-${e(t.getMonth()+1)}-${e(t.getDate())}T${e(t.getHours())}`;return g.join(r,`api-${n}.jsonl`)}function j(r){const t=g.basename(r).match(/^api-(\d{4}-\d{2}-\d{2}T\d{2})\.jsonl$/);return t?t[1]:null}const A=new WeakMap;export function noteRequestBody(r,t){A.get(r)?.(t)}export class ApiLogger{dir;chain=Promise.resolve();constructor(t={}){this.dir=t.dir??v()}begin(t,e){const n=Date.now(),o=[];let f=0,a=0,h="",d=0,l=!1;A.set(t,i=>{h=i,d=Buffer.byteLength(i,"utf8")});const c=i=>{const s=Buffer.isBuffer(i)?i:Buffer.from(typeof i=="string"?i:String(i??""),"utf8");if(a+=s.length,f<y){const u=s.subarray(0,y-f);o.push(u),f+=u.length}},p=e.write.bind(e),F=e.end.bind(e);let b="";const x=e.writeHead.bind(e);e.writeHead=((...i)=>{const s=i[1];if(s&&typeof s=="object"&&!Array.isArray(s)){const u=s,$=u["content-type"]??u["Content-Type"];typeof $=="string"&&(b=$)}return x(...i)}),e.write=((i,...s)=>(c(i),p(i,...s))),e.end=((i,...s)=>(typeof i!="function"&&i!=null&&c(i),F(i,...s)));const S=()=>{if(l)return;l=!0;const i=(String(e.getHeader("content-type")??"")||b).includes("event-stream"),s={ts:new Date(n).toISOString(),method:t.method??"GET",path:maskPath(t.url??"/"),status:e.statusCode,durationMs:Date.now()-n,ip:(t.socket?.remoteAddress??"").replace(/^::ffff:/,""),resBytes:a},u=t.headers["user-agent"];typeof u=="string"&&u&&(s.ua=u.slice(0,120)),d&&(s.req=N(h,d)),i?s.stream=!0:a&&(s.res=N(Buffer.concat(o).toString("utf8"),a)),e.writableEnded||(s.aborted=!0),this.write(logFileFor(this.dir,new Date(n)),`${JSON.stringify(s)}
2
+ `)};e.on("finish",S),e.on("close",S)}write(t,e){this.chain=this.chain.then(async()=>{try{await L(this.dir,{recursive:!0}),await B(t,e,"utf8"),await this.purge()}catch{}})}async purge(){const t=(await k(this.dir)).filter(e=>j(e)!=null);if(!(t.length<=MAX_LOG_FILES)){t.sort();for(const e of t.slice(0,t.length-MAX_LOG_FILES))await O(g.join(this.dir,e),{force:!0})}}onIdle(){return this.chain}async query(t){const e=(await k(this.dir).catch(()=>[])).filter(h=>j(h)!=null).sort().reverse(),n=Math.min(Math.max(t.limit??H,1),T),o=t.from?Date.parse(t.from):NaN,f=t.to?Date.parse(t.to):NaN,a=[];for(const h of e){if(a.length>=n)break;const d=await M(g.join(this.dir,h),"utf8").catch(()=>"");for(const l of d.split(`
3
+ `).reverse()){if(!l.trim())continue;let c;try{c=JSON.parse(l)}catch{continue}const p=Date.parse(c.ts);if(!(Number.isFinite(o)&&p<o)&&!(Number.isFinite(f)&&p>f)&&!(t.status!=null&&c.status!==t.status)&&!(t.method&&c.method.toUpperCase()!==t.method.toUpperCase())&&!(t.path&&!c.path.includes(t.path))&&(a.push(c),a.length>=n))break}}return{entries:a,files:e.length}}}
@@ -1 +1 @@
1
- import{clearedSessionCookie as c,sessionCookie as h}from"./dashboard-auth.js";import{readJson as i,sendJson as r}from"./http.js";const l=300,n=6,f=e=>new Promise(t=>setTimeout(t,e));export async function handleAuthRoutes(e,t,d,u){if(u!=="/auth"&&!u.startsWith("/auth/"))return!1;const o=d.auth;if(!o)return r(t,503,{error:"Auth subsystem unavailable"}),!0;if(u==="/auth/status"&&e.method==="GET")return r(t,200,{passwordSet:o.isPasswordSet(),authenticated:o.isAuthenticated(e.headers)}),!0;if(u==="/auth/login"&&e.method==="POST"){let s;try{s=await i(e)}catch{return r(t,400,{error:"Invalid JSON body"}),!0}const a=typeof s.password=="string"?s.password:"";return!a||!o.verifyPassword(a)?(await f(l),r(t,401,{error:"Invalid password"}),!0):(t.setHeader("set-cookie",h(o.issueSession())),r(t,200,{ok:!0}),!0)}if(u==="/auth/logout"&&e.method==="POST")return t.setHeader("set-cookie",c()),r(t,200,{ok:!0}),!0;if(u==="/auth/password"&&e.method==="PUT"){if(!o.isLocallyTrusted(e.headers))return r(t,401,{error:"Unauthorized (local token required)"}),!0;let s;try{s=await i(e)}catch{return r(t,400,{error:"Invalid JSON body"}),!0}const a=typeof s.next=="string"?s.next:"";return a.length<n?(r(t,400,{error:`Password must be at least ${n} characters`}),!0):(o.setPassword(a),r(t,200,{ok:!0}),!0)}return r(t,404,{error:"Not found"}),!0}
1
+ import{clearedSessionCookie as h,sessionCookie as c}from"./dashboard-auth.js";import{readJson as i,sendJson as e}from"./http.js";const l=300,d=6,f=s=>new Promise(r=>setTimeout(r,s));export async function handleAuthRoutes(s,r,u,a){if(a!=="/auth"&&!a.startsWith("/auth/"))return!1;const t=u.auth;if(!t)return e(r,503,{error:"Auth subsystem unavailable"}),!0;if(a==="/auth/status"&&s.method==="GET")return e(r,200,{passwordSet:t.isPasswordSet(),authenticated:t.isAuthenticated(s.headers)}),!0;if(a==="/auth/login"&&s.method==="POST"){let o;try{o=await i(s)}catch{return e(r,400,{error:"Invalid JSON body"}),!0}const n=typeof o.password=="string"?o.password:"";return!n||!t.verifyPassword(n)?(await f(l),e(r,401,{error:"Invalid password"}),!0):(r.setHeader("set-cookie",c(t.issueSession())),e(r,200,{ok:!0}),!0)}if(a==="/auth/logout"&&s.method==="POST")return r.setHeader("set-cookie",h()),e(r,200,{ok:!0}),!0;if(a==="/auth/password"&&s.method==="PUT"){if(!t.isLocallyTrusted(s.headers))return e(r,401,{error:"Unauthorized (local token required)"}),!0;let o;try{o=await i(s)}catch{return e(r,400,{error:"Invalid JSON body"}),!0}const n=typeof o.next=="string"?o.next:"";return n.length<d?(e(r,400,{error:`Password must be at least ${d} characters`}),!0):(t.setPassword(n),e(r,200,{ok:!0}),!0)}return e(r,404,{error:"Not found"}),!0}
@@ -1,17 +1,17 @@
1
- import{spawnSync as l}from"node:child_process";import{fileURLToPath as m}from"node:url";import{mkdirSync as a,writeFileSync as i,unlinkSync as c}from"node:fs";import{homedir as p}from"node:os";import r from"node:path";import{getAutoStartScriptPath as s,getDataDir as f}from"../db/paths.js";import{readDaemonSettingsSync as d}from"./settings.js";const o="weave-daemon",u="HKCU\\Software\\Microsoft\\Windows\\CurrentVersion\\Run";export function relaunchArgs(){return[process.execPath,...process.execArgv.map(t=>{if(t!=="tsx"&&!t.startsWith("tsx/"))return t;try{return m(import.meta.resolve(t))}catch{return t}}),r.resolve(process.argv[1]??process.argv[0])]}function h(t){return{platform:t.platform??process.platform,dataDir:t.dataDir??f(),home:t.home??p(),run:t.run??((e,n)=>({status:l(e,n,{stdio:"ignore"}).status}))}}function g(t){return t.map(e=>`"${e}"`).join(" ")}function y(t){const e=s(t.dataDir);a(r.dirname(e),{recursive:!0});const n=g(relaunchArgs());i(e,`' Generated by weave \u2014 daemon auto-start. Do not edit.
2
- CreateObject("WScript.Shell").Run "${n.replace(/"/g,'""')}", 0, False
3
- `),t.run("reg",["add",u,"/v",o,"/t","REG_SZ","/d",`wscript.exe "${e}"`,"/f"])}function v(t){t.run("reg",["delete",u,"/v",o,"/f"]);try{c(s(t.dataDir))}catch{}}function w(t){const e=n=>n.replace(/&/g,"&amp;").replace(/</g,"&lt;").replace(/>/g,"&gt;");return`<?xml version="1.0" encoding="UTF-8"?>
1
+ import{spawnSync as p}from"node:child_process";import{fileURLToPath as m}from"node:url";import{mkdirSync as a,writeFileSync as i,unlinkSync as c}from"node:fs";import{homedir as l}from"node:os";import n from"node:path";import{getAutoStartScriptPath as s,getDataDir as d}from"../db/paths.js";import{readDaemonSettingsSync as f}from"./settings.js";const o="weave-daemon",u="HKCU\\Software\\Microsoft\\Windows\\CurrentVersion\\Run";export function relaunchArgs(){return[process.execPath,...process.execArgv.map(e=>{if(e!=="tsx"&&!e.startsWith("tsx/"))return e;try{return m(import.meta.resolve(e))}catch{return e}}),n.resolve(process.argv[1]??process.argv[0])]}function g(e){return{platform:e.platform??process.platform,dataDir:e.dataDir??d(),home:e.home??l(),run:e.run??((r,t)=>({status:p(r,t,{stdio:"ignore"}).status}))}}function h(e){return e.map(r=>`"${r}"`).join(" ")}function y(e){const r=s(e.dataDir);a(n.dirname(r),{recursive:!0});const t=h(relaunchArgs());i(r,`' Generated by weave \u2014 daemon auto-start. Do not edit.
2
+ CreateObject("WScript.Shell").Run "${t.replace(/"/g,'""')}", 0, False
3
+ `),e.run("reg",["add",u,"/v",o,"/t","REG_SZ","/d",`wscript.exe "${r}"`,"/f"])}function v(e){e.run("reg",["delete",u,"/v",o,"/f"]);try{c(s(e.dataDir))}catch{}}function w(e){const r=t=>t.replace(/&/g,"&amp;").replace(/</g,"&lt;").replace(/>/g,"&gt;");return`<?xml version="1.0" encoding="UTF-8"?>
4
4
  <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
5
5
  <plist version="1.0">
6
6
  <dict>
7
7
  <key>Label</key><string>com.weave.daemon</string>
8
8
  <key>ProgramArguments</key>
9
9
  <array>
10
- `+t.map(n=>` <string>${e(n)}</string>`).join(`
10
+ `+e.map(t=>` <string>${r(t)}</string>`).join(`
11
11
  `)+`
12
12
  </array>
13
13
  <key>RunAtLoad</key><true/>
14
14
  </dict>
15
15
  </plist>
16
- `}function L(t){const e=r.join(t.home,"Library","LaunchAgents","com.weave.daemon.plist");a(r.dirname(e),{recursive:!0}),i(e,w(relaunchArgs())),t.run("launchctl",["unload",e]),t.run("launchctl",["load",e])}function D(t){const e=r.join(t.home,"Library","LaunchAgents","com.weave.daemon.plist");t.run("launchctl",["unload",e]);try{c(e)}catch{}}function k(t){return t.map(e=>/[\s"]/.test(e)?`"${e}"`:e).join(" ")}function x(t){const e=r.join(t.home,".config","autostart",`${o}.desktop`);a(r.dirname(e),{recursive:!0}),i(e,["[Desktop Entry]","Type=Application","Name=weave daemon",`Exec=${k(relaunchArgs())}`,"X-GNOME-Autostart-enabled=true",""].join(`
17
- `))}function S(t){try{c(r.join(t.home,".config","autostart",`${o}.desktop`))}catch{}}export function applyLaunchOnLogin(t,e={}){try{const n=h(e);n.platform==="win32"?t?y(n):v(n):n.platform==="darwin"?t?L(n):D(n):t?x(n):S(n)}catch(n){console.error(`[weave] auto-start ${t?"enable":"disable"} failed:`,n)}}export function syncLaunchOnLogin(t={}){const e=d().startup;applyLaunchOnLogin(e?.launchOnLogin??!1,t)}
16
+ `}function L(e){const r=n.join(e.home,"Library","LaunchAgents","com.weave.daemon.plist");a(n.dirname(r),{recursive:!0}),i(r,w(relaunchArgs())),e.run("launchctl",["unload",r]),e.run("launchctl",["load",r])}function D(e){const r=n.join(e.home,"Library","LaunchAgents","com.weave.daemon.plist");e.run("launchctl",["unload",r]);try{c(r)}catch{}}function S(e){return e.map(r=>/[\s"]/.test(r)?`"${r}"`:r).join(" ")}function k(e){const r=n.join(e.home,".config","autostart",`${o}.desktop`);a(n.dirname(r),{recursive:!0}),i(r,["[Desktop Entry]","Type=Application","Name=weave daemon",`Exec=${S(relaunchArgs())}`,"X-GNOME-Autostart-enabled=true",""].join(`
17
+ `))}function x(e){try{c(n.join(e.home,".config","autostart",`${o}.desktop`))}catch{}}export function applyLaunchOnLogin(e,r={}){try{const t=g(r);t.platform==="win32"?e?y(t):v(t):t.platform==="darwin"?e?L(t):D(t):e?k(t):x(t)}catch(t){console.error(`[weave] auto-start ${e?"enable":"disable"} failed:`,t)}}export function syncLaunchOnLogin(e={}){const r=f().startup;applyLaunchOnLogin(r?.launchOnLogin??!1,e)}
@@ -1 +1 @@
1
- import{z as n}from"zod";import{isHarness as f}from"@weavecode/core";import{WEAVE_VERSION as p}from"../version.js";import{readJson as d,sendJson as s}from"./http.js";import{captureSurfaces as i}from"../surfaces.js";const l=n.object({harness:n.string(),enabled:n.boolean()});export async function handleCaptureRoutes(o,t,u,c){if(c!=="/capture")return!1;if(o.method==="GET"){const e=await Promise.all(i().map(async({harness:a,surface:r})=>({harness:a,...await r.readUserCapture()})));return s(t,200,{rows:e}),!0}if(o.method==="PUT"){let e;try{e=l.parse(await d(o))}catch(r){return s(t,400,{error:r instanceof Error?r.message:"Invalid body"}),!0}if(!f(e.harness))return s(t,400,{error:`Unknown harness: ${e.harness}`}),!0;const a=i().find(r=>r.harness===e.harness);if(!a)return s(t,400,{error:`No capture surface for harness: ${e.harness}`}),!0;try{if(e.enabled){await a.surface.installUserCapture({version:p});for(const r of u.projects.list())await a.surface.stripProjectCapture(r.path)}else await a.surface.uninstallUserCapture();u.dataBus?.emit({key:"capture"}),s(t,200,{harness:a.harness,...await a.surface.readUserCapture()})}catch(r){s(t,400,{error:r instanceof Error?r.message:"Capture update failed"})}return!0}return s(t,405,{error:"Method not allowed"}),!0}
1
+ import{z as o}from"zod";import{isHarness as f}from"@weavecode/core";import{WEAVE_VERSION as p}from"../version.js";import{readJson as h,sendJson as t}from"./http.js";import{captureSurfaces as u}from"../surfaces.js";const d=o.object({harness:o.string(),enabled:o.boolean()});export async function handleCaptureRoutes(n,s,i,c){if(c!=="/capture")return!1;if(n.method==="GET"){const e=await Promise.all(u().map(async({harness:a,surface:r})=>({harness:a,...await r.readUserCapture()})));return t(s,200,{rows:e}),!0}if(n.method==="PUT"){let e;try{e=d.parse(await h(n))}catch(r){return t(s,400,{error:r instanceof Error?r.message:"Invalid body"}),!0}if(!f(e.harness))return t(s,400,{error:`Unknown harness: ${e.harness}`}),!0;const a=u().find(r=>r.harness===e.harness);if(!a)return t(s,400,{error:`No capture surface for harness: ${e.harness}`}),!0;try{if(e.enabled){await a.surface.installUserCapture({version:p});for(const r of i.projects.list())await a.surface.stripProjectCapture(r.path)}else await a.surface.uninstallUserCapture();i.dataBus?.emit({key:"capture"}),t(s,200,{harness:a.harness,...await a.surface.readUserCapture()})}catch(r){t(s,400,{error:r instanceof Error?r.message:"Capture update failed"})}return!0}return t(s,405,{error:"Method not allowed"}),!0}
@@ -1 +1 @@
1
- import{homedir as B}from"node:os";import{access as F}from"node:fs/promises";import{isHarness as I}from"@weavecode/core";import{configSurfaceFor as k}from"../surfaces.js";import{baselineSnapshot as U,createProfile as J,LASTSEEN_ID as C,listBackups as K,listProfiles as h,readBackup as E,readSnapshot as N,removeProfile as L,renameProfile as $,pushBackup as j,saveProfile as D,setActive as V,syncBaseline as P,writeSnapshot as M}from"../config/profiles.js";import{readBody as R,sendJson as a}from"./http.js";import{getHarnessConfigDir as G}from"../db/paths.js";const H=["user","project","projectLocal","global"];function x(c){return typeof c=="string"&&H.includes(c)?c:null}function y(c,r){return c.serializeRaw(r)}function _(c,r,p){const w=c.files(p).find(m=>m.id===r);return w?w.path(p):""}async function O(c){try{const r=JSON.parse(await R(c));return typeof r=="object"&&r!==null&&!Array.isArray(r)?r:null}catch{return null}}async function z(c){if(!c)return!1;try{return await F(c),!0}catch{return!1}}async function T(c,r,p,w,m){const i=_(p,w,m),n=await p.read(w,m),e=y(p,n),t=await h(c,r,w),s=await U(c,r,w,t);s||await M(c,r,w,C,n);const o=s?y(p,s):y(p,n);return{harness:r,file:w,path:i,exists:await z(i),values:n,managedKeys:p.managedKeys(n),managedEntries:p.managedEntries(n),profiles:t.profiles,activeId:t.activeId,liveText:e,activeText:o,drifted:o!==e,backups:await K(c,r,w)}}function S(c,r,p){let w=null;if(r==="project"||r==="projectLocal"){const m=Number(p);if(!Number.isInteger(m)||m<=0)return"\u9700\u8981 projectId";const i=c.projects.getById(m);if(!i)return"\u9879\u76EE\u4E0D\u5B58\u5728";w=i.path}return{projectPath:w,homedir:B()}}export async function handleConfigRoutes(c,r,p,w,m){if(!w.startsWith("/harness-config"))return!1;const i=G();if(w==="/harness-config/catalog"&&c.method==="GET"){const n=m.searchParams.get("harness");if(!I(n))return a(r,400,{error:"Unknown harness"}),!0;const e=k(n);if(!e)return a(r,200,{supported:!1}),!0;const t=x(m.searchParams.get("file"))??"user",s={projectPath:null,homedir:B()},o=e.catalog(t);return a(r,200,{supported:!0,harness:n,file:t,rawFormat:e.rawFormat,files:e.files(s).map(u=>({id:u.id,profiles:u.profiles})),groups:o.groups,keys:o.keys,envVars:o.envVars}),!0}if(w==="/harness-config"&&c.method==="GET"){const n=m.searchParams.get("harness"),e=x(m.searchParams.get("file"));if(!I(n)||!e)return a(r,400,{error:"Unknown harness or file"}),!0;const t=k(n);if(!t)return a(r,400,{error:"\u914D\u7F6E\u9762\u672A\u5B9E\u73B0"}),!0;const s=S(p,e,m.searchParams.get("projectId"));return typeof s=="string"?(a(r,400,{error:s}),!0):(a(r,200,await T(i,n,t,e,s)),!0)}if(w==="/harness-config/values"&&c.method==="PUT"){const n=await O(c);if(!n)return a(r,400,{error:"Invalid JSON body"}),!0;const e=n.harness,t=x(n.file);if(!I(e)||!t)return a(r,400,{error:"Unknown harness or file"}),!0;const s=k(e);if(!s)return a(r,400,{error:"\u914D\u7F6E\u9762\u672A\u5B9E\u73B0"}),!0;const o=S(p,t,n.projectId);if(typeof o=="string")return a(r,400,{error:o}),!0;const u=n.values;if(typeof u!="object"||u===null||Array.isArray(u))return a(r,400,{error:'Missing "values"'}),!0;try{const f=await s.read(t,o);await j(i,e,t,f),await s.write(t,o,u);const v=await h(i,e,t);await P(i,e,t,v,await s.read(t,o))}catch(f){return a(r,400,{error:f.message}),!0}return a(r,200,await T(i,e,s,t,o)),!0}if(w==="/harness-config/raw"&&c.method==="PUT"){const n=await O(c);if(!n)return a(r,400,{error:"Invalid JSON body"}),!0;const e=n.harness,t=x(n.file);if(!I(e)||!t)return a(r,400,{error:"Unknown harness or file"}),!0;const s=k(e);if(!s)return a(r,400,{error:"\u914D\u7F6E\u9762\u672A\u5B9E\u73B0"}),!0;const o=S(p,t,n.projectId);if(typeof o=="string")return a(r,400,{error:o}),!0;let u;try{u=s.parseRaw(String(n.text??""))}catch(f){return a(r,400,{error:`\u4E0D\u662F\u5408\u6CD5${s.rawFormat==="toml"?" TOML":" JSON"}\uFF1A${f.message}`}),!0}try{const f=await s.read(t,o);await j(i,e,t,f),await s.write(t,o,u);const v=await h(i,e,t);await P(i,e,t,v,await s.read(t,o))}catch(f){return a(r,400,{error:f.message}),!0}return a(r,200,await T(i,e,s,t,o)),!0}if(w==="/harness-config/profile"&&c.method==="POST"){const n=await O(c);if(!n)return a(r,400,{error:"Invalid JSON body"}),!0;const e=n.harness,t=x(n.file),s=n.action;if(!I(e)||!t||typeof s!="string")return a(r,400,{error:"Unknown harness, file or action"}),!0;const o=k(e);if(!o)return a(r,400,{error:"\u914D\u7F6E\u9762\u672A\u5B9E\u73B0"}),!0;const u=S(p,t,n.projectId);if(typeof u=="string")return a(r,400,{error:u}),!0;const f=typeof n.id=="string"?n.id:"",v=typeof n.name=="string"?n.name.trim():"",A=typeof n.values=="object"&&n.values!==null&&!Array.isArray(n.values)?n.values:null;switch(s){case"list":{const d=await h(i,e,t);return a(r,200,d),!0}case"create":{const d=await h(i,e,t),l=await J(i,e,t,v||`\u914D\u7F6E ${d.profiles.length+1}`,A??await o.read(t,u));return a(r,200,{profile:l,state:await h(i,e,t)}),!0}case"save":return(await h(i,e,t)).profiles.some(l=>l.id===f)?(await D(i,e,t,f,A??await o.read(t,u)),a(r,200,await h(i,e,t)),!0):(a(r,404,{error:"\u914D\u7F6E\u4E0D\u5B58\u5728"}),!0);case"compare":{const d=n.target;if(d==="live")return a(r,200,{text:y(o,await o.read(t,u))}),!0;if(d==="backup"){const g=typeof n.backupId=="string"?n.backupId:"",b=await E(i,e,t,g);return b?(a(r,200,{text:y(o,b)}),!0):(a(r,404,{error:"\u5907\u4EFD\u4E0D\u5B58\u5728"}),!0)}const l=await N(i,e,t,f);return l?(a(r,200,{text:y(o,l)}),!0):(a(r,404,{error:"\u914D\u7F6E\u4E0D\u5B58\u5728"}),!0)}case"duplicate":{const d=await N(i,e,t,f);if(!d)return a(r,404,{error:"\u914D\u7F6E\u4E0D\u5B58\u5728"}),!0;const l=await h(i,e,t),g=await J(i,e,t,v||`\u914D\u7F6E ${l.profiles.length+1}`,d);return a(r,200,{profile:g,state:await h(i,e,t)}),!0}case"rename":return v?(await $(i,e,t,f,v),a(r,200,await h(i,e,t)),!0):(a(r,400,{error:"\u7F3A\u5C11\u540D\u79F0"}),!0);case"remove":return await L(i,e,t,f),a(r,200,await h(i,e,t)),!0;case"activate":{const d=await N(i,e,t,f);if(!d)return a(r,404,{error:"\u914D\u7F6E\u4E0D\u5B58\u5728"}),!0;const l=await o.read(t,u);if(n.confirm!==!0)return a(r,200,{requiresConfirm:!0,liveText:y(o,l),profileText:y(o,d)}),!0;try{await j(i,e,t,l),await o.write(t,u,d),await V(i,e,t,f)}catch(g){return a(r,400,{error:g.message}),!0}return a(r,200,await T(i,e,o,t,u)),!0}case"acceptDrift":{const d=await h(i,e,t),l=await U(i,e,t,d);return l&&await j(i,e,t,l),await P(i,e,t,d,await o.read(t,u)),a(r,200,await T(i,e,o,t,u)),!0}case"restoreBaseline":{const d=await h(i,e,t),l=await U(i,e,t,d);if(!l)return a(r,404,{error:"\u6CA1\u6709\u53EF\u6062\u590D\u7684\u57FA\u7EBF"}),!0;const g=await o.read(t,u);if(n.confirm!==!0)return a(r,200,{requiresConfirm:!0,liveText:y(o,g),baselineText:y(o,l)}),!0;try{await j(i,e,t,g),await o.write(t,u,l),await P(i,e,t,d,l)}catch(b){return a(r,400,{error:b.message}),!0}return a(r,200,await T(i,e,o,t,u)),!0}case"restoreBackup":{const d=typeof n.backupId=="string"?n.backupId:"",l=await E(i,e,t,d);if(!l)return a(r,404,{error:"\u5907\u4EFD\u4E0D\u5B58\u5728"}),!0;const g=await o.read(t,u);if(n.confirm!==!0)return a(r,200,{requiresConfirm:!0,liveText:y(o,g),backupText:y(o,l)}),!0;try{await j(i,e,t,g),await o.write(t,u,l);const b=await h(i,e,t);await P(i,e,t,b,l)}catch(b){return a(r,400,{error:b.message}),!0}return a(r,200,await T(i,e,o,t,u)),!0}default:return a(r,400,{error:`\u672A\u77E5\u52A8\u4F5C\uFF1A${s}`}),!0}}if(w==="/harness-config/models"&&c.method==="POST"){const n=await O(c);if(!n)return a(r,400,{error:"Invalid JSON body"}),!0;const e=n.harness,t=x(n.file)??"user";if(!I(e))return a(r,400,{error:"Unknown harness"}),!0;const s=k(e);if(!s)return a(r,400,{error:"\u914D\u7F6E\u9762\u672A\u5B9E\u73B0"}),!0;const o=S(p,t,n.projectId);if(typeof o=="string")return a(r,400,{error:o}),!0;try{const u=await s.read(t,o),f=await s.models({values:u,file:t,homedir:o.homedir,baseUrl:typeof n.baseUrl=="string"?n.baseUrl:null,apiKey:typeof n.apiKey=="string"?n.apiKey:null,authToken:typeof n.authToken=="string"?n.authToken:null});a(r,200,f)}catch(u){a(r,502,{error:u.message})}return!0}if(w==="/harness-config/preview"&&c.method==="POST"){const n=await O(c);if(!n)return a(r,400,{error:"Invalid JSON body"}),!0;const e=n.harness,t=x(n.file);if(!I(e)||!t)return a(r,400,{error:"Unknown harness or file"}),!0;const s=k(e);if(!s)return a(r,400,{error:"\u914D\u7F6E\u9762\u672A\u5B9E\u73B0"}),!0;const o=S(p,t,n.projectId);if(typeof o=="string")return a(r,400,{error:o}),!0;const u=n.values;if(typeof u!="object"||u===null||Array.isArray(u))return a(r,400,{error:'Missing "values"'}),!0;try{const f=await s.read(t,o);a(r,200,{before:y(s,f),after:y(s,u)})}catch(f){a(r,400,{error:f.message})}return!0}return a(r,404,{error:"Not found"}),!0}
1
+ import{homedir as O}from"node:os";import{access as C}from"node:fs/promises";import{isHarness as B}from"@weavecode/core";import{configSurfaceFor as D}from"../surfaces.js";import{baselineSnapshot as P,createProfile as U,LASTSEEN_ID as J,listBackups as K,listProfiles as h,profileKeyOf as $,readBackup as N,readSnapshot as S,removeProfile as L,renameProfile as M,pushBackup as k,saveProfile as R,setActive as q,syncBaseline as j,writeSnapshot as G}from"../config/profiles.js";import{readBody as H,sendJson as n}from"./http.js";import{getHarnessConfigDir as V}from"../db/paths.js";const z=["user","project","projectLocal","global"];function u(f,r){return $(f,r.projectId)}function b(f){return typeof f=="string"&&z.includes(f)?f:null}function y(f,r){return f.serializeRaw(r)}function W(f,r,p){const m=f.files(p).find(g=>g.id===r);return m?m.path(p):""}async function T(f){try{const r=JSON.parse(await H(f));return typeof r=="object"&&r!==null&&!Array.isArray(r)?r:null}catch{return null}}async function _(f){if(!f)return!1;try{return await C(f),!0}catch{return!1}}async function I(f,r,p,m,g){const o=u(m,g),i=W(p,m,g),a=await p.read(m,g),e=y(p,a),c=await h(f,r,o),s=await P(f,r,o,c);s||await G(f,r,o,J,a);const t=s?y(p,s):y(p,a);return{harness:r,file:m,path:i,exists:await _(i),values:a,managedKeys:p.managedKeys(a),managedEntries:p.managedEntries(a),profiles:c.profiles,activeId:c.activeId,liveText:e,activeText:t,drifted:t!==e,backups:await K(f,r,o)}}function A(f,r,p){let m=null,g=null;if(r==="project"||r==="projectLocal"){const o=Number(p);if(!Number.isInteger(o)||o<=0)return"\u9700\u8981 projectId";const i=f.projects.getById(o);if(!i)return"\u9879\u76EE\u4E0D\u5B58\u5728";m=i.path,g=o}return{projectPath:m,projectId:g,homedir:O()}}export async function handleConfigRoutes(f,r,p,m,g){if(!m.startsWith("/harness-config"))return!1;const o=V();if(m==="/harness-config/catalog"&&f.method==="GET"){const i=g.searchParams.get("harness");if(!B(i))return n(r,400,{error:"Unknown harness"}),!0;const a=D(i);if(!a)return n(r,200,{supported:!1}),!0;const e=b(g.searchParams.get("file"))??"user",c={projectPath:null,projectId:null,homedir:O()},s=a.catalog(e);return n(r,200,{supported:!0,harness:i,file:e,rawFormat:a.rawFormat,files:a.files(c).map(t=>({id:t.id,profiles:t.profiles})),groups:s.groups,keys:s.keys,envVars:s.envVars}),!0}if(m==="/harness-config"&&f.method==="GET"){const i=g.searchParams.get("harness"),a=b(g.searchParams.get("file"));if(!B(i)||!a)return n(r,400,{error:"Unknown harness or file"}),!0;const e=D(i);if(!e)return n(r,400,{error:"\u914D\u7F6E\u9762\u672A\u5B9E\u73B0"}),!0;const c=A(p,a,g.searchParams.get("projectId"));return typeof c=="string"?(n(r,400,{error:c}),!0):(n(r,200,await I(o,i,e,a,c)),!0)}if(m==="/harness-config/values"&&f.method==="PUT"){const i=await T(f);if(!i)return n(r,400,{error:"Invalid JSON body"}),!0;const a=i.harness,e=b(i.file);if(!B(a)||!e)return n(r,400,{error:"Unknown harness or file"}),!0;const c=D(a);if(!c)return n(r,400,{error:"\u914D\u7F6E\u9762\u672A\u5B9E\u73B0"}),!0;const s=A(p,e,i.projectId);if(typeof s=="string")return n(r,400,{error:s}),!0;const t=i.values;if(typeof t!="object"||t===null||Array.isArray(t))return n(r,400,{error:'Missing "values"'}),!0;try{const l=await c.read(e,s);await k(o,a,u(e,s),l),await c.write(e,s,t);const v=await h(o,a,u(e,s));await j(o,a,u(e,s),v,await c.read(e,s))}catch(l){return n(r,400,{error:l.message}),!0}return n(r,200,await I(o,a,c,e,s)),!0}if(m==="/harness-config/raw"&&f.method==="PUT"){const i=await T(f);if(!i)return n(r,400,{error:"Invalid JSON body"}),!0;const a=i.harness,e=b(i.file);if(!B(a)||!e)return n(r,400,{error:"Unknown harness or file"}),!0;const c=D(a);if(!c)return n(r,400,{error:"\u914D\u7F6E\u9762\u672A\u5B9E\u73B0"}),!0;const s=A(p,e,i.projectId);if(typeof s=="string")return n(r,400,{error:s}),!0;let t;try{t=c.parseRaw(String(i.text??""))}catch(l){return n(r,400,{error:`\u4E0D\u662F\u5408\u6CD5${c.rawFormat==="toml"?" TOML":" JSON"}\uFF1A${l.message}`}),!0}try{const l=await c.read(e,s);await k(o,a,u(e,s),l),await c.write(e,s,t);const v=await h(o,a,u(e,s));await j(o,a,u(e,s),v,await c.read(e,s))}catch(l){return n(r,400,{error:l.message}),!0}return n(r,200,await I(o,a,c,e,s)),!0}if(m==="/harness-config/profile"&&f.method==="POST"){const i=await T(f);if(!i)return n(r,400,{error:"Invalid JSON body"}),!0;const a=i.harness,e=b(i.file),c=i.action;if(!B(a)||!e||typeof c!="string")return n(r,400,{error:"Unknown harness, file or action"}),!0;const s=D(a);if(!s)return n(r,400,{error:"\u914D\u7F6E\u9762\u672A\u5B9E\u73B0"}),!0;const t=A(p,e,i.projectId);if(typeof t=="string")return n(r,400,{error:t}),!0;const l=typeof i.id=="string"?i.id:"",v=typeof i.name=="string"?i.name.trim():"",x=typeof i.values=="object"&&i.values!==null&&!Array.isArray(i.values)?i.values:null;switch(c){case"list":{const w=await h(o,a,u(e,t));return n(r,200,w),!0}case"create":{const w=await h(o,a,u(e,t)),d=await U(o,a,u(e,t),v||`\u914D\u7F6E ${w.profiles.length+1}`,x??await s.read(e,t));return n(r,200,{profile:d,state:await h(o,a,u(e,t))}),!0}case"save":return(await h(o,a,u(e,t))).profiles.some(w=>w.id===l)?(await R(o,a,u(e,t),l,x??await s.read(e,t)),n(r,200,await h(o,a,u(e,t))),!0):(n(r,404,{error:"\u914D\u7F6E\u4E0D\u5B58\u5728"}),!0);case"compare":{const w=i.target;if(w==="live")return n(r,200,{text:y(s,await s.read(e,t))}),!0;if(w==="backup"){const E=typeof i.backupId=="string"?i.backupId:"",F=await N(o,a,u(e,t),E);return F?(n(r,200,{text:y(s,F)}),!0):(n(r,404,{error:"\u5907\u4EFD\u4E0D\u5B58\u5728"}),!0)}const d=await S(o,a,u(e,t),l);return d?(n(r,200,{text:y(s,d)}),!0):(n(r,404,{error:"\u914D\u7F6E\u4E0D\u5B58\u5728"}),!0)}case"duplicate":{const w=await S(o,a,u(e,t),l);if(!w)return n(r,404,{error:"\u914D\u7F6E\u4E0D\u5B58\u5728"}),!0;const d=await h(o,a,u(e,t)),E=await U(o,a,u(e,t),v||`\u914D\u7F6E ${d.profiles.length+1}`,w);return n(r,200,{profile:E,state:await h(o,a,u(e,t))}),!0}case"rename":return v?(await M(o,a,u(e,t),l,v),n(r,200,await h(o,a,u(e,t))),!0):(n(r,400,{error:"\u7F3A\u5C11\u540D\u79F0"}),!0);case"remove":return await L(o,a,u(e,t),l),n(r,200,await h(o,a,u(e,t))),!0;case"activate":{const w=await S(o,a,u(e,t),l);if(!w)return n(r,404,{error:"\u914D\u7F6E\u4E0D\u5B58\u5728"}),!0;const d=await s.read(e,t);if(i.confirm!==!0)return n(r,200,{requiresConfirm:!0,liveText:y(s,d),profileText:y(s,w)}),!0;try{await k(o,a,u(e,t),d),await s.write(e,t,w),await q(o,a,u(e,t),l)}catch(E){return n(r,400,{error:E.message}),!0}return n(r,200,await I(o,a,s,e,t)),!0}case"acceptDrift":{const w=await h(o,a,u(e,t)),d=await P(o,a,u(e,t),w);return d&&await k(o,a,u(e,t),d),await j(o,a,u(e,t),w,await s.read(e,t)),n(r,200,await I(o,a,s,e,t)),!0}case"restoreBaseline":{const w=await h(o,a,u(e,t)),d=await P(o,a,u(e,t),w);if(!d)return n(r,404,{error:"\u6CA1\u6709\u53EF\u6062\u590D\u7684\u57FA\u7EBF"}),!0;const E=await s.read(e,t);if(i.confirm!==!0)return n(r,200,{requiresConfirm:!0,liveText:y(s,E),baselineText:y(s,d)}),!0;try{await k(o,a,u(e,t),E),await s.write(e,t,d),await j(o,a,u(e,t),w,d)}catch(F){return n(r,400,{error:F.message}),!0}return n(r,200,await I(o,a,s,e,t)),!0}case"restoreBackup":{const w=typeof i.backupId=="string"?i.backupId:"",d=await N(o,a,u(e,t),w);if(!d)return n(r,404,{error:"\u5907\u4EFD\u4E0D\u5B58\u5728"}),!0;const E=await s.read(e,t);if(i.confirm!==!0)return n(r,200,{requiresConfirm:!0,liveText:y(s,E),backupText:y(s,d)}),!0;try{await k(o,a,u(e,t),E),await s.write(e,t,d);const F=await h(o,a,u(e,t));await j(o,a,u(e,t),F,d)}catch(F){return n(r,400,{error:F.message}),!0}return n(r,200,await I(o,a,s,e,t)),!0}default:return n(r,400,{error:`\u672A\u77E5\u52A8\u4F5C\uFF1A${c}`}),!0}}if(m==="/harness-config/models"&&f.method==="POST"){const i=await T(f);if(!i)return n(r,400,{error:"Invalid JSON body"}),!0;const a=i.harness,e=b(i.file)??"user";if(!B(a))return n(r,400,{error:"Unknown harness"}),!0;const c=D(a);if(!c)return n(r,400,{error:"\u914D\u7F6E\u9762\u672A\u5B9E\u73B0"}),!0;const s=A(p,e,i.projectId);if(typeof s=="string")return n(r,400,{error:s}),!0;try{const t=await c.read(e,s),l=await c.models({values:t,file:e,homedir:s.homedir,baseUrl:typeof i.baseUrl=="string"?i.baseUrl:null,apiKey:typeof i.apiKey=="string"?i.apiKey:null,authToken:typeof i.authToken=="string"?i.authToken:null});n(r,200,l)}catch(t){n(r,502,{error:t.message})}return!0}if(m==="/harness-config/preview"&&f.method==="POST"){const i=await T(f);if(!i)return n(r,400,{error:"Invalid JSON body"}),!0;const a=i.harness,e=b(i.file);if(!B(a)||!e)return n(r,400,{error:"Unknown harness or file"}),!0;const c=D(a);if(!c)return n(r,400,{error:"\u914D\u7F6E\u9762\u672A\u5B9E\u73B0"}),!0;const s=A(p,e,i.projectId);if(typeof s=="string")return n(r,400,{error:s}),!0;const t=i.values;if(typeof t!="object"||t===null||Array.isArray(t))return n(r,400,{error:'Missing "values"'}),!0;try{const l=await c.read(e,s);n(r,200,{before:y(c,l),after:y(c,t)})}catch(l){n(r,400,{error:l.message})}return!0}return n(r,404,{error:"Not found"}),!0}
@@ -1 +1 @@
1
- const d=[{min:0,max:59},{min:0,max:23},{min:1,max:31},{min:1,max:12},{min:0,max:7}];export function parseCron(t){const n=t.trim().split(/\s+/);if(n.length!==5)return null;const e=[];for(let u=0;u<5;u++){const r=a(n[u],d[u].min,d[u].max);if(!r)return null;e.push(r)}const s=[...new Set(e[4].map(u=>u===7?0:u))].sort((u,r)=>u-r);return{minutes:e[0],hours:e[1],doms:e[2],months:e[3],dows:s,domAny:n[2]==="*",dowAny:n[4]==="*"}}function a(t,n,e){const s=new Set;for(const u of t.split(",")){const[r,m]=u.split("/");if(r===void 0)return null;const c=m===void 0?1:Number(m);if(!Number.isInteger(c)||c<1||c>e)return null;let i,o;if(r==="*")i=n,o=e;else if(r.includes("-")){const[l,g]=r.split("-");i=Number(l),o=Number(g)}else i=Number(r),o=m===void 0?i:e;if(!Number.isInteger(i)||!Number.isInteger(o)||i<n||o>e||i>o)return null;for(let l=i;l<=o;l+=c)s.add(l)}return s.size===0?null:[...s].sort((u,r)=>u-r)}function f(t,n){const e=t.doms.includes(n.getDate()),s=t.dows.includes(n.getDay());return t.domAny&&t.dowAny?!0:t.domAny?s:t.dowAny?e:e||s}export function matchesMinute(t,n){return t.minutes.includes(n.getMinutes())&&t.hours.includes(n.getHours())&&t.months.includes(n.getMonth()+1)&&f(t,n)}export function nextRunAt(t,n=new Date){const e=new Date(n.getTime());e.setSeconds(0,0),e.setMinutes(e.getMinutes()+1);const s=new Date(n.getTime()+366*864e5);for(;e<=s;){if(!t.months.includes(e.getMonth()+1)){e.setMonth(e.getMonth()+1,1),e.setHours(0,0,0,0);continue}if(!f(t,e)){e.setDate(e.getDate()+1),e.setHours(0,0,0,0);continue}if(!t.hours.includes(e.getHours())){e.setHours(e.getHours()+1,0,0,0);continue}if(!t.minutes.includes(e.getMinutes())){e.setMinutes(e.getMinutes()+1,0,0);continue}return e.toISOString()}return null}export function minuteKey(t){const n=e=>String(e).padStart(2,"0");return`${t.getFullYear()}-${n(t.getMonth()+1)}-${n(t.getDate())}T${n(t.getHours())}:${n(t.getMinutes())}`}
1
+ const d=[{min:0,max:59},{min:0,max:23},{min:1,max:31},{min:1,max:12},{min:0,max:7}];export function parseCron(n){const t=n.trim().split(/\s+/);if(t.length!==5)return null;const e=[];for(let s=0;s<5;s++){const u=a(t[s],d[s].min,d[s].max);if(!u)return null;e.push(u)}const o=[...new Set(e[4].map(s=>s===7?0:s))].sort((s,u)=>s-u);return{minutes:e[0],hours:e[1],doms:e[2],months:e[3],dows:o,domAny:t[2]==="*",dowAny:t[4]==="*"}}function a(n,t,e){const o=new Set;for(const s of n.split(",")){const[u,c]=s.split("/");if(u===void 0)return null;const m=c===void 0?1:Number(c);if(!Number.isInteger(m)||m<1||m>e)return null;let i,r;if(u==="*")i=t,r=e;else if(u.includes("-")){const[l,f]=u.split("-");i=Number(l),r=Number(f)}else i=Number(u),r=c===void 0?i:e;if(!Number.isInteger(i)||!Number.isInteger(r)||i<t||r>e||i>r)return null;for(let l=i;l<=r;l+=m)o.add(l)}return o.size===0?null:[...o].sort((s,u)=>s-u)}function g(n,t){const e=n.doms.includes(t.getDate()),o=n.dows.includes(t.getDay());return n.domAny&&n.dowAny?!0:n.domAny?o:n.dowAny?e:e||o}export function matchesMinute(n,t){return n.minutes.includes(t.getMinutes())&&n.hours.includes(t.getHours())&&n.months.includes(t.getMonth()+1)&&g(n,t)}export function nextRunAt(n,t=new Date){const e=new Date(t.getTime());e.setSeconds(0,0),e.setMinutes(e.getMinutes()+1);const o=new Date(t.getTime()+366*864e5);for(;e<=o;){if(!n.months.includes(e.getMonth()+1)){e.setMonth(e.getMonth()+1,1),e.setHours(0,0,0,0);continue}if(!g(n,e)){e.setDate(e.getDate()+1),e.setHours(0,0,0,0);continue}if(!n.hours.includes(e.getHours())){e.setHours(e.getHours()+1,0,0,0);continue}if(!n.minutes.includes(e.getMinutes())){e.setMinutes(e.getMinutes()+1,0,0);continue}return e.toISOString()}return null}export function minuteKey(n){const t=e=>String(e).padStart(2,"0");return`${n.getFullYear()}-${t(n.getMonth()+1)}-${t(n.getDate())}T${t(n.getHours())}:${t(n.getMinutes())}`}
@@ -1,3 +1,3 @@
1
- import{createHmac as d,randomBytes as s,randomInt as m,scryptSync as o,timingSafeEqual as w}from"node:crypto";import{chmodSync as g,existsSync as p,mkdirSync as a,readFileSync as y,renameSync as P,rmSync as x,writeFileSync as c}from"node:fs";import h from"node:path";import{getAuthPath as k,getInitialPasswordPath as A}from"../db/paths.js";export const SESSION_COOKIE="weave_session",LOCAL_TOKEN_HEADER="x-weave-local",SESSION_TTL_MS=720*60*60*1e3;const u=64,T=16,l="abcdefghjkmnpqrstuvwxyz23456789";export function generatePassword(){const r=()=>Array.from({length:4},()=>l[m(l.length)]??"a").join("");return[r(),r(),r(),r()].join("-")}function f(r,t){const e=s(T).toString("hex");return{algo:"scrypt",salt:e,hash:o(r,e,u).toString("hex"),updatedAt:t}}function i(r,t){const e=Buffer.from(r),n=Buffer.from(t);return e.length===n.length&&w(e,n)}export function readCookie(r,t){if(r)for(const e of r.split(";")){const n=e.indexOf("=");if(!(n<0)&&e.slice(0,n).trim()===t)return e.slice(n+1).trim()}}export function sessionCookie(r){return`${SESSION_COOKIE}=${r}; HttpOnly; SameSite=Lax; Path=/; Max-Age=${Math.floor(SESSION_TTL_MS/1e3)}`}export function clearedSessionCookie(){return`${SESSION_COOKIE}=; HttpOnly; SameSite=Lax; Path=/; Max-Age=0`}function O(r){if(!p(r))return null;try{const t=JSON.parse(y(r,"utf8"));return t?.version!==1||typeof t.sessionSecret!="string"||typeof t.localToken!="string"?null:{version:1,password:t.password??null,sessionSecret:t.sessionSecret,localToken:t.localToken,createdAt:typeof t.createdAt=="string"?t.createdAt:new Date().toISOString()}}catch{return null}}function S(r,t){a(h.dirname(r),{recursive:!0});const e=`${r}.tmp`;c(e,`${JSON.stringify(t,null,2)}
2
- `,{encoding:"utf8",mode:384}),P(e,r);try{g(r,384)}catch{}}export class AuthService{file;authPath;markerPath;now;initialPassword;constructor(t={}){this.authPath=t.authPath??k(),this.markerPath=t.initialPasswordPath??A(),this.now=t.now??Date.now;const e=O(this.authPath);if(e){this.file=e,this.initialPassword=null;return}const n=generatePassword();this.file={version:1,password:f(n,this.nowIso()),sessionSecret:s(32).toString("hex"),localToken:s(24).toString("hex"),createdAt:this.nowIso()},S(this.authPath,this.file),this.writeMarker(n),this.initialPassword=n}isPasswordSet(){return this.file.password!==null}verifyPassword(t){const e=this.file.password;return e?i(o(t,e.salt,u).toString("hex"),e.hash):!1}setPassword(t){this.file={...this.file,password:f(t,this.nowIso()),sessionSecret:s(32).toString("hex")},S(this.authPath,this.file),x(this.markerPath,{force:!0})}getLocalToken(){return this.file.localToken}verifyLocalToken(t){return typeof t=="string"&&t!==""&&i(t,this.file.localToken)}issueSession(){const t=this.now()+SESSION_TTL_MS;return`${t}.${this.sign(t)}`}verifySession(t){if(!t)return!1;const e=t.indexOf(".");if(e<=0)return!1;const n=Number(t.slice(0,e));return!Number.isFinite(n)||n<=this.now()?!1:i(t.slice(e+1),this.sign(n))}isAuthenticated(t){return this.isLocallyTrusted(t)?!0:this.verifySession(readCookie(t.cookie,SESSION_COOKIE))}isLocallyTrusted(t){const e=t[LOCAL_TOKEN_HEADER];return this.verifyLocalToken(typeof e=="string"?e:void 0)}sign(t){return d("sha256",this.file.sessionSecret).update(`weave-session:${t}`).digest("hex")}nowIso(){return new Date(this.now()).toISOString()}writeMarker(t){a(h.dirname(this.markerPath),{recursive:!0}),c(this.markerPath,`${t}
1
+ import{createHmac as d,randomBytes as n,randomInt as m,scryptSync as o,timingSafeEqual as w}from"node:crypto";import{chmodSync as g,existsSync as p,mkdirSync as a,readFileSync as y,renameSync as P,rmSync as k,writeFileSync as c}from"node:fs";import h from"node:path";import{getAuthPath as x,getInitialPasswordPath as v}from"../db/paths.js";export const SESSION_COOKIE="weave_session",LOCAL_TOKEN_HEADER="x-weave-local",SESSION_TTL_MS=720*60*60*1e3;const l=64,O=16,u="abcdefghjkmnpqrstuvwxyz23456789";export function generatePassword(){const s=()=>Array.from({length:4},()=>u[m(u.length)]??"a").join("");return[s(),s(),s(),s()].join("-")}function f(s,t){const e=n(O).toString("hex");return{algo:"scrypt",salt:e,hash:o(s,e,l).toString("hex"),updatedAt:t}}function r(s,t){const e=Buffer.from(s),i=Buffer.from(t);return e.length===i.length&&w(e,i)}export function readCookie(s,t){if(s)for(const e of s.split(";")){const i=e.indexOf("=");if(!(i<0)&&e.slice(0,i).trim()===t)return e.slice(i+1).trim()}}export function sessionCookie(s){return`${SESSION_COOKIE}=${s}; HttpOnly; SameSite=Lax; Path=/; Max-Age=${Math.floor(SESSION_TTL_MS/1e3)}`}export function clearedSessionCookie(){return`${SESSION_COOKIE}=; HttpOnly; SameSite=Lax; Path=/; Max-Age=0`}function T(s){if(!p(s))return null;try{const t=JSON.parse(y(s,"utf8"));return t?.version!==1||typeof t.sessionSecret!="string"||typeof t.localToken!="string"?null:{version:1,password:t.password??null,sessionSecret:t.sessionSecret,localToken:t.localToken,createdAt:typeof t.createdAt=="string"?t.createdAt:new Date().toISOString()}}catch{return null}}function S(s,t){a(h.dirname(s),{recursive:!0});const e=`${s}.tmp`;c(e,`${JSON.stringify(t,null,2)}
2
+ `,{encoding:"utf8",mode:384}),P(e,s);try{g(s,384)}catch{}}export class AuthService{file;authPath;markerPath;now;initialPassword;constructor(t={}){this.authPath=t.authPath??x(),this.markerPath=t.initialPasswordPath??v(),this.now=t.now??Date.now;const e=T(this.authPath);if(e){this.file=e,this.initialPassword=null;return}const i=generatePassword();this.file={version:1,password:f(i,this.nowIso()),sessionSecret:n(32).toString("hex"),localToken:n(24).toString("hex"),createdAt:this.nowIso()},S(this.authPath,this.file),this.writeMarker(i),this.initialPassword=i}isPasswordSet(){return this.file.password!==null}verifyPassword(t){const e=this.file.password;return e?r(o(t,e.salt,l).toString("hex"),e.hash):!1}setPassword(t){this.file={...this.file,password:f(t,this.nowIso()),sessionSecret:n(32).toString("hex")},S(this.authPath,this.file),k(this.markerPath,{force:!0})}getLocalToken(){return this.file.localToken}verifyLocalToken(t){return typeof t=="string"&&t!==""&&r(t,this.file.localToken)}issueSession(){const t=this.now()+SESSION_TTL_MS;return`${t}.${this.sign(t)}`}verifySession(t){if(!t)return!1;const e=t.indexOf(".");if(e<=0)return!1;const i=Number(t.slice(0,e));return!Number.isFinite(i)||i<=this.now()?!1:r(t.slice(e+1),this.sign(i))}isAuthenticated(t){return this.isLocallyTrusted(t)?!0:this.verifySession(readCookie(t.cookie,SESSION_COOKIE))}isLocallyTrusted(t){const e=t[LOCAL_TOKEN_HEADER];return this.verifyLocalToken(typeof e=="string"?e:void 0)}sign(t){return d("sha256",this.file.sessionSecret).update(`weave-session:${t}`).digest("hex")}nowIso(){return new Date(this.now()).toISOString()}writeMarker(t){a(h.dirname(this.markerPath),{recursive:!0}),c(this.markerPath,`${t}
3
3
  `,{encoding:"utf8",mode:384})}}
@@ -1 +1 @@
1
- import{RATE_BUCKET_MS as s}from"../hooks/dashboard-rate.js";export const DASHBOARD_WINDOW_MS=36e5;const b=60,d=1e3,h=6e4;export function startDashboardPusher(t){let o=!1,i={projects:0,sessions:0},a=0;const r=()=>{i={projects:t.projects.list().length,sessions:t.sessions.countAll()},a=Date.now()},l=()=>({...i,...t.rate.totals}),m=()=>{queueMicrotask(()=>{const n=Date.now(),c=DASHBOARD_WINDOW_MS/s,u=Math.floor(n/s)*s-(c-1)*s,f=t.projects.list().map(e=>e.id);t.rate.isSeeded||(t.rate.seed(t.events.seriesBySecond(f,new Date(u).toISOString())),t.rate.seedTotals(t.events.countAll(),t.events.countSince(f,new Date(new Date(n).setHours(0,0,0,0)).toISOString())),r()),Date.now()-a>h&&r();const D=new Date(n).toISOString();t.bus.emit({kind:"dashboard.totals",at:D,totals:l()});for(let e=0;e<c;e+=b){const E=Math.min(b,c-e),_=u+e*s,I=t.rate.bucketsFor(_,E);t.bus.emit({kind:"dashboard.series",at:D,series:I.map((A,M)=>({at:new Date(_+M*s).toISOString().slice(0,19),n:A}))})}})},w=t.bus.subscribe(n=>{n.kind==="event.ingested"&&(o=!0)}),S=setInterval(()=>{o&&(o=!1,Date.now()-a>h&&r(),t.bus.emit({kind:"dashboard.delta",at:new Date().toISOString(),series:t.rate.recentBuckets(12),totals:l()}))},d);return S.unref?.(),{attach:m,stop:()=>{w(),clearInterval(S)}}}
1
+ import{RATE_BUCKET_MS as s}from"../hooks/dashboard-rate.js";export const DASHBOARD_WINDOW_MS=36e5;const w=60,f=1e3,h=6e4;export function startDashboardPusher(e){let o=!1,c={projects:0,sessions:0},a=0;const r=()=>{c={projects:e.projects.list().length,sessions:e.sessions.countAll()},a=Date.now()},l=()=>({...c,...e.rate.totals}),p=()=>{queueMicrotask(()=>{const n=Date.now(),i=DASHBOARD_WINDOW_MS/s,u=Math.floor(n/s)*s-(i-1)*s,S=e.projects.list().map(t=>t.id);e.rate.isSeeded||(e.rate.seed(e.events.seriesBySecond(S,new Date(u).toISOString())),e.rate.seedTotals(e.events.countAll(),e.events.countSince(S,new Date(new Date(n).setHours(0,0,0,0)).toISOString())),r()),Date.now()-a>h&&r();const D=new Date(n).toISOString();e.bus.emit({kind:"dashboard.totals",at:D,totals:l()});for(let t=0;t<i;t+=w){const I=Math.min(w,i-t),b=u+t*s,g=e.rate.bucketsFor(b,I);e.bus.emit({kind:"dashboard.series",at:D,series:g.map((k,O)=>({at:new Date(b+O*s).toISOString().slice(0,19),n:k}))})}})},m=e.bus.subscribe(n=>{n.kind==="event.ingested"&&(o=!0)}),d=setInterval(()=>{o&&(o=!1,Date.now()-a>h&&r(),e.bus.emit({kind:"dashboard.delta",at:new Date().toISOString(),series:e.rate.recentBuckets(12),totals:l()}))},f);return d.unref?.(),{attach:p,stop:()=>{m(),clearInterval(d)}}}
@@ -1 +1 @@
1
- import{EventEmitter as t}from"node:events";export class DataBus{emitter=new t;subscribers=0;constructor(){this.emitter.setMaxListeners(100)}emit(s){this.emitter.emit("change",s)}hasSubscribers(){return this.subscribers>0}subscribe(s){return this.subscribers+=1,this.emitter.on("change",s),()=>{this.subscribers-=1,this.emitter.off("change",s)}}}
1
+ import{EventEmitter as s}from"node:events";export class DataBus{emitter=new s;subscribers=0;constructor(){this.emitter.setMaxListeners(100)}emit(t){this.emitter.emit("change",t)}hasSubscribers(){return this.subscribers>0}subscribe(t){return this.subscribers+=1,this.emitter.on("change",t),()=>{this.subscribers-=1,this.emitter.off("change",t)}}}
@@ -1,2 +1,2 @@
1
- import{chmodSync as o,existsSync as c,mkdirSync as i,readFileSync as u,renameSync as y,rmSync as m,writeFileSync as s}from"node:fs";import p from"node:path";import{getDecisionKeyPath as t}from"../db/paths.js";export function readDecisionKey(n=t()){if(!c(n))return null;try{const r=JSON.parse(u(n,"utf8"));return typeof r.apiKey=="string"&&r.apiKey!==""?r.apiKey:null}catch{return null}}export function writeDecisionKey(n,r=t()){if(n===null||n===""){m(r,{force:!0});return}i(p.dirname(r),{recursive:!0});const e=`${r}.tmp`;s(e,`${JSON.stringify({apiKey:n},null,2)}
2
- `,{encoding:"utf8",mode:384}),y(e,r);try{o(r,384)}catch{}}export function hasDecisionKey(n=t()){return readDecisionKey(n)!==null}
1
+ import{chmodSync as t,existsSync as c,mkdirSync as o,readFileSync as s,renameSync as a,rmSync as y,writeFileSync as u}from"node:fs";import l from"node:path";import{getDecisionKeyPath as n}from"../db/paths.js";export function readDecisionKey(i=n()){if(!c(i))return null;try{const e=JSON.parse(s(i,"utf8"));return typeof e.apiKey=="string"&&e.apiKey!==""?e.apiKey:null}catch{return null}}export function writeDecisionKey(i,e=n()){if(i===null||i===""){y(e,{force:!0});return}o(l.dirname(e),{recursive:!0});const r=`${e}.tmp`;u(r,`${JSON.stringify({apiKey:i},null,2)}
2
+ `,{encoding:"utf8",mode:384}),a(r,e);try{t(e,384)}catch{}}export function hasDecisionKey(i=n()){return readDecisionKey(i)!==null}
@@ -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 ve}from"../repositories/hook-events.js";import{LibraryRepository as be}from"../repositories/libraries.js";import{HookRuleRepository as ne}from"../repositories/hook-rules.js";import{HookDispatchRepository as Re}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 W}from"@weavecode/core";import{messagingSurfaceFor as Pe,narrationSurfaceFor as Ee}from"../surfaces.js";import{syntheticSessionIds as Te}from"../hooks/synthetic-sessions.js";import{createEdgeExtract as Oe}from"../hooks/edge-extract.js";import{HookRuleRegistry as Ie}from"../hooks/registry.js";import{HookDispatcher as Ae}from"../hooks/dispatcher.js";import{HookEventBus as Ce}from"../hooks/bus.js";import{ResumeRunner as _e}from"../hooks/resume-runner.js";import{HeadlessRunner as Fe}from"../hooks/headless-runner.js";import{MessageDeliverer as He}from"../hooks/message-deliverer.js";import{QuestionTracker as $e}from"../hooks/question-tracker.js";import{SideQuestionRepository as Be}from"../repositories/side-questions.js";import{claimSideAnswer as Me}from"../hooks/side-questions.js";import{DashboardRateCache as Le}from"../hooks/dashboard-rate.js";import{startDashboardPusher as Ue}from"./dashboard-pusher.js";import{startPromptFlusher as Ne}from"../hooks/prompt-flusher.js";import{SessionWatchRepository as We}from"../repositories/session-watches.js";import{PushSubscriptionRepository as je}from"../repositories/push-subscriptions.js";import{UploadRepository as xe}from"../repositories/uploads.js";import{defaultUploadSessions as Qe}from"./upload-sessions.js";import{PushNotifier as qe}from"../hooks/push-notify.js";import{OrchestrationRepository as Ke,OrchestrationRunRepository as Ge}from"../repositories/orchestrations.js";import{WatchEngine as Je}from"../hooks/watch-engine.js";import{OrchestrationEngine as Ve,createForkConditionJudge as Ye}from"../hooks/orchestration-engine.js";import{createDecisionConditionJudge as ze}from"../hooks/decision-judge.js";import{readDecisionKey as Xe}from"./decision-config.js";import{openSessionTerminal as Ze}from"./session-open.js";import{loadAllPlugins as es}from"../hooks/plugin-loader.js";import{ensureBuiltinMarket as ss,builtinMarketDir as ts}from"../market/builtin.js";import{ToolkitService as os}from"../hooks/toolkit.js";import{startSessionSweeper as rs}from"../hooks/session-sweeper.js";import{startStatuslineCacheSweeper as ns}from"../statusline/cache-sweeper.js";import{readStatuslineFacts as is}from"../statusline/manager.js";import{WatchService as as}from"../watch/watch-service.js";import{weaveRequestHandler as ls}from"./server.js";import{startTlsServer as cs}from"./tls.js";import{DataBus as ps}from"./data-bus.js";import{TerminalTopologyRefresher as ms}from"./terminal-topology-refresher.js";import{SnapshotRefresher as j}from"./snapshot-refresher.js";import{SessionProbe as us,dbModelFactResolver as ds,dbTranscriptPathResolver as fs}from"./session-probe.js";import{NarrationWatcher as hs}from"./narration-watcher.js";import{InflightCountsRefresher as ws}from"./inflight-counts-refresher.js";import{ProjectUpdatesRefresher as gs}from"./project-updates-refresher.js";import{FingerprintCache as Ss}from"../install/fingerprint.js";import{detectProjectUpdateCounts as vs}from"../install/updates.js";import{pidAliveOf as bs}from"./claude-liveness.js";import{combinedLivenessOf as R}from"./liveness.js";import{promptTerminalChannel as ie,readTerminalCounts as Rs}from"./opener.js";import{wireHookFilePipeline as ys}from"./hook-pipeline.js";import{DEFAULT_PORT as x,DAEMON_HOST as ks,DEFAULT_BIND_HOST as Ds,findFreePort as Ps,isPortFree as Es}from"./port.js";import{writeDaemonState as ae}from"./state.js";import{ensureDataLayout as Ts}from"../db/layout.js";import{pruneFileIndexes as Os}from"./project-files.js";import{pruneInstallTmp as Is}from"../hooks/plugin-installer.js";import{readDaemonSettingsSync as y,setDaemonSettingsDb as As,DEFAULT_SERVER_SETTINGS as Cs}from"./settings.js";import{AuthService as _s}from"./dashboard-auth.js";import{resolveStaticDir as Fs}from"./static.js";const Hs="CLAUDE_CODE_CHILD_SESSION"in process.env;delete process.env.CLAUDE_CODE_CHILD_SESSION;for(const p of De)delete process.env[p];async function $s(){Ts();const p=await Es(x)?x:await Ps(x+1);ae({pid:process.pid,port:p,startedAt:new Date().toISOString()});const t=ge();As(t);const f=y().server?.bindHost??Ds,O=y().server?.tlsPort??Cs.tlsPort,I=new _s;I.initialPassword&&console.log(`[dev] initial dashboard password: ${I.initialPassword}`);const r=new Se(t);Os(r.list().map(e=>e.id)),Is();const a=new ve(t),u=new be(t),h=ke(),le=h.byCapability("events").flatMap(e=>e.events??[]),k=new Ie(new ne(t)),D=new Re(t),o=new ye(t),n=new Ce;{const e=await ss({libraries:u});e.error?console.error(`[dev] builtin market unavailable: ${e.error}`):e.changed&&console.log(`[dev] builtin market ${e.form==="link"?"linked":"copied"} -> ${ts(u.dataRoot)}`)}const{loader:m}=await es({rules:new ne(t),registry:k,states:new T(t),bus:n,libraries:u},r.list());{const e=m.list().filter(s=>s.status==="rejected");console.log(`[dev] plugins loaded: ${m.list().length} (rejected: ${e.length})`);for(const s of e)console.log(`[dev] rejected ${s.id}: ${s.error}`)}m.watchRoots();const Q={list:()=>m.list(),setPluginEnabled:(e,s)=>m.setPluginEnabled(e,s),reloadAll:()=>m.reloadAll(),rescan:()=>m.rescanRoots(r.list(),u)},ce=new os({projects:r,states:new T(t),plugins:Q,libraries:u}),A={run:null},q=new Ae({registry:k,dispatches:D,bus:n,projects:r,sessions:o,plugins:m,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 W(s)?h.get(s)?.titles?.sessionTitleOf(e)??null:null}}),P=new Fe,pe=new _e({dispatches:D,sessions:o,projects:r,bus:n,resumeSpec:h.get("claude")?.resume,headless:P}),c=new He({sessions:o,projects:r,hookEvents:a,bus:n,headless:P,terminal:ie(()=>y().terminal),blockedByQuestion:e=>w.get(e)!=null,livenessOf:R,sideAnswerStore:{answerById:(e,s,i)=>{$.answerById(e,s,i)}}});Ne(c);const C=new We(t),_=new Je({watches:C,deliverer:c,sessions:o,bus:n,livenessOf:R}),K=new je(t),F=new xe(t),me=new qe({subscriptions:K,sessions:o,bus:n}),H=new Ke(t),G=new Ge(t),d=new us(fs(a),ds(a,e=>o.getBySessionId(e)?.harness??null)),J=new hs(n,e=>Ee(W(e)?e:"claude"),e=>d.transcriptPathOf(e),e=>o.livenessRowOf(e)?.harness??null);J.start();const w=new $e({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?d.interruptedAt(e,s.lastSeenAt):null}});w.seedFromDb();const $=new Be(t),V=new Le,B=Ue({rate:V,events:a,sessions:o,projects:r,bus:n}),Y={repo:$,bus:n,settle:e=>{c.interrupt(e.sessionId)}},z=new as(r);z.start();const l=new ps,g=new ms(async()=>({counts:await Rs(r.list()),terminals:await c.sessionTerminals()}),l,{shouldRun:()=>l.hasSubscribers(),graceMs:1e4});g.start();const M=new j(()=>{const e=R(),s={};for(const i of o.listWithCounts()){const b=bs(i,e);b!==null&&(s[i.sessionId]=b)}return{alive:s}},l,{key:"sessionLiveness",shouldRun:()=>l.hasSubscribers()});M.start();const L=new j(()=>{const e={};for(const s of o.listWithCounts()){if(s.turnOpen!==!0)continue;const i=d.interruptedAt(s.sessionId,s.lastSeenAt);i!==null&&(e[s.sessionId]=i)}return{interrupted:e}},l,{key:"sessionInterrupt",intervalMs:5e3,shouldRun:()=>l.hasSubscribers()});L.start(),new j(()=>{const e={};for(const s of r.list())e[s.id]=is(s.path);return e},l,{key:"statusline",intervalMs:5e3,shouldRun:()=>l.hasSubscribers(),invalidateOnly:!0}).start();const ue=new ws(()=>c.listInflightCounts(),l,n);let X=null;const S=Oe({sessions:o,projects:r,harnessOf:e=>{const s=a.listBySession(e,1),i=s[s.length-1]?.source;return W(i)?i:null},surfaceFor:Pe,headless:P,onSyntheticChange:()=>X?.pushSyntheticSessions(Te())});A.run=e=>S.run(e);const de=ze({config:async()=>{const e=y().decision;if(!e?.baseUrl||!e.model)return null;const s=Xe();return s?{baseUrl:e.baseUrl,model:e.model,apiKey:s}:null},fallback:Ye({supports:e=>S.supports(e),extract:e=>S.run(e)})}),v=new Ve({orchestrations:H,runs:G,deliverer:c,sessions:o,bus:n,supportsExtract:e=>S.supports(e),extract:e=>S.run(e),conditionJudge:de,deferWhenUserPresent:!0,ensureOpen:async e=>{const s=a.listBySession(e,1).at(-1)?.id??0,i=await Ze({hookSessions:o,hookEvents:a,projects:r,harnesses:h,sessionProbe:d,terminalRefresher:g},e);if(!i.ok)return i;let b=!1;for(let re=0;re<60;re++){if(a.listBySession(e,20).some(E=>E.id>s&&E.eventType==="SessionStart"))return{ok:!0,ack:"session-start"};R().get(e)===!0&&(b=!0),await new Promise(E=>setTimeout(E,250))}return b?{ok:!0,ack:"registry"}:{ok:!1,error:"session did not report ready within 15s"}}});v.rearm();const Z=setInterval(()=>v.cronTick(),3e4);Z.unref();const fe=new Ss,he=new gs(()=>vs(r.list(),u.list(),fe),l,n,()=>l.hasSubscribers());rs({sessions:o,events:a,dispatches:D,deliverer:c,watches:C,orchestrations:H,watchEngine:_,orchestrationEngine:v,questions:w,sideQuestions:$,probe:d,uploads:F,uploadSessions:Qe,livenessOf:R}),ns();const U=ys({projects:r,rules:k,sessions:o,bus:n,dispatcher:q,watchEngine:_,orchestrationEngine:v,messagePipe:c,questionTracker:w,sideQuestions:{onEvent:e=>{Me(Y,e)}},sessionProbe:d,uploads:F,dashboardRate:V,terminalTopologyKick:()=>{g.refreshNow()}});X=U;const N=Fs(),ee=ls({projects:r,port:p,tlsPort:O,watch:z,hookEvents:a,adapters:le,harnesses:h,libraries:u,staticDir:N,hookRegistry:k,hookDispatches:D,hookSessions:o,hookBus:n,dataBus:l,terminalRefresher:g,interruptRefresher:L,livenessRefresher:M,sessionProbe:d,inflightRefresher:ue,updatesRefresher:he,hookDispatcher:q,hookRunner:pe,messageDeliverer:c,terminal:ie(()=>y().terminal),uploads:F,questionTracker:w,sideQuestions:Y,sessionWatches:C,watchEngine:_,orchestrations:H,orchestrationRuns:G,orchestrationEngine:v,pushSubscriptions:K,pushNotifier:me,onAttach:B.attach,dashboardRefresh:B.attach,hookPlugins:Q,hookMirror:U.mirror,pluginStates:new T(t),toolkit:ce,auth:I}),se=we.createServer(ee);let te=null;cs({port:O,bindHost:f,handler:ee}).then(e=>{te=e,e&&console.log(`[dev] weave daemon tls listening on https://${f}:${e.port}`)});const oe=()=>{g.stop(),M.stop(),L.stop(),P.killAll(),clearInterval(Z),J.stop(),B.stop(),U.stop(),se.close(),te?.server.close(),process.exit(0)};process.on("SIGTERM",oe),process.on("SIGINT",oe),se.listen(p,f,()=>{ae({pid:process.pid,port:p,startedAt:new Date().toISOString(),host:f,tlsPort:O}),console.log(`[dev] weave daemon listening on http://${f}:${p}`),console.log(`[dev] cli/dashboard local url: http://${ks}:${p}`),console.log(`[dev] child-session marker stripped: ${Hs}`),console.log(N?`[dev] static: ${N}`:"[dev] static: (web/dist not built \u2014 run pnpm build:web)")})}$s();
1
+ import ws from"node:http";import{openDatabase as Ss}from"../db/db.js";import{ProjectRepository as gs}from"../repositories/projects.js";import{HookEventRepository as bs}from"../repositories/hook-events.js";import{LibraryRepository as vs}from"../repositories/libraries.js";import{HookRuleRepository as ns}from"../repositories/hook-rules.js";import{HookDispatchRepository as Rs}from"../repositories/hook-dispatches.js";import{PluginStateRepository as I}from"../repositories/plugin-states.js";import{SessionRepository as ys}from"../repositories/sessions.js";import{createRuntimeRegistry as ks}from"@weavecode/harness";import{TERMINAL_LOCATOR_ENV_KEYS as Es,isHarness as N}from"@weavecode/core";import{messagingSurfaceFor as Ds,narrationSurfaceFor as Ps}from"../surfaces.js";import{syntheticSessionIds as Is}from"../hooks/synthetic-sessions.js";import{createEdgeExtract as Ts}from"../hooks/edge-extract.js";import{HookRuleRegistry as Os}from"../hooks/registry.js";import{HookDispatcher as As}from"../hooks/dispatcher.js";import{HookEventBus as Cs}from"../hooks/bus.js";import{ResumeRunner as Fs}from"../hooks/resume-runner.js";import{HeadlessRunner as Hs}from"../hooks/headless-runner.js";import{MessageDeliverer as _s}from"../hooks/message-deliverer.js";import{QuestionTracker as $s}from"../hooks/question-tracker.js";import{SideQuestionRepository as js}from"../repositories/side-questions.js";import{claimSideAnswer as Bs}from"../hooks/side-questions.js";import{DashboardRateCache as Ms}from"../hooks/dashboard-rate.js";import{startDashboardPusher as Ls}from"./dashboard-pusher.js";import{startPromptFlusher as Us}from"../hooks/prompt-flusher.js";import{SessionWatchRepository as Ns}from"../repositories/session-watches.js";import{PushSubscriptionRepository as Ws}from"../repositories/push-subscriptions.js";import{UploadRepository as qs}from"../repositories/uploads.js";import{defaultUploadSessions as xs}from"./upload-sessions.js";import{PushNotifier as Qs}from"../hooks/push-notify.js";import{OrchestrationRepository as Ks,OrchestrationRunRepository as Gs}from"../repositories/orchestrations.js";import{WatchEngine as Js}from"../hooks/watch-engine.js";import{OrchestrationEngine as Vs,createForkConditionJudge as Ys}from"../hooks/orchestration-engine.js";import{createDecisionConditionJudge as zs}from"../hooks/decision-judge.js";import{readDecisionKey as Xs}from"./decision-config.js";import{openSessionTerminal as Zs}from"./session-open.js";import{loadAllPlugins as se}from"../hooks/plugin-loader.js";import{ensureBuiltinMarket as ee,builtinMarketDir as oe}from"../market/builtin.js";import{ToolkitService as te}from"../hooks/toolkit.js";import{startSessionSweeper as re}from"../hooks/session-sweeper.js";import{startStatuslineCacheSweeper as ne}from"../statusline/cache-sweeper.js";import{readStatuslineFacts as ie}from"../statusline/manager.js";import{WatchService as ae}from"../watch/watch-service.js";import{weaveRequestHandler as le}from"./server.js";import{startTlsServer as pe}from"./tls.js";import{DataBus as ce}from"./data-bus.js";import{TerminalTopologyRefresher as me}from"./terminal-topology-refresher.js";import{SnapshotRefresher as W}from"./snapshot-refresher.js";import{SessionProbe as ue,dbModelFactResolver as de,dbTranscriptPathResolver as fe}from"./session-probe.js";import{NarrationWatcher as he}from"./narration-watcher.js";import{InflightCountsRefresher as we}from"./inflight-counts-refresher.js";import{ProjectUpdatesRefresher as Se}from"./project-updates-refresher.js";import{FingerprintCache as ge}from"../install/fingerprint.js";import{detectProjectUpdateCounts as be}from"../install/updates.js";import{pidAliveOf as ve}from"./claude-liveness.js";import{combinedLivenessOf as R}from"./liveness.js";import{promptTerminalChannel as is,readTerminalCounts as Re}from"./opener.js";import{wireHookFilePipeline as ye}from"./hook-pipeline.js";import{DEFAULT_PORT as q,DAEMON_HOST as ke,DEFAULT_BIND_HOST as Ee,findFreePort as De,isPortFree as Pe}from"./port.js";import{writeDaemonState as as}from"./state.js";import{ensureDataLayout as Ie}from"../db/layout.js";import{pruneFileIndexes as Te}from"./project-files.js";import{pruneInstallTmp as Oe}from"../hooks/plugin-installer.js";import{readDaemonSettingsSync as y,setDaemonSettingsDb as Ae,DEFAULT_SERVER_SETTINGS as Ce}from"./settings.js";import{AuthService as Fe}from"./dashboard-auth.js";import{resolveStaticDir as He}from"./static.js";const _e="CLAUDE_CODE_CHILD_SESSION"in process.env;delete process.env.CLAUDE_CODE_CHILD_SESSION;for(const c of Es)delete process.env[c];async function $e(){Ie();const c=await Pe(q)?q:await De(q+1);as({pid:process.pid,port:c,startedAt:new Date().toISOString()});const t=Ss();Ae(t);const f=y().server?.bindHost??Ee,T=y().server?.tlsPort??Ce.tlsPort,O=new Fe;O.initialPassword&&console.log(`[dev] initial dashboard password: ${O.initialPassword}`);const r=new gs(t);Te(r.list().map(s=>s.id)),Oe();const a=new bs(t),u=new vs(t),h=ks(),ls=h.byCapability("events").flatMap(s=>s.events??[]),k=new Os(new ns(t)),E=new Rs(t),o=new ys(t),n=new Cs;{const s=await ee({libraries:u});s.error?console.error(`[dev] builtin market unavailable: ${s.error}`):s.changed&&console.log(`[dev] builtin market ${s.form==="link"?"linked":"copied"} -> ${oe(u.dataRoot)}`)}const{loader:m}=await se({rules:new ns(t),registry:k,states:new I(t),bus:n,libraries:u},r.list());{const s=m.list().filter(e=>e.status==="rejected");console.log(`[dev] plugins loaded: ${m.list().length} (rejected: ${s.length})`);for(const e of s)console.log(`[dev] rejected ${e.id}: ${e.error}`)}m.watchRoots();const x={list:()=>m.list(),setPluginEnabled:(s,e)=>m.setPluginEnabled(s,e),reloadAll:()=>m.reloadAll(),rescan:()=>m.rescanRoots(r.list(),u)},ps=new te({projects:r,states:new I(t),plugins:x,libraries:u}),A={run:null},Q=new As({registry:k,dispatches:E,bus:n,projects:r,sessions:o,plugins:m,pluginStates:new I(t),classify:s=>A.run?A.run(s):Promise.resolve(null),sessionTitleOf:async s=>{const e=a.listBySession(s,1).at(-1)?.source;return N(e)?h.get(e)?.titles?.sessionTitleOf(s)??null:null}}),D=new Hs,cs=new Fs({dispatches:E,sessions:o,projects:r,bus:n,resumeSpec:h.get("claude")?.resume,headless:D}),p=new _s({sessions:o,projects:r,hookEvents:a,bus:n,headless:D,terminal:is(()=>y().terminal),blockedByQuestion:s=>w.get(s)!=null,livenessOf:R,sideAnswerStore:{answerById:(s,e,i)=>{$.answerById(s,e,i)}}});Us(p);const C=new Ns(t),F=new Js({watches:C,deliverer:p,sessions:o,bus:n,livenessOf:R}),K=new Ws(t),H=new qs(t),ms=new Qs({subscriptions:K,sessions:o,bus:n}),_=new Ks(t),G=new Gs(t),d=new ue(fe(a),de(a,s=>o.getBySessionId(s)?.harness??null)),J=new he(n,s=>Ps(N(s)?s:"claude"),s=>d.transcriptPathOf(s),s=>o.livenessRowOf(s)?.harness??null);J.start();const w=new $s({sessions:o,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=o.getBySessionId(s);return e?d.interruptedAt(s,o.lastMainEventAtOf(s)??e.lastSeenAt):null}});w.seedFromDb();const $=new js(t),V=new Ms,j=Ls({rate:V,events:a,sessions:o,projects:r,bus:n}),Y={repo:$,bus:n,settle:s=>{p.interrupt(s.sessionId)}},z=new ae(r);z.start();const l=new ce,S=new me(async()=>({counts:await Re(r.list()),terminals:await p.sessionTerminals()}),l,{shouldRun:()=>l.hasSubscribers(),graceMs:1e4});S.start();const B=new W(()=>{const s=R(),e={};for(const i of o.listWithCounts()){const v=ve(i,s);v!==null&&(e[i.sessionId]=v)}return{alive:e}},l,{key:"sessionLiveness",shouldRun:()=>l.hasSubscribers()});B.start();const M=new W(()=>{const s={};for(const e of o.listWithCounts()){if(e.turnOpen!==!0)continue;const i=d.interruptedAt(e.sessionId,o.lastMainEventAtOf(e.sessionId)??e.lastSeenAt);i!==null&&(s[e.sessionId]=i)}return{interrupted:s}},l,{key:"sessionInterrupt",intervalMs:5e3,shouldRun:()=>l.hasSubscribers()});M.start(),new W(()=>{const s={};for(const e of r.list())s[e.id]=ie(e.path);return s},l,{key:"statusline",intervalMs:5e3,shouldRun:()=>l.hasSubscribers(),invalidateOnly:!0}).start();const us=new we(()=>p.listInflightCounts(),l,n);let X=null;const g=Ts({sessions:o,projects:r,harnessOf:s=>{const e=a.listBySession(s,1),i=e[e.length-1]?.source;return N(i)?i:null},surfaceFor:Ds,headless:D,onSyntheticChange:()=>X?.pushSyntheticSessions(Is())});A.run=s=>g.run(s);const ds=zs({config:async()=>{const s=y().decision;if(!s?.baseUrl||!s.model)return null;const e=Xs();return e?{baseUrl:s.baseUrl,model:s.model,apiKey:e}:null},fallback:Ys({supports:s=>g.supports(s),extract:s=>g.run(s)})}),b=new Vs({orchestrations:_,runs:G,deliverer:p,sessions:o,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 Zs({hookSessions:o,hookEvents:a,projects:r,harnesses:h,sessionProbe:d,terminalRefresher:S},s);if(!i.ok)return i;let v=!1;for(let rs=0;rs<60;rs++){if(a.listBySession(s,20).some(P=>P.id>e&&P.eventType==="SessionStart"))return{ok:!0,ack:"session-start"};R().get(s)===!0&&(v=!0),await new Promise(P=>setTimeout(P,250))}return v?{ok:!0,ack:"registry"}:{ok:!1,error:"session did not report ready within 15s"}}});b.rearm();const Z=setInterval(()=>b.cronTick(),3e4);Z.unref();const fs=new ge,hs=new Se(()=>be(r.list(),u.list(),fs),l,n,()=>l.hasSubscribers());re({sessions:o,events:a,dispatches:E,deliverer:p,watches:C,orchestrations:_,watchEngine:F,orchestrationEngine:b,questions:w,sideQuestions:$,probe:d,uploads:H,uploadSessions:xs,livenessOf:R}),ne();const L=ye({projects:r,rules:k,sessions:o,bus:n,dispatcher:Q,watchEngine:F,orchestrationEngine:b,messagePipe:p,questionTracker:w,sideQuestions:{onEvent:s=>{Bs(Y,s)}},sessionProbe:d,uploads:H,dashboardRate:V,terminalTopologyKick:()=>{S.refreshNow()}});X=L;const U=He(),ss=le({projects:r,port:c,tlsPort:T,watch:z,hookEvents:a,adapters:ls,harnesses:h,libraries:u,staticDir:U,hookRegistry:k,hookDispatches:E,hookSessions:o,hookBus:n,dataBus:l,terminalRefresher:S,interruptRefresher:M,livenessRefresher:B,sessionProbe:d,inflightRefresher:us,updatesRefresher:hs,hookDispatcher:Q,hookRunner:cs,messageDeliverer:p,terminal:is(()=>y().terminal),uploads:H,questionTracker:w,sideQuestions:Y,sessionWatches:C,watchEngine:F,orchestrations:_,orchestrationRuns:G,orchestrationEngine:b,pushSubscriptions:K,pushNotifier:ms,onAttach:j.attach,dashboardRefresh:j.attach,hookPlugins:x,hookMirror:L.mirror,pluginStates:new I(t),toolkit:ps,auth:O}),es=ws.createServer(ss);let os=null;pe({port:T,bindHost:f,handler:ss}).then(s=>{os=s,s&&console.log(`[dev] weave daemon tls listening on https://${f}:${s.port}`)});const ts=()=>{S.stop(),B.stop(),M.stop(),D.killAll(),clearInterval(Z),J.stop(),j.stop(),L.stop(),es.close(),os?.server.close(),process.exit(0)};process.on("SIGTERM",ts),process.on("SIGINT",ts),es.listen(c,f,()=>{as({pid:process.pid,port:c,startedAt:new Date().toISOString(),host:f,tlsPort:T}),console.log(`[dev] weave daemon listening on http://${f}:${c}`),console.log(`[dev] cli/dashboard local url: http://${ke}:${c}`),console.log(`[dev] child-session marker stripped: ${_e}`),console.log(U?`[dev] static: ${U}`:"[dev] static: (web/dist not built \u2014 run pnpm build:web)")})}$e();
@@ -1 +1,7 @@
1
- import{startDaemon as m}from"./start.js";m();
1
+ import{appendFileSync as r,mkdirSync as c}from"node:fs";import s from"node:path";import{getLogsDir as a}from"../db/paths.js";import{startDaemon as m}from"./start.js";const i=(t,o)=>{const n=o instanceof Error?o.stack??o.message:String(o);try{const e=a();c(e,{recursive:!0}),r(s.join(e,"daemon-boot.log"),`[${new Date().toISOString()}] ${t}:
2
+ ${n}
3
+
4
+ `,"utf8")}catch{}process.exit(1)};process.on("uncaughtException",t=>i("uncaughtException",t)),process.on("unhandledRejection",t=>i("unhandledRejection",t));try{m()}catch(t){const o=t instanceof Error?t.stack??t.message:String(t);try{const n=a();c(n,{recursive:!0}),r(s.join(n,"daemon-boot.log"),`[${new Date().toISOString()}] boot crash:
5
+ ${o}
6
+
7
+ `,"utf8")}catch{}process.exit(1)}
@@ -1 +1 @@
1
- import{readdir as d,stat as l}from"node:fs/promises";import p from"node:os";import a from"node:path";function f(n,s){return new Promise((r,t)=>{const e=setTimeout(()=>t(new Error("timeout")),s);n.then(i=>{clearTimeout(e),r(i)},i=>{clearTimeout(e),t(i)})})}let c=null;const h=5*6e4;async function w(){if(c&&Date.now()-c.at<h)return c.drives;const n="ABCDEFGHIJKLMNOPQRSTUVWXYZ".split(""),r=(await Promise.all(n.map(async t=>{const e=`${t}:\\`;try{return await f(l(e),4e3),e}catch{return null}}))).filter(t=>t!==null);return c={at:Date.now(),drives:r},r}export async function listBrowseRoots(n){const s=[],r=new Set,t=(o,m)=>{r.has(o)||(r.add(o),s.push({path:o,kind:m}))},e=p.homedir();t(e,"home");const i=[["Desktop","desktop"],["Downloads","downloads"],["Documents","documents"]];for(const[o,m]of i){const u=a.join(e,o);try{await l(u),t(u,m)}catch{}}for(const o of n)typeof o=="string"&&o&&t(a.dirname(o),"library-parent");if(process.platform==="win32")for(const o of await w())t(o,"drive");else t(a.parse(e).root,"root");return s}export async function listDirectoryChildren(n){const r=(await d(n,{withFileTypes:!0})).filter(t=>t.isDirectory()).map(t=>({name:t.name,path:a.join(n,t.name)}));return r.sort((t,e)=>t.name.localeCompare(e.name,void 0,{numeric:!0})),r}
1
+ import{readdir as p,stat as u}from"node:fs/promises";import f from"node:os";import s from"node:path";function d(n,r){return new Promise((t,o)=>{const a=setTimeout(()=>o(new Error("timeout")),r);n.then(i=>{clearTimeout(a),t(i)},i=>{clearTimeout(a),o(i)})})}let c=null;const w=5*6e4;async function h(){if(c&&Date.now()-c.at<w)return c.drives;const n="ABCDEFGHIJKLMNOPQRSTUVWXYZ".split(""),r=(await Promise.all(n.map(async t=>{const o=`${t}:\\`;try{return await d(u(o),4e3),o}catch{return null}}))).filter(t=>t!==null);return c={at:Date.now(),drives:r},r}export async function listBrowseRoots(n){const r=[],t=new Set,o=(e,m)=>{t.has(e)||(t.add(e),r.push({path:e,kind:m}))},a=f.homedir();o(a,"home");const i=[["Desktop","desktop"],["Downloads","downloads"],["Documents","documents"]];for(const[e,m]of i){const l=s.join(a,e);try{await u(l),o(l,m)}catch{}}for(const e of n)typeof e=="string"&&e&&o(s.dirname(e),"library-parent");if(process.platform==="win32")for(const e of await h())o(e,"drive");else o(s.parse(a).root,"root");return r}export async function listDirectoryChildren(n){const r=(await p(n,{withFileTypes:!0})).filter(t=>t.isDirectory()).map(t=>({name:t.name,path:s.join(n,t.name)}));return r.sort((t,o)=>t.name.localeCompare(o.name,void 0,{numeric:!0})),r}
@@ -1 +1 @@
1
- import{readdirSync as m,unlinkSync as a}from"node:fs";import{join as c}from"node:path";import{getDbPath as h}from"../db/paths.js";import{MirrorWriter as b,hookShardId as l,hooksRoot as g,mirrorPathOf as x,outboxPathOf as k}from"../hooks/mirror.js";import{promptboxPathOf as P}from"../hooks/promptbox.js";import{messagingSurfaceFor as S}from"../surfaces.js";import{startInboxWorker as j,handleIngestedRecords as y,unparkFailedInbox as $,INBOX_CLAIM_SUFFIX as p,INBOX_FAILED_SUFFIX as u}from"../hooks/inbox-worker.js";function v(o,e){return[c(o,"inbox",`${e}.jsonl`),c(o,"inbox",`${e}${p}`),c(o,"inbox",`${e}${u}`),x(o,e),k(o,e),P(o,e)]}export function purgeProjectPipeline(o,e){for(const n of v(o,l(e)))try{a(n)}catch{}}function w(o){return(o.endsWith(".tmp")?o.slice(0,-4):o).replace(new RegExp(`(${p}|${u})$`),"").replace(/\.(jsonl|json)$/,"")}const F=/^[0-9a-f]{16}$/;export function purgeOrphanPipelineFiles(o){const e=new Set(o.projects.list().map(t=>l(t.token)));let n=0;for(const t of["inbox","mirror","outbox","promptbox"]){let i;try{i=m(c(o.hooksDir,t))}catch{continue}for(const s of i){const r=w(s);if(!(!F.test(r)||e.has(r)))try{a(c(o.hooksDir,t,s)),n++}catch{}}}return n}export function wireHookFilePipeline(o){const e=g(),n=purgeOrphanPipelineFiles({projects:o.projects,hooksDir:e});n>0&&console.log(`[weave] hook pipeline: purged ${n} orphan file(s)`);const t=$(e);t>0&&console.log(`[weave] hook pipeline: revived ${t} parked inbox file(s)`);const i=new b({projects:o.projects,rules:o.rules,sessions:o.sessions});o.rules.onChange=()=>i.syncAll(),i.attachToBus(o.bus),i.syncAll();const s=j({dbPath:h(),hooksDir:e});return s.on("message",r=>{y({projects:o.projects,hooksDir:e,bus:o.bus,dispatcher:o.dispatcher,watchEngine:o.watchEngine,orchestrationEngine:o.orchestrationEngine,messagePipe:o.messagePipe,questionTracker:o.questionTracker,sideQuestions:o.sideQuestions,dashboardRate:o.dashboardRate,sessionProbe:o.sessionProbe,uploads:o.uploads,terminalTopologyKick:o.terminalTopologyKick,paneEnvSource:f=>S(f).paneEnvSource},r)}),s.on("error",r=>console.error("[weave] inbox worker failed:",r)),{mirror:i,pushSyntheticSessions:r=>s.postMessage({type:"synthetic-sessions",ids:r}),stop:()=>s.terminate().then(()=>{})}}
1
+ import{readdirSync as m,unlinkSync as c}from"node:fs";import{join as a}from"node:path";import{getDbPath as f}from"../db/paths.js";import{MirrorWriter as d,hookShardId as p,hooksRoot as b,mirrorPathOf as g,outboxPathOf as k}from"../hooks/mirror.js";import{promptboxPathOf as x}from"../hooks/promptbox.js";import{messagingSurfaceFor as P}from"../surfaces.js";import{startInboxWorker as j,handleIngestedRecords as y,unparkFailedInbox as $,INBOX_CLAIM_SUFFIX as l,INBOX_FAILED_SUFFIX as h}from"../hooks/inbox-worker.js";function S(e,s){return[a(e,"inbox",`${s}.jsonl`),a(e,"inbox",`${s}${l}`),a(e,"inbox",`${s}${h}`),g(e,s),k(e,s),x(e,s)]}export function purgeProjectPipeline(e,s){for(const r of S(e,p(s)))try{c(r)}catch{}}function w(e){return(e.endsWith(".tmp")?e.slice(0,-4):e).replace(new RegExp(`(${l}|${h})$`),"").replace(/\.(jsonl|json)$/,"")}const F=/^[0-9a-f]{16}$/;export function purgeOrphanPipelineFiles(e){const s=new Set(e.projects.list().map(n=>p(n.token)));let r=0;for(const n of["inbox","mirror","outbox","promptbox"]){let t;try{t=m(a(e.hooksDir,n))}catch{continue}for(const i of t){const o=w(i);if(!(!F.test(o)||s.has(o)))try{c(a(e.hooksDir,n,i)),r++}catch{}}}return r}export function wireHookFilePipeline(e){const s=b(),r=purgeOrphanPipelineFiles({projects:e.projects,hooksDir:s});r>0&&console.log(`[weave] hook pipeline: purged ${r} orphan file(s)`);const n=$(s);n>0&&console.log(`[weave] hook pipeline: revived ${n} parked inbox file(s)`);const t=new d({projects:e.projects,rules:e.rules,sessions:e.sessions});e.rules.onChange=()=>t.syncAll(),t.attachToBus(e.bus),t.syncAll();const i=j({dbPath:f(),hooksDir:s});return i.on("message",o=>{y({projects:e.projects,hooksDir:s,bus:e.bus,dispatcher:e.dispatcher,watchEngine:e.watchEngine,orchestrationEngine:e.orchestrationEngine,messagePipe:e.messagePipe,questionTracker:e.questionTracker,sideQuestions:e.sideQuestions,dashboardRate:e.dashboardRate,sessionProbe:e.sessionProbe,uploads:e.uploads,terminalTopologyKick:e.terminalTopologyKick,paneEnvSource:u=>P(u).paneEnvSource},o)}),i.on("error",o=>console.error("[weave] inbox worker failed:",o)),{mirror:t,pushSyntheticSessions:o=>i.postMessage({type:"synthetic-sessions",ids:o}),stop:()=>i.terminate().then(()=>{})}}
@@ -1 +1 @@
1
- import{z as g}from"zod";import{HARNESS_SESSION_CONTROL as x,isHarness as P}from"@weavecode/core";import{aliasOfModel as O,modelAliasTargets as M}from"@weavecode/harness";import{readJson as k,sendJson as n}from"./http.js";import{purgeSession as D}from"../hooks/session-purge.js";import{readDaemonSettingsSync as A,readHooksEnabled as H}from"./settings.js";import{handleOrchestrationRoutes as W}from"./routes/orchestration.js";import{handleHookAdminRoutes as U}from"./routes/hooks-admin.js";import{handleUploadRoutes as N}from"./routes/uploads.js";import{handleSessionControlRoutes as $}from"./routes/session-control.js";import{handlePathRefRoutes as B}from"./routes/path-refs.js";import{handleSessionInsightRoutes as K}from"./routes/session-insights.js";import{handleWatchRoutes as G}from"./routes/watches.js";import{openSessionTerminal as L,transcriptState as Q}from"./session-open.js";import{pidAliveOf as j}from"./claude-liveness.js";import{combinedLivenessOf as E}from"./liveness.js";import{captureSurfaces as _,messagingSurfaces as F,sessionTitleSurfaceFor as V}from"../surfaces.js";import{getDataDir as J}from"../db/paths.js";import{WEAVE_VERSION as z}from"../version.js";const X=g.object({title:g.string().min(1).max(200)}),Y=g.object({text:g.string().max(2e4),fromKind:g.enum(["dashboard","session"]).optional(),fromSessionId:g.string().min(1).nullable().optional(),attachments:g.array(g.string().regex(/^[a-f0-9]{64}$/)).max(8).optional(),images:g.array(g.string().regex(/^[a-f0-9]{64}$/)).max(8).optional(),forceTerminal:g.boolean().optional()});function Z(a,s){return a.queuedPrompt!==null||a.prompt!==null||s}function q(a){const{diag:s,capture:e,eventCount:i}=a,l=[];return!e||e.source==="none"||!e.present?l.push("no-hook-script"):e.weaveOwned?!e.reportsInbox&&s?.inbox.reason!=="no-mechanism"&&l.push("hook-script-stale"):l.push("hook-script-not-weave"),i===0&&l.push("no-events"),s&&(s.alive===!1&&l.push("not-running"),s.inbox.reason==="no-credentials"&&e?.reportsInbox===!0&&l.push("no-inbox-credentials"),s.inbox.reason==="auth-token-required"&&l.push("inbox-token-required"),s.relay.reason==="no-peer-name"&&l.push("no-peer-name"),s.terminal.reason==="no-backend"&&l.push("terminal-no-backend"),s.terminal.reason==="no-pane-env"&&l.push("terminal-no-pane-env"),s.pending>0&&l.push("queued"),s.stalled&&l.push("stalled")),l}export async function handleHooksRoutes(a,s,e,i,l){if(!(i.startsWith("/hooks/")||i==="/dashboard/refresh"||i==="/sessions"||i.startsWith("/sessions/")||i.startsWith("/messaging")||i.startsWith("/webhooks/orchestrate/")||i==="/uploads"||i.startsWith("/uploads/")||i.startsWith("/images/")))return!1;if(await U(a,s,e,i,l))return!0;if(i==="/dashboard/refresh"&&a.method==="POST")return e.dashboardRefresh?.(),n(s,200,{ok:!0}),!0;if(i==="/sessions"&&a.method==="GET"){if(!e.hookSessions)return n(s,503,{error:"Hooks subsystem unavailable"}),!0;const t=l.searchParams.get("projectId"),r=t!=null&&t!==""?Number(t):void 0,o=e.hookSessions.listWithCounts(r),d=E(),h=e.terminalRefresher?.lastSnapshot?.terminals??{},m={};for(const u of o){const p=u.harness??"";p in m||(m[p]=M(x[u.harness]?.modelNames??[]))}return n(s,200,{sessions:o.map(u=>{const p=e.sessionProbe?.currentModel(u.sessionId)??null,S=e.sessionProbe?.transcriptPresent(u.sessionId)??null,c=P(u.harness)?e.harnesses?.get(u.harness)?.resume:void 0;return{...u,pidAlive:j(u,d),canOpenTerminal:!!(c?.supported&&c.openArgs),terminal:h[u.sessionId]??null,interruptedAt:u.turnOpen===!0?e.sessionProbe?.interruptedAt(u.sessionId,u.lastSeenAt)??null:null,model:p,modelAlias:O(m[u.harness??""]??[],p),mode:e.sessionProbe?.currentMode(u.sessionId)??null,effort:e.sessionProbe?.currentEffort(u.sessionId)??null,contextTokens:e.sessionProbe?.currentContextTokens(u.sessionId)??null,transcriptPresent:Q(S,u.hasRun)}}),modelCatalog:m}),!0}const v=i.match(/^\/sessions\/([^/]+)$/);if(v&&a.method==="PATCH"){if(!e.hookSessions)return n(s,503,{error:"Hooks subsystem unavailable"}),!0;const t=decodeURIComponent(v[1]);if(!e.hookSessions.getBySessionId(t))return n(s,404,{error:"Session not found"}),!0;try{const r=X.parse(await k(a)),o=e.hookEvents?.listBySession(t,1),d=o?.[o.length-1]?.source,h=P(d)?V(d):null;if(h){try{await h.setSessionTitle(t,r.title)}catch(p){return n(s,502,{error:p instanceof Error?p.message:"Host rename failed"}),!0}const u=e.hookSessions.setTitle(t,r.title);return u?.projectId!=null&&e.hookMirror?.syncProject(u.projectId),n(s,200,{session:u}),!0}const m=e.hookSessions.setPendingTitle(t,r.title);m?.projectId!=null&&e.hookMirror?.syncProject(m.projectId),n(s,200,{session:m})}catch(r){n(s,400,{error:r instanceof Error?r.message:"Invalid body"})}return!0}if(v&&a.method==="DELETE"){if(!e.hookSessions||!e.hookEvents)return n(s,503,{error:"Hooks subsystem unavailable"}),!0;const t=decodeURIComponent(v[1]),r=e.hookSessions.getBySessionId(t);if(!r)return n(s,404,{error:"Session not found"}),!0;const o=D({sessions:e.hookSessions,events:e.hookEvents,dispatches:e.hookDispatches,deliverer:e.messageDeliverer,watches:e.sessionWatches,orchestrations:e.orchestrations,questions:e.questionTracker,sideQuestions:e.sideQuestions?.repo,probe:e.sessionProbe,uploads:e.uploads},t);return r.projectId!=null&&e.hookMirror?.syncProject(r.projectId),n(s,200,{ok:!0,sessionId:t,...o}),!0}const y=i.match(/^\/sessions\/([^/]+)\/open-terminal$/);if(y&&a.method==="POST"){const t=decodeURIComponent(y[1]);let r;try{const d=await k(a);typeof d?.target=="string"&&d.target&&(r=d.target)}catch{}const o=await L(e,t,r);return o.ok?(n(s,200,{ok:!0,sessionId:o.sessionId,command:o.command,cwd:o.cwd,...o.target?{target:o.target}:{}}),!0):(n(s,o.status,{error:o.error}),!0)}if(await N(a,s,e,i,l))return!0;const R=i.match(/^\/sessions\/([^/]+)\/messages$/);if(R){const t=decodeURIComponent(R[1]);if(a.method==="GET")return e.messageDeliverer?e.hookSessions?.getBySessionId(t)?(n(s,200,{messages:e.messageDeliverer.listVisible(t)}),!0):(n(s,404,{error:"Session not found"}),!0):(n(s,503,{error:"Messaging subsystem unavailable"}),!0);if(a.method==="POST"){if(!e.messageDeliverer||!e.hookSessions)return n(s,503,{error:"Messaging subsystem unavailable"}),!0;let r;try{r=Y.parse(await k(a))}catch(m){return n(s,400,{error:m instanceof Error?m.message:"Invalid body"}),!0}const o=[...r.attachments??[],...r.images??[]];if(!r.text.trim()&&o.length===0)return n(s,400,{error:"Message is empty"}),!0;let d=[];if(o.length>0){const m=e.uploads?.refsOf(o)??null;if(!m)return n(s,404,{error:"Attachment not found"}),!0;d=m}const h=await e.messageDeliverer.send({toSessionId:t,text:r.text,...d.length>0?{attachments:d}:{},...r.forceTerminal===!0?{forceTerminal:!0}:{},mode:"prompt",fromKind:r.fromKind??"dashboard",fromSessionId:r.fromSessionId??null,oneWay:!0});return h.ok?n(s,201,{ok:!0,messageId:h.messageId,status:h.status,message:h.message}):n(s,h.status,{error:h.error}),!0}}if(await K(a,s,e,i,l)||await B(a,s,e,i,l))return!0;const w=i.match(/^\/sessions\/([^/]+)\/messages\/([^/]+)\/resend$/);if(w&&a.method==="POST"){if(!e.messageDeliverer)return n(s,503,{error:"Messaging subsystem unavailable"}),!0;const t=await e.messageDeliverer.resend(decodeURIComponent(w[2]));return t.ok?n(s,200,{ok:!0,messageId:t.messageId,status:t.status,message:t.message}):n(s,t.status,{error:t.error}),!0}const I=i.match(/^\/sessions\/([^/]+)\/messages\/([^/]+)\/dismiss$/);if(I&&a.method==="POST"){if(!e.messageDeliverer)return n(s,503,{error:"Messaging subsystem unavailable"}),!0;const t=e.messageDeliverer.dismiss(decodeURIComponent(I[1]),decodeURIComponent(I[2]));return t.ok?n(s,200,{ok:!0}):n(s,t.status,{error:t.error}),!0}if(await $(a,s,e,i,l)||await G(a,s,e,i)||await W(a,s,e,i,l))return!0;if(i==="/messaging/capabilities"&&a.method==="GET"){const t=e.messageDeliverer?.hasTerminalChannel()??!1;return n(s,200,{capabilities:F().map(({harness:r,surface:o})=>({harness:r,discovery:o.discovery,prompt:Z(o,t),inject:o.inject!==null,headless:o.headless!==null,watch:o.idleSignals.length>0,attachKinds:o.attach?.kinds??[],pathRefs:o.pathRefs!==null,pathRefLines:o.pathRefs?.lines===!0,pathRefKinds:o.pathRefs?.kinds??[],sideQuestion:o.sideQuestion!==null,unsupportedReasons:o.unsupportedReasons??null}))}),!0}if(i==="/messaging/diagnostics"&&a.method==="GET"){if(!e.messageDeliverer||!e.hookSessions)return n(s,503,{error:"Message subsystem unavailable"}),!0;const t=l.searchParams.get("session"),r=l.searchParams.get("project"),o=_(),d=e.projects.list(),h=await Promise.all(d.map(async c=>({id:c.id,name:c.name,path:c.path,captures:await Promise.all(o.map(async({harness:f,surface:b})=>({harness:f,...await b.scriptHealth({projectPath:c.path})})))}))),m=(c,f)=>h.find(b=>b.id===c)?.captures.find(b=>b.harness===f)??null,u=E(),S=e.hookSessions.listWithCounts(t?void 0:r?Number(r):void 0).filter(c=>t?c.sessionId===t:j(c,u)!==!1).map(c=>{const f=e.messageDeliverer.diagnose(c.sessionId),b=m(c.projectId,c.harness??null),T={inbox:f.inbox,queue:f.queue,relay:f.relay,terminal:f.terminal};return{sessionId:c.sessionId,projectId:c.projectId,harness:c.harness??null,title:c.title,lastSeenAt:c.lastSeenAt,eventCount:c.eventCount??0,lastEventType:c.lastEventType??null,alive:f.alive,paneEnvReported:f.paneEnvReported,channels:T,queue:{pending:f.pending,stalled:f.stalled},reachable:Object.values(T).some(C=>C.status==="ready"),hints:q({diag:f,capture:b,eventCount:c.eventCount??0})}});return n(s,200,{daemon:{version:z,platform:process.platform,dataDir:J(),uptimeMs:Math.round(process.uptime()*1e3),terminalPreset:A().terminal.preset,terminalTextChannel:e.messageDeliverer.hasTerminalChannel(),hooksEnabled:H()},projects:h,sessions:S}),!0}return!1}
1
+ import{z as f}from"zod";import{HARNESS_SESSION_CONTROL as j,isHarness as w}from"@weavecode/core";import{aliasOfModel as C,modelAliasTargets as D}from"@weavecode/harness";import{readJson as y,sendJson as t}from"./http.js";import{purgeSession as O}from"../hooks/session-purge.js";import{readDaemonSettingsSync as A,readHooksEnabled as M}from"./settings.js";import{handleOrchestrationRoutes as W}from"./routes/orchestration.js";import{handleHookAdminRoutes as H}from"./routes/hooks-admin.js";import{handleUploadRoutes as q}from"./routes/uploads.js";import{handleSessionControlRoutes as U}from"./routes/session-control.js";import{handlePathRefRoutes as N}from"./routes/path-refs.js";import{handleVisualizationRoutes as $}from"./routes/visualizations.js";import{handleSessionInsightRoutes as B}from"./routes/session-insights.js";import{handleWatchRoutes as K}from"./routes/watches.js";import{openSessionTerminal as G,transcriptState as L}from"./session-open.js";import{pidAliveOf as E}from"./claude-liveness.js";import{combinedLivenessOf as x}from"./liveness.js";import{captureSurfaces as Q,messagingSurfaces as V,sessionTitleSurfaceFor as z}from"../surfaces.js";import{getDataDir as _}from"../db/paths.js";import{WEAVE_VERSION as J}from"../version.js";const F=f.object({title:f.string().min(1).max(200)}),X=f.object({text:f.string().max(2e4),fromKind:f.enum(["dashboard","session"]).optional(),fromSessionId:f.string().min(1).nullable().optional(),attachments:f.array(f.string().regex(/^[a-f0-9]{64}$/)).max(8).optional(),images:f.array(f.string().regex(/^[a-f0-9]{64}$/)).max(8).optional(),forceTerminal:f.boolean().optional()});function Y(l,s){return l.queuedPrompt!==null||l.prompt!==null||s}function Z(l){const{diag:s,capture:e,eventCount:a}=l,m=[];return!e||e.source==="none"||!e.present?m.push("no-hook-script"):e.weaveOwned?!e.reportsInbox&&s?.inbox.reason!=="no-mechanism"&&m.push("hook-script-stale"):m.push("hook-script-not-weave"),a===0&&m.push("no-events"),s&&(s.alive===!1&&m.push("not-running"),s.inbox.reason==="no-credentials"&&e?.reportsInbox===!0&&m.push("no-inbox-credentials"),s.inbox.reason==="auth-token-required"&&m.push("inbox-token-required"),s.relay.reason==="no-peer-name"&&m.push("no-peer-name"),s.terminal.reason==="no-backend"&&m.push("terminal-no-backend"),s.terminal.reason==="no-pane-env"&&m.push("terminal-no-pane-env"),s.terminal.reason==="pane-env-conflict"&&m.push("terminal-pane-env-conflict"),s.pending>0&&m.push("queued"),s.stalled&&m.push("stalled")),m}export async function handleHooksRoutes(l,s,e,a,m){if(!(a.startsWith("/hooks/")||a==="/dashboard/refresh"||a==="/sessions"||a.startsWith("/sessions/")||a.startsWith("/messaging")||a.startsWith("/webhooks/orchestrate/")||a==="/uploads"||a.startsWith("/uploads/")||a.startsWith("/images/")||a==="/visualizations/fragment"))return!1;if(await H(l,s,e,a,m))return!0;if(a==="/dashboard/refresh"&&l.method==="POST")return e.dashboardRefresh?.(),t(s,200,{ok:!0}),!0;if(a==="/sessions"&&l.method==="GET"){if(!e.hookSessions)return t(s,503,{error:"Hooks subsystem unavailable"}),!0;const o=m.searchParams.get("projectId"),i=o!=null&&o!==""?Number(o):void 0,n=m.searchParams.get("ids"),c=n?n.split(",").map(r=>r.trim()).filter(Boolean).slice(0,100):void 0,u=e.hookSessions,p=u.listWithCounts(i,c),g=x(),v=e.terminalRefresher?.lastSnapshot?.terminals??{},d={};for(const r of p){const h=r.harness??"";h in d||(d[h]=D(j[r.harness]?.modelNames??[]))}return t(s,200,{sessions:p.map(r=>{const h=e.sessionProbe?.currentModel(r.sessionId)??null,k=e.sessionProbe?.transcriptPresent(r.sessionId)??null,I=w(r.harness)?e.harnesses?.get(r.harness)?.resume:void 0;return{...r,pidAlive:E(r,g),canOpenTerminal:!!(I?.supported&&I.openArgs),terminal:v[r.sessionId]??null,interruptedAt:r.turnOpen===!0?e.sessionProbe?.interruptedAt(r.sessionId,u.lastMainEventAtOf(r.sessionId)??r.lastSeenAt)??null:null,model:h,modelAlias:C(d[r.harness??""]??[],h),mode:e.sessionProbe?.currentMode(r.sessionId)??null,effort:e.sessionProbe?.currentEffort(r.sessionId)??null,contextTokens:e.sessionProbe?.currentContextTokens(r.sessionId)??null,transcriptPresent:L(k,r.hasRun)}}),modelCatalog:d}),!0}const b=a.match(/^\/sessions\/([^/]+)$/);if(b&&l.method==="PATCH"){if(!e.hookSessions)return t(s,503,{error:"Hooks subsystem unavailable"}),!0;const o=decodeURIComponent(b[1]);if(!e.hookSessions.getBySessionId(o))return t(s,404,{error:"Session not found"}),!0;try{const i=F.parse(await y(l)),n=e.hookEvents?.listBySession(o,1),c=n?.[n.length-1]?.source,u=w(c)?z(c):null;if(u){try{await u.setSessionTitle(o,i.title)}catch(v){return t(s,502,{error:v instanceof Error?v.message:"Host rename failed"}),!0}const g=e.hookSessions.setTitle(o,i.title);return g?.projectId!=null&&e.hookMirror?.syncProject(g.projectId),t(s,200,{session:g}),!0}const p=e.hookSessions.setPendingTitle(o,i.title);p?.projectId!=null&&e.hookMirror?.syncProject(p.projectId),t(s,200,{session:p})}catch(i){t(s,400,{error:i instanceof Error?i.message:"Invalid body"})}return!0}if(b&&l.method==="DELETE"){if(!e.hookSessions||!e.hookEvents)return t(s,503,{error:"Hooks subsystem unavailable"}),!0;const o=decodeURIComponent(b[1]),i=e.hookSessions.getBySessionId(o);if(!i)return t(s,404,{error:"Session not found"}),!0;const n=O({sessions:e.hookSessions,events:e.hookEvents,dispatches:e.hookDispatches,deliverer:e.messageDeliverer,watches:e.sessionWatches,orchestrations:e.orchestrations,questions:e.questionTracker,sideQuestions:e.sideQuestions?.repo,probe:e.sessionProbe,uploads:e.uploads},o);return i.projectId!=null&&e.hookMirror?.syncProject(i.projectId),t(s,200,{ok:!0,sessionId:o,...n}),!0}const R=a.match(/^\/sessions\/([^/]+)\/open-terminal$/);if(R&&l.method==="POST"){const o=decodeURIComponent(R[1]);let i;try{const c=await y(l);typeof c?.target=="string"&&c.target&&(i=c.target)}catch{}const n=await G(e,o,i);return n.ok?(t(s,200,{ok:!0,sessionId:n.sessionId,command:n.command,cwd:n.cwd,...n.target?{target:n.target}:{}}),!0):(t(s,n.status,{error:n.error}),!0)}if(await q(l,s,e,a,m))return!0;const T=a.match(/^\/sessions\/([^/]+)\/messages$/);if(T){const o=decodeURIComponent(T[1]);if(l.method==="GET")return e.messageDeliverer?e.hookSessions?.getBySessionId(o)?(t(s,200,{messages:e.messageDeliverer.listVisible(o)}),!0):(t(s,404,{error:"Session not found"}),!0):(t(s,503,{error:"Messaging subsystem unavailable"}),!0);if(l.method==="POST"){if(!e.messageDeliverer||!e.hookSessions)return t(s,503,{error:"Messaging subsystem unavailable"}),!0;let i;try{i=X.parse(await y(l))}catch(p){return t(s,400,{error:p instanceof Error?p.message:"Invalid body"}),!0}const n=[...i.attachments??[],...i.images??[]];if(!i.text.trim()&&n.length===0)return t(s,400,{error:"Message is empty"}),!0;let c=[];if(n.length>0){const p=e.uploads?.refsOf(n)??null;if(!p)return t(s,404,{error:"Attachment not found"}),!0;c=p}const u=await e.messageDeliverer.send({toSessionId:o,text:i.text,...c.length>0?{attachments:c}:{},...i.forceTerminal===!0?{forceTerminal:!0}:{},mode:"prompt",fromKind:i.fromKind??"dashboard",fromSessionId:i.fromSessionId??null,oneWay:!0});return u.ok?t(s,201,{ok:!0,messageId:u.messageId,status:u.status,message:u.message}):t(s,u.status,{error:u.error}),!0}}if(await B(l,s,e,a,m)||await N(l,s,e,a,m)||await $(l,s,e,a,m))return!0;const P=a.match(/^\/sessions\/([^/]+)\/messages\/([^/]+)\/resend$/);if(P&&l.method==="POST"){if(!e.messageDeliverer)return t(s,503,{error:"Messaging subsystem unavailable"}),!0;const o=await e.messageDeliverer.resend(decodeURIComponent(P[2]));return o.ok?t(s,200,{ok:!0,messageId:o.messageId,status:o.status,message:o.message}):t(s,o.status,{error:o.error}),!0}const S=a.match(/^\/sessions\/([^/]+)\/messages\/([^/]+)\/dismiss$/);if(S&&l.method==="POST"){if(!e.messageDeliverer)return t(s,503,{error:"Messaging subsystem unavailable"}),!0;const o=e.messageDeliverer.dismiss(decodeURIComponent(S[1]),decodeURIComponent(S[2]));return o.ok?t(s,200,{ok:!0}):t(s,o.status,{error:o.error}),!0}if(await U(l,s,e,a,m)||await K(l,s,e,a)||await W(l,s,e,a,m))return!0;if(a==="/messaging/capabilities"&&l.method==="GET"){const o=e.messageDeliverer?.hasTerminalChannel()??!1;return t(s,200,{capabilities:V().map(({harness:i,surface:n})=>({harness:i,discovery:n.discovery,prompt:Y(n,o),inject:n.inject!==null,headless:n.headless!==null,watch:n.idleSignals.length>0,attachKinds:n.attach?.kinds??[],pathRefs:n.pathRefs!==null,pathRefLines:n.pathRefs?.lines===!0,pathRefKinds:n.pathRefs?.kinds??[],sideQuestion:n.sideQuestion!==null,unsupportedReasons:n.unsupportedReasons??null}))}),!0}if(a==="/messaging/diagnostics"&&l.method==="GET"){if(!e.messageDeliverer||!e.hookSessions)return t(s,503,{error:"Message subsystem unavailable"}),!0;const o=m.searchParams.get("session"),i=m.searchParams.get("project"),n=Q(),c=e.projects.list(),u=await Promise.all(c.map(async d=>({id:d.id,name:d.name,path:d.path,captures:await Promise.all(n.map(async({harness:r,surface:h})=>({harness:r,...await h.scriptHealth({projectPath:d.path})})))}))),p=(d,r)=>u.find(h=>h.id===d)?.captures.find(h=>h.harness===r)??null,g=x(),v=e.hookSessions.listWithCounts(o?void 0:i?Number(i):void 0).filter(d=>o?d.sessionId===o:E(d,g)!==!1).map(d=>{const r=e.messageDeliverer.diagnose(d.sessionId),h=p(d.projectId,d.harness??null),k={inbox:r.inbox,queue:r.queue,relay:r.relay,terminal:r.terminal};return{sessionId:d.sessionId,projectId:d.projectId,harness:d.harness??null,title:d.title,lastSeenAt:d.lastSeenAt,eventCount:d.eventCount??0,lastEventType:d.lastEventType??null,alive:r.alive,paneEnvReported:r.paneEnvReported,channels:k,queue:{pending:r.pending,stalled:r.stalled},reachable:Object.values(k).some(I=>I.status==="ready"),hints:Z({diag:r,capture:h,eventCount:d.eventCount??0})}});return t(s,200,{daemon:{version:J,platform:process.platform,dataDir:_(),uptimeMs:Math.round(process.uptime()*1e3),terminalPreset:A().terminal.preset,terminalTextChannel:e.messageDeliverer.hasTerminalChannel(),hooksEnabled:M()},projects:u,sessions:v}),!0}return!1}
@@ -1 +1 @@
1
- import{noteRequestBody as u}from"./api-log.js";export function readBody(n){return new Promise((t,e)=>{const r=[];n.on("data",o=>r.push(o)),n.on("end",()=>{const o=Buffer.concat(r).toString("utf8");u(n,o),t(o)}),n.on("error",e)})}export async function readJson(n){return JSON.parse(await readBody(n))}export function readRawBody(n,t){return new Promise((e,r)=>{const o=[];let a=0;n.on("data",s=>{if(a+=s.length,a>t){n.destroy(),r(new Error("body too large"));return}o.push(s)}),n.on("end",()=>e(Buffer.concat(o))),n.on("error",r)})}export function sendJson(n,t,e){n.statusCode=t,n.setHeader("content-type","application/json"),n.end(JSON.stringify(e))}
1
+ import{noteRequestBody as d}from"./api-log.js";export function readBody(o){return new Promise((t,r)=>{const n=[];o.on("data",e=>n.push(e)),o.on("end",()=>{const e=Buffer.concat(n).toString("utf8");d(o,e),t(e)}),o.on("error",r)})}export async function readJson(o){return JSON.parse(await readBody(o))}export function readRawBody(o,t){return new Promise((r,n)=>{const e=[];let a=0;o.on("data",s=>{if(a+=s.length,a>t){o.destroy(),n(new Error("body too large"));return}e.push(s)}),o.on("end",()=>r(Buffer.concat(e))),o.on("error",n)})}export function sendJson(o,t,r){o.statusCode=t,o.setHeader("content-type","application/json"),o.end(JSON.stringify(r))}