@weavecode/weave 0.1.8 → 0.1.9

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 (351) hide show
  1. package/node_modules/@modelcontextprotocol/sdk/node_modules/@hono/node-server/dist/index.cjs +31 -6
  2. package/node_modules/@modelcontextprotocol/sdk/node_modules/@hono/node-server/dist/index.mjs +31 -6
  3. package/node_modules/@modelcontextprotocol/sdk/node_modules/@hono/node-server/package.json +1 -1
  4. package/node_modules/@modelcontextprotocol/sdk/node_modules/express-rate-limit/dist/index.cjs +1 -1
  5. package/node_modules/@modelcontextprotocol/sdk/node_modules/express-rate-limit/dist/index.mjs +1 -1
  6. package/node_modules/@modelcontextprotocol/sdk/node_modules/express-rate-limit/node_modules/ip-address/README.md +39 -39
  7. package/node_modules/@modelcontextprotocol/sdk/node_modules/express-rate-limit/node_modules/ip-address/dist/ipv6.js +1 -1
  8. package/node_modules/@modelcontextprotocol/sdk/node_modules/express-rate-limit/node_modules/ip-address/package.json +1 -1
  9. package/node_modules/@modelcontextprotocol/sdk/node_modules/express-rate-limit/package.json +1 -1
  10. package/node_modules/@weavecode/cli/dist/cli.js +4 -4
  11. package/node_modules/@weavecode/cli/dist/commands/chpass.js +1 -1
  12. package/node_modules/@weavecode/cli/dist/commands/daemon-auth.js +1 -1
  13. package/node_modules/@weavecode/cli/dist/commands/daemon.js +2 -2
  14. package/node_modules/@weavecode/cli/dist/commands/dashboard.js +2 -2
  15. package/node_modules/@weavecode/cli/dist/commands/doctor.js +1 -1
  16. package/node_modules/@weavecode/cli/dist/commands/init.js +1 -1
  17. package/node_modules/@weavecode/cli/dist/commands/msg.js +2 -2
  18. package/node_modules/@weavecode/cli/dist/commands/scan.js +1 -1
  19. package/node_modules/@weavecode/cli/dist/commands/status.js +2 -2
  20. package/node_modules/@weavecode/cli/dist/commands/uninstall.js +1 -1
  21. package/node_modules/@weavecode/cli/dist/i18n/dict/en.js +2 -2
  22. package/node_modules/@weavecode/cli/dist/i18n/dict/zh.d.ts +7 -0
  23. package/node_modules/@weavecode/cli/dist/i18n/dict/zh.js +3 -3
  24. package/node_modules/@weavecode/cli/dist/i18n/index.js +1 -1
  25. package/node_modules/@weavecode/cli/dist/i18n/t.js +1 -1
  26. package/node_modules/@weavecode/cli/dist/init/claudemd-gen.js +5 -5
  27. package/node_modules/@weavecode/cli/dist/init/executor.js +3 -3
  28. package/node_modules/@weavecode/cli/dist/init/git-commit.js +2 -2
  29. package/node_modules/@weavecode/cli/dist/init/git-exclude.d.ts +20 -0
  30. package/node_modules/@weavecode/cli/dist/init/git-exclude.js +7 -0
  31. package/node_modules/@weavecode/cli/dist/init/harnesses/claude.js +7 -7
  32. package/node_modules/@weavecode/cli/dist/init/harnesses/codex.js +1 -1
  33. package/node_modules/@weavecode/cli/dist/init/instruction-files.d.ts +14 -0
  34. package/node_modules/@weavecode/cli/dist/init/instruction-files.js +1 -0
  35. package/node_modules/@weavecode/cli/dist/init/instruction-link.js +1 -1
  36. package/node_modules/@weavecode/cli/dist/init/plugin-templates.js +1 -1
  37. package/node_modules/@weavecode/cli/dist/init/prompt.js +4 -4
  38. package/node_modules/@weavecode/cli/dist/init/provision.js +1 -1
  39. package/node_modules/@weavecode/cli/dist/init/uninstall.js +6 -6
  40. package/node_modules/@weavecode/cli/dist/init/wiring.js +1 -1
  41. package/node_modules/@weavecode/cli/dist/parser.js +1 -1
  42. package/node_modules/@weavecode/cli/dist/statusline/ansi.js +1 -1
  43. package/node_modules/@weavecode/cli/dist/statusline/mock-input.js +1 -1
  44. package/node_modules/@weavecode/cli/dist/statusline/preview.js +2 -2
  45. package/node_modules/@weavecode/cli/package.json +5 -5
  46. package/node_modules/@weavecode/core/dist/harness-checks.js +1 -1
  47. package/node_modules/@weavecode/core/dist/harness.d.ts +37 -0
  48. package/node_modules/@weavecode/core/dist/harness.js +1 -1
  49. package/node_modules/@weavecode/core/dist/index.d.ts +1 -1
  50. package/node_modules/@weavecode/core/dist/index.js +1 -1
  51. package/node_modules/@weavecode/core/dist/platform.js +1 -1
  52. package/node_modules/@weavecode/core/dist/types.d.ts +4 -4
  53. package/node_modules/@weavecode/core/dist/types.js +1 -1
  54. package/node_modules/@weavecode/core/dist/utils/fs.js +1 -1
  55. package/node_modules/@weavecode/core/package.json +1 -1
  56. package/node_modules/@weavecode/harness/dist/claude/assets.js +3 -3
  57. package/node_modules/@weavecode/harness/dist/claude/capture.js +9 -9
  58. package/node_modules/@weavecode/harness/dist/claude/commands.js +3 -3
  59. package/node_modules/@weavecode/harness/dist/claude/config.js +2 -2
  60. package/node_modules/@weavecode/harness/dist/claude/detect.js +1 -1
  61. package/node_modules/@weavecode/harness/dist/claude/edits.js +1 -1
  62. package/node_modules/@weavecode/harness/dist/claude/event-source.js +1 -1
  63. package/node_modules/@weavecode/harness/dist/claude/images.js +2 -2
  64. package/node_modules/@weavecode/harness/dist/claude/index.js +1 -1
  65. package/node_modules/@weavecode/harness/dist/claude/liveness.js +1 -1
  66. package/node_modules/@weavecode/harness/dist/claude/mcp-gen.js +1 -1
  67. package/node_modules/@weavecode/harness/dist/claude/messaging.js +2 -2
  68. package/node_modules/@weavecode/harness/dist/claude/model-aliases.js +1 -1
  69. package/node_modules/@weavecode/harness/dist/claude/narration.js +1 -1
  70. package/node_modules/@weavecode/harness/dist/claude/peers.js +1 -1
  71. package/node_modules/@weavecode/harness/dist/claude/plan.js +1 -1
  72. package/node_modules/@weavecode/harness/dist/claude/plugins.js +4 -4
  73. package/node_modules/@weavecode/harness/dist/claude/prompt-inbox.js +1 -1
  74. package/node_modules/@weavecode/harness/dist/claude/prompt.js +3 -3
  75. package/node_modules/@weavecode/harness/dist/claude/questions.js +2 -2
  76. package/node_modules/@weavecode/harness/dist/claude/resume.js +1 -1
  77. package/node_modules/@weavecode/harness/dist/claude/rewind.js +1 -1
  78. package/node_modules/@weavecode/harness/dist/claude/settings-gen.js +1 -1
  79. package/node_modules/@weavecode/harness/dist/claude/side-question.js +2 -2
  80. package/node_modules/@weavecode/harness/dist/claude/statusline/generator.d.ts +6 -0
  81. package/node_modules/@weavecode/harness/dist/claude/statusline/generator.js +21 -14
  82. package/node_modules/@weavecode/harness/dist/claude/statusline/git-cache.js +1 -1
  83. package/node_modules/@weavecode/harness/dist/claude/statusline/surface.js +2 -2
  84. package/node_modules/@weavecode/harness/dist/claude/transcript-cursor.js +2 -2
  85. package/node_modules/@weavecode/harness/dist/claude/transcript.js +7 -7
  86. package/node_modules/@weavecode/harness/dist/codex/assets.js +1 -1
  87. package/node_modules/@weavecode/harness/dist/codex/capture.js +2 -2
  88. package/node_modules/@weavecode/harness/dist/codex/commands.js +4 -4
  89. package/node_modules/@weavecode/harness/dist/codex/config.js +2 -2
  90. package/node_modules/@weavecode/harness/dist/codex/detect.js +1 -1
  91. package/node_modules/@weavecode/harness/dist/codex/event-source.js +2 -2
  92. package/node_modules/@weavecode/harness/dist/codex/images.js +1 -1
  93. package/node_modules/@weavecode/harness/dist/codex/index.js +1 -1
  94. package/node_modules/@weavecode/harness/dist/codex/liveness.js +1 -1
  95. package/node_modules/@weavecode/harness/dist/codex/mcp.js +1 -1
  96. package/node_modules/@weavecode/harness/dist/codex/messaging.js +2 -2
  97. package/node_modules/@weavecode/harness/dist/codex/narration.js +1 -1
  98. package/node_modules/@weavecode/harness/dist/codex/plugin-state.js +1 -1
  99. package/node_modules/@weavecode/harness/dist/codex/plugins.js +3 -3
  100. package/node_modules/@weavecode/harness/dist/codex/provision.js +1 -1
  101. package/node_modules/@weavecode/harness/dist/codex/questions.js +2 -2
  102. package/node_modules/@weavecode/harness/dist/codex/rollout.js +5 -5
  103. package/node_modules/@weavecode/harness/dist/codex/side-question.js +4 -4
  104. package/node_modules/@weavecode/harness/dist/codex/titles.js +4 -4
  105. package/node_modules/@weavecode/harness/dist/codex/toml.js +13 -13
  106. package/node_modules/@weavecode/harness/dist/codex/transcript.js +2 -2
  107. package/node_modules/@weavecode/harness/dist/driver.js +1 -1
  108. package/node_modules/@weavecode/harness/dist/init/generated.js +2 -2
  109. package/node_modules/@weavecode/harness/dist/init/pipeline.js +1 -1
  110. package/node_modules/@weavecode/harness/dist/registry-wiring.js +1 -1
  111. package/node_modules/@weavecode/harness/dist/shared/install-link.js +1 -1
  112. package/node_modules/@weavecode/harness/dist/shared/json-cap.js +1 -1
  113. package/node_modules/@weavecode/harness/dist/zcode/assets.js +1 -1
  114. package/node_modules/@weavecode/harness/dist/zcode/capture.js +3 -3
  115. package/node_modules/@weavecode/harness/dist/zcode/mcp.js +2 -2
  116. package/node_modules/@weavecode/harness/package.json +2 -2
  117. package/node_modules/@weavecode/server/dist/config/dotted.js +1 -1
  118. package/node_modules/@weavecode/server/dist/config/profiles.js +2 -2
  119. package/node_modules/@weavecode/server/dist/daemon/ai-config.js +2 -2
  120. package/node_modules/@weavecode/server/dist/daemon/ai-context.js +6 -6
  121. package/node_modules/@weavecode/server/dist/daemon/ai-routes.js +4 -4
  122. package/node_modules/@weavecode/server/dist/daemon/api-log.js +3 -3
  123. package/node_modules/@weavecode/server/dist/daemon/auth-routes.js +1 -1
  124. package/node_modules/@weavecode/server/dist/daemon/auto-start.js +3 -3
  125. package/node_modules/@weavecode/server/dist/daemon/capture-routes.js +1 -1
  126. package/node_modules/@weavecode/server/dist/daemon/config-routes.js +1 -1
  127. package/node_modules/@weavecode/server/dist/daemon/cron.js +1 -1
  128. package/node_modules/@weavecode/server/dist/daemon/dashboard-auth.js +2 -2
  129. package/node_modules/@weavecode/server/dist/daemon/dashboard-pusher.js +1 -1
  130. package/node_modules/@weavecode/server/dist/daemon/decision-config.js +2 -2
  131. package/node_modules/@weavecode/server/dist/daemon/dev-entry.js +1 -1
  132. package/node_modules/@weavecode/server/dist/daemon/entry.js +2 -2
  133. package/node_modules/@weavecode/server/dist/daemon/fs-browser.js +1 -1
  134. package/node_modules/@weavecode/server/dist/daemon/hook-pipeline.js +1 -1
  135. package/node_modules/@weavecode/server/dist/daemon/hooks-routes.js +1 -1
  136. package/node_modules/@weavecode/server/dist/daemon/http.js +1 -1
  137. package/node_modules/@weavecode/server/dist/daemon/liveness.js +1 -1
  138. package/node_modules/@weavecode/server/dist/daemon/mcp-orchestration.js +1 -1
  139. package/node_modules/@weavecode/server/dist/daemon/narration-watcher.js +2 -2
  140. package/node_modules/@weavecode/server/dist/daemon/opener/backend-ghostty.js +1 -1
  141. package/node_modules/@weavecode/server/dist/daemon/opener/backend-iterm.js +1 -1
  142. package/node_modules/@weavecode/server/dist/daemon/opener/backend-konsole.js +2 -2
  143. package/node_modules/@weavecode/server/dist/daemon/opener/backend-terminal-app.js +1 -1
  144. package/node_modules/@weavecode/server/dist/daemon/opener/backend-wezterm.js +1 -1
  145. package/node_modules/@weavecode/server/dist/daemon/opener/backend-wt.js +1 -1
  146. package/node_modules/@weavecode/server/dist/daemon/opener/backend.js +1 -1
  147. package/node_modules/@weavecode/server/dist/daemon/opener/launch.js +1 -1
  148. package/node_modules/@weavecode/server/dist/daemon/opener/pty-terminals.js +1 -1
  149. package/node_modules/@weavecode/server/dist/daemon/opener/shared.js +1 -1
  150. package/node_modules/@weavecode/server/dist/daemon/opener/wezterm-mux.js +1 -1
  151. package/node_modules/@weavecode/server/dist/daemon/opener/wt.js +3 -3
  152. package/node_modules/@weavecode/server/dist/daemon/opener.js +1 -1
  153. package/node_modules/@weavecode/server/dist/daemon/pet-seed.d.ts +4 -6
  154. package/node_modules/@weavecode/server/dist/daemon/pet-seed.js +2 -1
  155. package/node_modules/@weavecode/server/dist/daemon/pet-window.js +1 -1
  156. package/node_modules/@weavecode/server/dist/daemon/port.js +1 -1
  157. package/node_modules/@weavecode/server/dist/daemon/project-files.js +2 -2
  158. package/node_modules/@weavecode/server/dist/daemon/project-harnesses.js +2 -2
  159. package/node_modules/@weavecode/server/dist/daemon/project-updates-refresher.js +1 -1
  160. package/node_modules/@weavecode/server/dist/daemon/prompt-images.js +1 -1
  161. package/node_modules/@weavecode/server/dist/daemon/routes/hooks-admin.js +1 -1
  162. package/node_modules/@weavecode/server/dist/daemon/routes/installations.d.ts +29 -0
  163. package/node_modules/@weavecode/server/dist/daemon/routes/installations.js +1 -0
  164. package/node_modules/@weavecode/server/dist/daemon/routes/market.js +1 -1
  165. package/node_modules/@weavecode/server/dist/daemon/routes/orchestration.js +1 -1
  166. package/node_modules/@weavecode/server/dist/daemon/routes/path-refs.js +1 -1
  167. package/node_modules/@weavecode/server/dist/daemon/routes/pets.js +1 -1
  168. package/node_modules/@weavecode/server/dist/daemon/routes/project-files.js +1 -1
  169. package/node_modules/@weavecode/server/dist/daemon/routes/projects.js +1 -1
  170. package/node_modules/@weavecode/server/dist/daemon/routes/search.js +1 -1
  171. package/node_modules/@weavecode/server/dist/daemon/routes/session-control.js +1 -1
  172. package/node_modules/@weavecode/server/dist/daemon/routes/session-insights.js +1 -1
  173. package/node_modules/@weavecode/server/dist/daemon/routes/settings-statusline.js +1 -1
  174. package/node_modules/@weavecode/server/dist/daemon/routes/uploads.js +1 -1
  175. package/node_modules/@weavecode/server/dist/daemon/routes/visualizations.js +2 -2
  176. package/node_modules/@weavecode/server/dist/daemon/routes/watches.js +1 -1
  177. package/node_modules/@weavecode/server/dist/daemon/server.d.ts +2 -0
  178. package/node_modules/@weavecode/server/dist/daemon/server.js +8 -8
  179. package/node_modules/@weavecode/server/dist/daemon/session-open.js +1 -1
  180. package/node_modules/@weavecode/server/dist/daemon/session-probe.js +1 -1
  181. package/node_modules/@weavecode/server/dist/daemon/settings.js +2 -2
  182. package/node_modules/@weavecode/server/dist/daemon/snapshot-refresher.js +1 -1
  183. package/node_modules/@weavecode/server/dist/daemon/sse-hub.js +1 -1
  184. package/node_modules/@weavecode/server/dist/daemon/start.js +1 -1
  185. package/node_modules/@weavecode/server/dist/daemon/state.js +2 -2
  186. package/node_modules/@weavecode/server/dist/daemon/static.js +1 -1
  187. package/node_modules/@weavecode/server/dist/daemon/terminal-topology-refresher.js +1 -1
  188. package/node_modules/@weavecode/server/dist/daemon/tls.js +1 -1
  189. package/node_modules/@weavecode/server/dist/daemon/toolkit-routes.js +1 -1
  190. package/node_modules/@weavecode/server/dist/daemon/upload-sessions.js +1 -1
  191. package/node_modules/@weavecode/server/dist/db/db.js +2 -2
  192. package/node_modules/@weavecode/server/dist/db/layout.d.ts +5 -0
  193. package/node_modules/@weavecode/server/dist/db/layout.js +2 -1
  194. package/node_modules/@weavecode/server/dist/db/paths.d.ts +5 -0
  195. package/node_modules/@weavecode/server/dist/db/paths.js +1 -1
  196. package/node_modules/@weavecode/server/dist/hooks/answer-keys.js +1 -1
  197. package/node_modules/@weavecode/server/dist/hooks/dashboard-rate.js +1 -1
  198. package/node_modules/@weavecode/server/dist/hooks/decision-judge.js +1 -1
  199. package/node_modules/@weavecode/server/dist/hooks/delivery/ack-gate.js +1 -1
  200. package/node_modules/@weavecode/server/dist/hooks/delivery/channels.js +1 -1
  201. package/node_modules/@weavecode/server/dist/hooks/delivery/keys.js +1 -1
  202. package/node_modules/@weavecode/server/dist/hooks/delivery/queue.js +1 -1
  203. package/node_modules/@weavecode/server/dist/hooks/delivery/relay.js +1 -1
  204. package/node_modules/@weavecode/server/dist/hooks/delivery/send.js +2 -2
  205. package/node_modules/@weavecode/server/dist/hooks/delivery/views.js +1 -1
  206. package/node_modules/@weavecode/server/dist/hooks/dispatcher.js +6 -6
  207. package/node_modules/@weavecode/server/dist/hooks/edge-extract.js +1 -1
  208. package/node_modules/@weavecode/server/dist/hooks/handlers/webhook.js +1 -1
  209. package/node_modules/@weavecode/server/dist/hooks/headless-runner.js +2 -2
  210. package/node_modules/@weavecode/server/dist/hooks/inbox-socket.js +2 -2
  211. package/node_modules/@weavecode/server/dist/hooks/inbox-worker.js +3 -3
  212. package/node_modules/@weavecode/server/dist/hooks/match.js +1 -1
  213. package/node_modules/@weavecode/server/dist/hooks/message-deliverer.js +5 -5
  214. package/node_modules/@weavecode/server/dist/hooks/mirror.js +4 -4
  215. package/node_modules/@weavecode/server/dist/hooks/orchestration-engine.js +7 -7
  216. package/node_modules/@weavecode/server/dist/hooks/orchestration-graph.js +1 -1
  217. package/node_modules/@weavecode/server/dist/hooks/plugin-installer.js +3 -3
  218. package/node_modules/@weavecode/server/dist/hooks/plugin-loader.js +1 -1
  219. package/node_modules/@weavecode/server/dist/hooks/plugin-project-state.js +1 -1
  220. package/node_modules/@weavecode/server/dist/hooks/prompt-flusher.js +1 -1
  221. package/node_modules/@weavecode/server/dist/hooks/promptbox.js +8 -8
  222. package/node_modules/@weavecode/server/dist/hooks/push-notify.js +2 -2
  223. package/node_modules/@weavecode/server/dist/hooks/question-tracker.js +1 -1
  224. package/node_modules/@weavecode/server/dist/hooks/registry.js +1 -1
  225. package/node_modules/@weavecode/server/dist/hooks/resume-runner.js +1 -1
  226. package/node_modules/@weavecode/server/dist/hooks/session-purge.js +1 -1
  227. package/node_modules/@weavecode/server/dist/hooks/side-questions.js +1 -1
  228. package/node_modules/@weavecode/server/dist/hooks/synthetic-sessions.js +1 -1
  229. package/node_modules/@weavecode/server/dist/hooks/toolkit-scan.js +1 -1
  230. package/node_modules/@weavecode/server/dist/hooks/toolkit.js +5 -5
  231. package/node_modules/@weavecode/server/dist/hooks/watch-engine.js +1 -1
  232. package/node_modules/@weavecode/server/dist/install/apply-update.js +1 -1
  233. package/node_modules/@weavecode/server/dist/install/capabilities.js +1 -1
  234. package/node_modules/@weavecode/server/dist/install/codex-toml.js +1 -1
  235. package/node_modules/@weavecode/server/dist/install/file-assets.js +1 -1
  236. package/node_modules/@weavecode/server/dist/install/fingerprint.js +1 -1
  237. package/node_modules/@weavecode/server/dist/install/global-config.js +1 -1
  238. package/node_modules/@weavecode/server/dist/install/global-file-assets.js +1 -1
  239. package/node_modules/@weavecode/server/dist/install/init-files.d.ts +0 -9
  240. package/node_modules/@weavecode/server/dist/install/init-files.js +2 -2
  241. package/node_modules/@weavecode/server/dist/install/install-ledger.js +1 -1
  242. package/node_modules/@weavecode/server/dist/install/installer.js +1 -1
  243. package/node_modules/@weavecode/server/dist/install/library-index.js +1 -1
  244. package/node_modules/@weavecode/server/dist/install/mcp-rows.js +1 -1
  245. package/node_modules/@weavecode/server/dist/install/plugin-install.js +1 -1
  246. package/node_modules/@weavecode/server/dist/install/plugin-rows.js +1 -1
  247. package/node_modules/@weavecode/server/dist/install/plugin-templates.js +1 -1
  248. package/node_modules/@weavecode/server/dist/install/project-config.js +1 -1
  249. package/node_modules/@weavecode/server/dist/install/reader.js +1 -1
  250. package/node_modules/@weavecode/server/dist/install/scan-cache.js +1 -1
  251. package/node_modules/@weavecode/server/dist/install/scanner.js +1 -1
  252. package/node_modules/@weavecode/server/dist/install/settings-mcp.js +2 -2
  253. package/node_modules/@weavecode/server/dist/install/updates.js +1 -1
  254. package/node_modules/@weavecode/server/dist/market/builtin.js +1 -1
  255. package/node_modules/@weavecode/server/dist/market/identity.js +1 -1
  256. package/node_modules/@weavecode/server/dist/market/import.js +2 -2
  257. package/node_modules/@weavecode/server/dist/market/refresh.js +1 -1
  258. package/node_modules/@weavecode/server/dist/market/resolve.js +1 -1
  259. package/node_modules/@weavecode/server/dist/market/updates.js +1 -1
  260. package/node_modules/@weavecode/server/dist/registry.js +2 -2
  261. package/node_modules/@weavecode/server/dist/repositories/hook-dispatches.js +4 -4
  262. package/node_modules/@weavecode/server/dist/repositories/hook-events.js +6 -6
  263. package/node_modules/@weavecode/server/dist/repositories/hook-rules.js +4 -4
  264. package/node_modules/@weavecode/server/dist/repositories/libraries.js +1 -1
  265. package/node_modules/@weavecode/server/dist/repositories/orchestrations.js +7 -7
  266. package/node_modules/@weavecode/server/dist/repositories/plugin-states.js +1 -1
  267. package/node_modules/@weavecode/server/dist/repositories/projects.js +1 -1
  268. package/node_modules/@weavecode/server/dist/repositories/push-subscriptions.js +2 -2
  269. package/node_modules/@weavecode/server/dist/repositories/session-watches.js +4 -4
  270. package/node_modules/@weavecode/server/dist/repositories/sessions.js +2 -2
  271. package/node_modules/@weavecode/server/dist/repositories/uploads.js +11 -11
  272. package/node_modules/@weavecode/server/dist/statusline/cache-sweeper.js +1 -1
  273. package/node_modules/@weavecode/server/dist/statusline/generator.js +1 -1
  274. package/node_modules/@weavecode/server/dist/statusline/manager.js +3 -3
  275. package/node_modules/@weavecode/server/dist/surfaces.js +1 -1
  276. package/node_modules/@weavecode/server/dist/watch/cache.js +1 -1
  277. package/node_modules/@weavecode/server/dist/watch/classifier.js +1 -1
  278. package/node_modules/@weavecode/server/dist/watch/plugin-mods.js +1 -1
  279. package/node_modules/@weavecode/server/dist/watch/sync-scheduler.js +1 -1
  280. package/node_modules/@weavecode/server/dist/watch/watch-service.js +1 -1
  281. package/node_modules/@weavecode/server/package.json +4 -4
  282. package/node_modules/@weavecode/server/web/dist/assets/{abnfDiagram-WEYOIA3C-t5OQjhuS.js → abnfDiagram-WEYOIA3C-S1lL1V_n.js} +1 -1
  283. package/node_modules/@weavecode/server/web/dist/assets/{arc-De-uH_Q9.js → arc-CoTNHyHV.js} +1 -1
  284. package/node_modules/@weavecode/server/web/dist/assets/{architectureDiagram-ZHVYKT53-ImPclD43.js → architectureDiagram-ZHVYKT53-C6ttfnzW.js} +1 -1
  285. package/node_modules/@weavecode/server/web/dist/assets/{blockDiagram-RJAE7QA3-B5xEQs6X.js → blockDiagram-RJAE7QA3-CYr3Cpu9.js} +1 -1
  286. package/node_modules/@weavecode/server/web/dist/assets/{c4Diagram-XDPPPE54-DP8MjIgJ.js → c4Diagram-XDPPPE54-BFS7PhLD.js} +1 -1
  287. package/node_modules/@weavecode/server/web/dist/assets/channel-DxQHp3Yc.js +1 -0
  288. package/node_modules/@weavecode/server/web/dist/assets/{chunk-2E7WHVMD-C3UFIDyj.js → chunk-2E7WHVMD-DJ7X_Shu.js} +1 -1
  289. package/node_modules/@weavecode/server/web/dist/assets/{chunk-2Q5K7J3B-Bgw-3YfG.js → chunk-2Q5K7J3B-B8nr2rdz.js} +1 -1
  290. package/node_modules/@weavecode/server/web/dist/assets/{chunk-4EMNKR2T-Dy_Wq9qn.js → chunk-4EMNKR2T-DmnZmUMU.js} +1 -1
  291. package/node_modules/@weavecode/server/web/dist/assets/{chunk-55XCU76K-D32C0DXX.js → chunk-55XCU76K-Xz9a8dmp.js} +1 -1
  292. package/node_modules/@weavecode/server/web/dist/assets/{chunk-5VM5RSS4-Dpmi-9Gi.js → chunk-5VM5RSS4-Dg9mg7pf.js} +1 -1
  293. package/node_modules/@weavecode/server/web/dist/assets/{chunk-JWPE2WC7-CEYXaZDX.js → chunk-JWPE2WC7-CmjTZO8o.js} +1 -1
  294. package/node_modules/@weavecode/server/web/dist/assets/{chunk-VQ5W62QI-A616Pgzo.js → chunk-VQ5W62QI-D3YDdJ3E.js} +1 -1
  295. package/node_modules/@weavecode/server/web/dist/assets/{chunk-XXDRQBXY-CnxFMLWV.js → chunk-XXDRQBXY-s1OG9sqW.js} +1 -1
  296. package/node_modules/@weavecode/server/web/dist/assets/{chunk-ZCHMQSOR-BhjCTig8.js → chunk-ZCHMQSOR-C3hINQU3.js} +2 -2
  297. package/node_modules/@weavecode/server/web/dist/assets/{classDiagram-v2-4MYWR3UA-rzlq5tPv.js → classDiagram-v2-4MYWR3UA-BTsbYrVl.js} +1 -1
  298. package/node_modules/@weavecode/server/web/dist/assets/{cose-bilkent-JH36ORCC-CxWQXzj8.js → cose-bilkent-JH36ORCC-C0W8Y-jI.js} +1 -1
  299. package/node_modules/@weavecode/server/web/dist/assets/{cynefin-EF2NZ3EQ-AFHjx2wU.js → cynefin-EF2NZ3EQ-stAu4Rh-.js} +1 -1
  300. package/node_modules/@weavecode/server/web/dist/assets/{cynefinDiagram-WF24UDRP-Bp_Oaf9U.js → cynefinDiagram-WF24UDRP-CqYibiiv.js} +1 -1
  301. package/node_modules/@weavecode/server/web/dist/assets/{dagre-NK4GIZVX-7oUPIU35.js → dagre-NK4GIZVX-qqcoJAqB.js} +1 -1
  302. package/node_modules/@weavecode/server/web/dist/assets/{diagram-CBK3MWTC-D_rS_rSY.js → diagram-CBK3MWTC-D0YTopb7.js} +1 -1
  303. package/node_modules/@weavecode/server/web/dist/assets/{diagram-I5XIIV2D-Duc_cKMb.js → diagram-I5XIIV2D-Csvw6aYr.js} +1 -1
  304. package/node_modules/@weavecode/server/web/dist/assets/{diagram-ODIL2UCW-DA0XFVXm.js → diagram-ODIL2UCW-Dl0tYLkF.js} +1 -1
  305. package/node_modules/@weavecode/server/web/dist/assets/{diagram-PFBEJUXE-D1U0Xhtt.js → diagram-PFBEJUXE-BCPSWZPe.js} +1 -1
  306. package/node_modules/@weavecode/server/web/dist/assets/{diagram-RJA3I4VV-CbDFY871.js → diagram-RJA3I4VV-ETg-BrAJ.js} +1 -1
  307. package/node_modules/@weavecode/server/web/dist/assets/{diagram-TYUNFSNR-jPg9AxQv.js → diagram-TYUNFSNR-_M6ZxBG7.js} +1 -1
  308. package/node_modules/@weavecode/server/web/dist/assets/{ebnfDiagram-V4P3TTPT-ZHfGTB0N.js → ebnfDiagram-V4P3TTPT-C-e_W7qx.js} +1 -1
  309. package/node_modules/@weavecode/server/web/dist/assets/{elk-QONTBCTQ-C-ESJrUi.js → elk-QONTBCTQ-B5TBharB.js} +1 -1
  310. package/node_modules/@weavecode/server/web/dist/assets/{erDiagram-KYQIGQAA-DGK7TeHj.js → erDiagram-KYQIGQAA-D08rj2pv.js} +1 -1
  311. package/node_modules/@weavecode/server/web/dist/assets/{flowDiagram-IUGLLWBU-CVV4rL8v.js → flowDiagram-IUGLLWBU-BALTxsKh.js} +1 -1
  312. package/node_modules/@weavecode/server/web/dist/assets/{ganttDiagram-R7GPNTJY-CuAwNvbm.js → ganttDiagram-R7GPNTJY-Cts193jT.js} +1 -1
  313. package/node_modules/@weavecode/server/web/dist/assets/{gitGraphDiagram-PDYL7XHY-D_15Wtf-.js → gitGraphDiagram-PDYL7XHY-L9qYUX0v.js} +1 -1
  314. package/node_modules/@weavecode/server/web/dist/assets/{infoDiagram-MVDRKAX5-ClqhbrCa.js → infoDiagram-MVDRKAX5-Bv47rgU0.js} +1 -1
  315. package/node_modules/@weavecode/server/web/dist/assets/{ishikawaDiagram-HPEHV2GE-CUJ891JX.js → ishikawaDiagram-HPEHV2GE-Da8_s6cs.js} +1 -1
  316. package/node_modules/@weavecode/server/web/dist/assets/{journeyDiagram-BOSHW7O7-B4skiMu-.js → journeyDiagram-BOSHW7O7-Bj3CjZOf.js} +1 -1
  317. package/node_modules/@weavecode/server/web/dist/assets/{kanban-definition-FNSA4HC5-UNGJR_y_.js → kanban-definition-FNSA4HC5-D1hicmMu.js} +1 -1
  318. package/node_modules/@weavecode/server/web/dist/assets/{linear-BEB-UwbR.js → linear-CWQg2iA1.js} +1 -1
  319. package/node_modules/@weavecode/server/web/dist/assets/main-XLn3EZFh.css +11 -0
  320. package/node_modules/@weavecode/server/web/dist/assets/main-bsb0lQoL.js +1096 -0
  321. package/node_modules/@weavecode/server/web/dist/assets/{mermaid.core-knGXJfjz.js → mermaid.core-C-wP0Zg2.js} +4 -4
  322. package/node_modules/@weavecode/server/web/dist/assets/{mindmap-definition-6OY57UG3-CEldbr3a.js → mindmap-definition-6OY57UG3-Dk0VKqre.js} +1 -1
  323. package/node_modules/@weavecode/server/web/dist/assets/{pegDiagram-ECIUJNBX-cNCkGLx3.js → pegDiagram-ECIUJNBX-Bp1K_F9z.js} +1 -1
  324. package/node_modules/@weavecode/server/web/dist/assets/pet-J6izA90s.js +1 -0
  325. package/node_modules/@weavecode/server/web/dist/assets/{pieDiagram-GNMPY74T-CfMEFiQD.js → pieDiagram-GNMPY74T-BZ4rGy3t.js} +1 -1
  326. package/node_modules/@weavecode/server/web/dist/assets/{quadrantDiagram-D57K4MC3-knmi2rwP.js → quadrantDiagram-D57K4MC3-B4N5KRsR.js} +1 -1
  327. package/node_modules/@weavecode/server/web/dist/assets/{railroadDiagram-Y72NRBL7-BJ7AzhEo.js → railroadDiagram-Y72NRBL7-C8nx8oHf.js} +1 -1
  328. package/node_modules/@weavecode/server/web/dist/assets/{requirementDiagram-EQYSW5RA-Dte2LGQM.js → requirementDiagram-EQYSW5RA-VSH57d0d.js} +1 -1
  329. package/node_modules/@weavecode/server/web/dist/assets/{sankeyDiagram-SY24JHO5-3noLaWgd.js → sankeyDiagram-SY24JHO5-jUb1hcya.js} +1 -1
  330. package/node_modules/@weavecode/server/web/dist/assets/{sequenceDiagram-BLEHNHQU-CclOWTTc.js → sequenceDiagram-BLEHNHQU-E2BioCNi.js} +1 -1
  331. package/node_modules/@weavecode/server/web/dist/assets/{sizeCapture-INFHLROL-B82sbLhA.js → sizeCapture-INFHLROL-BdKrbRmI.js} +1 -1
  332. package/node_modules/@weavecode/server/web/dist/assets/{stateDiagram-v2-A6IESKWZ-BXfVDwSN.js → stateDiagram-v2-A6IESKWZ-tFz7uNM7.js} +1 -1
  333. package/node_modules/@weavecode/server/web/dist/assets/{swimlanes-B3ENRKFQ-D4lKZaeV.js → swimlanes-B3ENRKFQ-B9BAPDWw.js} +1 -1
  334. package/node_modules/@weavecode/server/web/dist/assets/swimlanesDiagram-AYQRV4AK-DQ2NPLl9.js +8 -0
  335. package/node_modules/@weavecode/server/web/dist/assets/{timeline-definition-JXYKGLGB-D6H6zP5b.js → timeline-definition-JXYKGLGB-CofNnFTK.js} +1 -1
  336. package/node_modules/@weavecode/server/web/dist/assets/{usecaseDiagram-WPOLBNNX-D2J2bKo_.js → usecaseDiagram-WPOLBNNX-DOvjhJjJ.js} +1 -1
  337. package/node_modules/@weavecode/server/web/dist/assets/{vennDiagram-Q3Y3IDCW-pdRbIkpB.js → vennDiagram-Q3Y3IDCW-BcFHWnhS.js} +1 -1
  338. package/node_modules/@weavecode/server/web/dist/assets/{wardleyDiagram-IVAIDKWA-Cyd2QPMf.js → wardleyDiagram-IVAIDKWA-Bz2aqRAs.js} +1 -1
  339. package/node_modules/@weavecode/server/web/dist/assets/{xychartDiagram-4URNHDU4-Bd4BkwVM.js → xychartDiagram-4URNHDU4-DpNF6Vsq.js} +1 -1
  340. package/node_modules/@weavecode/server/web/dist/index.html +2 -2
  341. package/node_modules/@weavecode/server/web/dist/pet.html +80 -10
  342. package/node_modules/@weavecode/templates/dist/resources/pets/weave-spider/pet.json +1 -1
  343. package/node_modules/@weavecode/templates/dist/resources/pets/weave-spider/spritesheet.png +0 -0
  344. package/node_modules/@weavecode/templates/package.json +2 -2
  345. package/package.json +6 -6
  346. package/scripts/preinstall.mjs +60 -22
  347. package/node_modules/@weavecode/server/web/dist/assets/channel-C0RGiobt.js +0 -1
  348. package/node_modules/@weavecode/server/web/dist/assets/main-B_0jS_Gz.js +0 -1096
  349. package/node_modules/@weavecode/server/web/dist/assets/main-Czzlavi4.css +0 -11
  350. package/node_modules/@weavecode/server/web/dist/assets/pet-DJCpIDM5.js +0 -1
  351. package/node_modules/@weavecode/server/web/dist/assets/swimlanesDiagram-AYQRV4AK-DbdFh_d6.js +0 -8
