@weavecode/weave 0.1.0 → 0.1.2

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 (300) hide show
  1. package/node_modules/@weavecode/cli/dist/cli.js +3 -3
  2. package/node_modules/@weavecode/cli/dist/commands/daemon.d.ts +7 -0
  3. package/node_modules/@weavecode/cli/dist/commands/daemon.js +2 -2
  4. package/node_modules/@weavecode/cli/dist/commands/dashboard.d.ts +0 -2
  5. package/node_modules/@weavecode/cli/dist/commands/dashboard.js +2 -1
  6. package/node_modules/@weavecode/cli/dist/commands/doctor.js +1 -1
  7. package/node_modules/@weavecode/cli/dist/commands/init.js +1 -1
  8. package/node_modules/@weavecode/cli/dist/commands/msg.js +2 -2
  9. package/node_modules/@weavecode/cli/dist/commands/scan.js +1 -1
  10. package/node_modules/@weavecode/cli/dist/commands/status.js +2 -2
  11. package/node_modules/@weavecode/cli/dist/i18n/dict/en.js +6 -12
  12. package/node_modules/@weavecode/cli/dist/i18n/dict/zh.d.ts +44 -2
  13. package/node_modules/@weavecode/cli/dist/i18n/dict/zh.js +6 -12
  14. package/node_modules/@weavecode/cli/dist/init/claudemd-gen.d.ts +2 -3
  15. package/node_modules/@weavecode/cli/dist/init/claudemd-gen.js +4 -4
  16. package/node_modules/@weavecode/cli/dist/init/executor.js +3 -3
  17. package/node_modules/@weavecode/cli/dist/init/git-commit.js +1 -1
  18. package/node_modules/@weavecode/cli/dist/init/harnesses/claude.js +7 -7
  19. package/node_modules/@weavecode/cli/dist/init/harnesses/zcode.d.ts +29 -0
  20. package/node_modules/@weavecode/cli/dist/init/harnesses/zcode.js +1 -0
  21. package/node_modules/@weavecode/cli/dist/init/helpers-gen.d.ts +4 -0
  22. package/node_modules/@weavecode/cli/dist/init/helpers-gen.js +1 -20
  23. package/node_modules/@weavecode/cli/dist/init/mcp-gen.d.ts +3 -20
  24. package/node_modules/@weavecode/cli/dist/init/mcp-gen.js +1 -1
  25. package/node_modules/@weavecode/cli/dist/init/prompt.js +4 -4
  26. package/node_modules/@weavecode/cli/dist/init/settings-gen.d.ts +3 -30
  27. package/node_modules/@weavecode/cli/dist/init/settings-gen.js +1 -1
  28. package/node_modules/@weavecode/cli/package.json +5 -5
  29. package/node_modules/@weavecode/core/dist/harness.d.ts +45 -2
  30. package/node_modules/@weavecode/core/dist/harness.js +1 -1
  31. package/node_modules/@weavecode/core/dist/index.d.ts +2 -2
  32. package/node_modules/@weavecode/core/dist/index.js +1 -1
  33. package/node_modules/@weavecode/core/dist/terminal.d.ts +28 -4
  34. package/node_modules/@weavecode/core/dist/terminal.js +1 -1
  35. package/node_modules/@weavecode/core/dist/types.d.ts +188 -19
  36. package/node_modules/@weavecode/core/dist/types.js +1 -1
  37. package/node_modules/@weavecode/core/package.json +1 -1
  38. package/node_modules/@weavecode/harness/dist/claude/assets.d.ts +10 -0
  39. package/node_modules/@weavecode/harness/dist/claude/assets.js +4 -1
  40. package/node_modules/@weavecode/harness/dist/claude/capture.d.ts +15 -3
  41. package/node_modules/@weavecode/harness/dist/claude/capture.js +15 -9
  42. package/node_modules/@weavecode/harness/dist/claude/event-source.d.ts +1 -1
  43. package/node_modules/@weavecode/harness/dist/claude/event-source.js +1 -1
  44. package/node_modules/@weavecode/harness/dist/claude/helpers-gen.d.ts +5 -0
  45. package/node_modules/@weavecode/harness/dist/claude/helpers-gen.js +20 -0
  46. package/node_modules/@weavecode/harness/dist/claude/index.d.ts +10 -1
  47. package/node_modules/@weavecode/harness/dist/claude/index.js +1 -1
  48. package/node_modules/@weavecode/harness/dist/claude/mcp-gen.d.ts +22 -0
  49. package/node_modules/@weavecode/harness/dist/claude/mcp-gen.js +1 -0
  50. package/node_modules/@weavecode/harness/dist/claude/messaging.d.ts +11 -2
  51. package/node_modules/@weavecode/harness/dist/claude/messaging.js +4 -1
  52. package/node_modules/@weavecode/harness/dist/claude/model-aliases.d.ts +39 -0
  53. package/node_modules/@weavecode/harness/dist/claude/model-aliases.js +1 -0
  54. package/node_modules/@weavecode/harness/dist/claude/plan.d.ts +2 -0
  55. package/node_modules/@weavecode/harness/dist/claude/plan.js +1 -0
  56. package/node_modules/@weavecode/harness/dist/claude/questions.js +2 -1
  57. package/node_modules/@weavecode/harness/dist/claude/settings-gen.d.ts +32 -0
  58. package/node_modules/@weavecode/harness/dist/claude/settings-gen.js +1 -0
  59. package/node_modules/@weavecode/harness/dist/claude/side-question.d.ts +12 -0
  60. package/node_modules/@weavecode/harness/dist/claude/side-question.js +1 -0
  61. package/node_modules/@weavecode/harness/dist/claude/statusline/config.d.ts +200 -0
  62. package/node_modules/@weavecode/harness/dist/claude/statusline/config.js +1 -0
  63. package/node_modules/@weavecode/harness/dist/claude/statusline/generator.d.ts +12 -0
  64. package/node_modules/@weavecode/harness/dist/claude/statusline/generator.js +745 -0
  65. package/node_modules/@weavecode/harness/dist/claude/statusline/git-cache.d.ts +10 -0
  66. package/node_modules/@weavecode/harness/dist/claude/statusline/git-cache.js +1 -0
  67. package/node_modules/@weavecode/harness/dist/claude/statusline/surface.d.ts +20 -0
  68. package/node_modules/@weavecode/harness/dist/claude/statusline/surface.js +2 -0
  69. package/node_modules/@weavecode/harness/dist/claude/transcript.d.ts +16 -0
  70. package/node_modules/@weavecode/harness/dist/claude/transcript.js +4 -2
  71. package/node_modules/@weavecode/harness/dist/codex/assets.js +1 -1
  72. package/node_modules/@weavecode/harness/dist/codex/index.d.ts +1 -0
  73. package/node_modules/@weavecode/harness/dist/codex/index.js +1 -1
  74. package/node_modules/@weavecode/harness/dist/codex/mcp.d.ts +30 -0
  75. package/node_modules/@weavecode/harness/dist/codex/mcp.js +1 -0
  76. package/node_modules/@weavecode/harness/dist/codex/messaging.js +1 -1
  77. package/node_modules/@weavecode/harness/dist/driver.d.ts +168 -3
  78. package/node_modules/@weavecode/harness/dist/index.d.ts +1 -0
  79. package/node_modules/@weavecode/harness/dist/index.js +1 -1
  80. package/node_modules/@weavecode/harness/dist/init/generated.d.ts +37 -0
  81. package/node_modules/@weavecode/harness/dist/init/generated.js +2 -0
  82. package/node_modules/@weavecode/harness/dist/registry-wiring.d.ts +3 -1
  83. package/node_modules/@weavecode/harness/dist/zcode/assets.d.ts +8 -0
  84. package/node_modules/@weavecode/harness/dist/zcode/assets.js +1 -0
  85. package/node_modules/@weavecode/harness/dist/zcode/capture.d.ts +36 -0
  86. package/node_modules/@weavecode/harness/dist/zcode/capture.js +3 -0
  87. package/node_modules/@weavecode/harness/dist/zcode/detect.d.ts +2 -0
  88. package/node_modules/@weavecode/harness/dist/zcode/detect.js +1 -0
  89. package/node_modules/@weavecode/harness/dist/zcode/event-source.d.ts +8 -0
  90. package/node_modules/@weavecode/harness/dist/zcode/event-source.js +1 -0
  91. package/node_modules/@weavecode/harness/dist/zcode/index.d.ts +13 -0
  92. package/node_modules/@weavecode/harness/dist/zcode/index.js +1 -0
  93. package/node_modules/@weavecode/harness/dist/zcode/mcp.d.ts +6 -0
  94. package/node_modules/@weavecode/harness/dist/zcode/mcp.js +2 -0
  95. package/node_modules/@weavecode/harness/dist/zcode/messaging.d.ts +13 -0
  96. package/node_modules/@weavecode/harness/dist/zcode/messaging.js +1 -0
  97. package/node_modules/@weavecode/harness/dist/zcode/resume.d.ts +7 -0
  98. package/node_modules/@weavecode/harness/dist/zcode/resume.js +1 -0
  99. package/node_modules/@weavecode/harness/package.json +2 -2
  100. package/node_modules/@weavecode/server/dist/daemon/ai-config.js +2 -2
  101. package/node_modules/@weavecode/server/dist/daemon/ai-context.js +6 -6
  102. package/node_modules/@weavecode/server/dist/daemon/ai-routes.js +4 -4
  103. package/node_modules/@weavecode/server/dist/daemon/api-log.d.ts +48 -0
  104. package/node_modules/@weavecode/server/dist/daemon/api-log.js +3 -0
  105. package/node_modules/@weavecode/server/dist/daemon/auth-routes.js +1 -1
  106. package/node_modules/@weavecode/server/dist/daemon/auto-start.js +6 -6
  107. package/node_modules/@weavecode/server/dist/daemon/capture-routes.js +1 -1
  108. package/node_modules/@weavecode/server/dist/daemon/claude-liveness.js +1 -1
  109. package/node_modules/@weavecode/server/dist/daemon/dashboard-auth.js +2 -2
  110. package/node_modules/@weavecode/server/dist/daemon/data-bus.js +1 -1
  111. package/node_modules/@weavecode/server/dist/daemon/dev-entry.js +1 -1
  112. package/node_modules/@weavecode/server/dist/daemon/fs-browser.js +1 -1
  113. package/node_modules/@weavecode/server/dist/daemon/hook-pipeline.d.ts +13 -1
  114. package/node_modules/@weavecode/server/dist/daemon/hook-pipeline.js +1 -1
  115. package/node_modules/@weavecode/server/dist/daemon/hooks-routes.js +1 -1
  116. package/node_modules/@weavecode/server/dist/daemon/http.js +1 -1
  117. package/node_modules/@weavecode/server/dist/daemon/opener.d.ts +102 -19
  118. package/node_modules/@weavecode/server/dist/daemon/opener.js +97 -7
  119. package/node_modules/@weavecode/server/dist/daemon/port.js +1 -1
  120. package/node_modules/@weavecode/server/dist/daemon/project-harnesses.js +2 -2
  121. package/node_modules/@weavecode/server/dist/daemon/project-updates-refresher.d.ts +4 -3
  122. package/node_modules/@weavecode/server/dist/daemon/project-updates-refresher.js +1 -1
  123. package/node_modules/@weavecode/server/dist/daemon/server.d.ts +15 -0
  124. package/node_modules/@weavecode/server/dist/daemon/server.js +8 -6
  125. package/node_modules/@weavecode/server/dist/daemon/session-probe.d.ts +72 -2
  126. package/node_modules/@weavecode/server/dist/daemon/session-probe.js +1 -1
  127. package/node_modules/@weavecode/server/dist/daemon/settings.d.ts +10 -0
  128. package/node_modules/@weavecode/server/dist/daemon/settings.js +2 -2
  129. package/node_modules/@weavecode/server/dist/daemon/snapshot-refresher.d.ts +7 -1
  130. package/node_modules/@weavecode/server/dist/daemon/snapshot-refresher.js +1 -1
  131. package/node_modules/@weavecode/server/dist/daemon/sse-hub.d.ts +40 -0
  132. package/node_modules/@weavecode/server/dist/daemon/sse-hub.js +1 -0
  133. package/node_modules/@weavecode/server/dist/daemon/start.js +1 -1
  134. package/node_modules/@weavecode/server/dist/daemon/state.js +2 -2
  135. package/node_modules/@weavecode/server/dist/daemon/static.js +1 -1
  136. package/node_modules/@weavecode/server/dist/daemon/terminal-topology-refresher.d.ts +4 -1
  137. package/node_modules/@weavecode/server/dist/daemon/tls.js +1 -1
  138. package/node_modules/@weavecode/server/dist/daemon/toolkit-routes.js +1 -1
  139. package/node_modules/@weavecode/server/dist/db/db.js +38 -2
  140. package/node_modules/@weavecode/server/dist/db/paths.d.ts +4 -0
  141. package/node_modules/@weavecode/server/dist/db/paths.js +1 -1
  142. package/node_modules/@weavecode/server/dist/hooks/answer-keys.js +1 -1
  143. package/node_modules/@weavecode/server/dist/hooks/bus.d.ts +5 -0
  144. package/node_modules/@weavecode/server/dist/hooks/bus.js +1 -1
  145. package/node_modules/@weavecode/server/dist/hooks/dispatcher.js +6 -6
  146. package/node_modules/@weavecode/server/dist/hooks/handlers/webhook.js +1 -1
  147. package/node_modules/@weavecode/server/dist/hooks/headless-runner.js +2 -2
  148. package/node_modules/@weavecode/server/dist/hooks/inbox-socket.d.ts +17 -4
  149. package/node_modules/@weavecode/server/dist/hooks/inbox-socket.js +2 -1
  150. package/node_modules/@weavecode/server/dist/hooks/inbox-worker.d.ts +27 -6
  151. package/node_modules/@weavecode/server/dist/hooks/inbox-worker.js +3 -3
  152. package/node_modules/@weavecode/server/dist/hooks/match.js +1 -1
  153. package/node_modules/@weavecode/server/dist/hooks/message-deliverer.d.ts +200 -13
  154. package/node_modules/@weavecode/server/dist/hooks/message-deliverer.js +3 -2
  155. package/node_modules/@weavecode/server/dist/hooks/mirror.d.ts +9 -4
  156. package/node_modules/@weavecode/server/dist/hooks/mirror.js +4 -4
  157. package/node_modules/@weavecode/server/dist/hooks/plugin-installer.js +3 -3
  158. package/node_modules/@weavecode/server/dist/hooks/plugin-loader.js +1 -1
  159. package/node_modules/@weavecode/server/dist/hooks/plugin-project-state.js +1 -1
  160. package/node_modules/@weavecode/server/dist/hooks/prompt-flusher.js +1 -1
  161. package/node_modules/@weavecode/server/dist/hooks/promptbox.d.ts +13 -0
  162. package/node_modules/@weavecode/server/dist/hooks/promptbox.js +8 -8
  163. package/node_modules/@weavecode/server/dist/hooks/push-notify.js +2 -2
  164. package/node_modules/@weavecode/server/dist/hooks/question-tracker.d.ts +6 -4
  165. package/node_modules/@weavecode/server/dist/hooks/question-tracker.js +1 -1
  166. package/node_modules/@weavecode/server/dist/hooks/registry.js +1 -1
  167. package/node_modules/@weavecode/server/dist/hooks/resume-runner.js +1 -1
  168. package/node_modules/@weavecode/server/dist/hooks/sequence-engine.js +1 -1
  169. package/node_modules/@weavecode/server/dist/hooks/session-purge.d.ts +7 -0
  170. package/node_modules/@weavecode/server/dist/hooks/session-purge.js +1 -1
  171. package/node_modules/@weavecode/server/dist/hooks/session-sweeper.d.ts +5 -8
  172. package/node_modules/@weavecode/server/dist/hooks/session-sweeper.js +1 -1
  173. package/node_modules/@weavecode/server/dist/hooks/side-questions.d.ts +41 -0
  174. package/node_modules/@weavecode/server/dist/hooks/side-questions.js +1 -0
  175. package/node_modules/@weavecode/server/dist/hooks/toolkit-scan.js +1 -1
  176. package/node_modules/@weavecode/server/dist/hooks/toolkit.d.ts +8 -0
  177. package/node_modules/@weavecode/server/dist/hooks/toolkit.js +5 -5
  178. package/node_modules/@weavecode/server/dist/hooks/watch-engine.d.ts +7 -0
  179. package/node_modules/@weavecode/server/dist/hooks/watch-engine.js +1 -1
  180. package/node_modules/@weavecode/server/dist/index.d.ts +1 -1
  181. package/node_modules/@weavecode/server/dist/install/apply-update.d.ts +1 -1
  182. package/node_modules/@weavecode/server/dist/install/apply-update.js +1 -1
  183. package/node_modules/@weavecode/server/dist/install/capabilities.d.ts +10 -0
  184. package/node_modules/@weavecode/server/dist/install/capabilities.js +1 -1
  185. package/node_modules/@weavecode/server/dist/install/codex-toml.d.ts +8 -26
  186. package/node_modules/@weavecode/server/dist/install/codex-toml.js +1 -1
  187. package/node_modules/@weavecode/server/dist/install/file-assets.js +1 -1
  188. package/node_modules/@weavecode/server/dist/install/fingerprint.d.ts +5 -1
  189. package/node_modules/@weavecode/server/dist/install/fingerprint.js +1 -1
  190. package/node_modules/@weavecode/server/dist/install/git-classify.d.ts +30 -0
  191. package/node_modules/@weavecode/server/dist/install/git-classify.js +1 -0
  192. package/node_modules/@weavecode/server/dist/install/global-config.d.ts +2 -4
  193. package/node_modules/@weavecode/server/dist/install/global-config.js +1 -2
  194. package/node_modules/@weavecode/server/dist/install/global-file-assets.js +1 -1
  195. package/node_modules/@weavecode/server/dist/install/init-files.d.ts +46 -0
  196. package/node_modules/@weavecode/server/dist/install/init-files.js +2 -0
  197. package/node_modules/@weavecode/server/dist/install/install-ledger.js +1 -1
  198. package/node_modules/@weavecode/server/dist/install/installer.d.ts +3 -5
  199. package/node_modules/@weavecode/server/dist/install/installer.js +1 -3
  200. package/node_modules/@weavecode/server/dist/install/library-index.js +1 -1
  201. package/node_modules/@weavecode/server/dist/install/mcp-rows.d.ts +5 -5
  202. package/node_modules/@weavecode/server/dist/install/mcp-rows.js +1 -1
  203. package/node_modules/@weavecode/server/dist/install/plugin-install.js +1 -1
  204. package/node_modules/@weavecode/server/dist/install/plugin-rows.js +1 -1
  205. package/node_modules/@weavecode/server/dist/install/plugin-templates.js +1 -1
  206. package/node_modules/@weavecode/server/dist/install/project-config.d.ts +0 -2
  207. package/node_modules/@weavecode/server/dist/install/project-config.js +2 -2
  208. package/node_modules/@weavecode/server/dist/install/reader.js +1 -1
  209. package/node_modules/@weavecode/server/dist/install/scan-cache.js +1 -1
  210. package/node_modules/@weavecode/server/dist/install/scanner.js +1 -1
  211. package/node_modules/@weavecode/server/dist/install/settings-mcp.js +2 -2
  212. package/node_modules/@weavecode/server/dist/install/updates.d.ts +17 -5
  213. package/node_modules/@weavecode/server/dist/install/updates.js +1 -1
  214. package/node_modules/@weavecode/server/dist/market/builtin.js +1 -1
  215. package/node_modules/@weavecode/server/dist/market/identity.js +1 -1
  216. package/node_modules/@weavecode/server/dist/market/import.js +2 -2
  217. package/node_modules/@weavecode/server/dist/market/refresh.js +1 -1
  218. package/node_modules/@weavecode/server/dist/market/resolve.js +1 -1
  219. package/node_modules/@weavecode/server/dist/market/updates.js +1 -1
  220. package/node_modules/@weavecode/server/dist/registry.js +2 -2
  221. package/node_modules/@weavecode/server/dist/repositories/hook-dispatches.js +5 -5
  222. package/node_modules/@weavecode/server/dist/repositories/hook-events.d.ts +7 -0
  223. package/node_modules/@weavecode/server/dist/repositories/hook-events.js +2 -2
  224. package/node_modules/@weavecode/server/dist/repositories/hook-rules.js +4 -4
  225. package/node_modules/@weavecode/server/dist/repositories/libraries.js +1 -1
  226. package/node_modules/@weavecode/server/dist/repositories/plugin-states.js +1 -1
  227. package/node_modules/@weavecode/server/dist/repositories/projects.d.ts +7 -0
  228. package/node_modules/@weavecode/server/dist/repositories/projects.js +2 -2
  229. package/node_modules/@weavecode/server/dist/repositories/push-subscriptions.js +2 -2
  230. package/node_modules/@weavecode/server/dist/repositories/session-watches.js +4 -4
  231. package/node_modules/@weavecode/server/dist/repositories/sessions.d.ts +32 -8
  232. package/node_modules/@weavecode/server/dist/repositories/sessions.js +2 -2
  233. package/node_modules/@weavecode/server/dist/repositories/side-questions.d.ts +50 -0
  234. package/node_modules/@weavecode/server/dist/repositories/side-questions.js +6 -0
  235. package/node_modules/@weavecode/server/dist/repositories/uploads.d.ts +66 -0
  236. package/node_modules/@weavecode/server/dist/repositories/uploads.js +7 -0
  237. package/node_modules/@weavecode/server/dist/statusline/cache-sweeper.js +1 -1
  238. package/node_modules/@weavecode/server/dist/statusline/config.d.ts +4 -198
  239. package/node_modules/@weavecode/server/dist/statusline/config.js +1 -1
  240. package/node_modules/@weavecode/server/dist/statusline/generator.d.ts +5 -0
  241. package/node_modules/@weavecode/server/dist/statusline/generator.js +1 -676
  242. package/node_modules/@weavecode/server/dist/statusline/manager.d.ts +7 -5
  243. package/node_modules/@weavecode/server/dist/statusline/manager.js +3 -4
  244. package/node_modules/@weavecode/server/dist/surfaces.d.ts +11 -1
  245. package/node_modules/@weavecode/server/dist/surfaces.js +1 -1
  246. package/node_modules/@weavecode/server/dist/watch/cache.js +1 -1
  247. package/node_modules/@weavecode/server/dist/watch/classifier.js +1 -1
  248. package/node_modules/@weavecode/server/dist/watch/plugin-mods.js +1 -1
  249. package/node_modules/@weavecode/server/dist/watch/sync-scheduler.d.ts +8 -4
  250. package/node_modules/@weavecode/server/dist/watch/sync-scheduler.js +1 -1
  251. package/node_modules/@weavecode/server/dist/watch/watch-service.js +1 -1
  252. package/node_modules/@weavecode/server/package.json +4 -4
  253. package/node_modules/@weavecode/server/web/dist/assets/index-CHWbLAje.js +594 -0
  254. package/node_modules/@weavecode/server/web/dist/assets/index-D0s5v8QS.css +11 -0
  255. package/node_modules/@weavecode/server/web/dist/index.html +14 -2
  256. package/node_modules/@weavecode/templates/dist/resources/weave-market/plugins/core-skills/weave-plugin-creator/skills/weave-plugin-creator/SKILL.md +2 -2
  257. package/node_modules/@weavecode/templates/package.json +2 -2
  258. package/node_modules/selfsigned/node_modules/@peculiar/x509/node_modules/@peculiar/asn1-cms/node_modules/asn1js/README.md +50 -32
  259. package/node_modules/selfsigned/node_modules/@peculiar/x509/node_modules/@peculiar/asn1-cms/node_modules/asn1js/build/index.d.ts +86 -40
  260. package/node_modules/selfsigned/node_modules/@peculiar/x509/node_modules/@peculiar/asn1-cms/node_modules/asn1js/build/index.es.js +860 -353
  261. package/node_modules/selfsigned/node_modules/@peculiar/x509/node_modules/@peculiar/asn1-cms/node_modules/asn1js/build/index.js +860 -353
  262. package/node_modules/selfsigned/node_modules/@peculiar/x509/node_modules/@peculiar/asn1-cms/node_modules/asn1js/package.json +20 -17
  263. package/node_modules/selfsigned/node_modules/@peculiar/x509/node_modules/@peculiar/asn1-csr/node_modules/asn1js/README.md +50 -32
  264. package/node_modules/selfsigned/node_modules/@peculiar/x509/node_modules/@peculiar/asn1-csr/node_modules/asn1js/build/index.d.ts +86 -40
  265. package/node_modules/selfsigned/node_modules/@peculiar/x509/node_modules/@peculiar/asn1-csr/node_modules/asn1js/build/index.es.js +860 -353
  266. package/node_modules/selfsigned/node_modules/@peculiar/x509/node_modules/@peculiar/asn1-csr/node_modules/asn1js/build/index.js +860 -353
  267. package/node_modules/selfsigned/node_modules/@peculiar/x509/node_modules/@peculiar/asn1-csr/node_modules/asn1js/package.json +20 -17
  268. package/node_modules/selfsigned/node_modules/@peculiar/x509/node_modules/@peculiar/asn1-ecc/node_modules/asn1js/README.md +50 -32
  269. package/node_modules/selfsigned/node_modules/@peculiar/x509/node_modules/@peculiar/asn1-ecc/node_modules/asn1js/build/index.d.ts +86 -40
  270. package/node_modules/selfsigned/node_modules/@peculiar/x509/node_modules/@peculiar/asn1-ecc/node_modules/asn1js/build/index.es.js +860 -353
  271. package/node_modules/selfsigned/node_modules/@peculiar/x509/node_modules/@peculiar/asn1-ecc/node_modules/asn1js/build/index.js +860 -353
  272. package/node_modules/selfsigned/node_modules/@peculiar/x509/node_modules/@peculiar/asn1-ecc/node_modules/asn1js/package.json +20 -17
  273. package/node_modules/selfsigned/node_modules/@peculiar/x509/node_modules/@peculiar/asn1-pkcs9/node_modules/asn1js/README.md +50 -32
  274. package/node_modules/selfsigned/node_modules/@peculiar/x509/node_modules/@peculiar/asn1-pkcs9/node_modules/asn1js/build/index.d.ts +86 -40
  275. package/node_modules/selfsigned/node_modules/@peculiar/x509/node_modules/@peculiar/asn1-pkcs9/node_modules/asn1js/build/index.es.js +860 -353
  276. package/node_modules/selfsigned/node_modules/@peculiar/x509/node_modules/@peculiar/asn1-pkcs9/node_modules/asn1js/build/index.js +860 -353
  277. package/node_modules/selfsigned/node_modules/@peculiar/x509/node_modules/@peculiar/asn1-pkcs9/node_modules/asn1js/package.json +20 -17
  278. package/node_modules/selfsigned/node_modules/@peculiar/x509/node_modules/@peculiar/asn1-rsa/node_modules/asn1js/README.md +50 -32
  279. package/node_modules/selfsigned/node_modules/@peculiar/x509/node_modules/@peculiar/asn1-rsa/node_modules/asn1js/build/index.d.ts +86 -40
  280. package/node_modules/selfsigned/node_modules/@peculiar/x509/node_modules/@peculiar/asn1-rsa/node_modules/asn1js/build/index.es.js +860 -353
  281. package/node_modules/selfsigned/node_modules/@peculiar/x509/node_modules/@peculiar/asn1-rsa/node_modules/asn1js/build/index.js +860 -353
  282. package/node_modules/selfsigned/node_modules/@peculiar/x509/node_modules/@peculiar/asn1-rsa/node_modules/asn1js/package.json +20 -17
  283. package/node_modules/selfsigned/node_modules/@peculiar/x509/node_modules/@peculiar/asn1-schema/node_modules/asn1js/README.md +50 -32
  284. package/node_modules/selfsigned/node_modules/@peculiar/x509/node_modules/@peculiar/asn1-schema/node_modules/asn1js/build/index.d.ts +86 -40
  285. package/node_modules/selfsigned/node_modules/@peculiar/x509/node_modules/@peculiar/asn1-schema/node_modules/asn1js/build/index.es.js +860 -353
  286. package/node_modules/selfsigned/node_modules/@peculiar/x509/node_modules/@peculiar/asn1-schema/node_modules/asn1js/build/index.js +860 -353
  287. package/node_modules/selfsigned/node_modules/@peculiar/x509/node_modules/@peculiar/asn1-schema/node_modules/asn1js/package.json +20 -17
  288. package/node_modules/selfsigned/node_modules/@peculiar/x509/node_modules/@peculiar/asn1-x509/node_modules/asn1js/README.md +50 -32
  289. package/node_modules/selfsigned/node_modules/@peculiar/x509/node_modules/@peculiar/asn1-x509/node_modules/asn1js/build/index.d.ts +86 -40
  290. package/node_modules/selfsigned/node_modules/@peculiar/x509/node_modules/@peculiar/asn1-x509/node_modules/asn1js/build/index.es.js +860 -353
  291. package/node_modules/selfsigned/node_modules/@peculiar/x509/node_modules/@peculiar/asn1-x509/node_modules/asn1js/build/index.js +860 -353
  292. package/node_modules/selfsigned/node_modules/@peculiar/x509/node_modules/@peculiar/asn1-x509/node_modules/asn1js/package.json +20 -17
  293. package/node_modules/selfsigned/node_modules/pkijs/node_modules/asn1js/README.md +50 -32
  294. package/node_modules/selfsigned/node_modules/pkijs/node_modules/asn1js/build/index.d.ts +86 -40
  295. package/node_modules/selfsigned/node_modules/pkijs/node_modules/asn1js/build/index.es.js +860 -353
  296. package/node_modules/selfsigned/node_modules/pkijs/node_modules/asn1js/build/index.js +860 -353
  297. package/node_modules/selfsigned/node_modules/pkijs/node_modules/asn1js/package.json +20 -17
  298. package/package.json +6 -6
  299. package/node_modules/@weavecode/server/web/dist/assets/index-BOzaRlQE.js +0 -560
  300. package/node_modules/@weavecode/server/web/dist/assets/index-ChX8G8cT.css +0 -11