@@ -1,2 +1,2 @@
1
- import{mkdir as m,readFile as p,writeFile as d}from"node:fs/promises";import a from"node:path";function i(n){return typeof n=="object"&&n!==null&&!Array.isArray(n)}async function s(n){let e;try{e=await p(n,"utf-8")}catch{return{}}let r;try{r=JSON.parse(e)}catch(t){throw new Error(`${n} is not valid JSON \u2014 refusing to write: ${t instanceof Error?t.message:String(t)}`)}if(!i(r))throw new Error(`${n} is not a JSON object \u2014 refusing to write`);return r}async function f(n,e){await m(a.dirname(n),{recursive:!0}),await d(n,`${JSON.stringify(e,null,2)}
2
- `,"utf-8")}function u(n){const e=n.mcp;return i(e)&&i(e.servers)?e.servers:{}}export async function readZcodeMcp(n){const e=u(await s(n)),r={};for(const[t,o]of Object.entries(e)){if(!i(o)||typeof o.command!="string")continue;const c={command:o.command};Array.isArray(o.args)&&(c.args=o.args),i(o.env)&&(c.env=o.env),r[t]=c}return r}export async function upsertZcodeMcp(n,e,r){const t=await s(n),o=i(t.mcp)?t.mcp:{},c={type:"stdio",command:r.command};r.args&&(c.args=r.args),r.env&&(c.env=r.env),o.servers={...u(t),[e]:c},t.mcp=o,await f(n,t)}export async function removeZcodeMcp(n,e){const r=await s(n),t=u(r);if(!(e in t))return!1;delete t[e];const o=i(r.mcp)?r.mcp:{};return o.servers=t,r.mcp=o,await f(n,r),!0}export function zcodeMcpFile(n,e,r){return n==="project"?a.join(e,".zcode","config.json"):a.join(r,".zcode","cli","config.json")}
1
+ import{mkdir as m,readFile as p,writeFile as d}from"node:fs/promises";import a from"node:path";function i(r){return typeof r=="object"&&r!==null&&!Array.isArray(r)}async function s(r){let e;try{e=await p(r,"utf-8")}catch{return{}}let t;try{t=JSON.parse(e)}catch(n){throw new Error(`${r} is not valid JSON \u2014 refusing to write: ${n instanceof Error?n.message:String(n)}`)}if(!i(t))throw new Error(`${r} is not a JSON object \u2014 refusing to write`);return t}async function f(r,e){await m(a.dirname(r),{recursive:!0}),await d(r,`${JSON.stringify(e,null,2)}
2
+ `,"utf-8")}function u(r){const e=r.mcp;return i(e)&&i(e.servers)?e.servers:{}}export async function readZcodeMcp(r){const e=u(await s(r)),t={};for(const[n,o]of Object.entries(e)){if(!i(o)||typeof o.command!="string")continue;const c={command:o.command};Array.isArray(o.args)&&(c.args=o.args),i(o.env)&&(c.env=o.env),t[n]=c}return t}export async function upsertZcodeMcp(r,e,t){const n=await s(r),o=i(n.mcp)?n.mcp:{},c={type:"stdio",command:t.command};t.args&&(c.args=t.args),t.env&&(c.env=t.env),o.servers={...u(n),[e]:c},n.mcp=o,await f(r,n)}export async function removeZcodeMcp(r,e){const t=await s(r),n=u(t);if(!(e in n))return!1;delete n[e];const o=i(t.mcp)?t.mcp:{};return o.servers=n,t.mcp=o,await f(r,t),!0}export function zcodeMcpFile(r,e,t){return r==="project"?a.join(e,".zcode","config.json"):a.join(t,".zcode","cli","config.json")}
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@weavecode/harness",
3
- "version": "0.1.8",
3
+ "version": "0.1.9",
4
4
  "description": "Pluggable harness drivers — registry, init pipeline template method, and harness integration modules",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",