@@ -1,4 +1,4 @@
1
- import{mkdirSync as e}from"node:fs";import s from"node:path";import{DatabaseSync as N}from"node:sqlite";import{getDbPath as t}from"./paths.js";const F=`
1
+ import{mkdirSync as i}from"node:fs";import o from"node:path";import{DatabaseSync as a}from"node:sqlite";import{getDbPath as L}from"./paths.js";import{projectKey as n}from"../repositories/projects.js";const r=`
2
2
  CREATE TABLE IF NOT EXISTS projects (
3
3
  id INTEGER PRIMARY KEY AUTOINCREMENT,
4
4
  path TEXT NOT NULL UNIQUE,
@@ -98,6 +98,24 @@ CREATE TABLE IF NOT EXISTS session_watches (
98
98
  );
99
99
  CREATE INDEX IF NOT EXISTS idx_session_watches_target ON session_watches(target_session_id, fired_at);
100
100
 
101
+ -- \u65C1\u8DEF\u4F1A\u8BDD\uFF08claude = /btw\uFF09\uFF1A\u5BBF\u4E3B\u4FA7\u95EE\u7684\u95EE\u9898\u4E0E\u56DE\u7B54**\u90FD\u4E0D\u843D\u4EFB\u4F55\u6587\u4EF6**\uFF08\u4FA7\u95EE\u67E5\u8BE2\u5F00\u7740
102
+ -- skipTranscript\uFF0C\u9762\u677F\u5386\u53F2\u53EA\u5728\u5BBF\u4E3B\u5185\u5B58\u91CC\uFF09\uFF0C\u6545 weave \u81EA\u5DF1\u53D1\u51FA\u53BB\u7684\u95EE\u9898\u53EA\u80FD\u8BB0\u5728\u8FD9\uFF1B
103
+ -- \u56DE\u7B54\u7531\u91C7\u96C6\u4E8B\u4EF6\u8BA4\u9886\uFF08answer_event_id \u6307\u56DE\u90A3\u6761 SubagentStop\uFF0Canswer \u5B58\u539F\u6587\u2014\u2014
104
+ -- \u4E8B\u4EF6\u4F1A\u6309\u4FDD\u7559\u7B56\u7565\u6E05\u6389\uFF0C\u800C\u8FD9\u6761\u95EE\u7B54\u662F\u7528\u6237\u7684\u5386\u53F2\uFF09\u3002
105
+ -- status: pending\uFF08\u5DF2\u6253\u51FA\u3001\u7B49\u56DE\u7B54\uFF09| answered\uFF08\u8BA4\u9886\u5230\uFF09| timeout\uFF08\u8D85\u7A97\u6CA1\u7B49\u5230\uFF09\u3002
106
+ CREATE TABLE IF NOT EXISTS side_questions (
107
+ id INTEGER PRIMARY KEY AUTOINCREMENT,
108
+ session_id TEXT NOT NULL,
109
+ project_id INTEGER,
110
+ question TEXT NOT NULL,
111
+ answer TEXT,
112
+ answer_event_id INTEGER,
113
+ status TEXT NOT NULL,
114
+ asked_at TEXT NOT NULL,
115
+ answered_at TEXT
116
+ );
117
+ CREATE INDEX IF NOT EXISTS idx_side_questions_session ON side_questions(session_id, id);
118
+
101
119
  -- \u8DE8\u4F1A\u8BDD\u5E8F\u5217\uFF08\u6279 3\uFF09\uFF1A\u624B\u5DE5\u7F16\u6392\u7684\u591A\u6B65\u94FE\u3002steps JSON = [{to,text,mode,
102
120
  -- messageId?}]\uFF0CmessageId \u4E3A\u6B65\u89E6\u53D1\u540E\u56DE\u586B\u7684\u7BA1\u9053\u53D1\u53F7\uFF08\u5185\u5B58\u5173\u8054\uFF09\uFF1B
103
121
  -- cursor = \u6B63\u5728\u7B49\u5F85\u5B8C\u6210\u7684\u6B65\u4E0B\u6807\u3002\u5F15\u64CE\u65E0\u5185\u5B58\u6743\u5A01\u6001\uFF0C\u5168\u90E8\u72B6\u6001\u5728\u884C\u3002
@@ -131,4 +149,22 @@ CREATE TABLE IF NOT EXISTS push_subscriptions (
131
149
  user_agent TEXT,
132
150
  created_at TEXT NOT NULL
133
151
  );
134
- `;export function openDatabase(E=t()){E!==":memory:"&&e(s.dirname(E),{recursive:!0});const u=new N(E);return u.exec("PRAGMA journal_mode = WAL"),u.exec("PRAGMA foreign_keys = ON"),u.exec("PRAGMA busy_timeout = 5000"),u.exec(F),u.exec("DROP TABLE IF EXISTS session_messages"),o(u),i(u),L(u),u}function L(E){const u=new Set(E.prepare("PRAGMA table_info(session_watches)").all().map(T=>String(T.name)));u.size!==0&&(u.has("on_events")||E.exec("ALTER TABLE session_watches ADD COLUMN on_events TEXT"),u.has("remaining")||(E.exec("ALTER TABLE session_watches ADD COLUMN remaining INTEGER"),E.exec("UPDATE session_watches SET remaining = 1")))}function i(E){const u=new Set(E.prepare("PRAGMA table_info(projects)").all().map(T=>String(T.name)));u.size!==0&&(u.has("sort_order")||E.exec("ALTER TABLE projects ADD COLUMN sort_order INTEGER"),u.has("archived_at")||E.exec("ALTER TABLE projects ADD COLUMN archived_at TEXT"))}function o(E){const u=new Set(E.prepare("PRAGMA table_info(hook_rules)").all().map(T=>String(T.name)));u.size!==0&&(u.has("origin")||E.exec("ALTER TABLE hook_rules ADD COLUMN origin TEXT NOT NULL DEFAULT 'user'"),u.has("plugin_id")||E.exec("ALTER TABLE hook_rules ADD COLUMN plugin_id TEXT"),E.exec("CREATE INDEX IF NOT EXISTS idx_hook_rules_plugin ON hook_rules(plugin_id)"))}
152
+
153
+ -- \u4F1A\u8BDD\u56FE\u7247\u4E0A\u4F20\uFF1A\u5185\u5BB9\u5BFB\u5740 id = sha256\uFF08\u5929\u7136\u53BB\u91CD\uFF09\uFF0C\u6587\u4EF6\u843D <dataDir>/uploads/\u3002
154
+ -- \u4E0A\u4F20 \u2260 \u6295\u9012\uFF08\u8D44\u6E90\u4E09\u5C42\u91CC\u7684\u300C\u88C5\u5230\u76EE\u6807\u4F4D\u300D\uFF09\uFF1B\u4E0E\u4F1A\u8BDD\u7684\u5173\u7CFB\u7ECF event_images\u3002
155
+ CREATE TABLE IF NOT EXISTS uploads (
156
+ id TEXT PRIMARY KEY,
157
+ media_type TEXT NOT NULL,
158
+ name TEXT NOT NULL,
159
+ size INTEGER NOT NULL,
160
+ created_at TEXT NOT NULL
161
+ );
162
+
163
+ -- \u6D88\u606F\u968F\u9644\u7684\u56FE\uFF08\u5BF9\u8BDD\u6C14\u6CE1\u7684\u7F29\u7565\u56FE\uFF09\uFF1A\u6302\u5728**\u5F00\u8F6E\u4E8B\u4EF6**\u4E0A\u2014\u2014\u6D88\u606F\u57DF\u4E0D\u843D\u5E93\uFF0C
164
+ -- \u56FE\u7684\u5F52\u5BBF\u662F\u4F1A\u8BDD\u81EA\u5DF1\u7684\u8F6C\u5F55\u4E8B\u4EF6\uFF0C\u8FD9\u91CC\u53EA\u5B58\u6307\u9488\u3002\u968F hook_events \u7EA7\u8054\u5220\u3002
165
+ CREATE TABLE IF NOT EXISTS event_images (
166
+ event_id INTEGER NOT NULL REFERENCES hook_events(id) ON DELETE CASCADE,
167
+ upload_id TEXT NOT NULL,
168
+ PRIMARY KEY (event_id, upload_id)
169
+ );
170
+ `;export function openDatabase(e=L()){e!==":memory:"&&i(o.dirname(e),{recursive:!0});const T=new a(e);return T.exec("PRAGMA busy_timeout = 5000"),T.exec("PRAGMA journal_mode = WAL"),T.exec("PRAGMA foreign_keys = ON"),T.exec(r),T.exec("DROP TABLE IF EXISTS session_messages"),O(T),A(T),_(T),d(T),T}function _(e){const T=e.prepare("SELECT id, path FROM projects ORDER BY id").all(),E=new Set(T.map(s=>s.path)),N=e.prepare("UPDATE projects SET path = ? WHERE id = ?");for(const s of T){const t=n(s.path);t===s.path||E.has(t)||(E.delete(s.path),E.add(t),N.run(t,s.id))}}function d(e){const T=new Set(e.prepare("PRAGMA table_info(session_watches)").all().map(E=>String(E.name)));T.size!==0&&(T.has("on_events")||e.exec("ALTER TABLE session_watches ADD COLUMN on_events TEXT"),T.has("remaining")||(e.exec("ALTER TABLE session_watches ADD COLUMN remaining INTEGER"),e.exec("UPDATE session_watches SET remaining = 1")))}function A(e){const T=new Set(e.prepare("PRAGMA table_info(projects)").all().map(E=>String(E.name)));T.size!==0&&(T.has("sort_order")||e.exec("ALTER TABLE projects ADD COLUMN sort_order INTEGER"),T.has("archived_at")||e.exec("ALTER TABLE projects ADD COLUMN archived_at TEXT"))}function O(e){const T=new Set(e.prepare("PRAGMA table_info(hook_rules)").all().map(E=>String(E.name)));T.size!==0&&(T.has("origin")||e.exec("ALTER TABLE hook_rules ADD COLUMN origin TEXT NOT NULL DEFAULT 'user'"),T.has("plugin_id")||e.exec("ALTER TABLE hook_rules ADD COLUMN plugin_id TEXT"),e.exec("CREATE INDEX IF NOT EXISTS idx_hook_rules_plugin ON hook_rules(plugin_id)"))}
@@ -12,3 +12,7 @@ export declare function getInitialPasswordPath(): string;
12
12
  export declare function getAiKeyPath(): string;
13
13
  /** Absolute path to the Web Push VAPID keypair file (`{ publicKey, privateKey }`, 0600). */
14
14
  export declare function getPushKeysPath(): string;
15
+ /** 会话图片上传的落盘根(内容寻址 `<sha256>.<ext>`;绝对路径由 harness 引用)。 */
16
+ export declare function getUploadsDir(): string;
17
+ /** 接口日志根(按小时 JSONL:`api-YYYY-MM-DDTHH.jsonl`,见 daemon/api-log.ts)。 */
18
+ export declare function getApiLogsDir(): string;
@@ -1 +1 @@
1
- import t from"node:path";import{detectPlatform as n}from"@weavecode/core";export function getDataDir(){return t.join(n().configDir,"weave")}export function getDbPath(){return t.join(getDataDir(),"weave.db")}export function getDaemonStatePath(){return t.join(getDataDir(),"daemon.json")}export function getAuthPath(){return t.join(getDataDir(),"auth.json")}export function getInitialPasswordPath(){return t.join(getDataDir(),"initial-password")}export function getAiKeyPath(){return t.join(getDataDir(),"ai.json")}export function getPushKeysPath(){return t.join(getDataDir(),"push.json")}
1
+ import t from"node:path";import{detectPlatform as n}from"@weavecode/core";export function getDataDir(){return t.join(n().configDir,"weave")}export function getDbPath(){return t.join(getDataDir(),"weave.db")}export function getDaemonStatePath(){return t.join(getDataDir(),"daemon.json")}export function getAuthPath(){return t.join(getDataDir(),"auth.json")}export function getInitialPasswordPath(){return t.join(getDataDir(),"initial-password")}export function getAiKeyPath(){return t.join(getDataDir(),"ai.json")}export function getPushKeysPath(){return t.join(getDataDir(),"push.json")}export function getUploadsDir(){return t.join(getDataDir(),"uploads")}export function getApiLogsDir(){return t.join(getDataDir(),"logs","api")}
@@ -1 +1 @@
1
- const l=" ";export function composeAnswerAtoms(i,p){if(i.every(o=>o.options.length===0))return{ok:!1,error:"Question face has no answerable options"};const u=new Map(p.map(o=>[o.questionKey,o]));for(const o of u.keys())if(!i.some(s=>s.key===o))return{ok:!1,error:`Unknown question: ${o}`};const n=[];for(const o of i){const s=u.get(o.key),t=(s?.options??[]).map(e=>o.options[e]);if(t.some(e=>!e))return{ok:!1,error:`Invalid option index: ${o.key}`};if(o.submit&&t.length!==1)return{ok:!1,error:"Submit choice required to finish the call"};const c=t.filter(e=>!e.input);if(!o.multiSelect&&c.length>1)return{ok:!1,error:`Single-select question got ${c.length} options: ${o.key}`};const f=s?.text?.trim()??"",r=t.find(e=>e.input);if(r&&!f)return{ok:!1,error:`Text required for this option: ${o.key}`};for(const e of t)n.push(...e.keys);if(r)n.push(...r.textFocus??[],f,...r.textTail??["\r"]);else for(const e of t)n.push(...e.commit??[]);if(o.submit||t.some(e=>e.chat))break;!r&&(o.multiSelect||t.length===0)&&n.push(" ")}return{ok:!0,atoms:n}}
1
+ const p=" ";export function composeAnswerAtoms(i,l){if(i.every(e=>e.options.length===0))return{ok:!1,error:"Question face has no answerable options"};const f=new Map(l.map(e=>[e.questionKey,e]));for(const e of f.keys())if(!i.some(s=>s.key===e))return{ok:!1,error:`Unknown question: ${e}`};const n=[];for(const e of i){const s=f.get(e.key),t=(s?.options??[]).map(o=>e.options[o]);if(t.some(o=>!o))return{ok:!1,error:`Invalid option index: ${e.key}`};if(e.submit&&t.length!==1)return{ok:!1,error:"Submit choice required to finish the call"};const c=t.filter(o=>!o.input);if(!e.multiSelect&&c.length>1)return{ok:!1,error:`Single-select question got ${c.length} options: ${e.key}`};const u=s?.text?.trim()??"",r=t.find(o=>o.input);if(r&&!u)return{ok:!1,error:`Text required for this option: ${e.key}`};for(const o of t)n.push(...o.keys);if(r)n.push(...r.textFocus??[],u,...r.textTail??["\r"]);else for(const o of t)n.push(...o.commit??[]);if(e.submit||t.some(o=>o.chat))break;!r&&(e.multiSelect||t.length===0)&&n.push(" ")}return{ok:!0,atoms:n}}
@@ -121,6 +121,11 @@ export type HookBusMessage = {
121
121
  harness: string;
122
122
  count: number;
123
123
  at: string;
124
+ } | {
125
+ kind: 'sideQuestion.answered';
126
+ sessionId: string;
127
+ sideQuestionId: number;
128
+ at: string;
124
129
  } | {
125
130
  kind: 'sequence.step';
126
131
  sequenceId: number;
@@ -1 +1 @@
1
- import{EventEmitter as t}from"node:events";export class HookEventBus{emitter=new t;constructor(){this.emitter.setMaxListeners(100)}emit(e){this.emitter.emit("change",e)}subscribe(e){return this.emitter.on("change",e),()=>this.emitter.off("change",e)}}
1
+ import{EventEmitter as e}from"node:events";export class HookEventBus{emitter=new e;constructor(){this.emitter.setMaxListeners(100)}emit(t){this.emitter.emit("change",t)}subscribe(t){return this.emitter.on("change",t),()=>this.emitter.off("change",t)}}
@@ -1,8 +1,8 @@
1
- import{INJECTABLE_EVENTS as I,TITLE_EFFECTIVE_EVENTS as y,hookSourceHarness as b}from"@weavecode/core";import{createPluginLogger as P}from"./plugin-loader.js";import{readHooksEnabled as S}from"../daemon/settings.js";import{effective as v,pluginsStateOf as k}from"./plugin-project-state.js";import{runWebhook as w}from"./handlers/webhook.js";import{DISPATCH_MARKER as h,extractFilePath as c,isCrossProjectPath as j,matchesAnyGlob as T,projectLabel as D,renderTemplate as W,templateVars as E}from"./match.js";const m=6e4,N=4,O=4,C=3e3;export class HookDispatcher{deps;runningWebhooks=new Set;recentPool=new Map;activeWebhooks=0;pendingWebhooks=[];activePlugins=0;pendingPlugins=[];constructor(t){this.deps=t}async onIngest(t){try{if(!S())return{};this.deps.plugins?.notifyEvent?.(t.payload.eventType,t.payload,t.sessionId);const e={};if(t.sessionId){const s=H(t.payload);s!==null&&this.deps.sessions.applyReportedTitle(t.sessionId,s)&&this.deps.bus.emit({kind:"session.renamed",sessionId:t.sessionId,title:s,at:new Date().toISOString()});const o=this.deps.sessions.getBySessionId(t.sessionId)?.pendingTitle;if(o){e.sessionTitle=o;const l=y[t.source].includes(t.payload.eventType);(t.deliveredTitle===o&&l||s!==null)&&this.deps.sessions.confirmPendingTitle(t.sessionId,o)&&this.deps.bus.emit({kind:"session.renamed",sessionId:t.sessionId,title:o,at:new Date().toISOString()})}}const a=this.match(t);if(a.length===0)return e;const n=[],i=[],r=Date.now(),d=r+C;for(const s of a)if(this.deps.bus.emit({kind:"rule.matched",ruleId:s.id,eventId:t.eventId,sessionId:t.sessionId,at:new Date(r).toISOString()}),s.handler.type!=="log"){if(s.handler.type==="manual"||s.handler.type==="inject"){if(this.dedupe(s,t,r))continue;const o=W(s.handler.template,E({event:t.payload.eventType,tool:t.payload.toolName,filePath:c(t.payload.toolInput),cwd:t.payload.cwd,session:t.sessionId,project:D(t.project.path),rule:s.name}))+`
2
- ${h}`,l=s.handler.type==="inject"?"injected":"pending";this.createDispatch(s,t,{prompt:o,status:l,mode:s.handler.type==="inject"?"auto":"manual"}),s.handler.type==="inject"&&(s.filter.crossProjectOnly?i.push(o):n.push(o));continue}if(s.handler.type==="webhook"){if(this.runningWebhooks.has(s.id))continue;this.runningWebhooks.add(s.id);const o=this.createDispatch(s,t,{prompt:`webhook ${s.handler.url}`,status:"running",mode:"auto"});this.deps.bus.emit({kind:"dispatch.started",ruleId:s.id,dispatchId:o.id,sessionId:t.sessionId,at:new Date().toISOString()}),this.runWebhookAsync(s,this.summary(s,t),o.id);continue}if(s.handler.type==="plugin"){const o=this.deps.plugins;if(!o)continue;const l=o.getHandler(s.handler.pluginId,s.handler.handlerType);if(!l||this.dedupe(s,t,r))continue;if(!this.injectable(t)){this.runPluginDetached(s,t,o,l);continue}const u=d-Date.now();if(u<=0)continue;const p=await this.runPluginHandler(s,t,o,l,u);if(!p)continue;p.prompt&&this.createDispatch(s,t,{prompt:p.prompt+`
3
- ${h}`,status:"pending",mode:"auto"}),p.additionalContext&&i.push(p.additionalContext)}}return(n.length>0||i.length>0)&&(e.additionalContext=[...n,...i].join(`
1
+ import{INJECTABLE_EVENTS as I,TITLE_EFFECTIVE_EVENTS as y,hookSourceHarness as P}from"@weavecode/core";import{createPluginLogger as b}from"./plugin-loader.js";import{readHooksEnabled as S}from"../daemon/settings.js";import{effective as k,pluginsStateOf as v}from"./plugin-project-state.js";import{runWebhook as w}from"./handlers/webhook.js";import{DISPATCH_MARKER as c,extractFilePath as h,isCrossProjectPath as j,matchesAnyGlob as T,projectLabel as D,renderTemplate as E,templateVars as W}from"./match.js";const g=6e4,N=4,_=4,O=3e3;export class HookDispatcher{deps;runningWebhooks=new Set;recentPool=new Map;activeWebhooks=0;pendingWebhooks=[];activePlugins=0;pendingPlugins=[];constructor(e){this.deps=e}async onIngest(e){try{if(!S())return{};this.deps.plugins?.notifyEvent?.(e.payload.eventType,e.payload,e.sessionId);const t={};if(e.sessionId){const s=C(e.payload);s!==null&&this.deps.sessions.applyReportedTitle(e.sessionId,s)&&this.deps.bus.emit({kind:"session.renamed",sessionId:e.sessionId,title:s,at:new Date().toISOString()});const o=this.deps.sessions.getBySessionId(e.sessionId)?.pendingTitle;if(o){t.sessionTitle=o;const l=y[e.source].includes(e.payload.eventType);(e.deliveredTitle===o&&l||s!==null)&&this.deps.sessions.confirmPendingTitle(e.sessionId,o)&&this.deps.bus.emit({kind:"session.renamed",sessionId:e.sessionId,title:o,at:new Date().toISOString()})}}const r=this.match(e);if(r.length===0)return t;const n=[],i=[],a=Date.now(),d=a+O;for(const s of r)if(this.deps.bus.emit({kind:"rule.matched",ruleId:s.id,eventId:e.eventId,sessionId:e.sessionId,at:new Date(a).toISOString()}),s.handler.type!=="log"){if(s.handler.type==="manual"||s.handler.type==="inject"){if(this.dedupe(s,e,a))continue;const o=E(s.handler.template,W({event:e.payload.eventType,tool:e.payload.toolName,filePath:h(e.payload.toolInput),cwd:e.payload.cwd,session:e.sessionId,project:D(e.project.path),rule:s.name}))+`
2
+ ${c}`,l=s.handler.type==="inject"?"injected":"pending";this.createDispatch(s,e,{prompt:o,status:l,mode:s.handler.type==="inject"?"auto":"manual"}),s.handler.type==="inject"&&(s.filter.crossProjectOnly?i.push(o):n.push(o));continue}if(s.handler.type==="webhook"){if(this.runningWebhooks.has(s.id))continue;this.runningWebhooks.add(s.id);const o=this.createDispatch(s,e,{prompt:`webhook ${s.handler.url}`,status:"running",mode:"auto"});this.deps.bus.emit({kind:"dispatch.started",ruleId:s.id,dispatchId:o.id,sessionId:e.sessionId,at:new Date().toISOString()}),this.runWebhookAsync(s,this.summary(s,e),o.id);continue}if(s.handler.type==="plugin"){const o=this.deps.plugins;if(!o)continue;const l=o.getHandler(s.handler.pluginId,s.handler.handlerType);if(!l||this.dedupe(s,e,a))continue;if(!this.injectable(e)){this.runPluginDetached(s,e,o,l);continue}const u=d-Date.now();if(u<=0)continue;const p=await this.runPluginHandler(s,e,o,l,u);if(!p)continue;p.prompt&&this.createDispatch(s,e,{prompt:p.prompt+`
3
+ ${c}`,status:"pending",mode:"auto"}),p.additionalContext&&i.push(p.additionalContext)}}return(n.length>0||i.length>0)&&(t.additionalContext=[...n,...i].join(`
4
4
 
5
- `)),i.length>0&&(e.deferred=i.join(`
5
+ `)),i.length>0&&(t.deferred=i.join(`
6
6
 
7
- `)),e}catch{return{}}}createDispatch(t,e,a){const n=this.deps.dispatches.insert({ruleId:t.id,eventId:e.eventId,sessionId:e.sessionId,...a});return this.deps.bus.emit({kind:"dispatch.created",ruleId:t.id,dispatchId:n.id,status:a.status,mode:n.mode,sessionId:e.sessionId,at:n.startedAt}),n}dedupe(t,e,a){const n=`${t.id}:${e.sessionId??""}`,i=this.recentPool.get(n);return i!==void 0&&a-i<m?!0:(this.recentPool.set(n,a),this.trimDedupe(a),!1)}match(t){const e=this.deps.pluginStates,a=e?k(t.project.meta).enabled:null;let n=null;return this.deps.registry.candidates(t.payload.eventType,e?{includeDisabled:!0}:void 0).filter(i=>{const r=b(i.source);if(r!==null&&r!=="any"&&r!==t.source||i.projectId!==null&&i.projectId!==t.project.id)return!1;if(i.pluginId!==null){if(!i.enabled&&a?.[i.pluginId]!==!0||e&&!v(t.project,i.pluginId,{states:e}))return!1}else if(!i.enabled)return!1;const d=i.filter;if(d.toolNames?.length&&(!t.payload.toolName||!d.toolNames.includes(t.payload.toolName)))return!1;if(d.pathGlobs?.length){const s=c(t.payload.toolInput);if(!s||!T(s,d.pathGlobs))return!1}if(d.crossProjectOnly){const s=c(t.payload.toolInput)??t.payload.cwd;if(!s||(n??=this.deps.projects.list().map(o=>o.path).filter(o=>o!==t.project.path),!j(s,t.project.path,n)))return!1}return!0})}injectable(t){const e=t.payload.eventType;return e!==null&&I[t.source].includes(e)}async runPluginHandler(t,e,a,n,i){if(t.handler.type!=="plugin")return;const{pluginId:r}=t.handler,d=P(r),s=i===void 0?t.timeoutMs:Math.min(t.timeoutMs,i);let o;try{const l=(async()=>{await this.acquirePluginSlot();try{return await n.execute({event:e.payload,rule:t,config:a.getConfig(r),logger:d})}finally{this.releasePluginSlot()}})(),u=await Promise.race([l,new Promise((p,f)=>{o=setTimeout(()=>f(new Error("plugin handler timeout")),s)})]);return u&&typeof u=="object"?u:void 0}catch{return}finally{o&&clearTimeout(o)}}async runPluginDetached(t,e,a,n){try{const i=await this.runPluginHandler(t,e,a,n);if(!i?.prompt)return;this.createDispatch(t,e,{prompt:i.prompt+`
8
- ${h}`,status:"pending",mode:"auto"})}catch{}}summary(t,e){return{ruleId:t.id,ruleName:t.name,projectId:e.project.id,sessionId:e.sessionId,event:e.payload.eventType,toolName:e.payload.toolName,filePath:c(e.payload.toolInput),cwd:e.payload.cwd,at:new Date().toISOString()}}async runWebhookAsync(t,e,a){await this.acquireWebhookSlot();try{const n=await w(t,e,this.deps.fetchImpl);this.deps.dispatches.updateStatus(a,{status:n.status,output:n.output??null,error:n.error??null,finished:!0}),this.deps.bus.emit({kind:"dispatch.finished",ruleId:t.id,dispatchId:a,status:n.status,sessionId:e.sessionId,at:new Date().toISOString()})}catch(n){this.deps.dispatches.updateStatus(a,{status:"failed",error:String(n),finished:!0}),this.deps.bus.emit({kind:"dispatch.finished",ruleId:t.id,dispatchId:a,status:"failed",sessionId:e.sessionId,at:new Date().toISOString()})}finally{this.runningWebhooks.delete(t.id),this.releaseWebhookSlot()}}acquireWebhookSlot(){return this.activeWebhooks<N?(this.activeWebhooks++,Promise.resolve()):new Promise(t=>{this.pendingWebhooks.push(()=>{this.activeWebhooks++,t()})})}releaseWebhookSlot(){this.activeWebhooks--;const t=this.pendingWebhooks.shift();t&&t()}acquirePluginSlot(){return this.activePlugins<O?(this.activePlugins++,Promise.resolve()):new Promise(t=>{this.pendingPlugins.push(()=>{this.activePlugins++,t()})})}releasePluginSlot(){this.activePlugins--;const t=this.pendingPlugins.shift();t&&t()}trimDedupe(t){if(!(this.recentPool.size<1e3))for(const[e,a]of this.recentPool)t-a>=m&&this.recentPool.delete(e)}}function H(g){const t=g.raw;if(typeof t!="object"||t===null)return null;const e=t.session_title;return typeof e=="string"&&e.length>0?e:null}
7
+ `)),t}catch{return{}}}createDispatch(e,t,r){const n=this.deps.dispatches.insert({ruleId:e.id,eventId:t.eventId,sessionId:t.sessionId,...r});return this.deps.bus.emit({kind:"dispatch.created",ruleId:e.id,dispatchId:n.id,status:r.status,mode:n.mode,sessionId:t.sessionId,at:n.startedAt}),n}dedupe(e,t,r){const n=`${e.id}:${t.sessionId??""}`,i=this.recentPool.get(n);return i!==void 0&&r-i<g?!0:(this.recentPool.set(n,r),this.trimDedupe(r),!1)}match(e){const t=this.deps.pluginStates,r=t?v(e.project.meta).enabled:null;let n=null;return this.deps.registry.candidates(e.payload.eventType,t?{includeDisabled:!0}:void 0).filter(i=>{const a=P(i.source);if(a!==null&&a!=="any"&&a!==e.source||i.projectId!==null&&i.projectId!==e.project.id)return!1;if(i.pluginId!==null){if(!i.enabled&&r?.[i.pluginId]!==!0||t&&!k(e.project,i.pluginId,{states:t}))return!1}else if(!i.enabled)return!1;const d=i.filter;if(d.toolNames?.length&&(!e.payload.toolName||!d.toolNames.includes(e.payload.toolName)))return!1;if(d.pathGlobs?.length){const s=h(e.payload.toolInput);if(!s||!T(s,d.pathGlobs))return!1}if(d.crossProjectOnly){const s=h(e.payload.toolInput)??e.payload.cwd;if(!s||(n??=this.deps.projects.list().map(o=>o.path).filter(o=>o!==e.project.path),!j(s,e.project.path,n)))return!1}return!0})}injectable(e){const t=e.payload.eventType;return t!==null&&I[e.source].includes(t)}async runPluginHandler(e,t,r,n,i){if(e.handler.type!=="plugin")return;const{pluginId:a}=e.handler,d=b(a),s=i===void 0?e.timeoutMs:Math.min(e.timeoutMs,i);let o;try{const l=(async()=>{await this.acquirePluginSlot();try{return await n.execute({event:t.payload,rule:e,config:r.getConfig(a),logger:d})}finally{this.releasePluginSlot()}})(),u=await Promise.race([l,new Promise((p,m)=>{o=setTimeout(()=>m(new Error("plugin handler timeout")),s)})]);return u&&typeof u=="object"?u:void 0}catch{return}finally{o&&clearTimeout(o)}}async runPluginDetached(e,t,r,n){try{const i=await this.runPluginHandler(e,t,r,n);if(!i?.prompt)return;this.createDispatch(e,t,{prompt:i.prompt+`
8
+ ${c}`,status:"pending",mode:"auto"})}catch{}}summary(e,t){return{ruleId:e.id,ruleName:e.name,projectId:t.project.id,sessionId:t.sessionId,event:t.payload.eventType,toolName:t.payload.toolName,filePath:h(t.payload.toolInput),cwd:t.payload.cwd,at:new Date().toISOString()}}async runWebhookAsync(e,t,r){await this.acquireWebhookSlot();try{const n=await w(e,t,this.deps.fetchImpl);this.deps.dispatches.updateStatus(r,{status:n.status,output:n.output??null,error:n.error??null,finished:!0}),this.deps.bus.emit({kind:"dispatch.finished",ruleId:e.id,dispatchId:r,status:n.status,sessionId:t.sessionId,at:new Date().toISOString()})}catch(n){this.deps.dispatches.updateStatus(r,{status:"failed",error:String(n),finished:!0}),this.deps.bus.emit({kind:"dispatch.finished",ruleId:e.id,dispatchId:r,status:"failed",sessionId:t.sessionId,at:new Date().toISOString()})}finally{this.runningWebhooks.delete(e.id),this.releaseWebhookSlot()}}acquireWebhookSlot(){return this.activeWebhooks<N?(this.activeWebhooks++,Promise.resolve()):new Promise(e=>{this.pendingWebhooks.push(()=>{this.activeWebhooks++,e()})})}releaseWebhookSlot(){this.activeWebhooks--;const e=this.pendingWebhooks.shift();e&&e()}acquirePluginSlot(){return this.activePlugins<_?(this.activePlugins++,Promise.resolve()):new Promise(e=>{this.pendingPlugins.push(()=>{this.activePlugins++,e()})})}releasePluginSlot(){this.activePlugins--;const e=this.pendingPlugins.shift();e&&e()}trimDedupe(e){if(!(this.recentPool.size<1e3))for(const[t,r]of this.recentPool)e-r>=g&&this.recentPool.delete(t)}}function C(f){const e=f.raw;if(typeof e!="object"||e===null)return null;const t=e.session_title;return typeof t=="string"&&t.length>0?t:null}
@@ -1 +1 @@
1
- import{createHmac as l}from"node:crypto";const u=5e3,d=4096;export async function runWebhook(a,i,c=fetch){const e=a.handler;if(e.type!=="webhook")return{ok:!1,status:"failed",error:`rule ${a.id} is not a webhook handler`};let r;try{r=new URL(e.url)}catch{return{ok:!1,status:"failed",error:`invalid url: ${e.url}`}}if(r.protocol!=="http:"&&r.protocol!=="https:")return{ok:!1,status:"failed",error:`unsupported protocol: ${r.protocol}`};const s=JSON.stringify(i),n={"content-type":"application/json","user-agent":"weave-daemon",...e.headers??{}};e.secret&&(n["x-weave-signature"]=`sha256=${l("sha256",e.secret).update(s).digest("hex")}`);try{const t=await c(r,{method:"POST",headers:n,body:s,signal:AbortSignal.timeout(u)}),o=(await t.text()).slice(0,d);return t.ok?{ok:!0,status:"succeeded",output:o||`HTTP ${t.status}`}:{ok:!1,status:"failed",error:`HTTP ${t.status}`,output:o}}catch(t){const o=t instanceof Error&&(t.name==="TimeoutError"||t.name==="AbortError");return{ok:!1,status:o?"timeout":"failed",error:o?`webhook timed out after ${u}ms`:String(t)}}}
1
+ import{createHmac as l}from"node:crypto";const u=5e3,d=4096;export async function runWebhook(s,i,c=fetch){const e=s.handler;if(e.type!=="webhook")return{ok:!1,status:"failed",error:`rule ${s.id} is not a webhook handler`};let r;try{r=new URL(e.url)}catch{return{ok:!1,status:"failed",error:`invalid url: ${e.url}`}}if(r.protocol!=="http:"&&r.protocol!=="https:")return{ok:!1,status:"failed",error:`unsupported protocol: ${r.protocol}`};const a=JSON.stringify(i),n={"content-type":"application/json","user-agent":"weave-daemon",...e.headers??{}};e.secret&&(n["x-weave-signature"]=`sha256=${l("sha256",e.secret).update(a).digest("hex")}`);try{const t=await c(r,{method:"POST",headers:n,body:a,signal:AbortSignal.timeout(u)}),o=(await t.text()).slice(0,d);return t.ok?{ok:!0,status:"succeeded",output:o||`HTTP ${t.status}`}:{ok:!1,status:"failed",error:`HTTP ${t.status}`,output:o}}catch(t){const o=t instanceof Error&&(t.name==="TimeoutError"||t.name==="AbortError");return{ok:!1,status:o?"timeout":"failed",error:o?`webhook timed out after ${u}ms`:String(t)}}}
@@ -1,2 +1,2 @@
1
- import{spawn as k}from"node:child_process";const L=3e5,y=32*1024,E=2e3;export class HeadlessRunner{spawnImpl;killImpl;active=new Set;livePids=new Map;constructor(t={}){this.spawnImpl=t.spawnImpl??k,this.killImpl=t.killImpl??defaultKill}isBusy(t){return this.active.has(t)}killAll(){let t=0;for(const s of this.livePids.values())try{this.killImpl(s),t++}catch{}return this.livePids.clear(),t}run(t){if(this.active.has(t.sessionId))return!1;this.active.add(t.sessionId);const s={settled:!1};try{this.watch(t,s)}catch(n){this.settle(t,s,{status:"failed",output:null,error:P(n)})}return!0}watch(t,s){const n=t.timeoutMs??L,a=t.spec.promptStdin===!0,f=t.spec.args(t.sessionId,a?"":t.prompt),d=a&&process.platform==="win32"&&!/[\s"\\/]/.test(t.bin),T=(t.detached??!0)&&!d,m={cwd:t.cwd,detached:T,windowsHide:!0,shell:d,stdio:[a?"pipe":"ignore","pipe","pipe"],env:(()=>{const e={...process.env,WEAVE_HOOK_DISPATCH:"1"};return delete e.CLAUDE_CODE_CHILD_SESSION,e})()},i=d?this.spawnImpl([t.bin,...f].join(" "),[],m):this.spawnImpl(t.bin,f,m);if(i.pid!==void 0&&this.livePids.set(t.sessionId,i.pid),a){i.stdin?.on("error",()=>{});try{i.stdin?.write(t.prompt),i.stdin?.end()}catch{}}const I=[],p=[];let w=0,v=0;const S=(e,o,l)=>{if(o>=y)return o;const c=y-o;return e.push(l.length>c?l.subarray(0,c):l),o+Math.min(l.length,c)},h=()=>Buffer.concat([...I,...p]).toString("utf8"),H=()=>{const e=Buffer.concat(p).toString("utf8");return e.length>E?e.slice(-E):e};i.stdout?.on("data",e=>{w=S(I,w,e)}),i.stderr?.on("data",e=>{v=S(p,v,e)});const u=n>0?setTimeout(()=>{if(i.pid!==void 0)try{this.killImpl(i.pid)}catch{}this.settle(t,s,{status:"timeout",output:h(),error:`Timeout after ${n}ms`})},n):null;i.on("error",e=>{u!==null&&clearTimeout(u),this.settle(t,s,{status:"failed",output:h(),error:P(e)})}),i.on("exit",(e,o)=>{u!==null&&clearTimeout(u);const l=h();if(e===0){this.settle(t,s,{status:"succeeded",output:l,error:null});return}const c=e!==null?`exit ${e}`:`exit signal ${o??"unknown"}`,g=H();this.settle(t,s,{status:"failed",output:l,error:g?`${c}
2
- ${g}`:c})})}settle(t,s,n){if(!s.settled){s.settled=!0,this.active.delete(t.sessionId),this.livePids.delete(t.sessionId);try{t.onSettle(n)}catch{}}}}export function defaultKill(r){if(process.platform==="win32"){try{k("taskkill",["/PID",String(r),"/T","/F"],{windowsHide:!0,stdio:"ignore"}).on("error",()=>{})}catch{}return}try{process.kill(-r,"SIGKILL")}catch{try{process.kill(r,"SIGKILL")}catch{}}}function P(r){return r instanceof Error?r.message:String(r)}
1
+ import{spawn as k}from"node:child_process";const A=3e5,T=32*1024,_=2e3;export class HeadlessRunner{spawnImpl;killImpl;active=new Set;livePids=new Map;constructor(t={}){this.spawnImpl=t.spawnImpl??k,this.killImpl=t.killImpl??defaultKill}isBusy(t){return this.active.has(t)}killAll(){let t=0;for(const s of this.livePids.values())try{this.killImpl(s),t++}catch{}return this.livePids.clear(),t}run(t){if(this.active.has(t.sessionId))return!1;this.active.add(t.sessionId);const s={settled:!1};try{this.watch(t,s)}catch(l){this.settle(t,s,{status:"failed",output:null,error:y(l)})}return!0}watch(t,s){const l=t.timeoutMs??A,a=t.spec.promptStdin===!0,p=t.spec.args(t.sessionId,a?"":t.prompt),u=a&&process.platform==="win32"&&!/[\s"\\/]/.test(t.bin),E=(t.detached??!0)&&!u,m={cwd:t.cwd,detached:E,windowsHide:!0,shell:u,stdio:[a?"pipe":"ignore","pipe","pipe"],env:(()=>{const e={...process.env,WEAVE_HOOK_DISPATCH:"1"};return delete e.CLAUDE_CODE_CHILD_SESSION,e})()},r=u?this.spawnImpl([t.bin,...p].join(" "),[],m):this.spawnImpl(t.bin,p,m);if(r.pid!==void 0&&this.livePids.set(t.sessionId,r.pid),a){r.stdin?.on("error",()=>{});try{r.stdin?.write(t.prompt),r.stdin?.end()}catch{}}const I=[],h=[];let w=0,S=0;const v=(e,n,o)=>{if(n>=T)return n;const c=T-n;return e.push(o.length>c?o.subarray(0,c):o),n+Math.min(o.length,c)},f=()=>Buffer.concat([...I,...h]).toString("utf8"),M=()=>{const e=Buffer.concat(h).toString("utf8");return e.length>_?e.slice(-_):e};r.stdout?.on("data",e=>{w=v(I,w,e)}),r.stderr?.on("data",e=>{S=v(h,S,e)});const d=l>0?setTimeout(()=>{if(r.pid!==void 0)try{this.killImpl(r.pid)}catch{}this.settle(t,s,{status:"timeout",output:f(),error:`Timeout after ${l}ms`})},l):null;r.on("error",e=>{d!==null&&clearTimeout(d),this.settle(t,s,{status:"failed",output:f(),error:y(e)})}),r.on("exit",(e,n)=>{d!==null&&clearTimeout(d);const o=f();if(e===0){this.settle(t,s,{status:"succeeded",output:o,error:null});return}const c=e!==null?`exit ${e}`:`exit signal ${n??"unknown"}`,g=M();this.settle(t,s,{status:"failed",output:o,error:g?`${c}
2
+ ${g}`:c})})}settle(t,s,l){if(!s.settled){s.settled=!0,this.active.delete(t.sessionId),this.livePids.delete(t.sessionId);try{t.onSettle(l)}catch{}}}}export function defaultKill(i){if(process.platform==="win32"){try{k("taskkill",["/PID",String(i),"/T","/F"],{windowsHide:!0,stdio:"ignore"}).on("error",()=>{})}catch{}return}try{process.kill(-i,"SIGKILL")}catch{try{process.kill(i,"SIGKILL")}catch{}}}function y(i){return i instanceof Error?i.message:String(i)}
@@ -24,16 +24,29 @@ export interface InboxDeliveryOptions {
24
24
  /** `/status` 的 Peer address 带 `uds:` 前缀;env 里不带。两种都接受。 */
25
25
  export declare function inboxSocketPathOf(socket: string): string;
26
26
  export declare function deliverViaInboxSocket(spec: PromptInboxSpec, target: InboxTarget, text: string, options?: InboxDeliveryOptions): Promise<void>;
27
+ /** 直投凭据落盘文件名(放 `<dataDir>/hooks/` 下;装配侧拼路径用同一常量)。 */
28
+ export declare const INBOX_TARGETS_FILE = "inbox-targets.json";
27
29
  /**
28
- * sessionId → 该会话的 inbox 目标(内存态,**凭据不落库、不进 UI、不写日志**):
29
- * 由 hook 事件旁路上报(hook 进程是会话自己的 child,继承会话导出的 env)。
30
- * 凭据**每会话进程一份**(resume 后 socket 名重生成、旧值即废),所以不持久化;
31
- * 会话删除/归档时 forget。
30
+ * sessionId → 该会话的 inbox 目标:由 hook 事件旁路上报(hook 进程是会话自己的 child,
31
+ * 继承会话导出的 env),并落 `<dataDir>/hooks/inbox-targets.json`(0600,与 auth.json
32
+ * 同口径的非 UI 面)。**凭据不进 payload、不落库、不进 UI、不写日志**。
33
+ *
34
+ * 为什么要落盘:凭据活在**会话进程**里(socket 由它托管、token 每进程一份),daemon
35
+ * 重启不动它们——只落 daemon 自己的记忆。于是「重启后首条手动消息只能走终端/中继」
36
+ * 这个窗口消失(原先要等下一次 hook 事件把凭据带回来)。会话自己 resume/重启换了
37
+ * socket(旧值即废)时,覆盖前那一刻只会**连不上 → 回落**,不猜不误投;新值随下一次
38
+ * hook 事件覆盖写回。会话删除/归档时 forget(落盘行一并清)。
32
39
  */
33
40
  export declare class InboxSocketRegistry {
41
+ private readonly file?;
34
42
  private readonly bySession;
43
+ /** 上次落盘的内容(hook 每次事件都上报,值没变就不重写盘)。 */
44
+ private persisted;
45
+ constructor(file?: string | undefined);
35
46
  /** 上报/刷新(hook 每次事件都会带,覆盖写即最新)。socket 为空 = 该会话没有可用 inbox。 */
36
47
  set(sessionId: string, target: InboxTarget | null): void;
37
48
  get(sessionId: string): InboxTarget | undefined;
38
49
  forget(sessionId: string): void;
50
+ /** 原子写(临时文件 + rename)+ 0600(Windows 上 chmod 近似 no-op,无害)。 */
51
+ private persist;
39
52
  }
@@ -1 +1,2 @@
1
- import k from"node:net";export function inboxSocketPathOf(o){return o.startsWith("uds:")?o.slice(4):o}export function deliverViaInboxSocket(o,e,r,c={}){const u=c.platform??process.platform,m=c.timeoutMs??3e3,l=inboxSocketPathOf(e.socket);return o.requiresAuthOn(u)&&!e.token?Promise.reject(new Error(`inbox delivery requires a token on platform "${u}"`)):new Promise((a,b)=>{const f=o.frame({token:e.token,text:r});let n=!1;const i=s=>{n||(n=!0,t.destroy(),b(s))},t=k.connect(l);t.setTimeout(m),t.on("timeout",()=>i(new Error(`inbox socket timeout after ${m}ms`))),t.on("error",s=>i(s)),t.on("connect",()=>{t.write(f,s=>{s?i(s):t.end()})}),t.on("close",()=>{n||(n=!0,a())})})}export class InboxSocketRegistry{bySession=new Map;set(e,r){r?.socket?this.bySession.set(e,r):this.bySession.delete(e)}get(e){return this.bySession.get(e)}forget(e){this.bySession.delete(e)}}
1
+ import a from"node:net";import{chmodSync as y,mkdirSync as d,readFileSync as k,renameSync as S,writeFileSync as b}from"node:fs";import{dirname as x}from"node:path";export function inboxSocketPathOf(s){return s.startsWith("uds:")?s.slice(4):s}export function deliverViaInboxSocket(s,t,e,o={}){const c=o.platform??process.platform,n=o.timeoutMs??3e3,l=inboxSocketPathOf(t.socket);return s.requiresAuthOn(c)&&!t.token?Promise.reject(new Error(`inbox delivery requires a token on platform "${c}"`)):new Promise((p,m)=>{const h=s.frame({token:t.token,text:e});let f=!1;const u=i=>{f||(f=!0,r.destroy(),m(i))},r=a.connect(l);r.setTimeout(n),r.on("timeout",()=>u(new Error(`inbox socket timeout after ${n}ms`))),r.on("error",i=>u(i)),r.on("connect",()=>{r.write(h,i=>{i?u(i):r.end()})}),r.on("close",()=>{f||(f=!0,p())})})}export const INBOX_TARGETS_FILE="inbox-targets.json";function O(s){try{const t=JSON.parse(k(s,"utf8"));if(typeof t!="object"||t===null)return{};const e={};for(const[o,c]of Object.entries(t)){const n=c;typeof n?.socket!="string"||!n.socket||(e[o]={socket:n.socket,token:typeof n.token=="string"&&n.token?n.token:null})}return e}catch{return{}}}export class InboxSocketRegistry{file;bySession;persisted;constructor(t){this.file=t;const e=t?O(t):{};this.bySession=new Map(Object.entries(e)),this.persisted=JSON.stringify(e)}set(t,e){const o=this.bySession.get(t);if(!e?.socket){o&&(this.bySession.delete(t),this.persist());return}o&&o.socket===e.socket&&o.token===e.token||(this.bySession.set(t,e),this.persist())}get(t){return this.bySession.get(t)}forget(t){this.bySession.delete(t)&&this.persist()}persist(){if(!this.file)return;const t=JSON.stringify(Object.fromEntries(this.bySession));if(t!==this.persisted)try{d(x(this.file),{recursive:!0});const e=`${this.file}.tmp`;b(e,`${t}
2
+ `,{encoding:"utf8",mode:384}),S(e,this.file),y(this.file,384),this.persisted=t}catch{}}}
@@ -9,6 +9,7 @@ import type { WatchEngine } from './watch-engine.js';
9
9
  import type { SequenceEngine } from './sequence-engine.js';
10
10
  import type { MessageDeliverer } from './message-deliverer.js';
11
11
  import type { QuestionTracker } from './question-tracker.js';
12
+ import type { SideQuestionEvent } from './side-questions.js';
12
13
  /**
13
14
  * inbox 消费线程(hook 文件化管道的 daemon 侧):hook-handler.cjs 把事件追加到
14
15
  * `<dataDir>/hooks/inbox/<shard>.jsonl`(行形 `{v, token, report}`,纯传输缓冲、
@@ -20,6 +21,11 @@ import type { QuestionTracker } from './question-tracker.js';
20
21
  * 为 `.failed.jsonl` 防毒丸热循环。行内 token 解析项目(项目已删 → 丢行,同
21
22
  * 旧 /hooks 401 语义;归档项目同样丢行——server 不消费,行即焚);不可归因
22
23
  * 的坏行直接丢(重试无意义)。
24
+ *
25
+ * **shard 按项目 token 分片**(hook-handler 认 token 不认会话)⇒ 同一 claim 里
26
+ * 常混着**同项目多个会话**的行。故凡会话级事实(inbox 凭据、pane env、改名回执)
27
+ * 一律**逐行**取,不得按组聚合——取整组最后一个会把 A 会话的 socket 记到 B 头上,
28
+ * 而直投照这个映射送,消息就落进别的会话(实事故,见 docs/DECISIONS.md)。
23
29
  */
24
30
  export declare const INBOX_TICK_MS = 200;
25
31
  export declare const INBOX_CLAIM_SUFFIX = ".claim.jsonl";
@@ -33,7 +39,8 @@ export interface InboxRecord {
33
39
  deliveredTitle?: string | null;
34
40
  /**
35
41
  * 该会话的 inbox 直投凭据(hook 进程是会话自己的 child,继承这两个 env)。
36
- * **旁路字段:不进 payload、不落库**——主线程只放内存供 layer① 直投用。
42
+ * **逐行字段**(同 claim 里各会话的 socket 不同);**旁路字段:不进 payload、
43
+ * 不落库**——主线程只放内存供 layer① 直投用。
37
44
  */
38
45
  messaging?: {
39
46
  socket: string;
@@ -41,8 +48,8 @@ export interface InboxRecord {
41
48
  } | null;
42
49
  /**
43
50
  * 该会话所在终端 pane 的定位 env(hook 进程生在会话自己的 pane 里)。
44
- * **逐行字段**(同一 claim 里不同会话的 pane 不同,不能像 messaging 那样取整组
45
- * 最后一个——错配会把键序打进别的会话的模态框);同样不进 payload、不落库。
51
+ * **逐行字段**(同一 claim 里不同会话的 pane 不同——错配会把键序打进别的会话
52
+ * 的模态框);同样不进 payload、不落库。
46
53
  */
47
54
  terminalEnv?: Record<string, string> | null;
48
55
  }
@@ -85,14 +92,28 @@ export interface IngestedHandlerDeps {
85
92
  } | null): void;
86
93
  /** hook 旁路上报的会话 pane 定位 env(内存态;层② 精确定位用)。 */
87
94
  notePaneEnv?(sessionId: string, env: Record<string, string>): void;
88
- /** UPS 事件 = 投递回执判据(prompt 原文与在途条目匹配)。 */
89
- onSessionPrompt?(sessionId: string, prompt: string): void;
95
+ /** UPS 事件 = 投递回执判据(prompt 原文与在途条目匹配);返回命中消息的随附图 id。
96
+ * `eventId` 随回执记下(对话面按它把投递行挂到这条事件的气泡上)。 */
97
+ onSessionPrompt?(sessionId: string, prompt: string, eventId?: number): string[];
98
+ /** 会话退出事件(`HARNESS_LIFECYCLE[<harness>].sessionExit`)= 旁路事实作废点。 */
99
+ sessionExited?(sessionId: string): void;
90
100
  };
91
101
  /** 阻塞式问答跟踪(toolName 不进帧域,挂点在此);缺省不跟踪。 */
92
102
  questionTracker?: Pick<QuestionTracker, 'onEvent'>;
93
- /** 会话转录路径上报(中断态探测用;转录路径在 payload 里,帧域不带)。 */
103
+ /** 旁路会话回答认领(claude = `/btw`):判据归 harness 能力面;缺省不认领。 */
104
+ sideQuestions?: {
105
+ onEvent(input: SideQuestionEvent): void;
106
+ };
107
+ /** 会话转录路径上报(中断态探测用;转录路径在 payload 里,帧域不带)+ 换模型落定 + 推理档位。 */
94
108
  sessionProbe?: {
95
109
  noteTranscript(sessionId: string, path: string | null): void;
110
+ noteModel(sessionId: string, model: string): void;
111
+ sessionStarted(sessionId: string, model: string | null): void;
112
+ noteEffort(sessionId: string, level: string): void;
113
+ };
114
+ /** 上传件落库面:回执命中时把该消息的随附图挂到开轮事件上(气泡缩略图)。 */
115
+ uploads?: {
116
+ linkToEvent(eventId: number, uploadIds: readonly string[]): void;
96
117
  };
97
118
  }
98
119
  /**
@@ -1,4 +1,4 @@
1
- import{existsSync as h,readdirSync as g,readFileSync as k,renameSync as f,unlinkSync as j,writeFileSync as S}from"node:fs";import{join as u}from"node:path";import{isMainThread as b,parentPort as T,Worker as w,workerData as I}from"node:worker_threads";import{createRuntimeRegistry as x,frameFacts as E}from"@weavecode/harness";import{openDatabase as P}from"../db/db.js";import{HookEventRepository as M}from"../repositories/hook-events.js";import{ProjectRepository as O}from"../repositories/projects.js";import{SessionRepository as W}from"../repositories/sessions.js";import{appendOutbox as D}from"./mirror.js";export const INBOX_TICK_MS=200,INBOX_CLAIM_SUFFIX=".claim.jsonl",INBOX_FAILED_SUFFIX=".failed.jsonl";const F=5;export function drainInboxOnce(t,n=new Map){const e=u(t.hooksDir,"inbox");let o;try{o=g(e)}catch{return[]}const i=[];for(const p of o)p.endsWith(INBOX_FAILED_SUFFIX)||p.endsWith(".tmp")||p.endsWith(INBOX_CLAIM_SUFFIX)||p.endsWith(".jsonl")&&i.push(p);const s=[];for(const p of o)p.endsWith(INBOX_CLAIM_SUFFIX)&&s.push(...y(t,u(e,p),n));for(const p of i){const l=u(e,`${p.slice(0,-6)}${INBOX_CLAIM_SUFFIX}`);if(!h(l)){try{f(u(e,p),l)}catch{continue}s.push(...y(t,l,n))}}return s}function y(t,n,e){let o;try{o=k(n,"utf8").split(`
2
- `)}catch{return[]}const i=new Map;for(const c of o){const d=c.trim();if(!d)continue;const r=_(d);if(!r)continue;const a=i.get(r.token)??{lines:[],inputs:[],delivered:[],terminals:[],messaging:null};if(r.messaging&&(a.messaging=r.messaging),a.lines.push(d),a.project||(a.project=t.projects.getByToken(r.token),i.set(r.token,a)),!a.project||a.project.archivedAt)continue;const m=r.report&&typeof r.report=="object"?t.adapters.find(v=>v.source===r.report.source):void 0;if(!(!m||!r.report.eventType))try{a.inputs.push(m.normalize(r.report,a.project.id)),a.delivered.push(r.report.deliveredTitle??null),a.terminals.push(r.terminalEnv)}catch{}}const s=[],p=[];for(const c of i.values())if(!(!c.project||c.inputs.length===0))try{const d=R(t,c.project,c.inputs);for(let r=0;r<c.inputs.length;r++)s.push({eventId:d[r],projectId:c.project.id,input:c.inputs[r],deliveredTitle:c.delivered[r]??null,messaging:c.messaging,terminalEnv:c.terminals[r]??null})}catch{p.push(...c.lines)}if(p.length===0){e.delete(n);try{j(n)}catch{}return s}const l=(e.get(n)??0)+1;if(e.set(n,l),l>=F){e.delete(n);try{f(n,n.replace(INBOX_CLAIM_SUFFIX,INBOX_FAILED_SUFFIX))}catch{}return s}try{S(n,p.join(`
1
+ import{existsSync as I,readdirSync as m,readFileSync as k,renameSync as f,unlinkSync as T,writeFileSync as b}from"node:fs";import{join as d}from"node:path";import{isMainThread as j,parentPort as x,Worker as E,workerData as g}from"node:worker_threads";import{createRuntimeRegistry as S,effortLevelOf as w,frameFacts as M,startedModelOf as O,switchedModelOf as P}from"@weavecode/harness";import{HARNESS_LIFECYCLE as F,isHarness as W}from"@weavecode/core";import{openDatabase as D}from"../db/db.js";import{HookEventRepository as L}from"../repositories/hook-events.js";import{ProjectRepository as R}from"../repositories/projects.js";import{SessionRepository as _}from"../repositories/sessions.js";import{appendOutbox as A}from"./mirror.js";export const INBOX_TICK_MS=200,INBOX_CLAIM_SUFFIX=".claim.jsonl",INBOX_FAILED_SUFFIX=".failed.jsonl";const C=5;export function drainInboxOnce(n,t=new Map){const e=d(n.hooksDir,"inbox");let i;try{i=m(e)}catch{return[]}const s=[];for(const c of i)c.endsWith(INBOX_FAILED_SUFFIX)||c.endsWith(".tmp")||c.endsWith(INBOX_CLAIM_SUFFIX)||c.endsWith(".jsonl")&&s.push(c);const o=[];for(const c of i)c.endsWith(INBOX_CLAIM_SUFFIX)&&o.push(...h(n,d(e,c),t));for(const c of s){const l=d(e,`${c.slice(0,-6)}${INBOX_CLAIM_SUFFIX}`);if(!I(l)){try{f(d(e,c),l)}catch{continue}o.push(...h(n,l,t))}}return o}function h(n,t,e){let i;try{i=k(t,"utf8").split(`
2
+ `)}catch{return[]}const s=new Map;for(const u of i){const a=u.trim();if(!a)continue;const r=B(a);if(!r)continue;const p=s.get(r.token)??{lines:[],inputs:[],delivered:[],terminals:[],messaging:[]};if(p.lines.push(a),p.project||(p.project=n.projects.getByToken(r.token),s.set(r.token,p)),!p.project||p.project.archivedAt)continue;const v=r.report&&typeof r.report=="object"?n.adapters.find(y=>y.source===r.report.source):void 0;if(!(!v||!r.report.eventType))try{p.inputs.push(v.normalize(r.report,p.project.id)),p.delivered.push(r.report.deliveredTitle??null),p.terminals.push(r.terminalEnv),p.messaging.push(r.messaging)}catch{}}const o=[],c=[];for(const u of s.values())if(!(!u.project||u.inputs.length===0))try{const a=N(n,u.project,u.inputs);for(let r=0;r<u.inputs.length;r++)o.push({eventId:a[r],projectId:u.project.id,input:u.inputs[r],deliveredTitle:u.delivered[r]??null,messaging:u.messaging[r]??null,terminalEnv:u.terminals[r]??null})}catch{c.push(...u.lines)}if(c.length===0){e.delete(t);try{T(t)}catch{}return o}const l=(e.get(t)??0)+1;if(e.set(t,l),l>=C){e.delete(t);try{f(t,t.replace(INBOX_CLAIM_SUFFIX,INBOX_FAILED_SUFFIX))}catch{}return o}try{b(t,c.join(`
3
3
  `)+`
4
- `)}catch{}return s}function R(t,n,e){const o=t.hookEvents.insertMany(e),i=new Set;for(const s of e)s.sessionId&&!i.has(s.sessionId)&&(i.add(s.sessionId),B(t.hookSessions,s.sessionId,e)&&t.hookSessions.touch(s.sessionId,n.id));return o}function B(t,n,e){return t.getBySessionId(n)?!0:e.some(o=>o.sessionId===n&&o.eventType!=="SessionStart")}function _(t){try{const n=JSON.parse(t);if(!n||typeof n.token!="string"||!n.token||!n.report||typeof n.report!="object")return null;const e=n.messaging?.socket,o=typeof e=="string"&&e?{socket:e,token:typeof n.messaging?.token=="string"?n.messaging.token:null}:null;return{token:n.token,report:n.report,messaging:o,terminalEnv:N(n.terminal)}}catch{return null}}function N(t){if(typeof t!="object"||t===null)return null;const n={};for(const[e,o]of Object.entries(t))typeof o=="string"&&o&&(n[e]=o);return Object.keys(n).length>0?n:null}export function unparkFailedInbox(t){const n=u(t,"inbox");let e;try{e=g(n)}catch{return 0}let o=0;for(const i of e){if(!i.endsWith(INBOX_FAILED_SUFFIX))continue;const s=u(n,`${i.slice(0,-INBOX_FAILED_SUFFIX.length)}${INBOX_CLAIM_SUFFIX}`);if(!h(s))try{f(u(n,i),s),o++}catch{}}return o}export function handleIngestedRecords(t,n){for(const e of n){const o=t.projects.getById(e.projectId);if(!o)continue;let i=null;try{i=JSON.parse(e.input.payload)}catch{i=null}if(t.bus?.emit({kind:"event.ingested",eventId:e.eventId,projectId:o.id,sessionId:e.input.sessionId??null,eventType:e.input.eventType,...E(i),at:new Date().toISOString()}),e.input.sessionId){if(t.questionTracker?.onEvent({sessionId:e.input.sessionId,source:e.input.source,payload:i}),t.watchEngine?.onEvent({sessionId:e.input.sessionId,eventType:e.input.eventType,source:e.input.source}),t.sequenceEngine?.onEvent({sessionId:e.input.sessionId,eventType:e.input.eventType,source:e.input.source}),e.messaging&&t.messagePipe?.noteInboxSocket?.(e.input.sessionId,e.messaging),t.sessionProbe?.noteTranscript(e.input.sessionId,i?.transcriptPath??null),e.terminalEnv&&t.messagePipe?.notePaneEnv?.(e.input.sessionId,e.terminalEnv),e.input.eventType==="UserPromptSubmit"){const s=X(i);s&&t.messagePipe?.onSessionPrompt?.(e.input.sessionId,s)}t.messagePipe?.hasQueued(e.input.sessionId)&&t.messagePipe.flushSession(e.input.sessionId)}t.dispatcher&&t.dispatcher.onIngest({eventId:e.eventId,project:o,sessionId:e.input.sessionId??null,payload:i??{eventType:e.input.eventType,toolName:null,toolInput:null,toolResponse:null,cwd:null,transcriptPath:null,raw:null},source:e.input.source,deliveredTitle:e.deliveredTitle??null}).then(s=>{s.deferred&&e.input.sessionId&&D(t.hooksDir,o.token,[{sessionId:e.input.sessionId,text:s.deferred}])}).catch(()=>{})}}function X(t){const n=t?.raw;return typeof n?.prompt=="string"&&n.prompt?n.prompt:null}export function startInboxWorker(t){return new w(new URL(import.meta.url),{workerData:{inboxWorker:!0,...t}})}if(!b&&I?.inboxWorker===!0){const t=I,n=P(t.dbPath),e={hooksDir:t.hooksDir,projects:new O(n),hookEvents:new M(n),hookSessions:new W(n),adapters:x().byCapability("events").flatMap(s=>s.events??[])},o=new Map,i=()=>{try{const s=drainInboxOnce(e,o);s.length>0&&T?.postMessage(s)}catch(s){console.error("[weave] inbox drain failed:",s)}};i(),setInterval(i,t.tickMs??INBOX_TICK_MS)}
4
+ `)}catch{}return o}function N(n,t,e){const i=n.hookEvents.insertMany(e),s=new Set;for(const o of e)!o.sessionId||s.has(o.sessionId)||(s.add(o.sessionId),n.hookSessions.touch(o.sessionId,t.id));return i}function B(n){try{const t=JSON.parse(n);if(!t||typeof t.token!="string"||!t.token||!t.report||typeof t.report!="object")return null;const e=t.messaging?.socket,i=typeof e=="string"&&e?{socket:e,token:typeof t.messaging?.token=="string"?t.messaging.token:null}:null;return{token:t.token,report:t.report,messaging:i,terminalEnv:X(t.terminal)}}catch{return null}}function X(n){if(typeof n!="object"||n===null)return null;const t={};for(const[e,i]of Object.entries(n))typeof i=="string"&&i&&(t[e]=i);return Object.keys(t).length>0?t:null}export function unparkFailedInbox(n){const t=d(n,"inbox");let e;try{e=m(t)}catch{return 0}let i=0;for(const s of e){if(!s.endsWith(INBOX_FAILED_SUFFIX))continue;const o=d(t,`${s.slice(0,-INBOX_FAILED_SUFFIX.length)}${INBOX_CLAIM_SUFFIX}`);if(!I(o))try{f(d(t,s),o),i++}catch{}}return i}export function handleIngestedRecords(n,t){for(const e of t){const i=n.projects.getById(e.projectId);if(!i)continue;let s=null;try{s=JSON.parse(e.input.payload)}catch{s=null}if(n.bus?.emit({kind:"event.ingested",eventId:e.eventId,projectId:i.id,sessionId:e.input.sessionId??null,eventType:e.input.eventType,...M(s),at:new Date().toISOString()}),e.input.sessionId){n.questionTracker?.onEvent({sessionId:e.input.sessionId,source:e.input.source,payload:s}),n.sideQuestions?.onEvent({sessionId:e.input.sessionId,source:e.input.source,eventType:e.input.eventType,payload:s,eventId:e.eventId}),n.watchEngine?.onEvent({sessionId:e.input.sessionId,eventType:e.input.eventType,source:e.input.source}),n.sequenceEngine?.onEvent({sessionId:e.input.sessionId,eventType:e.input.eventType,source:e.input.source}),e.messaging&&n.messagePipe?.noteInboxSocket?.(e.input.sessionId,e.messaging),n.sessionProbe?.noteTranscript(e.input.sessionId,s?.transcriptPath??null);const o=P(e.input.eventType,s?.raw);o&&n.sessionProbe?.noteModel?.(e.input.sessionId,o);const c=O(e.input.eventType,s?.raw);c&&n.sessionProbe?.sessionStarted?.(e.input.sessionId,c.model);const l=w(s?.raw);if(l&&n.sessionProbe?.noteEffort?.(e.input.sessionId,l),e.terminalEnv&&n.messagePipe?.notePaneEnv?.(e.input.sessionId,e.terminalEnv),e.input.eventType==="UserPromptSubmit"){const a=n.messagePipe?.onSessionPrompt?.(e.input.sessionId,U(s)??"",e.eventId)??[];a.length>0&&n.uploads?.linkToEvent(e.eventId,a)}const u=W(e.input.source)?F[e.input.source].sessionExit:null;u!==null&&e.input.eventType===u&&n.messagePipe?.sessionExited?.(e.input.sessionId),n.messagePipe?.hasQueued(e.input.sessionId)&&n.messagePipe.flushSession(e.input.sessionId)}n.dispatcher&&n.dispatcher.onIngest({eventId:e.eventId,project:i,sessionId:e.input.sessionId??null,payload:s??{eventType:e.input.eventType,toolName:null,toolInput:null,toolResponse:null,cwd:null,transcriptPath:null,raw:null},source:e.input.source,deliveredTitle:e.deliveredTitle??null}).then(o=>{o.deferred&&e.input.sessionId&&A(n.hooksDir,i.token,[{sessionId:e.input.sessionId,text:o.deferred}])}).catch(()=>{})}}function U(n){const t=n?.raw;return typeof t?.prompt=="string"&&t.prompt?t.prompt:null}export function startInboxWorker(n){return new E(new URL(import.meta.url),{workerData:{inboxWorker:!0,...n}})}if(!j&&g?.inboxWorker===!0){const n=g,t=D(n.dbPath),e={hooksDir:n.hooksDir,projects:new R(t),hookEvents:new L(t),hookSessions:new _(t),adapters:S().byCapability("events").flatMap(o=>o.events??[])},i=new Map,s=()=>{try{const o=drainInboxOnce(e,i);o.length>0&&x?.postMessage(o)}catch(o){console.error("[weave] inbox drain failed:",o)}};s(),setInterval(s,n.tickMs??INBOX_TICK_MS)}
@@ -1 +1 @@
1
- import i from"node:path";export const DISPATCH_MARKER="<!--weave-dispatch-->";const c=t=>process.platform==="win32"?t.toLowerCase():t;export function normalizePosix(t){return t.replace(/\\/g,"/")}function p(t){return/[.+^${}()|[\]\\]/.test(t)?`\\${t}`:t}const s=new Map;export function globToRegex(t){const o=s.get(t);if(o)return o;let n="";for(let r=0;r<t.length;r++){const l=t[r];l==="*"?t[r+1]==="*"?(r++,t[r+1]==="/"?(r++,n+="(?:.*/)?"):n+=".*"):n+="[^/]*":l==="?"?n+="[^/]":n+=p(l)}const e=new RegExp(`^${n}$`,"i");return s.set(t,e),e}export function matchGlob(t,o){return globToRegex(o).test(normalizePosix(t))}export function extractFilePath(t){if(typeof t!="object"||t===null)return null;const o=t;for(const n of["file_path","notebook_path","filePath"]){const e=o[n];if(typeof e=="string"&&e.length>0)return e}return null}function u(t,o){const n=c(normalizePosix(t)),e=c(normalizePosix(o).replace(/\/+$/,""));return n===e||n.startsWith(`${e}/`)}export function isCrossProjectPath(t,o,n){const e=c(normalizePosix(o));return u(t,o)?!1:n.some(r=>c(normalizePosix(r))!==e&&u(t,r))}export function renderTemplate(t,o){return t.replace(/\{(\w+)\}/g,(n,e)=>{const r=o[e];return r==null?n:String(r)})}export function templateVars(t){return{event:t.event,tool:t.tool,file:t.filePath?normalizePosix(t.filePath):null,cwd:t.cwd?normalizePosix(t.cwd):null,session:t.session,project:t.project,rule:t.rule}}export function matchesAnyGlob(t,o){return o.some(n=>matchGlob(t,n))}export function projectLabel(t){return i.basename(normalizePosix(t).replace(/\/+$/,""))||t}
1
+ import f from"node:path";export const DISPATCH_MARKER="<!--weave-dispatch-->";const s=e=>process.platform==="win32"?e.toLowerCase():e;export function normalizePosix(e){return e.replace(/\\/g,"/")}function a(e){return/[.+^${}()|[\]\\]/.test(e)?`\\${e}`:e}const l=new Map;export function globToRegex(e){const r=l.get(e);if(r)return r;let t="";for(let n=0;n<e.length;n++){const c=e[n];c==="*"?e[n+1]==="*"?(n++,e[n+1]==="/"?(n++,t+="(?:.*/)?"):t+=".*"):t+="[^/]*":c==="?"?t+="[^/]":t+=a(c)}const o=new RegExp(`^${t}$`,"i");return l.set(e,o),o}export function matchGlob(e,r){return globToRegex(r).test(normalizePosix(e))}export function extractFilePath(e){if(typeof e!="object"||e===null)return null;const r=e;for(const t of["file_path","notebook_path","filePath"]){const o=r[t];if(typeof o=="string"&&o.length>0)return o}return null}function i(e,r){const t=s(normalizePosix(e)),o=s(normalizePosix(r).replace(/\/+$/,""));return t===o||t.startsWith(`${o}/`)}export function isCrossProjectPath(e,r,t){const o=s(normalizePosix(r));return i(e,r)?!1:t.some(n=>s(normalizePosix(n))!==o&&i(e,n))}export function renderTemplate(e,r){return e.replace(/\{(\w+)\}/g,(t,o)=>{const n=r[o];return n==null?t:String(n)})}export function templateVars(e){return{event:e.event,tool:e.tool,file:e.filePath?normalizePosix(e.filePath):null,cwd:e.cwd?normalizePosix(e.cwd):null,session:e.session,project:e.project,rule:e.rule}}export function matchesAnyGlob(e,r){return r.some(t=>matchGlob(e,t))}export function projectLabel(e){return f.basename(normalizePosix(e).replace(/\/+$/,""))||e}