@@ -20,7 +20,7 @@
20
20
  "node": ">=22.5.0"
21
21
  },
22
22
  "dependencies": {
23
- "@weavecode/core": "^0.1.8",
23
+ "@weavecode/core": "^0.1.9",
24
24
  "smol-toml": "^1.3.0"
25
25
  }
26
26
  }
@@ -1 +1 @@
1
- function i(n){return n==="__proto__"||n==="constructor"||n==="prototype"}function f(n){const e=n.split(".");if(e.some(t=>!t||i(t)))throw new Error(`\u975E\u6CD5\u914D\u7F6E\u952E\uFF1A${n}`);return e}function c(n){return typeof n=="object"&&n!==null&&!Array.isArray(n)}const u=Symbol("absent");function s(n,e){let t=n;for(const o of e){if(!c(t))return u;t=t[o]}return t===void 0?u:t}function l(n,e){let t=n;for(const o of e.slice(0,-1)){const r=t[o];if(!c(r))return;t=r}delete t[e[e.length-1]]}function p(n,e,t){let o=n;for(const r of e.slice(0,-1))c(o[r])||(o[r]={}),o=o[r];o[e[e.length-1]]=t}export function getDotted(n,e){const t=s(n,f(e));return t===u?void 0:t}export function applyUpdates(n,e){const t=structuredClone(n);for(const o of e){const r=f(o.path);o.remove?l(t,r):p(t,r,o.value)}return t}
1
+ function s(n){return n==="__proto__"||n==="constructor"||n==="prototype"}function f(n){const o=n.split(".");if(o.some(t=>!t||s(t)))throw new Error(`\u975E\u6CD5\u914D\u7F6E\u952E\uFF1A${n}`);return o}function u(n){return typeof n=="object"&&n!==null&&!Array.isArray(n)}const c=Symbol("absent");function i(n,o){let t=n;for(const e of o){if(!u(t))return c;t=t[e]}return t===void 0?c:t}function l(n,o){let t=n;for(const e of o.slice(0,-1)){const r=t[e];if(!u(r))return;t=r}delete t[o[o.length-1]]}function p(n,o,t){let e=n;for(const r of o.slice(0,-1))u(e[r])||(e[r]={}),e=e[r];e[o[o.length-1]]=t}export function getDotted(n,o){const t=i(n,f(o));return t===c?void 0:t}export function applyUpdates(n,o){const t=structuredClone(n);for(const e of o){const r=f(e.path);e.remove?l(t,r):p(t,r,e.value)}return t}
@@ -1,2 +1,2 @@
1
- import s from"node:fs/promises";import p from"node:path";import{randomUUID as h}from"node:crypto";export function profileKeyOf(t,n){return(t==="project"||t==="projectLocal")&&n!==null?`${t}@p${n}`:t}const I=20;function l(t,n){return p.join(t,n)}function S(t,n){return p.join(l(t,n),"profiles.json")}function w(t,n,e,r){return p.join(l(t,n),`${e}-${r}.json`)}function m(t,n){return p.join(l(t,n),"backups")}function $(t,n,e,r){return p.join(m(t,n),`${e}-${r}.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(p.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 f(t,n,e,r){const a=await j(t,n),c=v(a,e);return r(c),a[e]=c,await x(S(t,n),a),c}function d(){return new Date().toISOString()}export async function writeSnapshot(t,n,e,r,a){await x(w(t,n,e,r),a)}export async function readSnapshot(t,n,e,r){return y(w(t,n,e,r))}export async function createProfile(t,n,e,r,a){const c={id:h().slice(0,8),name:r,createdAt:d(),updatedAt:d()};return await writeSnapshot(t,n,e,c.id,a),await f(t,n,e,i=>{i.profiles.push(c)}),c}export async function saveProfile(t,n,e,r,a){await writeSnapshot(t,n,e,r,a),await f(t,n,e,c=>{const i=c.profiles.find(o=>o.id===r);i&&(i.updatedAt=d())})}export async function renameProfile(t,n,e,r,a){await f(t,n,e,c=>{const i=c.profiles.find(o=>o.id===r);i&&(i.name=a,i.updatedAt=d())})}export async function removeProfile(t,n,e,r){await f(t,n,e,a=>{a.profiles=a.profiles.filter(c=>c.id!==r),a.activeId===r&&(a.activeId=null)}),await s.rm(w(t,n,e,r),{force:!0})}export async function setActive(t,n,e,r){await f(t,n,e,a=>{a.activeId=r})}export const LASTSEEN_ID="_lastseen";export async function baselineSnapshot(t,n,e,r){if(r.activeId){const a=await readSnapshot(t,n,e,r.activeId);if(a)return a}return readSnapshot(t,n,e,LASTSEEN_ID)}export async function syncBaseline(t,n,e,r,a){r.activeId&&await saveProfile(t,n,e,r.activeId,a),await writeSnapshot(t,n,e,LASTSEEN_ID,a)}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,r){const a=A(new Date),c=new Set((await s.readdir(m(t,n)).catch(()=>[])).filter(u=>u.startsWith(`${e}-${a}`)));let i=a;for(let u=2;c.has(`${e}-${i}.json`);u++)i=`${a}-${u}`;await x($(t,n,e,i),r);const o=(await listBackups(t,n,e)).slice(I);for(const u of o)await s.rm($(t,n,e,u),{force:!0})}export async function listBackups(t,n,e){const r=`${e}-`,a=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(r)&&i.endsWith(".json")).map(i=>i.slice(r.length,-5)).sort((i,o)=>a(i)-a(o)).reverse()}export async function readBackup(t,n,e,r){return/^[A-Za-z0-9-]+$/.test(r)?y($(t,n,e,r)):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,r){return u.join(d(t,n),`${e}-${r}.json`)}function $(t,n){return u.join(d(t,n),"backups")}function y(t,n,e,r){return u.join($(t,n),`${e}-${r}.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,r){const i=await j(t,n),a=v(i,e);return r(a),i[e]=a,await x(h(t,n),i),a}function p(){return new Date().toISOString()}export async function writeSnapshot(t,n,e,r,i){await x(w(t,n,e,r),i)}export async function readSnapshot(t,n,e,r){return m(w(t,n,e,r))}export async function createProfile(t,n,e,r,i){const a={id:S().slice(0,8),name:r,createdAt:p(),updatedAt:p()};return await writeSnapshot(t,n,e,a.id,i),await l(t,n,e,o=>{o.profiles.push(a)}),a}export async function saveProfile(t,n,e,r,i){await writeSnapshot(t,n,e,r,i),await l(t,n,e,a=>{const o=a.profiles.find(f=>f.id===r);o&&(o.updatedAt=p())})}export async function renameProfile(t,n,e,r,i){await l(t,n,e,a=>{const o=a.profiles.find(f=>f.id===r);o&&(o.name=i,o.updatedAt=p())})}export async function removeProfile(t,n,e,r){await l(t,n,e,i=>{i.profiles=i.profiles.filter(a=>a.id!==r),i.activeId===r&&(i.activeId=null)}),await c.rm(w(t,n,e,r),{force:!0})}export async function setActive(t,n,e,r){await l(t,n,e,i=>{i.activeId=r})}export const LASTSEEN_ID="_lastseen";export async function baselineSnapshot(t,n,e,r){if(r.activeId){const i=await readSnapshot(t,n,e,r.activeId);if(i)return i}return readSnapshot(t,n,e,LASTSEEN_ID)}export async function syncBaseline(t,n,e,r,i){r.activeId&&await saveProfile(t,n,e,r.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,r){const i=A(new Date),a=new Set((await c.readdir($(t,n)).catch(()=>[])).filter(s=>s.startsWith(`${e}-${i}`)));let o=i;for(let s=2;a.has(`${e}-${o}.json`);s++)o=`${i}-${s}`;await x(y(t,n,e,o),r);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 r=`${e}-`,i=a=>{const o=/^(\d{4}-\d{2}-\d{2}-\d{6})(?:-(\d+))?$/.exec(a);return o?+`${o[1].replace(/-/g,"")}${o[2]??"1"}`:0};return(await c.readdir($(t,n)).catch(()=>[])).filter(a=>a.startsWith(r)&&a.endsWith(".json")).map(a=>a.slice(r.length,-5)).sort((a,o)=>i(a)-i(o)).reverse()}export async function readBackup(t,n,e,r){return/^[A-Za-z0-9-]+$/.test(r)?m(y(t,n,e,r)):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 n,existsSync as a,mkdirSync as c,readFileSync as o,renameSync as y,rmSync as s,writeFileSync as u}from"node:fs";import l from"node:path";import{getAiKeyPath as e}from"../db/paths.js";export function readAiKey(t=e()){if(!a(t))return null;try{const r=JSON.parse(o(t,"utf8"));return typeof r.apiKey=="string"&&r.apiKey!==""?r.apiKey:null}catch{return null}}export function writeAiKey(t,r=e()){if(t===null||t===""){s(r,{force:!0});return}c(l.dirname(r),{recursive:!0});const i=`${r}.tmp`;u(i,`${JSON.stringify({apiKey:t},null,2)}
2
+ `,{encoding:"utf8",mode:384}),y(i,r);try{n(r,384)}catch{}}export function hasAiKey(t=e()){return readAiKey(t)!==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 n from"node:path";import{builtinMarketDir as f}from"../market/builtin.js";const l=6e4,p=40,d=6;export function findDocsDir(e){let F=n.resolve(e);for(let E=0;E<d;E++){const o=n.join(F,"docs");if(C(n.join(o,"FEATURES.md")))return o;const D=n.dirname(F);if(D===F)break;F=D}return null}export function collectSkillFiles(e,F=p){const E=[],o=(D,r)=>{if(E.length>=F||r>6)return;let s;try{s=i(D,{withFileTypes:!0})}catch{return}for(const B of s){if(E.length>=F)return;const u=n.join(D,B.name);B.isDirectory()?o(u,r+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=n.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:n.relative(o,u).split(n.sep).join("/"),text:t})}const D=["\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
+ `),r=[];let s=D.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(s+t.length>l){const A=l-s;A>500&&(r.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}s+=t.length,r.push(t),B.push(u.label)}return{prompt:D+r.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,q=40,C=2e4;export function normalizeMessages(r){if(!Array.isArray(r)||r.length===0||r.length>q)return null;const e=[];for(const t of r){const n=t;if(n?.role!=="user"&&n?.role!=="assistant")return null;const o=n.content;if(typeof o!="string"||o===""||o.length>C)return null;e.push({role:n.role,content:o})}return e}export function aiConfigured(r,e,t){return r!==""&&e!==""&&t}export async function handleAiRoutes(r,e,t,n){if(n!=="/ai"&&!n.startsWith("/ai/"))return!1;const o=(await P()).ai??M,a=I(t.aiKeyPath);if(n==="/ai/status"&&r.method==="GET")return u(e,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(e,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(t.aiKeyPath);if(d===""||l===null)return u(e,409,{error:"AI assistant is not configured"}),!0;const m=await G(d,l);return m.ok?(u(e,200,{models:m.models}),!0):(u(e,502,{error:m.error}),!0)}if(n==="/ai/chat"&&r.method==="POST"){const i=T(t.aiKeyPath);if(!aiConfigured(o.baseUrl,o.model,a)||i===null)return u(e,409,{error:"AI assistant is not configured"}),!0;let d;try{d=await O(r)}catch{return u(e,400,{error:"Invalid JSON body"}),!0}const l=normalizeMessages(d.messages);if(!l)return u(e,400,{error:"Invalid messages"}),!0;const m=j({dataRoot:t.libraries?.dataRoot??J()});return await L({req:r,res:e,baseUrl:o.baseUrl,model:o.model,apiKey:i,messages:l,system:m.prompt}),!0}return u(e,404,{error:"Not found"}),!0}function $(r){const e=r?.choices?.[0],t=e?.delta?.content??e?.message?.content;return typeof t=="string"&&t!==""?t:null}export const STREAM_MEMO_TTL_MS=1440*60*1e3;const w=new Map;export function streamMemoKey(r,e){return`${r}#${e}`}export function streamSupported(r,e=Date.now()){const t=w.get(r);return!t||e-t.checkedAt>STREAM_MEMO_TTL_MS?!0:t.streaming}export function rememberStreamSupport(r,e,t=Date.now()){const n=w.get(r);n!==void 0&&n.streaming!==e&&console.log(`[weave] ai gateway ${e?"supports":"rejects"} streaming: ${r}`),w.set(r,{streaming:e,checkedAt:t})}export function resetStreamMemory(){w.clear()}async function G(r,e){try{const t=await fetch(`${r.replace(/\/+$/,"")}/models`,{headers:{authorization:`Bearer ${e}`},signal:AbortSignal.timeout(z)});if(!t.ok){const a=await t.text().catch(()=>"");return{ok:!1,error:`upstream ${t.status}${a?`: ${a.slice(0,200)}`:""}`}}const n=await t.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(t){return{ok:!1,error:t instanceof Error?t.message:String(t)}}}async function U(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 n=await e.text().catch(()=>"");return{ok:!1,error:`upstream ${e.status}${n?`: ${n.slice(0,300)}`:""}`}}const t=$(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 L(r){const{req:e,res:t,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(),_);e.on("close",()=>g.abort()),t.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{t.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{t.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
+ `),t.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 v,readdir as k,readFile as L,rm as M}from"node:fs/promises";import g from"node:path";import{getApiLogsDir as O}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(o=>m(o,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[o,i]of Object.entries(r))e[o]=E.has(o.toLowerCase())?"[redacted]":m(i,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=i=>String(i).padStart(2,"0"),o=`${t.getFullYear()}-${e(t.getMonth()+1)}-${e(t.getDate())}T${e(t.getHours())}`;return g.join(r,`api-${o}.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??O()}begin(t,e){const o=Date.now(),i=[];let f=0,a=0,h="",d=0,l=!1;A.set(t,n=>{h=n,d=Buffer.byteLength(n,"utf8")});const c=n=>{const s=Buffer.isBuffer(n)?n:Buffer.from(typeof n=="string"?n:String(n??""),"utf8");if(a+=s.length,f<y){const u=s.subarray(0,y-f);i.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=((...n)=>{const s=n[1];if(s&&typeof s=="object"&&!Array.isArray(s)){const u=s,$=u["content-type"]??u["Content-Type"];typeof $=="string"&&(b=$)}return x(...n)}),e.write=((n,...s)=>(c(n),p(n,...s))),e.end=((n,...s)=>(typeof n!="function"&&n!=null&&c(n),F(n,...s)));const S=()=>{if(l)return;l=!0;const n=(String(e.getHeader("content-type")??"")||b).includes("event-stream"),s={ts:new Date(o).toISOString(),method:t.method??"GET",path:maskPath(t.url??"/"),status:e.statusCode,durationMs:Date.now()-o,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)),n?s.stream=!0:a&&(s.res=N(Buffer.concat(i).toString("utf8"),a)),e.writableEnded||(s.aborted=!0),this.write(logFileFor(this.dir,new Date(o)),`${JSON.stringify(s)}
2
+ `)};e.on("finish",S),e.on("close",S)}write(t,e){this.chain=this.chain.then(async()=>{try{await v(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 M(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(),o=Math.min(Math.max(t.limit??H,1),T),i=t.from?Date.parse(t.from):NaN,f=t.to?Date.parse(t.to):NaN,a=[];for(const h of e){if(a.length>=o)break;const d=await L(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(i)&&p<i)&&!(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>=o))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 r}from"./http.js";const l=300,u=6,f=e=>new Promise(t=>setTimeout(t,e));export async function handleAuthRoutes(e,t,d,a){if(a!=="/auth"&&!a.startsWith("/auth/"))return!1;const o=d.auth;if(!o)return r(t,503,{error:"Auth subsystem unavailable"}),!0;if(a==="/auth/status"&&e.method==="GET")return r(t,200,{passwordSet:o.isPasswordSet(),authenticated:o.isAuthenticated(e.headers)}),!0;if(a==="/auth/login"&&e.method==="POST"){let s;try{s=await i(e)}catch{return r(t,400,{error:"Invalid JSON body"}),!0}const n=typeof s.password=="string"?s.password:"";return!n||!o.verifyPassword(n)?(await f(l),r(t,401,{error:"Invalid password"}),!0):(t.setHeader("set-cookie",c(o.issueSession())),r(t,200,{ok:!0}),!0)}if(a==="/auth/logout"&&e.method==="POST")return t.setHeader("set-cookie",h()),r(t,200,{ok:!0}),!0;if(a==="/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 n=typeof s.next=="string"?s.next:"";return n.length<u?(r(t,400,{error:`Password must be at least ${u} characters`}),!0):(o.setPassword(n),r(t,200,{ok:!0}),!0)}return r(t,404,{error:"Not found"}),!0}
@@ -1,4 +1,4 @@
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.
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 r 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(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 g(t){return{platform:t.platform??process.platform,dataDir:t.dataDir??d(),home:t.home??l(),run:t.run??((e,n)=>({status:p(e,n,{stdio:"ignore"}).status}))}}function h(t){return t.map(e=>`"${e}"`).join(" ")}function y(t){const e=s(t.dataDir);a(r.dirname(e),{recursive:!0});const n=h(relaunchArgs());i(e,`' Generated by weave \u2014 daemon auto-start. Do not edit.
2
2
  CreateObject("WScript.Shell").Run "${n.replace(/"/g,'""')}", 0, False
3
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"?>
4
4
  <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
@@ -13,5 +13,5 @@ CreateObject("WScript.Shell").Run "${n.replace(/"/g,'""')}", 0, False
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(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 S(t){return t.map(e=>/[\s"]/.test(e)?`"${e}"`:e).join(" ")}function k(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=${S(relaunchArgs())}`,"X-GNOME-Autostart-enabled=true",""].join(`
17
+ `))}function x(t){try{c(r.join(t.home,".config","autostart",`${o}.desktop`))}catch{}}export function applyLaunchOnLogin(t,e={}){try{const n=g(e);n.platform==="win32"?t?y(n):v(n):n.platform==="darwin"?t?L(n):D(n):t?k(n):x(n)}catch(n){console.error(`[weave] auto-start ${t?"enable":"disable"} failed:`,n)}}export function syncLaunchOnLogin(t={}){const e=f().startup;applyLaunchOnLogin(e?.launchOnLogin??!1,t)}
@@ -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 J}from"node:os";import{access as K}from"node:fs/promises";import{isHarness as k}from"@weavecode/core";import{configSurfaceFor as j}from"../surfaces.js";import{baselineSnapshot as N,createProfile as E,LASTSEEN_ID as C,listBackups as L,listProfiles as m,profileKeyOf as $,readBackup as F,readSnapshot as A,removeProfile as D,renameProfile as V,pushBackup as S,saveProfile as M,setActive as R,syncBaseline as O,writeSnapshot as G}from"../config/profiles.js";import{readBody as H,sendJson as n}from"./http.js";import{getHarnessConfigDir as _}from"../db/paths.js";const z=["user","project","projectLocal","global"];function u(f,t){return $(f,t.projectId)}function T(f){return typeof f=="string"&&z.includes(f)?f:null}function g(f,t){return f.serializeRaw(t)}function W(f,t,p){const h=f.files(p).find(y=>y.id===t);return h?h.path(p):""}async function U(f){try{const t=JSON.parse(await H(f));return typeof t=="object"&&t!==null&&!Array.isArray(t)?t:null}catch{return null}}async function Q(f){if(!f)return!1;try{return await K(f),!0}catch{return!1}}async function x(f,t,p,h,y){const s=u(h,y),o=W(p,h,y),e=await p.read(h,y),r=g(p,e),c=await m(f,t,s),i=await N(f,t,s,c);i||await G(f,t,s,C,e);const a=i?g(p,i):g(p,e);return{harness:t,file:h,path:o,exists:await Q(o),values:e,managedKeys:p.managedKeys(e),managedEntries:p.managedEntries(e),profiles:c.profiles,activeId:c.activeId,liveText:r,activeText:a,drifted:a!==r,backups:await L(f,t,s)}}function P(f,t,p){let h=null,y=null;if(t==="project"||t==="projectLocal"){const s=Number(p);if(!Number.isInteger(s)||s<=0)return"\u9700\u8981 projectId";const o=f.projects.getById(s);if(!o)return"\u9879\u76EE\u4E0D\u5B58\u5728";h=o.path,y=s}return{projectPath:h,projectId:y,homedir:J()}}export async function handleConfigRoutes(f,t,p,h,y){if(!h.startsWith("/harness-config"))return!1;const s=_();if(h==="/harness-config/catalog"&&f.method==="GET"){const o=y.searchParams.get("harness");if(!k(o))return n(t,400,{error:"Unknown harness"}),!0;const e=j(o);if(!e)return n(t,200,{supported:!1}),!0;const r=T(y.searchParams.get("file"))??"user",c={projectPath:null,projectId:null,homedir:J()},i=e.catalog(r);return n(t,200,{supported:!0,harness:o,file:r,rawFormat:e.rawFormat,files:e.files(c).map(a=>({id:a.id,profiles:a.profiles})),groups:i.groups,keys:i.keys,envVars:i.envVars}),!0}if(h==="/harness-config"&&f.method==="GET"){const o=y.searchParams.get("harness"),e=T(y.searchParams.get("file"));if(!k(o)||!e)return n(t,400,{error:"Unknown harness or file"}),!0;const r=j(o);if(!r)return n(t,400,{error:"\u914D\u7F6E\u9762\u672A\u5B9E\u73B0"}),!0;const c=P(p,e,y.searchParams.get("projectId"));return typeof c=="string"?(n(t,400,{error:c}),!0):(n(t,200,await x(s,o,r,e,c)),!0)}if(h==="/harness-config/values"&&f.method==="PUT"){const o=await U(f);if(!o)return n(t,400,{error:"Invalid JSON body"}),!0;const e=o.harness,r=T(o.file);if(!k(e)||!r)return n(t,400,{error:"Unknown harness or file"}),!0;const c=j(e);if(!c)return n(t,400,{error:"\u914D\u7F6E\u9762\u672A\u5B9E\u73B0"}),!0;const i=P(p,r,o.projectId);if(typeof i=="string")return n(t,400,{error:i}),!0;const a=o.values;if(typeof a!="object"||a===null||Array.isArray(a))return n(t,400,{error:'Missing "values"'}),!0;try{const l=await c.read(r,i);await S(s,e,u(r,i),l),await c.write(r,i,a);const b=await m(s,e,u(r,i));await O(s,e,u(r,i),b,await c.read(r,i))}catch(l){return n(t,400,{error:l.message}),!0}return n(t,200,await x(s,e,c,r,i)),!0}if(h==="/harness-config/raw"&&f.method==="PUT"){const o=await U(f);if(!o)return n(t,400,{error:"Invalid JSON body"}),!0;const e=o.harness,r=T(o.file);if(!k(e)||!r)return n(t,400,{error:"Unknown harness or file"}),!0;const c=j(e);if(!c)return n(t,400,{error:"\u914D\u7F6E\u9762\u672A\u5B9E\u73B0"}),!0;const i=P(p,r,o.projectId);if(typeof i=="string")return n(t,400,{error:i}),!0;let a;try{a=c.parseRaw(String(o.text??""))}catch(l){return n(t,400,{error:`\u4E0D\u662F\u5408\u6CD5${c.rawFormat==="toml"?" TOML":" JSON"}\uFF1A${l.message}`}),!0}try{const l=await c.read(r,i);await S(s,e,u(r,i),l),await c.write(r,i,a);const b=await m(s,e,u(r,i));await O(s,e,u(r,i),b,await c.read(r,i))}catch(l){return n(t,400,{error:l.message}),!0}return n(t,200,await x(s,e,c,r,i)),!0}if(h==="/harness-config/profile"&&f.method==="POST"){const o=await U(f);if(!o)return n(t,400,{error:"Invalid JSON body"}),!0;const e=o.harness,r=T(o.file),c=o.action;if(!k(e)||!r||typeof c!="string")return n(t,400,{error:"Unknown harness, file or action"}),!0;const i=j(e);if(!i)return n(t,400,{error:"\u914D\u7F6E\u9762\u672A\u5B9E\u73B0"}),!0;const a=P(p,r,o.projectId);if(typeof a=="string")return n(t,400,{error:a}),!0;const l=typeof o.id=="string"?o.id:"",b=typeof o.name=="string"?o.name.trim():"",B=typeof o.values=="object"&&o.values!==null&&!Array.isArray(o.values)?o.values:null;switch(c){case"list":{const d=await m(s,e,u(r,a));return n(t,200,d),!0}case"create":{const d=await m(s,e,u(r,a)),w=await E(s,e,u(r,a),b||`\u914D\u7F6E ${d.profiles.length+1}`,B??await i.read(r,a));return n(t,200,{profile:w,state:await m(s,e,u(r,a))}),!0}case"save":return(await m(s,e,u(r,a))).profiles.some(w=>w.id===l)?(await M(s,e,u(r,a),l,B??await i.read(r,a)),n(t,200,await m(s,e,u(r,a))),!0):(n(t,404,{error:"\u914D\u7F6E\u4E0D\u5B58\u5728"}),!0);case"compare":{const d=o.target;if(d==="live")return n(t,200,{text:g(i,await i.read(r,a))}),!0;if(d==="backup"){const v=typeof o.backupId=="string"?o.backupId:"",I=await F(s,e,u(r,a),v);return I?(n(t,200,{text:g(i,I)}),!0):(n(t,404,{error:"\u5907\u4EFD\u4E0D\u5B58\u5728"}),!0)}const w=await A(s,e,u(r,a),l);return w?(n(t,200,{text:g(i,w)}),!0):(n(t,404,{error:"\u914D\u7F6E\u4E0D\u5B58\u5728"}),!0)}case"duplicate":{const d=await A(s,e,u(r,a),l);if(!d)return n(t,404,{error:"\u914D\u7F6E\u4E0D\u5B58\u5728"}),!0;const w=await m(s,e,u(r,a)),v=await E(s,e,u(r,a),b||`\u914D\u7F6E ${w.profiles.length+1}`,d);return n(t,200,{profile:v,state:await m(s,e,u(r,a))}),!0}case"rename":return b?(await V(s,e,u(r,a),l,b),n(t,200,await m(s,e,u(r,a))),!0):(n(t,400,{error:"\u7F3A\u5C11\u540D\u79F0"}),!0);case"remove":return await D(s,e,u(r,a),l),n(t,200,await m(s,e,u(r,a))),!0;case"activate":{const d=await A(s,e,u(r,a),l);if(!d)return n(t,404,{error:"\u914D\u7F6E\u4E0D\u5B58\u5728"}),!0;const w=await i.read(r,a);if(o.confirm!==!0)return n(t,200,{requiresConfirm:!0,liveText:g(i,w),profileText:g(i,d)}),!0;try{await S(s,e,u(r,a),w),await i.write(r,a,d),await R(s,e,u(r,a),l)}catch(v){return n(t,400,{error:v.message}),!0}return n(t,200,await x(s,e,i,r,a)),!0}case"acceptDrift":{const d=await m(s,e,u(r,a)),w=await N(s,e,u(r,a),d);return w&&await S(s,e,u(r,a),w),await O(s,e,u(r,a),d,await i.read(r,a)),n(t,200,await x(s,e,i,r,a)),!0}case"restoreBaseline":{const d=await m(s,e,u(r,a)),w=await N(s,e,u(r,a),d);if(!w)return n(t,404,{error:"\u6CA1\u6709\u53EF\u6062\u590D\u7684\u57FA\u7EBF"}),!0;const v=await i.read(r,a);if(o.confirm!==!0)return n(t,200,{requiresConfirm:!0,liveText:g(i,v),baselineText:g(i,w)}),!0;try{await S(s,e,u(r,a),v),await i.write(r,a,w),await O(s,e,u(r,a),d,w)}catch(I){return n(t,400,{error:I.message}),!0}return n(t,200,await x(s,e,i,r,a)),!0}case"restoreBackup":{const d=typeof o.backupId=="string"?o.backupId:"",w=await F(s,e,u(r,a),d);if(!w)return n(t,404,{error:"\u5907\u4EFD\u4E0D\u5B58\u5728"}),!0;const v=await i.read(r,a);if(o.confirm!==!0)return n(t,200,{requiresConfirm:!0,liveText:g(i,v),backupText:g(i,w)}),!0;try{await S(s,e,u(r,a),v),await i.write(r,a,w);const I=await m(s,e,u(r,a));await O(s,e,u(r,a),I,w)}catch(I){return n(t,400,{error:I.message}),!0}return n(t,200,await x(s,e,i,r,a)),!0}default:return n(t,400,{error:`\u672A\u77E5\u52A8\u4F5C\uFF1A${c}`}),!0}}if(h==="/harness-config/models"&&f.method==="POST"){const o=await U(f);if(!o)return n(t,400,{error:"Invalid JSON body"}),!0;const e=o.harness,r=T(o.file)??"user";if(!k(e))return n(t,400,{error:"Unknown harness"}),!0;const c=j(e);if(!c)return n(t,400,{error:"\u914D\u7F6E\u9762\u672A\u5B9E\u73B0"}),!0;const i=P(p,r,o.projectId);if(typeof i=="string")return n(t,400,{error:i}),!0;try{const a=await c.read(r,i),l=await c.models({values:a,file:r,homedir:i.homedir,baseUrl:typeof o.baseUrl=="string"?o.baseUrl:null,apiKey:typeof o.apiKey=="string"?o.apiKey:null,authToken:typeof o.authToken=="string"?o.authToken:null});n(t,200,l)}catch(a){n(t,502,{error:a.message})}return!0}if(h==="/harness-config/preview"&&f.method==="POST"){const o=await U(f);if(!o)return n(t,400,{error:"Invalid JSON body"}),!0;const e=o.harness,r=T(o.file);if(!k(e)||!r)return n(t,400,{error:"Unknown harness or file"}),!0;const c=j(e);if(!c)return n(t,400,{error:"\u914D\u7F6E\u9762\u672A\u5B9E\u73B0"}),!0;const i=P(p,r,o.projectId);if(typeof i=="string")return n(t,400,{error:i}),!0;const a=o.values;if(typeof a!="object"||a===null||Array.isArray(a))return n(t,400,{error:'Missing "values"'}),!0;try{const l=await c.read(r,i);n(t,200,{before:g(c,l),after:g(c,a)})}catch(l){n(t,400,{error:l.message})}return!0}return n(t,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 m,profileKeyOf as $,readBackup as N,readSnapshot as S,removeProfile as L,renameProfile as q,pushBackup as k,saveProfile as M,setActive as R,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 g(f,r){return f.serializeRaw(r)}function W(f,r,p){const h=f.files(p).find(y=>y.id===r);return h?h.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,h,y){const o=u(h,y),i=W(p,h,y),t=await p.read(h,y),e=g(p,t),c=await m(f,r,o),s=await P(f,r,o,c);s||await G(f,r,o,J,t);const a=s?g(p,s):g(p,t);return{harness:r,file:h,path:i,exists:await _(i),values:t,managedKeys:p.managedKeys(t),managedEntries:p.managedEntries(t),profiles:c.profiles,activeId:c.activeId,liveText:e,activeText:a,drifted:a!==e,backups:await K(f,r,o)}}function A(f,r,p){let h=null,y=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";h=i.path,y=o}return{projectPath:h,projectId:y,homedir:O()}}export async function handleConfigRoutes(f,r,p,h,y){if(!h.startsWith("/harness-config"))return!1;const o=V();if(h==="/harness-config/catalog"&&f.method==="GET"){const i=y.searchParams.get("harness");if(!B(i))return n(r,400,{error:"Unknown harness"}),!0;const t=D(i);if(!t)return n(r,200,{supported:!1}),!0;const e=b(y.searchParams.get("file"))??"user",c={projectPath:null,projectId:null,homedir:O()},s=t.catalog(e);return n(r,200,{supported:!0,harness:i,file:e,rawFormat:t.rawFormat,files:t.files(c).map(a=>({id:a.id,profiles:a.profiles})),groups:s.groups,keys:s.keys,envVars:s.envVars}),!0}if(h==="/harness-config"&&f.method==="GET"){const i=y.searchParams.get("harness"),t=b(y.searchParams.get("file"));if(!B(i)||!t)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,t,y.searchParams.get("projectId"));return typeof c=="string"?(n(r,400,{error:c}),!0):(n(r,200,await I(o,i,e,t,c)),!0)}if(h==="/harness-config/values"&&f.method==="PUT"){const i=await T(f);if(!i)return n(r,400,{error:"Invalid JSON body"}),!0;const t=i.harness,e=b(i.file);if(!B(t)||!e)return n(r,400,{error:"Unknown harness or file"}),!0;const c=D(t);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 a=i.values;if(typeof a!="object"||a===null||Array.isArray(a))return n(r,400,{error:'Missing "values"'}),!0;try{const l=await c.read(e,s);await k(o,t,u(e,s),l),await c.write(e,s,a);const v=await m(o,t,u(e,s));await j(o,t,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,t,c,e,s)),!0}if(h==="/harness-config/raw"&&f.method==="PUT"){const i=await T(f);if(!i)return n(r,400,{error:"Invalid JSON body"}),!0;const t=i.harness,e=b(i.file);if(!B(t)||!e)return n(r,400,{error:"Unknown harness or file"}),!0;const c=D(t);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 a;try{a=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,t,u(e,s),l),await c.write(e,s,a);const v=await m(o,t,u(e,s));await j(o,t,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,t,c,e,s)),!0}if(h==="/harness-config/profile"&&f.method==="POST"){const i=await T(f);if(!i)return n(r,400,{error:"Invalid JSON body"}),!0;const t=i.harness,e=b(i.file),c=i.action;if(!B(t)||!e||typeof c!="string")return n(r,400,{error:"Unknown harness, file or action"}),!0;const s=D(t);if(!s)return n(r,400,{error:"\u914D\u7F6E\u9762\u672A\u5B9E\u73B0"}),!0;const a=A(p,e,i.projectId);if(typeof a=="string")return n(r,400,{error:a}),!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 m(o,t,u(e,a));return n(r,200,w),!0}case"create":{const w=await m(o,t,u(e,a)),d=await U(o,t,u(e,a),v||`\u914D\u7F6E ${w.profiles.length+1}`,x??await s.read(e,a));return n(r,200,{profile:d,state:await m(o,t,u(e,a))}),!0}case"save":return(await m(o,t,u(e,a))).profiles.some(w=>w.id===l)?(await M(o,t,u(e,a),l,x??await s.read(e,a)),n(r,200,await m(o,t,u(e,a))),!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:g(s,await s.read(e,a))}),!0;if(w==="backup"){const E=typeof i.backupId=="string"?i.backupId:"",F=await N(o,t,u(e,a),E);return F?(n(r,200,{text:g(s,F)}),!0):(n(r,404,{error:"\u5907\u4EFD\u4E0D\u5B58\u5728"}),!0)}const d=await S(o,t,u(e,a),l);return d?(n(r,200,{text:g(s,d)}),!0):(n(r,404,{error:"\u914D\u7F6E\u4E0D\u5B58\u5728"}),!0)}case"duplicate":{const w=await S(o,t,u(e,a),l);if(!w)return n(r,404,{error:"\u914D\u7F6E\u4E0D\u5B58\u5728"}),!0;const d=await m(o,t,u(e,a)),E=await U(o,t,u(e,a),v||`\u914D\u7F6E ${d.profiles.length+1}`,w);return n(r,200,{profile:E,state:await m(o,t,u(e,a))}),!0}case"rename":return v?(await q(o,t,u(e,a),l,v),n(r,200,await m(o,t,u(e,a))),!0):(n(r,400,{error:"\u7F3A\u5C11\u540D\u79F0"}),!0);case"remove":return await L(o,t,u(e,a),l),n(r,200,await m(o,t,u(e,a))),!0;case"activate":{const w=await S(o,t,u(e,a),l);if(!w)return n(r,404,{error:"\u914D\u7F6E\u4E0D\u5B58\u5728"}),!0;const d=await s.read(e,a);if(i.confirm!==!0)return n(r,200,{requiresConfirm:!0,liveText:g(s,d),profileText:g(s,w)}),!0;try{await k(o,t,u(e,a),d),await s.write(e,a,w),await R(o,t,u(e,a),l)}catch(E){return n(r,400,{error:E.message}),!0}return n(r,200,await I(o,t,s,e,a)),!0}case"acceptDrift":{const w=await m(o,t,u(e,a)),d=await P(o,t,u(e,a),w);return d&&await k(o,t,u(e,a),d),await j(o,t,u(e,a),w,await s.read(e,a)),n(r,200,await I(o,t,s,e,a)),!0}case"restoreBaseline":{const w=await m(o,t,u(e,a)),d=await P(o,t,u(e,a),w);if(!d)return n(r,404,{error:"\u6CA1\u6709\u53EF\u6062\u590D\u7684\u57FA\u7EBF"}),!0;const E=await s.read(e,a);if(i.confirm!==!0)return n(r,200,{requiresConfirm:!0,liveText:g(s,E),baselineText:g(s,d)}),!0;try{await k(o,t,u(e,a),E),await s.write(e,a,d),await j(o,t,u(e,a),w,d)}catch(F){return n(r,400,{error:F.message}),!0}return n(r,200,await I(o,t,s,e,a)),!0}case"restoreBackup":{const w=typeof i.backupId=="string"?i.backupId:"",d=await N(o,t,u(e,a),w);if(!d)return n(r,404,{error:"\u5907\u4EFD\u4E0D\u5B58\u5728"}),!0;const E=await s.read(e,a);if(i.confirm!==!0)return n(r,200,{requiresConfirm:!0,liveText:g(s,E),backupText:g(s,d)}),!0;try{await k(o,t,u(e,a),E),await s.write(e,a,d);const F=await m(o,t,u(e,a));await j(o,t,u(e,a),F,d)}catch(F){return n(r,400,{error:F.message}),!0}return n(r,200,await I(o,t,s,e,a)),!0}default:return n(r,400,{error:`\u672A\u77E5\u52A8\u4F5C\uFF1A${c}`}),!0}}if(h==="/harness-config/models"&&f.method==="POST"){const i=await T(f);if(!i)return n(r,400,{error:"Invalid JSON body"}),!0;const t=i.harness,e=b(i.file)??"user";if(!B(t))return n(r,400,{error:"Unknown harness"}),!0;const c=D(t);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 a=await c.read(e,s),l=await c.models({values:a,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(a){n(r,502,{error:a.message})}return!0}if(h==="/harness-config/preview"&&f.method==="POST"){const i=await T(f);if(!i)return n(r,400,{error:"Invalid JSON body"}),!0;const t=i.harness,e=b(i.file);if(!B(t)||!e)return n(r,400,{error:"Unknown harness or file"}),!0;const c=D(t);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 a=i.values;if(typeof a!="object"||a===null||Array.isArray(a))return n(r,400,{error:'Missing "values"'}),!0;try{const l=await c.read(e,s);n(r,200,{before:g(c,l),after:g(c,a)})}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(e){const n=e.trim().split(/\s+/);if(n.length!==5)return null;const t=[];for(let s=0;s<5;s++){const o=a(n[s],d[s].min,d[s].max);if(!o)return null;t.push(o)}const u=[...new Set(t[4].map(s=>s===7?0:s))].sort((s,o)=>s-o);return{minutes:t[0],hours:t[1],doms:t[2],months:t[3],dows:u,domAny:n[2]==="*",dowAny:n[4]==="*"}}function a(e,n,t){const u=new Set;for(const s of e.split(",")){const[o,c]=s.split("/");if(o===void 0)return null;const m=c===void 0?1:Number(c);if(!Number.isInteger(m)||m<1||m>t)return null;let i,r;if(o==="*")i=n,r=t;else if(o.includes("-")){const[l,f]=o.split("-");i=Number(l),r=Number(f)}else i=Number(o),r=c===void 0?i:t;if(!Number.isInteger(i)||!Number.isInteger(r)||i<n||r>t||i>r)return null;for(let l=i;l<=r;l+=m)u.add(l)}return u.size===0?null:[...u].sort((s,o)=>s-o)}function g(e,n){const t=e.doms.includes(n.getDate()),u=e.dows.includes(n.getDay());return e.domAny&&e.dowAny?!0:e.domAny?u:e.dowAny?t:t||u}export function matchesMinute(e,n){return e.minutes.includes(n.getMinutes())&&e.hours.includes(n.getHours())&&e.months.includes(n.getMonth()+1)&&g(e,n)}export function nextRunAt(e,n=new Date){const t=new Date(n.getTime());t.setSeconds(0,0),t.setMinutes(t.getMinutes()+1);const u=new Date(n.getTime()+366*864e5);for(;t<=u;){if(!e.months.includes(t.getMonth()+1)){t.setMonth(t.getMonth()+1,1),t.setHours(0,0,0,0);continue}if(!g(e,t)){t.setDate(t.getDate()+1),t.setHours(0,0,0,0);continue}if(!e.hours.includes(t.getHours())){t.setHours(t.getHours()+1,0,0,0);continue}if(!e.minutes.includes(t.getMinutes())){t.setMinutes(t.getMinutes()+1,0,0);continue}return t.toISOString()}return null}export function minuteKey(e){const n=t=>String(t).padStart(2,"0");return`${e.getFullYear()}-${n(e.getMonth()+1)}-${n(e.getDate())}T${n(e.getHours())}:${n(e.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 r,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=r(O).toString("hex");return{algo:"scrypt",salt:e,hash:o(s,e,l).toString("hex"),updatedAt:t}}function n(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:r(32).toString("hex"),localToken:r(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?n(o(t,e.salt,l).toString("hex"),e.hash):!1}setPassword(t){this.file={...this.file,password:f(t,this.nowIso()),sessionSecret:r(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!==""&&n(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:n(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 p=60,f=1e3,w=6e4;export function startDashboardPusher(t){let o=!1,c={projects:0,sessions:0},a=0;const r=()=>{c={projects:t.projects.list().length,sessions:t.sessions.countAll()},a=Date.now()},l=()=>({...c,...t.rate.totals}),h=()=>{queueMicrotask(()=>{const n=Date.now(),i=DASHBOARD_WINDOW_MS/s,u=Math.floor(n/s)*s-(i-1)*s,S=t.projects.list().map(e=>e.id);t.rate.isSeeded||(t.rate.seed(t.events.seriesBySecond(S,new Date(u).toISOString())),t.rate.seedTotals(t.events.countAll(),t.events.countSince(S,new Date(new Date(n).setHours(0,0,0,0)).toISOString())),r()),Date.now()-a>w&&r();const D=new Date(n).toISOString();t.bus.emit({kind:"dashboard.totals",at:D,totals:l()});for(let e=0;e<i;e+=p){const I=Math.min(p,i-e),b=u+e*s,g=t.rate.bucketsFor(b,I);t.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=t.bus.subscribe(n=>{n.kind==="event.ingested"&&(o=!0)}),d=setInterval(()=>{o&&(o=!1,Date.now()-a>w&&r(),t.bus.emit({kind:"dashboard.delta",at:new Date().toISOString(),series:t.rate.recentBuckets(12),totals:l()}))},f);return d.unref?.(),{attach:h,stop:()=>{m(),clearInterval(d)}}}
@@ -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 i,existsSync as c,mkdirSync as o,readFileSync as a,renameSync as s,rmSync as y,writeFileSync as u}from"node:fs";import l from"node:path";import{getDecisionKeyPath as e}from"../db/paths.js";export function readDecisionKey(r=e()){if(!c(r))return null;try{const n=JSON.parse(a(r,"utf8"));return typeof n.apiKey=="string"&&n.apiKey!==""?n.apiKey:null}catch{return null}}export function writeDecisionKey(r,n=e()){if(r===null||r===""){y(n,{force:!0});return}o(l.dirname(n),{recursive:!0});const t=`${n}.tmp`;u(t,`${JSON.stringify({apiKey:r},null,2)}
2
+ `,{encoding:"utf8",mode:384}),s(t,n);try{i(n,384)}catch{}}export function hasDecisionKey(r=e()){return readDecisionKey(r)!==null}
@@ -1 +1 @@
1
- import he from"node:http";import{openDatabase as we}from"../db/db.js";import{ProjectRepository as ge}from"../repositories/projects.js";import{HookEventRepository as ve}from"../repositories/hook-events.js";import{LibraryRepository as Se}from"../repositories/libraries.js";import{HookRuleRepository as oe}from"../repositories/hook-rules.js";import{HookDispatchRepository as be}from"../repositories/hook-dispatches.js";import{PluginStateRepository as E}from"../repositories/plugin-states.js";import{SessionRepository as Re}from"../repositories/sessions.js";import{createRuntimeRegistry as ye}from"@weavecode/harness";import{TERMINAL_LOCATOR_ENV_KEYS as ke,isHarness as L}from"@weavecode/core";import{messagingSurfaceFor as Pe,narrationSurfaceFor as De}from"../surfaces.js";import{syntheticSessionIds as Ee}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 Te}from"../hooks/dispatcher.js";import{HookEventBus as Ae}from"../hooks/bus.js";import{ResumeRunner as Ce}from"../hooks/resume-runner.js";import{HeadlessRunner as _e}from"../hooks/headless-runner.js";import{MessageDeliverer as Fe}from"../hooks/message-deliverer.js";import{QuestionTracker as He}from"../hooks/question-tracker.js";import{SideQuestionRepository as $e}from"../repositories/side-questions.js";import{claimSideAnswer as Me}from"../hooks/side-questions.js";import{DashboardRateCache as Be}from"../hooks/dashboard-rate.js";import{startDashboardPusher as Ue}from"./dashboard-pusher.js";import{startPromptFlusher as Le}from"../hooks/prompt-flusher.js";import{SessionWatchRepository as Ne}from"../repositories/session-watches.js";import{PushSubscriptionRepository as We}from"../repositories/push-subscriptions.js";import{UploadRepository as je}from"../repositories/uploads.js";import{defaultUploadSessions as xe}from"./upload-sessions.js";import{PushNotifier as Qe}from"../hooks/push-notify.js";import{OrchestrationRepository as qe,OrchestrationRunRepository as Ke}from"../repositories/orchestrations.js";import{WatchEngine as Ge}from"../hooks/watch-engine.js";import{OrchestrationEngine as Je,createForkConditionJudge as Ve}from"../hooks/orchestration-engine.js";import{createDecisionConditionJudge as Ye}from"../hooks/decision-judge.js";import{readDecisionKey as ze}from"./decision-config.js";import{createEnsureOpen as Xe}from"./session-open.js";import{loadAllPlugins as Ze}from"../hooks/plugin-loader.js";import{ensureBuiltinMarket as es,builtinMarketDir as ss}from"../market/builtin.js";import{ToolkitService as ts}from"../hooks/toolkit.js";import{startSessionSweeper as os}from"../hooks/session-sweeper.js";import{startStatuslineCacheSweeper as rs}from"../statusline/cache-sweeper.js";import{readStatuslineFacts as ns}from"../statusline/manager.js";import{WatchService as is}from"../watch/watch-service.js";import{weaveRequestHandler as as}from"./server.js";import{startTlsServer as ls}from"./tls.js";import{DataBus as cs}from"./data-bus.js";import{TerminalTopologyRefresher as ps}from"./terminal-topology-refresher.js";import{SnapshotRefresher as N}from"./snapshot-refresher.js";import{SessionProbe as ms,dbModelFactResolver as us,dbTranscriptPathResolver as ds}from"./session-probe.js";import{NarrationWatcher as fs}from"./narration-watcher.js";import{InflightCountsRefresher as hs}from"./inflight-counts-refresher.js";import{ProjectUpdatesRefresher as ws}from"./project-updates-refresher.js";import{FingerprintCache as gs}from"../install/fingerprint.js";import{detectProjectUpdateCounts as vs}from"../install/updates.js";import{pidAliveOf as Ss}from"./claude-liveness.js";import{combinedLivenessOf as b}from"./liveness.js";import{promptTerminalChannel as re,readTerminalCounts as bs}from"./opener.js";import{wireHookFilePipeline as Rs}from"./hook-pipeline.js";import{DEFAULT_PORT as W,DAEMON_HOST as ys,DEFAULT_BIND_HOST as ks,findFreePort as Ps,isPortFree as Ds}from"./port.js";import{writeDaemonState as ne}from"./state.js";import{ensureDataLayout as Es}from"../db/layout.js";import{pruneFileIndexes as Os}from"./project-files.js";import{pruneInstallTmp as Is}from"../hooks/plugin-installer.js";import{readDaemonSettingsSync as R,setDaemonSettingsDb as Ts,DEFAULT_SERVER_SETTINGS as As}from"./settings.js";import{AuthService as Cs}from"./dashboard-auth.js";import{openPetWindow as _s,shutdownPetWindow as Fs}from"./pet-window.js";import{seedBuiltinPets as Hs}from"./pet-seed.js";import{resolveStaticDir as $s}from"./static.js";const Ms="CLAUDE_CODE_CHILD_SESSION"in process.env;delete process.env.CLAUDE_CODE_CHILD_SESSION;for(const c of ke)delete process.env[c];async function Bs(){Es();const c=await Ds(W)?W:await Ps(W+1);ne({pid:process.pid,port:c,startedAt:new Date().toISOString()});const o=we();Ts(o);const f=R().server?.bindHost??ks,O=R().server?.tlsPort??As.tlsPort,y=new Cs;y.initialPassword&&console.log(`[dev] initial dashboard password: ${y.initialPassword}`);const r=new ge(o);Os(r.list().map(e=>e.id)),Is();const a=new ve(o),u=new Se(o),h=ye(),ie=h.byCapability("events").flatMap(e=>e.events??[]),k=new Ie(new oe(o)),P=new be(o),t=new Re(o),n=new Ae;{const e=await es({libraries:u});e.error?console.error(`[dev] builtin market unavailable: ${e.error}`):e.changed&&console.log(`[dev] builtin market ${e.form==="link"?"linked":"copied"} -> ${ss(u.dataRoot)}`)}const{loader:m}=await Ze({rules:new oe(o),registry:k,states:new E(o),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 j={list:()=>m.list(),setPluginEnabled:(e,s)=>m.setPluginEnabled(e,s),reloadAll:()=>m.reloadAll(),rescan:()=>m.rescanRoots(r.list(),u)},ae=new ts({projects:r,states:new E(o),plugins:j,libraries:u}),I={run:null},x=new Te({registry:k,dispatches:P,bus:n,projects:r,sessions:t,plugins:m,pluginStates:new E(o),classify:e=>I.run?I.run(e):Promise.resolve(null),sessionTitleOf:async e=>{const s=a.listBySession(e,1).at(-1)?.source;return L(s)?h.get(s)?.titles?.sessionTitleOf(e)??null:null}}),D=new _e,le=new Ce({dispatches:P,sessions:t,projects:r,bus:n,resumeSpec:h.get("claude")?.resume,headless:D}),p=new Fe({sessions:t,projects:r,hookEvents:a,bus:n,headless:D,terminal:re(()=>R().terminal),blockedByQuestion:e=>w.get(e)!=null,livenessOf:b,sideAnswerStore:{answerById:(e,s,l)=>{F.answerById(e,s,l)}}});Le(p);const T=new Ne(o),A=new Ge({watches:T,deliverer:p,sessions:t,bus:n,livenessOf:b}),Q=new We(o),C=new je(o),ce=new Qe({subscriptions:Q,sessions:t,bus:n}),_=new qe(o),q=new Ke(o),d=new ms(ds(a),us(a,e=>t.getBySessionId(e)?.harness??null)),K=new fs(n,e=>De(L(e)?e:"claude"),e=>d.transcriptPathOf(e),e=>t.livenessRowOf(e)?.harness??null);K.start();const w=new He({sessions:t,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=t.getBySessionId(e);return s?d.interruptedAt(e,t.lastMainEventAtOf(e)??s.lastSeenAt):null}});w.seedFromDb();const F=new $e(o),G=new Be,H=Ue({rate:G,events:a,sessions:t,projects:r,bus:n}),J={repo:F,bus:n,settle:e=>{p.interrupt(e.sessionId)}},V=new is(r);V.start();const i=new cs,g=new ps(async()=>({counts:await bs(r.list()),terminals:await p.sessionTerminals()}),i,{shouldRun:()=>i.hasSubscribers(),graceMs:1e4});g.start();const $=new N(()=>{const e=b(),s={};for(const l of t.listWithCounts()){const te=Ss(l,e);te!==null&&(s[l.sessionId]=te)}return{alive:s}},i,{key:"sessionLiveness",shouldRun:()=>i.hasSubscribers()});$.start();const M=new N(()=>{const e={};for(const s of t.listWithCounts()){if(s.turnOpen!==!0)continue;const l=d.interruptedAt(s.sessionId,t.lastMainEventAtOf(s.sessionId)??s.lastSeenAt);l!==null&&(e[s.sessionId]=l)}return{interrupted:e}},i,{key:"sessionInterrupt",intervalMs:5e3,shouldRun:()=>i.hasSubscribers()});M.start(),new N(()=>{const e={};for(const s of r.list())e[s.id]=ns(s.path);return e},i,{key:"statusline",intervalMs:5e3,shouldRun:()=>i.hasSubscribers(),invalidateOnly:!0}).start();const pe=new hs(()=>p.listInflightCounts(),i,n);let Y=null;const v=Oe({sessions:t,projects:r,harnessOf:e=>{const s=a.listBySession(e,1),l=s[s.length-1]?.source;return L(l)?l:null},surfaceFor:Pe,headless:D,onSyntheticChange:()=>Y?.pushSyntheticSessions(Ee())});I.run=e=>v.run(e);const me=Ye({config:async()=>{const e=R().decision;if(!e?.baseUrl||!e.model)return null;const s=ze();return s?{baseUrl:e.baseUrl,model:e.model,apiKey:s}:null},fallback:Ve({supports:e=>v.supports(e),extract:e=>v.run(e)})}),ue=Xe({hookSessions:t,hookEvents:a,projects:r,harnesses:h,sessionProbe:d,terminalRefresher:g,livenessOf:b}),S=new Je({orchestrations:_,runs:q,deliverer:p,sessions:t,bus:n,supportsExtract:e=>v.supports(e),extract:e=>v.run(e),conditionJudge:me,deferWhenUserPresent:!0,ensureOpen:ue});S.rearm();const z=setInterval(()=>S.cronTick(),3e4);z.unref();const de=new gs,fe=new ws(()=>vs(r.list(),u.list(),de),i,n,()=>i.hasSubscribers());os({sessions:t,events:a,dispatches:P,deliverer:p,watches:T,orchestrations:_,watchEngine:A,orchestrationEngine:S,questions:w,sideQuestions:F,probe:d,uploads:C,uploadSessions:xe,livenessOf:b}),rs();const B=Rs({projects:r,rules:k,sessions:t,bus:n,dispatcher:x,watchEngine:A,orchestrationEngine:S,messagePipe:p,questionTracker:w,sideQuestions:{onEvent:e=>{Me(J,e)}},sessionProbe:d,uploads:C,dashboardRate:G,terminalTopologyKick:()=>{g.refreshNow()}});Y=B;const U=$s(),X=as({projects:r,port:c,tlsPort:O,watch:V,hookEvents:a,adapters:ie,harnesses:h,libraries:u,staticDir:U,hookRegistry:k,hookDispatches:P,hookSessions:t,hookBus:n,dataBus:i,terminalRefresher:g,interruptRefresher:M,livenessRefresher:$,sessionProbe:d,inflightRefresher:pe,updatesRefresher:fe,hookDispatcher:x,hookRunner:le,messageDeliverer:p,terminal:re(()=>R().terminal),uploads:C,questionTracker:w,sideQuestions:J,sessionWatches:T,watchEngine:A,orchestrations:_,orchestrationRuns:q,orchestrationEngine:S,pushSubscriptions:Q,pushNotifier:ce,onAttach:H.attach,dashboardRefresh:H.attach,hookPlugins:j,hookMirror:B.mirror,pluginStates:new E(o),toolkit:ae,auth:y}),Z=he.createServer(X);let ee=null;ls({port:O,bindHost:f,handler:X}).then(e=>{ee=e,e&&console.log(`[dev] weave daemon tls listening on https://${f}:${e.port}`)});const se=()=>{g.stop(),$.stop(),M.stop(),Fs(),D.killAll(),clearInterval(z),K.stop(),H.stop(),B.stop(),Z.close(),ee?.server.close(),process.exit(0)};process.on("SIGTERM",se),process.on("SIGINT",se),Z.listen(c,f,()=>{ne({pid:process.pid,port:c,startedAt:new Date().toISOString(),host:f,tlsPort:O}),console.log(`[dev] weave daemon listening on http://${f}:${c}`),console.log(`[dev] cli/dashboard local url: http://${ys}:${c}`),console.log(`[dev] child-session marker stripped: ${Ms}`),console.log(U?`[dev] static: ${U}`:"[dev] static: (web/dist not built \u2014 run pnpm build:web)"),Hs().then(()=>{_s({baseUrl:`http://localhost:${c}`,auth:y})})})}Bs();
1
+ import ws from"node:http";import{openDatabase as gs}from"../db/db.js";import{ProjectRepository as Ss}from"../repositories/projects.js";import{HookEventRepository as bs}from"../repositories/hook-events.js";import{LibraryRepository as vs}from"../repositories/libraries.js";import{HookRuleRepository as rs}from"../repositories/hook-rules.js";import{HookDispatchRepository as Rs}from"../repositories/hook-dispatches.js";import{PluginStateRepository as D}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 L}from"@weavecode/core";import{messagingSurfaceFor as Ps,narrationSurfaceFor as Ds}from"../surfaces.js";import{syntheticSessionIds as Os}from"../hooks/synthetic-sessions.js";import{createEdgeExtract as Ts}from"../hooks/edge-extract.js";import{HookRuleRegistry as Is}from"../hooks/registry.js";import{HookDispatcher as As}from"../hooks/dispatcher.js";import{HookEventBus as Cs}from"../hooks/bus.js";import{ResumeRunner as $s}from"../hooks/resume-runner.js";import{HeadlessRunner as Fs}from"../hooks/headless-runner.js";import{MessageDeliverer as Hs}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 Ms}from"../hooks/side-questions.js";import{DashboardRateCache as Us}from"../hooks/dashboard-rate.js";import{startDashboardPusher as Bs}from"./dashboard-pusher.js";import{startPromptFlusher as Ls}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 xs}from"../repositories/uploads.js";import{defaultUploadSessions as qs}from"./upload-sessions.js";import{PushNotifier as Qs}from"../hooks/push-notify.js";import{OrchestrationRepository as Gs,OrchestrationRunRepository as Ks}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{createEnsureOpen as Zs}from"./session-open.js";import{loadAllPlugins as se}from"../hooks/plugin-loader.js";import{ensureBuiltinMarket as ee,builtinMarketDir as te}from"../market/builtin.js";import{ToolkitService as oe}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 N}from"./snapshot-refresher.js";import{SessionProbe as ue,dbModelFactResolver as de,dbTranscriptPathResolver as he}from"./session-probe.js";import{NarrationWatcher as fe}from"./narration-watcher.js";import{InflightCountsRefresher as we}from"./inflight-counts-refresher.js";import{ProjectUpdatesRefresher as ge}from"./project-updates-refresher.js";import{FingerprintCache as Se}from"../install/fingerprint.js";import{detectProjectUpdateCounts as be}from"../install/updates.js";import{pidAliveOf as ve}from"./claude-liveness.js";import{combinedLivenessOf as v}from"./liveness.js";import{promptTerminalChannel as ns,readTerminalCounts as Re}from"./opener.js";import{wireHookFilePipeline as ye}from"./hook-pipeline.js";import{DEFAULT_PORT as W,DAEMON_HOST as ke,DEFAULT_BIND_HOST as Ee,findFreePort as Pe,isPortFree as De}from"./port.js";import{writeDaemonState as is}from"./state.js";import{ensureDataLayout as Oe}from"../db/layout.js";import{pruneFileIndexes as Te}from"./project-files.js";import{pruneInstallTmp as Ie}from"../hooks/plugin-installer.js";import{readDaemonSettingsSync as R,setDaemonSettingsDb as Ae,DEFAULT_SERVER_SETTINGS as Ce}from"./settings.js";import{AuthService as $e}from"./dashboard-auth.js";import{openPetWindow as Fe,shutdownPetWindow as He}from"./pet-window.js";import{seedBuiltinPets as _e}from"./pet-seed.js";import{resolveStaticDir as je}from"./static.js";const Me="CLAUDE_CODE_CHILD_SESSION"in process.env;delete process.env.CLAUDE_CODE_CHILD_SESSION;for(const p of Es)delete process.env[p];async function Ue(){Oe();const p=await De(W)?W:await Pe(W+1);is({pid:process.pid,port:p,startedAt:new Date().toISOString()});const t=gs();Ae(t);const h=R().server?.bindHost??Ee,O=R().server?.tlsPort??Ce.tlsPort,y=new $e;y.initialPassword&&console.log(`[dev] initial dashboard password: ${y.initialPassword}`);const r=new Ss(t);Te(r.list().map(s=>s.id)),Ie();const a=new bs(t),u=new vs(t),f=ks(),as=f.byCapability("events").flatMap(s=>s.events??[]),k=new Is(new rs(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"} -> ${te(u.dataRoot)}`)}const{loader:m}=await se({rules:new rs(t),registry:k,states:new D(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)},ls=new oe({projects:r,states:new D(t),plugins:x,libraries:u}),T={run:null},q=new As({registry:k,dispatches:E,bus:n,projects:r,sessions:o,plugins:m,pluginStates:new D(t),classify:s=>T.run?T.run(s):Promise.resolve(null),sessionTitleOf:async s=>{const e=a.listBySession(s,1).at(-1)?.source;return L(e)?f.get(e)?.titles?.sessionTitleOf(s)??null:null}}),P=new Fs,ps=new $s({dispatches:E,sessions:o,projects:r,bus:n,resumeSpec:f.get("claude")?.resume,headless:P}),c=new Hs({sessions:o,projects:r,hookEvents:a,bus:n,headless:P,terminal:ns(()=>R().terminal),blockedByQuestion:s=>w.get(s)!=null,livenessOf:v,sideAnswerStore:{answerById:(s,e,l)=>{F.answerById(s,e,l)}}});Ls(c);const I=new Ns(t),A=new Js({watches:I,deliverer:c,sessions:o,bus:n,livenessOf:v}),Q=new Ws(t),C=new xs(t),cs=new Qs({subscriptions:Q,sessions:o,bus:n}),$=new Gs(t),G=new Ks(t),d=new ue(he(a),de(a,s=>o.getBySessionId(s)?.harness??null)),K=new fe(n,s=>Ds(L(s)?s:"claude"),s=>d.transcriptPathOf(s),s=>o.livenessRowOf(s)?.harness??null);K.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 F=new js(t),J=new Us,H=Bs({rate:J,events:a,sessions:o,projects:r,bus:n}),V={repo:F,bus:n,settle:s=>{c.interrupt(s.sessionId)}},Y=new ae(r);Y.start();const i=new ce,g=new me(async()=>({counts:await Re(r.list()),terminals:await c.sessionTerminals()}),i,{shouldRun:()=>i.hasSubscribers(),graceMs:1e4});g.start();const _=new N(()=>{const s=v(),e={};for(const l of o.listWithCounts()){const os=ve(l,s);os!==null&&(e[l.sessionId]=os)}return{alive:e}},i,{key:"sessionLiveness",shouldRun:()=>i.hasSubscribers()});_.start();const j=new N(()=>{const s={};for(const e of o.listWithCounts()){if(e.turnOpen!==!0)continue;const l=d.interruptedAt(e.sessionId,o.lastMainEventAtOf(e.sessionId)??e.lastSeenAt);l!==null&&(s[e.sessionId]=l)}return{interrupted:s}},i,{key:"sessionInterrupt",intervalMs:5e3,shouldRun:()=>i.hasSubscribers()});j.start(),new N(()=>{const s={};for(const e of r.list())s[e.id]=ie(e.path);return s},i,{key:"statusline",intervalMs:5e3,shouldRun:()=>i.hasSubscribers(),invalidateOnly:!0}).start();const ms=new we(()=>c.listInflightCounts(),i,n);let z=null;const S=Ts({sessions:o,projects:r,harnessOf:s=>{const e=a.listBySession(s,1),l=e[e.length-1]?.source;return L(l)?l:null},surfaceFor:Ps,headless:P,onSyntheticChange:()=>z?.pushSyntheticSessions(Os())});T.run=s=>S.run(s);const us=zs({config:async()=>{const s=R().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=>S.supports(s),extract:s=>S.run(s)})}),ds=Zs({hookSessions:o,hookEvents:a,projects:r,harnesses:f,sessionProbe:d,terminalRefresher:g,livenessOf:v}),b=new Vs({orchestrations:$,runs:G,deliverer:c,sessions:o,bus:n,supportsExtract:s=>S.supports(s),extract:s=>S.run(s),conditionJudge:us,deferWhenUserPresent:!0,ensureOpen:ds});b.rearm();const X=setInterval(()=>b.cronTick(),3e4);X.unref();const hs=new Se,fs=new ge(()=>be(r.list(),u.list(),hs),i,n,()=>i.hasSubscribers());re({sessions:o,events:a,dispatches:E,deliverer:c,watches:I,orchestrations:$,watchEngine:A,orchestrationEngine:b,questions:w,sideQuestions:F,probe:d,uploads:C,uploadSessions:qs,livenessOf:v}),ne();const M=ye({projects:r,rules:k,sessions:o,bus:n,dispatcher:q,watchEngine:A,orchestrationEngine:b,messagePipe:c,questionTracker:w,sideQuestions:{onEvent:s=>{Ms(V,s)}},sessionProbe:d,uploads:C,dashboardRate:J,terminalTopologyKick:()=>{g.refreshNow()}});z=M;const U=je(),Z={},ss=le({projects:r,port:p,tlsPort:O,watch:Y,hookEvents:a,adapters:as,harnesses:f,libraries:u,staticDir:U,hookRegistry:k,hookDispatches:E,hookSessions:o,hookBus:n,dataBus:i,terminalRefresher:g,interruptRefresher:j,livenessRefresher:_,sessionProbe:d,inflightRefresher:ms,updatesRefresher:fs,hookDispatcher:q,hookRunner:ps,messageDeliverer:c,terminal:ns(()=>R().terminal),uploads:C,questionTracker:w,sideQuestions:V,sessionWatches:I,watchEngine:A,orchestrations:$,orchestrationRuns:G,orchestrationEngine:b,pushSubscriptions:Q,pushNotifier:cs,onAttach:H.attach,dashboardRefresh:H.attach,hookPlugins:x,hookMirror:M.mirror,pluginStates:new D(t),toolkit:ls,auth:y,requestShutdown:()=>Z.fn?.()}),es=ws.createServer(ss);let ts=null;pe({port:O,bindHost:h,handler:ss}).then(s=>{ts=s,s&&console.log(`[dev] weave daemon tls listening on https://${h}:${s.port}`)});const B=()=>{g.stop(),_.stop(),j.stop(),He(),P.killAll(),clearInterval(X),K.stop(),H.stop(),es.close(),ts?.server.close();const s=()=>{try{t.exec("PRAGMA wal_checkpoint(TRUNCATE)"),t.close()}catch{}},e=setTimeout(()=>{s(),process.exit(0)},3e3);M.stop().catch(()=>{}).finally(()=>{clearTimeout(e),s(),process.exit(0)})};Z.fn=B,process.on("SIGTERM",B),process.on("SIGINT",B),es.listen(p,h,()=>{is({pid:process.pid,port:p,startedAt:new Date().toISOString(),host:h,tlsPort:O}),console.log(`[dev] weave daemon listening on http://${h}:${p}`),console.log(`[dev] cli/dashboard local url: http://${ke}:${p}`),console.log(`[dev] child-session marker stripped: ${Me}`),console.log(U?`[dev] static: ${U}`:"[dev] static: (web/dist not built \u2014 run pnpm build:web)"),_e().then(()=>{Fe({baseUrl:`http://localhost:${p}`,auth:y})})})}Ue();
@@ -1,7 +1,7 @@
1
- import{appendFileSync as r,mkdirSync as s}from"node:fs";import c 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();s(e,{recursive:!0}),r(c.join(e,"daemon-boot.log"),`[${new Date().toISOString()}] ${t}:
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
2
  ${n}
3
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();s(n,{recursive:!0}),r(c.join(n,"daemon-boot.log"),`[${new Date().toISOString()}] boot crash:
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
5
  ${o}
6
6
 
7
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,e){return new Promise((t,o)=>{const a=setTimeout(()=>o(new Error("timeout")),e);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(""),e=(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:e},e}export async function listBrowseRoots(n){const e=[],t=new Set,o=(r,m)=>{t.has(r)||(t.add(r),e.push({path:r,kind:m}))},a=f.homedir();o(a,"home");const i=[["Desktop","desktop"],["Downloads","downloads"],["Documents","documents"]];for(const[r,m]of i){const l=s.join(a,r);try{await u(l),o(l,m)}catch{}}for(const r of n)typeof r=="string"&&r&&o(s.dirname(r),"library-parent");if(process.platform==="win32")for(const r of await h())o(r,"drive");else o(s.parse(a).root,"root");return e}export async function listDirectoryChildren(n){const e=(await p(n,{withFileTypes:!0})).filter(t=>t.isDirectory()).map(t=>({name:t.name,path:s.join(n,t.name)}));return e.sort((t,o)=>t.name.localeCompare(o.name,void 0,{numeric:!0})),e}
@@ -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(o,s){return[a(o,"inbox",`${s}.jsonl`),a(o,"inbox",`${s}${l}`),a(o,"inbox",`${s}${h}`),g(o,s),k(o,s),x(o,s)]}export function purgeProjectPipeline(o,s){for(const e of S(o,p(s)))try{c(e)}catch{}}function w(o){return(o.endsWith(".tmp")?o.slice(0,-4):o).replace(new RegExp(`(${l}|${h})$`),"").replace(/\.(jsonl|json)$/,"")}const F=/^[0-9a-f]{16}$/;export function purgeOrphanPipelineFiles(o){const s=new Set(o.projects.list().map(n=>p(n.token)));let e=0;for(const n of["inbox","mirror","outbox","promptbox"]){let t;try{t=m(a(o.hooksDir,n))}catch{continue}for(const i of t){const r=w(i);if(!(!F.test(r)||s.has(r)))try{c(a(o.hooksDir,n,i)),e++}catch{}}}return e}export function wireHookFilePipeline(o){const s=b(),e=purgeOrphanPipelineFiles({projects:o.projects,hooksDir:s});e>0&&console.log(`[weave] hook pipeline: purged ${e} orphan file(s)`);const n=$(s);n>0&&console.log(`[weave] hook pipeline: revived ${n} parked inbox file(s)`);const t=new d({projects:o.projects,rules:o.rules,sessions:o.sessions});o.rules.onChange=()=>t.syncAll(),t.attachToBus(o.bus),t.syncAll();const i=j({dbPath:f(),hooksDir:s});return i.on("message",r=>{y({projects:o.projects,hooksDir:s,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:u=>P(u).paneEnvSource},r)}),i.on("error",r=>console.error("[weave] inbox worker failed:",r)),{mirror:t,pushSyntheticSessions:r=>i.postMessage({type:"synthetic-sessions",ids:r}),stop:()=>i.terminate().then(()=>{})}}
@@ -1 +1 @@
1
- import{z as h}from"zod";import{HARNESS_SESSION_CONTROL as x,isHarness as T}from"@weavecode/core";import{aliasOfModel as O,modelAliasTargets as M}from"@weavecode/harness";import{readJson as y,sendJson as i}from"./http.js";import{purgeSession as D}from"../hooks/session-purge.js";import{readDaemonSettingsSync as A,readHooksEnabled as W}from"./settings.js";import{handleOrchestrationRoutes as H}from"./routes/orchestration.js";import{handleHookAdminRoutes as U}from"./routes/hooks-admin.js";import{handleUploadRoutes as B}from"./routes/uploads.js";import{handleSessionControlRoutes as N}from"./routes/session-control.js";import{handlePathRefRoutes as $}from"./routes/path-refs.js";import{handleVisualizationRoutes as K}from"./routes/visualizations.js";import{handlePetRoutes as G}from"./routes/pets.js";import{handleSessionInsightRoutes as L}from"./routes/session-insights.js";import{handleWatchRoutes as Q}from"./routes/watches.js";import{openSessionTerminal as V,transcriptState as _}from"./session-open.js";import{pidAliveOf as j}from"./claude-liveness.js";import{combinedLivenessOf as E}from"./liveness.js";import{captureSurfaces as z,messagingSurfaces as F,sessionTitleSurfaceFor as J}from"../surfaces.js";import{getDataDir as X}from"../db/paths.js";import{WEAVE_VERSION as Y}from"../version.js";const Z=h.object({title:h.string().min(1).max(200)}),q=h.object({text:h.string().max(2e4),fromKind:h.enum(["dashboard","session"]).optional(),fromSessionId:h.string().min(1).nullable().optional(),attachments:h.array(h.string().regex(/^[a-f0-9]{64}$/)).max(8).optional(),images:h.array(h.string().regex(/^[a-f0-9]{64}$/)).max(8).optional(),forceTerminal:h.boolean().optional()});function ee(l,s){return l.queuedPrompt!==null||l.prompt!==null||s}function se(l){const{diag:s,capture:e,eventCount:r}=l,u=[];return!e||e.source==="none"||!e.present?u.push("no-hook-script"):e.weaveOwned?!e.reportsInbox&&s?.inbox.reason!=="no-mechanism"&&u.push("hook-script-stale"):u.push("hook-script-not-weave"),r===0&&u.push("no-events"),s&&(s.alive===!1&&u.push("not-running"),s.inbox.reason==="no-credentials"&&e?.reportsInbox===!0&&u.push("no-inbox-credentials"),s.inbox.reason==="auth-token-required"&&u.push("inbox-token-required"),s.relay.reason==="no-peer-name"&&u.push("no-peer-name"),s.terminal.reason==="no-backend"&&u.push("terminal-no-backend"),s.terminal.reason==="no-pane-env"&&u.push("terminal-no-pane-env"),s.terminal.reason==="pane-env-conflict"&&u.push("terminal-pane-env-conflict"),s.pending>0&&u.push("queued"),s.stalled&&u.push("stalled")),u}export async function handleHooksRoutes(l,s,e,r,u){if(!(r.startsWith("/hooks/")||r==="/dashboard/refresh"||r==="/sessions"||r.startsWith("/sessions/")||r.startsWith("/messaging")||r.startsWith("/webhooks/orchestrate/")||r==="/uploads"||r.startsWith("/uploads/")||r.startsWith("/images/")||r.startsWith("/visualizations/")||r==="/pets"||r.startsWith("/pets/")))return!1;if(await U(l,s,e,r,u))return!0;if(r==="/dashboard/refresh"&&l.method==="POST")return e.dashboardRefresh?.(),i(s,200,{ok:!0}),!0;if(r==="/sessions"&&l.method==="GET"){if(!e.hookSessions)return i(s,503,{error:"Hooks subsystem unavailable"}),!0;const o=u.searchParams.get("projectId"),a=o!=null&&o!==""?Number(o):void 0,n=u.searchParams.get("ids"),d=n?n.split(",").map(t=>t.trim()).filter(Boolean).slice(0,100):void 0,m=e.hookSessions,f=m.listWithCounts(a,d),p=E(),v=e.terminalRefresher?.lastSnapshot?.terminals??{},b={};for(const t of f){const c=t.harness??"";c in b||(b[c]=M(x[t.harness]?.modelNames??[]))}return i(s,200,{sessions:f.map(t=>{const c=e.sessionProbe?.currentModel(t.sessionId)??null,g=e.sessionProbe?.transcriptPresent(t.sessionId)??null,I=T(t.harness)?e.harnesses?.get(t.harness)?.resume:void 0;return{...t,pidAlive:j(t,p),canOpenTerminal:!!(I?.supported&&I.openArgs),terminal:v[t.sessionId]??null,interruptedAt:t.turnOpen===!0?e.sessionProbe?.interruptedAt(t.sessionId,m.lastMainEventAtOf(t.sessionId)??t.lastSeenAt)??null:null,model:c,modelAlias:O(b[t.harness??""]??[],c),mode:e.sessionProbe?.currentMode(t.sessionId)??null,effort:e.sessionProbe?.currentEffort(t.sessionId)??null,contextTokens:e.sessionProbe?.currentContextTokens(t.sessionId)??null,transcriptPresent:_(g,t.hasRun)}}),modelCatalog:b}),!0}const S=r.match(/^\/sessions\/([^/]+)$/);if(S&&l.method==="PATCH"){if(!e.hookSessions)return i(s,503,{error:"Hooks subsystem unavailable"}),!0;const o=decodeURIComponent(S[1]);if(!e.hookSessions.getBySessionId(o))return i(s,404,{error:"Session not found"}),!0;try{const a=Z.parse(await y(l)),n=e.hookEvents?.listBySession(o,1),d=n?.[n.length-1]?.source,m=T(d)?J(d):null;if(m){try{await m.setSessionTitle(o,a.title)}catch(v){return i(s,502,{error:v instanceof Error?v.message:"Host rename failed"}),!0}const p=e.hookSessions.setTitle(o,a.title);return p?.projectId!=null&&e.hookMirror?.syncProject(p.projectId),i(s,200,{session:p}),!0}const f=e.hookSessions.setPendingTitle(o,a.title);f?.projectId!=null&&e.hookMirror?.syncProject(f.projectId),i(s,200,{session:f})}catch(a){i(s,400,{error:a instanceof Error?a.message:"Invalid body"})}return!0}if(S&&l.method==="DELETE"){if(!e.hookSessions||!e.hookEvents)return i(s,503,{error:"Hooks subsystem unavailable"}),!0;const o=decodeURIComponent(S[1]),a=e.hookSessions.getBySessionId(o);if(!a)return i(s,404,{error:"Session not found"}),!0;const n=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},o);return a.projectId!=null&&e.hookMirror?.syncProject(a.projectId),i(s,200,{ok:!0,sessionId:o,...n}),!0}const R=r.match(/^\/sessions\/([^/]+)\/open-terminal$/);if(R&&l.method==="POST"){const o=decodeURIComponent(R[1]);let a;try{const d=await y(l);typeof d?.target=="string"&&d.target&&(a=d.target)}catch{}const n=await V(e,o,a);return n.ok?(i(s,200,{ok:!0,sessionId:n.sessionId,command:n.command,cwd:n.cwd,...n.target?{target:n.target}:{}}),!0):(i(s,n.status,{error:n.error}),!0)}if(await B(l,s,e,r,u))return!0;const w=r.match(/^\/sessions\/([^/]+)\/messages$/);if(w){const o=decodeURIComponent(w[1]);if(l.method==="GET")return e.messageDeliverer?e.hookSessions?.getBySessionId(o)?(i(s,200,{messages:e.messageDeliverer.listVisible(o)}),!0):(i(s,404,{error:"Session not found"}),!0):(i(s,503,{error:"Messaging subsystem unavailable"}),!0);if(l.method==="POST"){if(!e.messageDeliverer||!e.hookSessions)return i(s,503,{error:"Messaging subsystem unavailable"}),!0;let a;try{a=q.parse(await y(l))}catch(f){return i(s,400,{error:f instanceof Error?f.message:"Invalid body"}),!0}const n=[...a.attachments??[],...a.images??[]];if(!a.text.trim()&&n.length===0)return i(s,400,{error:"Message is empty"}),!0;let d=[];if(n.length>0){const f=e.uploads?.refsOf(n)??null;if(!f)return i(s,404,{error:"Attachment not found"}),!0;d=f}const m=await e.messageDeliverer.send({toSessionId:o,text:a.text,...d.length>0?{attachments:d}:{},...a.forceTerminal===!0?{forceTerminal:!0}:{},mode:"prompt",fromKind:a.fromKind??"dashboard",fromSessionId:a.fromSessionId??null,oneWay:!0});return m.ok?i(s,201,{ok:!0,messageId:m.messageId,status:m.status,message:m.message}):i(s,m.status,{error:m.error}),!0}}if(await L(l,s,e,r,u)||await $(l,s,e,r,u)||await K(l,s,e,r,u)||await G(l,s,e,r,u))return!0;const P=r.match(/^\/sessions\/([^/]+)\/messages\/([^/]+)\/resend$/);if(P&&l.method==="POST"){if(!e.messageDeliverer)return i(s,503,{error:"Messaging subsystem unavailable"}),!0;const o=await e.messageDeliverer.resend(decodeURIComponent(P[2]));return o.ok?i(s,200,{ok:!0,messageId:o.messageId,status:o.status,message:o.message}):i(s,o.status,{error:o.error}),!0}const k=r.match(/^\/sessions\/([^/]+)\/messages\/([^/]+)\/dismiss$/);if(k&&l.method==="POST"){if(!e.messageDeliverer)return i(s,503,{error:"Messaging subsystem unavailable"}),!0;const o=e.messageDeliverer.dismiss(decodeURIComponent(k[1]),decodeURIComponent(k[2]));return o.ok?i(s,200,{ok:!0}):i(s,o.status,{error:o.error}),!0}if(await N(l,s,e,r,u)||await Q(l,s,e,r)||await H(l,s,e,r,u))return!0;if(r==="/messaging/capabilities"&&l.method==="GET"){const o=e.messageDeliverer?.hasTerminalChannel()??!1;return i(s,200,{capabilities:F().map(({harness:a,surface:n})=>({harness:a,discovery:n.discovery,prompt:ee(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(r==="/messaging/diagnostics"&&l.method==="GET"){if(!e.messageDeliverer||!e.hookSessions)return i(s,503,{error:"Message subsystem unavailable"}),!0;const o=u.searchParams.get("session"),a=u.searchParams.get("project"),n=z(),d=e.projects.list(),m=await Promise.all(d.map(async t=>({id:t.id,name:t.name,path:t.path,captures:await Promise.all(n.map(async({harness:c,surface:g})=>({harness:c,...await g.scriptHealth({projectPath:t.path})})))}))),f=(t,c)=>m.find(g=>g.id===t)?.captures.find(g=>g.harness===c)??null,p=E(),b=e.hookSessions.listWithCounts(o?void 0:a?Number(a):void 0).filter(t=>o?t.sessionId===o:j(t,p)!==!1).map(t=>{const c=e.messageDeliverer.diagnose(t.sessionId),g=f(t.projectId,t.harness??null),I={inbox:c.inbox,queue:c.queue,relay:c.relay,terminal:c.terminal};return{sessionId:t.sessionId,projectId:t.projectId,harness:t.harness??null,title:t.title,lastSeenAt:t.lastSeenAt,eventCount:t.eventCount??0,lastEventType:t.lastEventType??null,alive:c.alive,paneEnvReported:c.paneEnvReported,channels:I,queue:{pending:c.pending,stalled:c.stalled},reachable:Object.values(I).some(C=>C.status==="ready"),hints:se({diag:c,capture:g,eventCount:t.eventCount??0})}});return i(s,200,{daemon:{version:Y,platform:process.platform,dataDir:X(),uptimeMs:Math.round(process.uptime()*1e3),terminalPreset:A().terminal.preset,terminalTextChannel:e.messageDeliverer.hasTerminalChannel(),hooksEnabled:W()},projects:m,sessions:b}),!0}return!1}
1
+ import{z as f}from"zod";import{HARNESS_SESSION_CONTROL as j,isHarness as P}from"@weavecode/core";import{aliasOfModel as C,modelAliasTargets as O}from"@weavecode/harness";import{readJson as y,sendJson as a}from"./http.js";import{purgeSession as D}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 q}from"./routes/hooks-admin.js";import{handleUploadRoutes as H}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{handlePetRoutes as B}from"./routes/pets.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 E}from"./claude-liveness.js";import{combinedLivenessOf as x}from"./liveness.js";import{captureSurfaces as V,messagingSurfaces as z,sessionTitleSurfaceFor as _}from"../surfaces.js";import{getDataDir as J}from"../db/paths.js";import{WEAVE_VERSION as F}from"../version.js";const X=f.object({title:f.string().min(1).max(200)}),Y=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 Z(i,s){return i.queuedPrompt!==null||i.prompt!==null||s}function ee(i){const{diag:s,capture:e,eventCount:n}=i,d=[];return!e||e.source==="none"||!e.present?d.push("no-hook-script"):e.weaveOwned?!e.reportsInbox&&s?.inbox.reason!=="no-mechanism"&&d.push("hook-script-stale"):d.push("hook-script-not-weave"),n===0&&d.push("no-events"),s&&(s.alive===!1&&d.push("not-running"),s.inbox.reason==="no-credentials"&&e?.reportsInbox===!0&&d.push("no-inbox-credentials"),s.inbox.reason==="auth-token-required"&&d.push("inbox-token-required"),s.relay.reason==="no-peer-name"&&d.push("no-peer-name"),s.terminal.reason==="no-backend"&&d.push("terminal-no-backend"),s.terminal.reason==="no-pane-env"&&d.push("terminal-no-pane-env"),s.terminal.reason==="pane-env-conflict"&&d.push("terminal-pane-env-conflict"),s.pending>0&&d.push("queued"),s.stalled&&d.push("stalled")),d}export async function handleHooksRoutes(i,s,e,n,d){if(!(n.startsWith("/hooks/")||n==="/dashboard/refresh"||n==="/sessions"||n.startsWith("/sessions/")||n.startsWith("/messaging")||n.startsWith("/webhooks/orchestrate/")||n==="/uploads"||n.startsWith("/uploads/")||n.startsWith("/images/")||n.startsWith("/visualizations/")||n==="/daemon/shutdown"||n==="/pets"||n.startsWith("/pets/")))return!1;if(await q(i,s,e,n,d))return!0;if(n==="/daemon/shutdown"&&i.method==="POST")return e.requestShutdown?(a(s,200,{ok:!0}),setTimeout(()=>e.requestShutdown?.(),0),!0):(a(s,503,{error:"Shutdown is not available"}),!0);if(n==="/dashboard/refresh"&&i.method==="POST")return e.dashboardRefresh?.(),a(s,200,{ok:!0}),!0;if(n==="/sessions"&&i.method==="GET"){if(!e.hookSessions)return a(s,503,{error:"Hooks subsystem unavailable"}),!0;const o=d.searchParams.get("projectId"),l=o!=null&&o!==""?Number(o):void 0,r=d.searchParams.get("ids"),h=r?r.split(",").map(t=>t.trim()).filter(Boolean).slice(0,100):void 0,u=e.hookSessions,c=u.listWithCounts(l,h),g=x(),v=e.terminalRefresher?.lastSnapshot?.terminals??{},m={};for(const t of c){const p=t.harness??"";p in m||(m[p]=O(j[t.harness]?.modelNames??[]))}return a(s,200,{sessions:c.map(t=>{const p=e.sessionProbe?.currentModel(t.sessionId)??null,S=e.sessionProbe?.transcriptPresent(t.sessionId)??null,k=P(t.harness)?e.harnesses?.get(t.harness)?.resume:void 0;return{...t,pidAlive:E(t,g),canOpenTerminal:!!(k?.supported&&k.openArgs),terminal:v[t.sessionId]??null,interruptedAt:t.turnOpen===!0?e.sessionProbe?.interruptedAt(t.sessionId,u.lastMainEventAtOf(t.sessionId)??t.lastSeenAt)??null:null,model:p,modelAlias:C(m[t.harness??""]??[],p),mode:e.sessionProbe?.currentMode(t.sessionId)??null,effort:e.sessionProbe?.currentEffort(t.sessionId)??null,contextTokens:e.sessionProbe?.currentContextTokens(t.sessionId)??null,transcriptPresent:Q(S,t.hasRun)}}),modelCatalog:m}),!0}const b=n.match(/^\/sessions\/([^/]+)$/);if(b&&i.method==="PATCH"){if(!e.hookSessions)return a(s,503,{error:"Hooks subsystem unavailable"}),!0;const o=decodeURIComponent(b[1]);if(!e.hookSessions.getBySessionId(o))return a(s,404,{error:"Session not found"}),!0;try{const l=X.parse(await y(i)),r=e.hookEvents?.listBySession(o,1),h=r?.[r.length-1]?.source,u=P(h)?_(h):null;if(u){try{await u.setSessionTitle(o,l.title)}catch(v){return a(s,502,{error:v instanceof Error?v.message:"Host rename failed"}),!0}const g=e.hookSessions.setTitle(o,l.title);return g?.projectId!=null&&e.hookMirror?.syncProject(g.projectId),a(s,200,{session:g}),!0}const c=e.hookSessions.setPendingTitle(o,l.title);c?.projectId!=null&&e.hookMirror?.syncProject(c.projectId),a(s,200,{session:c})}catch(l){a(s,400,{error:l instanceof Error?l.message:"Invalid body"})}return!0}if(b&&i.method==="DELETE"){if(!e.hookSessions||!e.hookEvents)return a(s,503,{error:"Hooks subsystem unavailable"}),!0;const o=decodeURIComponent(b[1]),l=e.hookSessions.getBySessionId(o);if(!l)return a(s,404,{error:"Session not found"}),!0;const r=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},o);return l.projectId!=null&&e.hookMirror?.syncProject(l.projectId),a(s,200,{ok:!0,sessionId:o,...r}),!0}const R=n.match(/^\/sessions\/([^/]+)\/open-terminal$/);if(R&&i.method==="POST"){const o=decodeURIComponent(R[1]);let l;try{const h=await y(i);typeof h?.target=="string"&&h.target&&(l=h.target)}catch{}const r=await L(e,o,l);return r.ok?(a(s,200,{ok:!0,sessionId:r.sessionId,command:r.command,cwd:r.cwd,...r.target?{target:r.target}:{}}),!0):(a(s,r.status,{error:r.error}),!0)}if(await H(i,s,e,n,d))return!0;const w=n.match(/^\/sessions\/([^/]+)\/messages$/);if(w){const o=decodeURIComponent(w[1]);if(i.method==="GET")return e.messageDeliverer?e.hookSessions?.getBySessionId(o)?(a(s,200,{messages:e.messageDeliverer.listVisible(o)}),!0):(a(s,404,{error:"Session not found"}),!0):(a(s,503,{error:"Messaging subsystem unavailable"}),!0);if(i.method==="POST"){if(!e.messageDeliverer||!e.hookSessions)return a(s,503,{error:"Messaging subsystem unavailable"}),!0;let l;try{l=Y.parse(await y(i))}catch(c){return a(s,400,{error:c instanceof Error?c.message:"Invalid body"}),!0}const r=[...l.attachments??[],...l.images??[]];if(!l.text.trim()&&r.length===0)return a(s,400,{error:"Message is empty"}),!0;let h=[];if(r.length>0){const c=e.uploads?.refsOf(r)??null;if(!c)return a(s,404,{error:"Attachment not found"}),!0;h=c}const u=await e.messageDeliverer.send({toSessionId:o,text:l.text,...h.length>0?{attachments:h}:{},...l.forceTerminal===!0?{forceTerminal:!0}:{},mode:"prompt",fromKind:l.fromKind??"dashboard",fromSessionId:l.fromSessionId??null,oneWay:!0});return u.ok?a(s,201,{ok:!0,messageId:u.messageId,status:u.status,message:u.message}):a(s,u.status,{error:u.error}),!0}}if(await K(i,s,e,n,d)||await N(i,s,e,n,d)||await $(i,s,e,n,d)||await B(i,s,e,n,d))return!0;const T=n.match(/^\/sessions\/([^/]+)\/messages\/([^/]+)\/resend$/);if(T&&i.method==="POST"){if(!e.messageDeliverer)return a(s,503,{error:"Messaging subsystem unavailable"}),!0;const o=await e.messageDeliverer.resend(decodeURIComponent(T[2]));return o.ok?a(s,200,{ok:!0,messageId:o.messageId,status:o.status,message:o.message}):a(s,o.status,{error:o.error}),!0}const I=n.match(/^\/sessions\/([^/]+)\/messages\/([^/]+)\/dismiss$/);if(I&&i.method==="POST"){if(!e.messageDeliverer)return a(s,503,{error:"Messaging subsystem unavailable"}),!0;const o=e.messageDeliverer.dismiss(decodeURIComponent(I[1]),decodeURIComponent(I[2]));return o.ok?a(s,200,{ok:!0}):a(s,o.status,{error:o.error}),!0}if(await U(i,s,e,n,d)||await G(i,s,e,n)||await W(i,s,e,n,d))return!0;if(n==="/messaging/capabilities"&&i.method==="GET"){const o=e.messageDeliverer?.hasTerminalChannel()??!1;return a(s,200,{capabilities:z().map(({harness:l,surface:r})=>({harness:l,discovery:r.discovery,prompt:Z(r,o),inject:r.inject!==null,headless:r.headless!==null,watch:r.idleSignals.length>0,attachKinds:r.attach?.kinds??[],pathRefs:r.pathRefs!==null,pathRefLines:r.pathRefs?.lines===!0,pathRefKinds:r.pathRefs?.kinds??[],sideQuestion:r.sideQuestion!==null,unsupportedReasons:r.unsupportedReasons??null}))}),!0}if(n==="/messaging/diagnostics"&&i.method==="GET"){if(!e.messageDeliverer||!e.hookSessions)return a(s,503,{error:"Message subsystem unavailable"}),!0;const o=d.searchParams.get("session"),l=d.searchParams.get("project"),r=V(),h=e.projects.list(),u=await Promise.all(h.map(async m=>({id:m.id,name:m.name,path:m.path,captures:await Promise.all(r.map(async({harness:t,surface:p})=>({harness:t,...await p.scriptHealth({projectPath:m.path})})))}))),c=(m,t)=>u.find(p=>p.id===m)?.captures.find(p=>p.harness===t)??null,g=x(),v=e.hookSessions.listWithCounts(o?void 0:l?Number(l):void 0).filter(m=>o?m.sessionId===o:E(m,g)!==!1).map(m=>{const t=e.messageDeliverer.diagnose(m.sessionId),p=c(m.projectId,m.harness??null),S={inbox:t.inbox,queue:t.queue,relay:t.relay,terminal:t.terminal};return{sessionId:m.sessionId,projectId:m.projectId,harness:m.harness??null,title:m.title,lastSeenAt:m.lastSeenAt,eventCount:m.eventCount??0,lastEventType:m.lastEventType??null,alive:t.alive,paneEnvReported:t.paneEnvReported,channels:S,queue:{pending:t.pending,stalled:t.stalled},reachable:Object.values(S).some(k=>k.status==="ready"),hints:ee({diag:t,capture:p,eventCount:m.eventCount??0})}});return a(s,200,{daemon:{version:F,platform:process.platform,dataDir:J(),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(n){return new Promise((t,r)=>{const o=[];n.on("data",e=>o.push(e)),n.on("end",()=>{const e=Buffer.concat(o).toString("utf8");d(n,e),t(e)}),n.on("error",r)})}export async function readJson(n){return JSON.parse(await readBody(n))}export function readRawBody(n,t){return new Promise((r,o)=>{const e=[];let a=0;n.on("data",s=>{if(a+=s.length,a>t){n.destroy(),o(new Error("body too large"));return}e.push(s)}),n.on("end",()=>r(Buffer.concat(e))),n.on("error",o)})}export function sendJson(n,t,r){n.statusCode=t,n.setHeader("content-type","application/json"),n.end(JSON.stringify(r))}
@@ -1 +1 @@
1
- import{claudeLivenessById as s}from"./claude-liveness.js";import{codexLivenessById as c}from"@weavecode/harness";const i=15e3;let o=new Map;async function a(n){try{o=await c(void 0,n)}catch{}}let e=null;function f(){e||(e=setInterval(()=>{a(Date.now())},i),e.unref())}export function combinedLivenessOf(){f();const n=s();for(const[t,r]of o)n.set(t,r);return n}export function resetCombinedLivenessForTest(){e&&(clearInterval(e),e=null),o=new Map}
1
+ import{claudeLivenessById as r}from"./claude-liveness.js";import{codexLivenessById as c}from"@weavecode/harness";const i=15e3;let t=new Map;async function a(n){try{t=await c(void 0,n)}catch{}}let e=null;function f(){e||(e=setInterval(()=>{a(Date.now())},i),e.unref())}export function combinedLivenessOf(){f();const n=r();for(const[o,s]of t)n.set(o,s);return n}export function resetCombinedLivenessForTest(){e&&(clearInterval(e),e=null),t=new Map}