@weavecode/weave 0.1.5 → 0.1.7

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 (249) hide show
  1. package/node_modules/@modelcontextprotocol/sdk/node_modules/express/node_modules/encodeurl/README.md +14 -0
  2. package/node_modules/@modelcontextprotocol/sdk/node_modules/express/node_modules/encodeurl/index.js +5 -10
  3. package/node_modules/@modelcontextprotocol/sdk/node_modules/express/node_modules/encodeurl/package.json +10 -6
  4. package/node_modules/@modelcontextprotocol/sdk/node_modules/express/node_modules/qs/CHANGELOG.md +42 -0
  5. package/node_modules/@modelcontextprotocol/sdk/node_modules/express/node_modules/qs/README.md +38 -10
  6. package/node_modules/@modelcontextprotocol/sdk/node_modules/express/node_modules/qs/dist/qs.js +18 -18
  7. package/node_modules/@modelcontextprotocol/sdk/node_modules/express/node_modules/qs/lib/parse.js +16 -4
  8. package/node_modules/@modelcontextprotocol/sdk/node_modules/express/node_modules/qs/lib/utils.js +13 -2
  9. package/node_modules/@modelcontextprotocol/sdk/node_modules/express/node_modules/qs/package.json +1 -1
  10. package/node_modules/@modelcontextprotocol/sdk/node_modules/express-rate-limit/dist/index.cjs +6 -2
  11. package/node_modules/@modelcontextprotocol/sdk/node_modules/express-rate-limit/dist/index.mjs +6 -2
  12. package/node_modules/@modelcontextprotocol/sdk/node_modules/express-rate-limit/package.json +10 -10
  13. package/node_modules/@modelcontextprotocol/sdk/node_modules/jose/dist/types/jwt/decrypt.d.ts +3 -0
  14. package/node_modules/@modelcontextprotocol/sdk/node_modules/jose/dist/types/jwt/unsecured.d.ts +2 -0
  15. package/node_modules/@modelcontextprotocol/sdk/node_modules/jose/dist/types/jwt/verify.d.ts +3 -0
  16. package/node_modules/@modelcontextprotocol/sdk/node_modules/jose/dist/types/types.d.ts +8 -0
  17. package/node_modules/@modelcontextprotocol/sdk/node_modules/jose/dist/types/util/decode_jwt.d.ts +1 -0
  18. package/node_modules/@modelcontextprotocol/sdk/node_modules/jose/dist/webapi/jwks/remote.js +1 -1
  19. package/node_modules/@modelcontextprotocol/sdk/node_modules/jose/package.json +1 -1
  20. package/node_modules/@weavecode/cli/dist/cli.js +4 -4
  21. package/node_modules/@weavecode/cli/dist/commands/chpass.js +1 -1
  22. package/node_modules/@weavecode/cli/dist/commands/daemon-auth.js +1 -1
  23. package/node_modules/@weavecode/cli/dist/commands/daemon.d.ts +2 -0
  24. package/node_modules/@weavecode/cli/dist/commands/daemon.js +2 -2
  25. package/node_modules/@weavecode/cli/dist/commands/dashboard.js +2 -2
  26. package/node_modules/@weavecode/cli/dist/commands/doctor.js +1 -1
  27. package/node_modules/@weavecode/cli/dist/commands/init.js +1 -1
  28. package/node_modules/@weavecode/cli/dist/commands/msg.js +2 -2
  29. package/node_modules/@weavecode/cli/dist/commands/scan.js +1 -1
  30. package/node_modules/@weavecode/cli/dist/commands/status.js +2 -2
  31. package/node_modules/@weavecode/cli/dist/commands/uninstall.js +1 -1
  32. package/node_modules/@weavecode/cli/dist/i18n/dict/en.js +5 -5
  33. package/node_modules/@weavecode/cli/dist/i18n/dict/zh.d.ts +6 -1
  34. package/node_modules/@weavecode/cli/dist/i18n/dict/zh.js +5 -5
  35. package/node_modules/@weavecode/cli/dist/i18n/index.js +1 -1
  36. package/node_modules/@weavecode/cli/dist/i18n/t.js +1 -1
  37. package/node_modules/@weavecode/cli/dist/init/claudemd-gen.js +3 -3
  38. package/node_modules/@weavecode/cli/dist/init/executor.js +3 -3
  39. package/node_modules/@weavecode/cli/dist/init/git-commit.js +2 -2
  40. package/node_modules/@weavecode/cli/dist/init/harnesses/claude.js +7 -7
  41. package/node_modules/@weavecode/cli/dist/init/harnesses/codex.js +1 -1
  42. package/node_modules/@weavecode/cli/dist/init/instruction-link.js +1 -1
  43. package/node_modules/@weavecode/cli/dist/init/plugin-templates.js +1 -1
  44. package/node_modules/@weavecode/cli/dist/init/prompt.js +4 -4
  45. package/node_modules/@weavecode/cli/dist/init/provision.js +1 -1
  46. package/node_modules/@weavecode/cli/dist/init/uninstall.js +6 -6
  47. package/node_modules/@weavecode/cli/dist/init/wiring.js +1 -1
  48. package/node_modules/@weavecode/cli/dist/parser.js +1 -1
  49. package/node_modules/@weavecode/cli/dist/statusline/ansi.js +1 -1
  50. package/node_modules/@weavecode/cli/dist/statusline/mock-input.js +1 -1
  51. package/node_modules/@weavecode/cli/dist/statusline/preview.js +2 -2
  52. package/node_modules/@weavecode/cli/package.json +5 -5
  53. package/node_modules/@weavecode/core/dist/harness-checks.js +1 -1
  54. package/node_modules/@weavecode/core/dist/harness.d.ts +25 -0
  55. package/node_modules/@weavecode/core/dist/harness.js +1 -1
  56. package/node_modules/@weavecode/core/dist/index.d.ts +1 -1
  57. package/node_modules/@weavecode/core/dist/index.js +1 -1
  58. package/node_modules/@weavecode/core/dist/platform.js +1 -1
  59. package/node_modules/@weavecode/core/dist/types.js +1 -1
  60. package/node_modules/@weavecode/core/dist/utils/fs.js +1 -1
  61. package/node_modules/@weavecode/core/dist/utils/logger.js +1 -1
  62. package/node_modules/@weavecode/core/package.json +1 -1
  63. package/node_modules/@weavecode/harness/dist/claude/assets.js +4 -4
  64. package/node_modules/@weavecode/harness/dist/claude/capture.js +9 -9
  65. package/node_modules/@weavecode/harness/dist/claude/commands.d.ts +3 -0
  66. package/node_modules/@weavecode/harness/dist/claude/commands.js +2 -3
  67. package/node_modules/@weavecode/harness/dist/claude/config.js +2 -2
  68. package/node_modules/@weavecode/harness/dist/claude/detect.js +1 -1
  69. package/node_modules/@weavecode/harness/dist/claude/edits.js +1 -1
  70. package/node_modules/@weavecode/harness/dist/claude/event-source.js +1 -1
  71. package/node_modules/@weavecode/harness/dist/claude/images.js +2 -2
  72. package/node_modules/@weavecode/harness/dist/claude/index.d.ts +1 -0
  73. package/node_modules/@weavecode/harness/dist/claude/index.js +1 -1
  74. package/node_modules/@weavecode/harness/dist/claude/liveness.js +1 -1
  75. package/node_modules/@weavecode/harness/dist/claude/mcp-gen.js +1 -1
  76. package/node_modules/@weavecode/harness/dist/claude/messaging.js +2 -2
  77. package/node_modules/@weavecode/harness/dist/claude/model-aliases.js +1 -1
  78. package/node_modules/@weavecode/harness/dist/claude/narration.d.ts +0 -11
  79. package/node_modules/@weavecode/harness/dist/claude/narration.js +1 -1
  80. package/node_modules/@weavecode/harness/dist/claude/peers.js +1 -1
  81. package/node_modules/@weavecode/harness/dist/claude/plan.js +1 -1
  82. package/node_modules/@weavecode/harness/dist/claude/plugins.js +4 -4
  83. package/node_modules/@weavecode/harness/dist/claude/prompt-inbox.js +1 -1
  84. package/node_modules/@weavecode/harness/dist/claude/prompt.js +3 -3
  85. package/node_modules/@weavecode/harness/dist/claude/questions.js +2 -2
  86. package/node_modules/@weavecode/harness/dist/claude/resume.js +1 -1
  87. package/node_modules/@weavecode/harness/dist/claude/rewind.d.ts +8 -0
  88. package/node_modules/@weavecode/harness/dist/claude/rewind.js +1 -0
  89. package/node_modules/@weavecode/harness/dist/claude/settings-gen.js +1 -1
  90. package/node_modules/@weavecode/harness/dist/claude/side-question.js +2 -2
  91. package/node_modules/@weavecode/harness/dist/claude/statusline/generator.js +36 -15
  92. package/node_modules/@weavecode/harness/dist/claude/statusline/git-cache.js +1 -1
  93. package/node_modules/@weavecode/harness/dist/claude/statusline/surface.js +2 -2
  94. package/node_modules/@weavecode/harness/dist/claude/transcript-cursor.d.ts +26 -0
  95. package/node_modules/@weavecode/harness/dist/claude/transcript-cursor.js +2 -0
  96. package/node_modules/@weavecode/harness/dist/claude/transcript.js +7 -7
  97. package/node_modules/@weavecode/harness/dist/codex/assets.js +1 -1
  98. package/node_modules/@weavecode/harness/dist/codex/capture.js +2 -2
  99. package/node_modules/@weavecode/harness/dist/codex/commands.js +4 -4
  100. package/node_modules/@weavecode/harness/dist/codex/config.js +2 -2
  101. package/node_modules/@weavecode/harness/dist/codex/detect.js +1 -1
  102. package/node_modules/@weavecode/harness/dist/codex/event-source.js +2 -2
  103. package/node_modules/@weavecode/harness/dist/codex/images.js +1 -1
  104. package/node_modules/@weavecode/harness/dist/codex/index.js +1 -1
  105. package/node_modules/@weavecode/harness/dist/codex/liveness.js +1 -1
  106. package/node_modules/@weavecode/harness/dist/codex/mcp.js +1 -1
  107. package/node_modules/@weavecode/harness/dist/codex/messaging.js +2 -2
  108. package/node_modules/@weavecode/harness/dist/codex/narration.js +1 -1
  109. package/node_modules/@weavecode/harness/dist/codex/plugin-state.js +1 -1
  110. package/node_modules/@weavecode/harness/dist/codex/plugins.js +3 -3
  111. package/node_modules/@weavecode/harness/dist/codex/provision.js +1 -1
  112. package/node_modules/@weavecode/harness/dist/codex/questions.js +2 -2
  113. package/node_modules/@weavecode/harness/dist/codex/rollout.js +5 -5
  114. package/node_modules/@weavecode/harness/dist/codex/side-question.js +4 -4
  115. package/node_modules/@weavecode/harness/dist/codex/titles.js +4 -4
  116. package/node_modules/@weavecode/harness/dist/codex/toml.js +13 -13
  117. package/node_modules/@weavecode/harness/dist/codex/transcript.js +2 -2
  118. package/node_modules/@weavecode/harness/dist/driver.d.ts +56 -1
  119. package/node_modules/@weavecode/harness/dist/driver.js +1 -1
  120. package/node_modules/@weavecode/harness/dist/init/generated.js +2 -2
  121. package/node_modules/@weavecode/harness/dist/init/pipeline.js +1 -1
  122. package/node_modules/@weavecode/harness/dist/registry-wiring.js +1 -1
  123. package/node_modules/@weavecode/harness/dist/shared/install-link.js +1 -1
  124. package/node_modules/@weavecode/harness/dist/shared/json-cap.js +1 -1
  125. package/node_modules/@weavecode/harness/package.json +2 -2
  126. package/node_modules/@weavecode/server/dist/config/profiles.d.ts +19 -13
  127. package/node_modules/@weavecode/server/dist/config/profiles.js +2 -2
  128. package/node_modules/@weavecode/server/dist/daemon/config-routes.js +1 -1
  129. package/node_modules/@weavecode/server/dist/daemon/dev-entry.js +1 -1
  130. package/node_modules/@weavecode/server/dist/daemon/entry.js +7 -1
  131. package/node_modules/@weavecode/server/dist/daemon/hooks-routes.js +1 -1
  132. package/node_modules/@weavecode/server/dist/daemon/opener/launch.js +1 -1
  133. package/node_modules/@weavecode/server/dist/daemon/opener.d.ts +2 -0
  134. package/node_modules/@weavecode/server/dist/daemon/opener.js +1 -1
  135. package/node_modules/@weavecode/server/dist/daemon/routes/session-control.js +1 -1
  136. package/node_modules/@weavecode/server/dist/daemon/routes/session-insights.js +1 -1
  137. package/node_modules/@weavecode/server/dist/daemon/routes/uploads.js +1 -1
  138. package/node_modules/@weavecode/server/dist/daemon/routes/visualizations.d.ts +3 -0
  139. package/node_modules/@weavecode/server/dist/daemon/routes/visualizations.js +1 -0
  140. package/node_modules/@weavecode/server/dist/daemon/server.js +2 -2
  141. package/node_modules/@weavecode/server/dist/daemon/session-open.d.ts +17 -0
  142. package/node_modules/@weavecode/server/dist/daemon/session-open.js +1 -1
  143. package/node_modules/@weavecode/server/dist/daemon/session-probe.d.ts +5 -4
  144. package/node_modules/@weavecode/server/dist/daemon/start.js +1 -1
  145. package/node_modules/@weavecode/server/dist/db/db.js +6 -2
  146. package/node_modules/@weavecode/server/dist/hooks/bus.d.ts +3 -1
  147. package/node_modules/@weavecode/server/dist/hooks/delivery/ack-gate.d.ts +12 -6
  148. package/node_modules/@weavecode/server/dist/hooks/delivery/ack-gate.js +1 -1
  149. package/node_modules/@weavecode/server/dist/hooks/delivery/channels.d.ts +3 -3
  150. package/node_modules/@weavecode/server/dist/hooks/delivery/channels.js +1 -1
  151. package/node_modules/@weavecode/server/dist/hooks/delivery/keys.d.ts +19 -9
  152. package/node_modules/@weavecode/server/dist/hooks/delivery/keys.js +1 -1
  153. package/node_modules/@weavecode/server/dist/hooks/delivery/relay.d.ts +2 -2
  154. package/node_modules/@weavecode/server/dist/hooks/delivery/relay.js +1 -1
  155. package/node_modules/@weavecode/server/dist/hooks/delivery/views.d.ts +5 -1
  156. package/node_modules/@weavecode/server/dist/hooks/delivery/views.js +1 -1
  157. package/node_modules/@weavecode/server/dist/hooks/message-deliverer.d.ts +45 -38
  158. package/node_modules/@weavecode/server/dist/hooks/message-deliverer.js +5 -3
  159. package/node_modules/@weavecode/server/dist/repositories/hook-events.d.ts +1 -1
  160. package/node_modules/@weavecode/server/dist/repositories/hook-events.js +4 -4
  161. package/node_modules/@weavecode/server/dist/repositories/sessions.d.ts +11 -1
  162. package/node_modules/@weavecode/server/dist/repositories/sessions.js +4 -2
  163. package/node_modules/@weavecode/server/dist/repositories/uploads.d.ts +14 -4
  164. package/node_modules/@weavecode/server/dist/repositories/uploads.js +11 -11
  165. package/node_modules/@weavecode/server/dist/surfaces.d.ts +3 -1
  166. package/node_modules/@weavecode/server/dist/surfaces.js +1 -1
  167. package/node_modules/@weavecode/server/package.json +4 -4
  168. package/node_modules/@weavecode/server/web/dist/assets/{abnfDiagram-WEYOIA3C-C-f9WfD3.js → abnfDiagram-WEYOIA3C-DDeQkTf5.js} +1 -1
  169. package/node_modules/@weavecode/server/web/dist/assets/{arc-D62qulAD.js → arc-CRZTRyjb.js} +1 -1
  170. package/node_modules/@weavecode/server/web/dist/assets/{architectureDiagram-ZHVYKT53-B6ZJRpcL.js → architectureDiagram-ZHVYKT53-Dj54DE3O.js} +1 -1
  171. package/node_modules/@weavecode/server/web/dist/assets/{blockDiagram-RJAE7QA3-DOtDFeiT.js → blockDiagram-RJAE7QA3-BIH8mSIZ.js} +1 -1
  172. package/node_modules/@weavecode/server/web/dist/assets/{c4Diagram-XDPPPE54-DWn3ng8X.js → c4Diagram-XDPPPE54-5YoKWFOD.js} +1 -1
  173. package/node_modules/@weavecode/server/web/dist/assets/channel-5VM93AJ8.js +1 -0
  174. package/node_modules/@weavecode/server/web/dist/assets/{chunk-2E7WHVMD-B5IIc9cn.js → chunk-2E7WHVMD-B653kMXt.js} +1 -1
  175. package/node_modules/@weavecode/server/web/dist/assets/{chunk-2Q5K7J3B-BUU9Zvt8.js → chunk-2Q5K7J3B-f_A4_eDz.js} +1 -1
  176. package/node_modules/@weavecode/server/web/dist/assets/{chunk-4EMNKR2T-CqEGIghP.js → chunk-4EMNKR2T-v5j5qNGj.js} +1 -1
  177. package/node_modules/@weavecode/server/web/dist/assets/{chunk-55XCU76K-D36o_E2b.js → chunk-55XCU76K-CgEqeP7j.js} +1 -1
  178. package/node_modules/@weavecode/server/web/dist/assets/{chunk-5VM5RSS4-sxws8ERh.js → chunk-5VM5RSS4-BeROhLXN.js} +1 -1
  179. package/node_modules/@weavecode/server/web/dist/assets/{chunk-JWPE2WC7-CJo_rEEb.js → chunk-JWPE2WC7-D6dXb_jr.js} +1 -1
  180. package/node_modules/@weavecode/server/web/dist/assets/{chunk-VQ5W62QI-9UlLCpsb.js → chunk-VQ5W62QI-CnHdSEMi.js} +1 -1
  181. package/node_modules/@weavecode/server/web/dist/assets/{chunk-XXDRQBXY-CX9CPbWb.js → chunk-XXDRQBXY-BkG_e6PE.js} +1 -1
  182. package/node_modules/@weavecode/server/web/dist/assets/{chunk-ZCHMQSOR-DwEfdZcF.js → chunk-ZCHMQSOR-DxR-fxzs.js} +2 -2
  183. package/node_modules/@weavecode/server/web/dist/assets/{classDiagram-v2-4MYWR3UA-CFCmIyt8.js → classDiagram-v2-4MYWR3UA-DQe1b_k8.js} +1 -1
  184. package/node_modules/@weavecode/server/web/dist/assets/{cose-bilkent-JH36ORCC-qWXeXJTn.js → cose-bilkent-JH36ORCC-DThrA8S5.js} +1 -1
  185. package/node_modules/@weavecode/server/web/dist/assets/{cynefin-EF2NZ3EQ-CXabWQxz.js → cynefin-EF2NZ3EQ-OZotFKUu.js} +1 -1
  186. package/node_modules/@weavecode/server/web/dist/assets/{cynefinDiagram-WF24UDRP-Bzpj8Qbj.js → cynefinDiagram-WF24UDRP-DJjq2hfT.js} +1 -1
  187. package/node_modules/@weavecode/server/web/dist/assets/{dagre-NK4GIZVX-CXsL8t30.js → dagre-NK4GIZVX-C2vH93HT.js} +1 -1
  188. package/node_modules/@weavecode/server/web/dist/assets/{diagram-CBK3MWTC-xfR-zlAD.js → diagram-CBK3MWTC-DrF_ScM-.js} +1 -1
  189. package/node_modules/@weavecode/server/web/dist/assets/{diagram-I5XIIV2D-BjMqEsXr.js → diagram-I5XIIV2D-D1qoUJ4t.js} +1 -1
  190. package/node_modules/@weavecode/server/web/dist/assets/{diagram-ODIL2UCW-QZpf8KhT.js → diagram-ODIL2UCW-D9A6W8oB.js} +1 -1
  191. package/node_modules/@weavecode/server/web/dist/assets/{diagram-PFBEJUXE-Cw1ESWft.js → diagram-PFBEJUXE-PeI-eyu2.js} +1 -1
  192. package/node_modules/@weavecode/server/web/dist/assets/{diagram-RJA3I4VV-CAy2RYYZ.js → diagram-RJA3I4VV-DITY0Rd8.js} +1 -1
  193. package/node_modules/@weavecode/server/web/dist/assets/{diagram-TYUNFSNR-B09WciWt.js → diagram-TYUNFSNR-D5KieEw5.js} +1 -1
  194. package/node_modules/@weavecode/server/web/dist/assets/{ebnfDiagram-V4P3TTPT-DuLmHG0U.js → ebnfDiagram-V4P3TTPT-DDylK-gz.js} +1 -1
  195. package/node_modules/@weavecode/server/web/dist/assets/{elk-QONTBCTQ--zzx0EVP.js → elk-QONTBCTQ-D3xrVg0U.js} +1 -1
  196. package/node_modules/@weavecode/server/web/dist/assets/{erDiagram-KYQIGQAA-BPDjG5vB.js → erDiagram-KYQIGQAA-y_V1cor7.js} +1 -1
  197. package/node_modules/@weavecode/server/web/dist/assets/{flowDiagram-IUGLLWBU-DtE2M9a_.js → flowDiagram-IUGLLWBU-BJ8Z0MkF.js} +1 -1
  198. package/node_modules/@weavecode/server/web/dist/assets/{ganttDiagram-R7GPNTJY-B-4AaWVa.js → ganttDiagram-R7GPNTJY-C0q-CS1T.js} +1 -1
  199. package/node_modules/@weavecode/server/web/dist/assets/{gitGraphDiagram-PDYL7XHY-CYj5FGYx.js → gitGraphDiagram-PDYL7XHY-BYTComiB.js} +1 -1
  200. package/node_modules/@weavecode/server/web/dist/assets/index-BKxAxaVG.js +1091 -0
  201. package/node_modules/@weavecode/server/web/dist/assets/index-C0Sd4MH7.css +11 -0
  202. package/node_modules/@weavecode/server/web/dist/assets/{infoDiagram-MVDRKAX5-DHYSDj-3.js → infoDiagram-MVDRKAX5-DtixgjLP.js} +1 -1
  203. package/node_modules/@weavecode/server/web/dist/assets/{ishikawaDiagram-HPEHV2GE-CumAEBoU.js → ishikawaDiagram-HPEHV2GE-ChEnND76.js} +1 -1
  204. package/node_modules/@weavecode/server/web/dist/assets/{journeyDiagram-BOSHW7O7-ES3O3X05.js → journeyDiagram-BOSHW7O7-DHcNtpYF.js} +1 -1
  205. package/node_modules/@weavecode/server/web/dist/assets/{kanban-definition-FNSA4HC5-BMIrf0d9.js → kanban-definition-FNSA4HC5-Dft7qpW5.js} +1 -1
  206. package/node_modules/@weavecode/server/web/dist/assets/{linear-DEZ5FO1r.js → linear-DEo11t-X.js} +1 -1
  207. package/node_modules/@weavecode/server/web/dist/assets/{mermaid.core-D7gm2szA.js → mermaid.core-D_Dp_Kl2.js} +4 -4
  208. package/node_modules/@weavecode/server/web/dist/assets/{mindmap-definition-6OY57UG3-BBQP8lyN.js → mindmap-definition-6OY57UG3-CM6OAd_-.js} +1 -1
  209. package/node_modules/@weavecode/server/web/dist/assets/{pegDiagram-ECIUJNBX-DzkKsqmg.js → pegDiagram-ECIUJNBX-_QkY0h8Q.js} +1 -1
  210. package/node_modules/@weavecode/server/web/dist/assets/{pieDiagram-GNMPY74T-zR3q7Qs1.js → pieDiagram-GNMPY74T-ZGr5vtDj.js} +1 -1
  211. package/node_modules/@weavecode/server/web/dist/assets/{quadrantDiagram-D57K4MC3-B4xuIsMW.js → quadrantDiagram-D57K4MC3-D8pQ_PU2.js} +1 -1
  212. package/node_modules/@weavecode/server/web/dist/assets/{railroadDiagram-Y72NRBL7-D2I52m9D.js → railroadDiagram-Y72NRBL7-DUIo-WmA.js} +1 -1
  213. package/node_modules/@weavecode/server/web/dist/assets/{requirementDiagram-EQYSW5RA-aJ1KfKj2.js → requirementDiagram-EQYSW5RA-C90DU5Ny.js} +1 -1
  214. package/node_modules/@weavecode/server/web/dist/assets/{sankeyDiagram-SY24JHO5-CEq16Ecf.js → sankeyDiagram-SY24JHO5-B_poYGgJ.js} +1 -1
  215. package/node_modules/@weavecode/server/web/dist/assets/{sequenceDiagram-BLEHNHQU-Bc66KG9f.js → sequenceDiagram-BLEHNHQU-DDW7b2Dn.js} +1 -1
  216. package/node_modules/@weavecode/server/web/dist/assets/{sizeCapture-INFHLROL-Ddizw_UG.js → sizeCapture-INFHLROL-CmKoqX6K.js} +1 -1
  217. package/node_modules/@weavecode/server/web/dist/assets/{stateDiagram-v2-A6IESKWZ-C1eVtEX9.js → stateDiagram-v2-A6IESKWZ-CkVMAyxG.js} +1 -1
  218. package/node_modules/@weavecode/server/web/dist/assets/{swimlanes-B3ENRKFQ-CCd_KlpZ.js → swimlanes-B3ENRKFQ-Dm_Omzky.js} +1 -1
  219. package/node_modules/@weavecode/server/web/dist/assets/swimlanesDiagram-AYQRV4AK-Bjj8ZA4d.js +8 -0
  220. package/node_modules/@weavecode/server/web/dist/assets/{timeline-definition-JXYKGLGB-DqpBhIII.js → timeline-definition-JXYKGLGB-DnhkRGLb.js} +1 -1
  221. package/node_modules/@weavecode/server/web/dist/assets/{usecaseDiagram-WPOLBNNX-bX_jNjSt.js → usecaseDiagram-WPOLBNNX-_TdIjC6Z.js} +1 -1
  222. package/node_modules/@weavecode/server/web/dist/assets/{vennDiagram-Q3Y3IDCW-D07CUHl3.js → vennDiagram-Q3Y3IDCW-FzgsymXB.js} +1 -1
  223. package/node_modules/@weavecode/server/web/dist/assets/{wardleyDiagram-IVAIDKWA-CZ5ovcWa.js → wardleyDiagram-IVAIDKWA-BwqimStC.js} +1 -1
  224. package/node_modules/@weavecode/server/web/dist/assets/{xychartDiagram-4URNHDU4-CBTh52hU.js → xychartDiagram-4URNHDU4-CFjjVPIV.js} +1 -1
  225. package/node_modules/@weavecode/server/web/dist/icons/apple-touch-icon.png +0 -0
  226. package/node_modules/@weavecode/server/web/dist/icons/icon-192.png +0 -0
  227. package/node_modules/@weavecode/server/web/dist/icons/icon-512.png +0 -0
  228. package/node_modules/@weavecode/server/web/dist/icons/icon-maskable-512.png +0 -0
  229. package/node_modules/@weavecode/server/web/dist/index.html +11 -2
  230. package/node_modules/@weavecode/server/web/dist/manifest.webmanifest +16 -0
  231. package/node_modules/@weavecode/server/web/dist/sw.js +14 -12
  232. package/node_modules/@weavecode/templates/package.json +2 -2
  233. package/node_modules/selfsigned/node_modules/@peculiar/x509/node_modules/tslib/README.md +3 -8
  234. package/node_modules/selfsigned/node_modules/@peculiar/x509/node_modules/tslib/package.json +1 -1
  235. package/node_modules/selfsigned/node_modules/@peculiar/x509/node_modules/tslib/tslib.d.ts +4 -2
  236. package/node_modules/selfsigned/node_modules/@peculiar/x509/node_modules/tslib/tslib.es6.js +10 -1
  237. package/node_modules/selfsigned/node_modules/@peculiar/x509/node_modules/tslib/tslib.es6.mjs +10 -1
  238. package/node_modules/selfsigned/node_modules/@peculiar/x509/node_modules/tslib/tslib.js +10 -1
  239. package/node_modules/selfsigned/node_modules/pkijs/node_modules/tslib/README.md +3 -8
  240. package/node_modules/selfsigned/node_modules/pkijs/node_modules/tslib/package.json +1 -1
  241. package/node_modules/selfsigned/node_modules/pkijs/node_modules/tslib/tslib.d.ts +4 -2
  242. package/node_modules/selfsigned/node_modules/pkijs/node_modules/tslib/tslib.es6.js +10 -1
  243. package/node_modules/selfsigned/node_modules/pkijs/node_modules/tslib/tslib.es6.mjs +10 -1
  244. package/node_modules/selfsigned/node_modules/pkijs/node_modules/tslib/tslib.js +10 -1
  245. package/package.json +6 -6
  246. package/node_modules/@weavecode/server/web/dist/assets/channel-CjSr3Zfg.js +0 -1
  247. package/node_modules/@weavecode/server/web/dist/assets/index-BGdTLG4q.js +0 -1031
  248. package/node_modules/@weavecode/server/web/dist/assets/index-CEpJpR7P.css +0 -11
  249. package/node_modules/@weavecode/server/web/dist/assets/swimlanesDiagram-AYQRV4AK-yIifcHaR.js +0 -8
@@ -1 +1 @@
1
- import{homedir as B}from"node:os";import{access as F}from"node:fs/promises";import{isHarness as I}from"@weavecode/core";import{configSurfaceFor as k}from"../surfaces.js";import{baselineSnapshot as U,createProfile as J,LASTSEEN_ID as C,listBackups as K,listProfiles as h,readBackup as E,readSnapshot as N,removeProfile as L,renameProfile as $,pushBackup as j,saveProfile as D,setActive as V,syncBaseline as P,writeSnapshot as M}from"../config/profiles.js";import{readBody as R,sendJson as a}from"./http.js";import{getHarnessConfigDir as G}from"../db/paths.js";const H=["user","project","projectLocal","global"];function x(c){return typeof c=="string"&&H.includes(c)?c:null}function y(c,r){return c.serializeRaw(r)}function _(c,r,p){const w=c.files(p).find(m=>m.id===r);return w?w.path(p):""}async function O(c){try{const r=JSON.parse(await R(c));return typeof r=="object"&&r!==null&&!Array.isArray(r)?r:null}catch{return null}}async function z(c){if(!c)return!1;try{return await F(c),!0}catch{return!1}}async function T(c,r,p,w,m){const i=_(p,w,m),n=await p.read(w,m),e=y(p,n),t=await h(c,r,w),s=await U(c,r,w,t);s||await M(c,r,w,C,n);const o=s?y(p,s):y(p,n);return{harness:r,file:w,path:i,exists:await z(i),values:n,managedKeys:p.managedKeys(n),managedEntries:p.managedEntries(n),profiles:t.profiles,activeId:t.activeId,liveText:e,activeText:o,drifted:o!==e,backups:await K(c,r,w)}}function S(c,r,p){let w=null;if(r==="project"||r==="projectLocal"){const m=Number(p);if(!Number.isInteger(m)||m<=0)return"\u9700\u8981 projectId";const i=c.projects.getById(m);if(!i)return"\u9879\u76EE\u4E0D\u5B58\u5728";w=i.path}return{projectPath:w,homedir:B()}}export async function handleConfigRoutes(c,r,p,w,m){if(!w.startsWith("/harness-config"))return!1;const i=G();if(w==="/harness-config/catalog"&&c.method==="GET"){const n=m.searchParams.get("harness");if(!I(n))return a(r,400,{error:"Unknown harness"}),!0;const e=k(n);if(!e)return a(r,200,{supported:!1}),!0;const t=x(m.searchParams.get("file"))??"user",s={projectPath:null,homedir:B()},o=e.catalog(t);return a(r,200,{supported:!0,harness:n,file:t,rawFormat:e.rawFormat,files:e.files(s).map(u=>({id:u.id,profiles:u.profiles})),groups:o.groups,keys:o.keys,envVars:o.envVars}),!0}if(w==="/harness-config"&&c.method==="GET"){const n=m.searchParams.get("harness"),e=x(m.searchParams.get("file"));if(!I(n)||!e)return a(r,400,{error:"Unknown harness or file"}),!0;const t=k(n);if(!t)return a(r,400,{error:"\u914D\u7F6E\u9762\u672A\u5B9E\u73B0"}),!0;const s=S(p,e,m.searchParams.get("projectId"));return typeof s=="string"?(a(r,400,{error:s}),!0):(a(r,200,await T(i,n,t,e,s)),!0)}if(w==="/harness-config/values"&&c.method==="PUT"){const n=await O(c);if(!n)return a(r,400,{error:"Invalid JSON body"}),!0;const e=n.harness,t=x(n.file);if(!I(e)||!t)return a(r,400,{error:"Unknown harness or file"}),!0;const s=k(e);if(!s)return a(r,400,{error:"\u914D\u7F6E\u9762\u672A\u5B9E\u73B0"}),!0;const o=S(p,t,n.projectId);if(typeof o=="string")return a(r,400,{error:o}),!0;const u=n.values;if(typeof u!="object"||u===null||Array.isArray(u))return a(r,400,{error:'Missing "values"'}),!0;try{const f=await s.read(t,o);await j(i,e,t,f),await s.write(t,o,u);const v=await h(i,e,t);await P(i,e,t,v,await s.read(t,o))}catch(f){return a(r,400,{error:f.message}),!0}return a(r,200,await T(i,e,s,t,o)),!0}if(w==="/harness-config/raw"&&c.method==="PUT"){const n=await O(c);if(!n)return a(r,400,{error:"Invalid JSON body"}),!0;const e=n.harness,t=x(n.file);if(!I(e)||!t)return a(r,400,{error:"Unknown harness or file"}),!0;const s=k(e);if(!s)return a(r,400,{error:"\u914D\u7F6E\u9762\u672A\u5B9E\u73B0"}),!0;const o=S(p,t,n.projectId);if(typeof o=="string")return a(r,400,{error:o}),!0;let u;try{u=s.parseRaw(String(n.text??""))}catch(f){return a(r,400,{error:`\u4E0D\u662F\u5408\u6CD5${s.rawFormat==="toml"?" TOML":" JSON"}\uFF1A${f.message}`}),!0}try{const f=await s.read(t,o);await j(i,e,t,f),await s.write(t,o,u);const v=await h(i,e,t);await P(i,e,t,v,await s.read(t,o))}catch(f){return a(r,400,{error:f.message}),!0}return a(r,200,await T(i,e,s,t,o)),!0}if(w==="/harness-config/profile"&&c.method==="POST"){const n=await O(c);if(!n)return a(r,400,{error:"Invalid JSON body"}),!0;const e=n.harness,t=x(n.file),s=n.action;if(!I(e)||!t||typeof s!="string")return a(r,400,{error:"Unknown harness, file or action"}),!0;const o=k(e);if(!o)return a(r,400,{error:"\u914D\u7F6E\u9762\u672A\u5B9E\u73B0"}),!0;const u=S(p,t,n.projectId);if(typeof u=="string")return a(r,400,{error:u}),!0;const f=typeof n.id=="string"?n.id:"",v=typeof n.name=="string"?n.name.trim():"",A=typeof n.values=="object"&&n.values!==null&&!Array.isArray(n.values)?n.values:null;switch(s){case"list":{const d=await h(i,e,t);return a(r,200,d),!0}case"create":{const d=await h(i,e,t),l=await J(i,e,t,v||`\u914D\u7F6E ${d.profiles.length+1}`,A??await o.read(t,u));return a(r,200,{profile:l,state:await h(i,e,t)}),!0}case"save":return(await h(i,e,t)).profiles.some(l=>l.id===f)?(await D(i,e,t,f,A??await o.read(t,u)),a(r,200,await h(i,e,t)),!0):(a(r,404,{error:"\u914D\u7F6E\u4E0D\u5B58\u5728"}),!0);case"compare":{const d=n.target;if(d==="live")return a(r,200,{text:y(o,await o.read(t,u))}),!0;if(d==="backup"){const g=typeof n.backupId=="string"?n.backupId:"",b=await E(i,e,t,g);return b?(a(r,200,{text:y(o,b)}),!0):(a(r,404,{error:"\u5907\u4EFD\u4E0D\u5B58\u5728"}),!0)}const l=await N(i,e,t,f);return l?(a(r,200,{text:y(o,l)}),!0):(a(r,404,{error:"\u914D\u7F6E\u4E0D\u5B58\u5728"}),!0)}case"duplicate":{const d=await N(i,e,t,f);if(!d)return a(r,404,{error:"\u914D\u7F6E\u4E0D\u5B58\u5728"}),!0;const l=await h(i,e,t),g=await J(i,e,t,v||`\u914D\u7F6E ${l.profiles.length+1}`,d);return a(r,200,{profile:g,state:await h(i,e,t)}),!0}case"rename":return v?(await $(i,e,t,f,v),a(r,200,await h(i,e,t)),!0):(a(r,400,{error:"\u7F3A\u5C11\u540D\u79F0"}),!0);case"remove":return await L(i,e,t,f),a(r,200,await h(i,e,t)),!0;case"activate":{const d=await N(i,e,t,f);if(!d)return a(r,404,{error:"\u914D\u7F6E\u4E0D\u5B58\u5728"}),!0;const l=await o.read(t,u);if(n.confirm!==!0)return a(r,200,{requiresConfirm:!0,liveText:y(o,l),profileText:y(o,d)}),!0;try{await j(i,e,t,l),await o.write(t,u,d),await V(i,e,t,f)}catch(g){return a(r,400,{error:g.message}),!0}return a(r,200,await T(i,e,o,t,u)),!0}case"acceptDrift":{const d=await h(i,e,t),l=await U(i,e,t,d);return l&&await j(i,e,t,l),await P(i,e,t,d,await o.read(t,u)),a(r,200,await T(i,e,o,t,u)),!0}case"restoreBaseline":{const d=await h(i,e,t),l=await U(i,e,t,d);if(!l)return a(r,404,{error:"\u6CA1\u6709\u53EF\u6062\u590D\u7684\u57FA\u7EBF"}),!0;const g=await o.read(t,u);if(n.confirm!==!0)return a(r,200,{requiresConfirm:!0,liveText:y(o,g),baselineText:y(o,l)}),!0;try{await j(i,e,t,g),await o.write(t,u,l),await P(i,e,t,d,l)}catch(b){return a(r,400,{error:b.message}),!0}return a(r,200,await T(i,e,o,t,u)),!0}case"restoreBackup":{const d=typeof n.backupId=="string"?n.backupId:"",l=await E(i,e,t,d);if(!l)return a(r,404,{error:"\u5907\u4EFD\u4E0D\u5B58\u5728"}),!0;const g=await o.read(t,u);if(n.confirm!==!0)return a(r,200,{requiresConfirm:!0,liveText:y(o,g),backupText:y(o,l)}),!0;try{await j(i,e,t,g),await o.write(t,u,l);const b=await h(i,e,t);await P(i,e,t,b,l)}catch(b){return a(r,400,{error:b.message}),!0}return a(r,200,await T(i,e,o,t,u)),!0}default:return a(r,400,{error:`\u672A\u77E5\u52A8\u4F5C\uFF1A${s}`}),!0}}if(w==="/harness-config/models"&&c.method==="POST"){const n=await O(c);if(!n)return a(r,400,{error:"Invalid JSON body"}),!0;const e=n.harness,t=x(n.file)??"user";if(!I(e))return a(r,400,{error:"Unknown harness"}),!0;const s=k(e);if(!s)return a(r,400,{error:"\u914D\u7F6E\u9762\u672A\u5B9E\u73B0"}),!0;const o=S(p,t,n.projectId);if(typeof o=="string")return a(r,400,{error:o}),!0;try{const u=await s.read(t,o),f=await s.models({values:u,file:t,homedir:o.homedir,baseUrl:typeof n.baseUrl=="string"?n.baseUrl:null,apiKey:typeof n.apiKey=="string"?n.apiKey:null,authToken:typeof n.authToken=="string"?n.authToken:null});a(r,200,f)}catch(u){a(r,502,{error:u.message})}return!0}if(w==="/harness-config/preview"&&c.method==="POST"){const n=await O(c);if(!n)return a(r,400,{error:"Invalid JSON body"}),!0;const e=n.harness,t=x(n.file);if(!I(e)||!t)return a(r,400,{error:"Unknown harness or file"}),!0;const s=k(e);if(!s)return a(r,400,{error:"\u914D\u7F6E\u9762\u672A\u5B9E\u73B0"}),!0;const o=S(p,t,n.projectId);if(typeof o=="string")return a(r,400,{error:o}),!0;const u=n.values;if(typeof u!="object"||u===null||Array.isArray(u))return a(r,400,{error:'Missing "values"'}),!0;try{const f=await s.read(t,o);a(r,200,{before:y(s,f),after:y(s,u)})}catch(f){a(r,400,{error:f.message})}return!0}return a(r,404,{error:"Not found"}),!0}
1
+ import{homedir as 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 +1 @@
1
- import we from"node:http";import{openDatabase as ge}from"../db/db.js";import{ProjectRepository as Se}from"../repositories/projects.js";import{HookEventRepository as ve}from"../repositories/hook-events.js";import{LibraryRepository as be}from"../repositories/libraries.js";import{HookRuleRepository as ne}from"../repositories/hook-rules.js";import{HookDispatchRepository as Re}from"../repositories/hook-dispatches.js";import{PluginStateRepository as T}from"../repositories/plugin-states.js";import{SessionRepository as ye}from"../repositories/sessions.js";import{createRuntimeRegistry as ke}from"@weavecode/harness";import{TERMINAL_LOCATOR_ENV_KEYS as De,isHarness as W}from"@weavecode/core";import{messagingSurfaceFor as Pe,narrationSurfaceFor as Ee}from"../surfaces.js";import{syntheticSessionIds as Te}from"../hooks/synthetic-sessions.js";import{createEdgeExtract as Oe}from"../hooks/edge-extract.js";import{HookRuleRegistry as Ie}from"../hooks/registry.js";import{HookDispatcher as Ae}from"../hooks/dispatcher.js";import{HookEventBus as Ce}from"../hooks/bus.js";import{ResumeRunner as _e}from"../hooks/resume-runner.js";import{HeadlessRunner as Fe}from"../hooks/headless-runner.js";import{MessageDeliverer as He}from"../hooks/message-deliverer.js";import{QuestionTracker as $e}from"../hooks/question-tracker.js";import{SideQuestionRepository as Be}from"../repositories/side-questions.js";import{claimSideAnswer as Me}from"../hooks/side-questions.js";import{DashboardRateCache as Le}from"../hooks/dashboard-rate.js";import{startDashboardPusher as Ue}from"./dashboard-pusher.js";import{startPromptFlusher as Ne}from"../hooks/prompt-flusher.js";import{SessionWatchRepository as We}from"../repositories/session-watches.js";import{PushSubscriptionRepository as je}from"../repositories/push-subscriptions.js";import{UploadRepository as xe}from"../repositories/uploads.js";import{defaultUploadSessions as Qe}from"./upload-sessions.js";import{PushNotifier as qe}from"../hooks/push-notify.js";import{OrchestrationRepository as Ke,OrchestrationRunRepository as Ge}from"../repositories/orchestrations.js";import{WatchEngine as Je}from"../hooks/watch-engine.js";import{OrchestrationEngine as Ve,createForkConditionJudge as Ye}from"../hooks/orchestration-engine.js";import{createDecisionConditionJudge as ze}from"../hooks/decision-judge.js";import{readDecisionKey as Xe}from"./decision-config.js";import{openSessionTerminal as Ze}from"./session-open.js";import{loadAllPlugins as es}from"../hooks/plugin-loader.js";import{ensureBuiltinMarket as ss,builtinMarketDir as ts}from"../market/builtin.js";import{ToolkitService as os}from"../hooks/toolkit.js";import{startSessionSweeper as rs}from"../hooks/session-sweeper.js";import{startStatuslineCacheSweeper as ns}from"../statusline/cache-sweeper.js";import{readStatuslineFacts as is}from"../statusline/manager.js";import{WatchService as as}from"../watch/watch-service.js";import{weaveRequestHandler as ls}from"./server.js";import{startTlsServer as cs}from"./tls.js";import{DataBus as ps}from"./data-bus.js";import{TerminalTopologyRefresher as ms}from"./terminal-topology-refresher.js";import{SnapshotRefresher as j}from"./snapshot-refresher.js";import{SessionProbe as us,dbModelFactResolver as ds,dbTranscriptPathResolver as fs}from"./session-probe.js";import{NarrationWatcher as hs}from"./narration-watcher.js";import{InflightCountsRefresher as ws}from"./inflight-counts-refresher.js";import{ProjectUpdatesRefresher as gs}from"./project-updates-refresher.js";import{FingerprintCache as Ss}from"../install/fingerprint.js";import{detectProjectUpdateCounts as vs}from"../install/updates.js";import{pidAliveOf as bs}from"./claude-liveness.js";import{combinedLivenessOf as R}from"./liveness.js";import{promptTerminalChannel as ie,readTerminalCounts as Rs}from"./opener.js";import{wireHookFilePipeline as ys}from"./hook-pipeline.js";import{DEFAULT_PORT as x,DAEMON_HOST as ks,DEFAULT_BIND_HOST as Ds,findFreePort as Ps,isPortFree as Es}from"./port.js";import{writeDaemonState as ae}from"./state.js";import{ensureDataLayout as Ts}from"../db/layout.js";import{pruneFileIndexes as Os}from"./project-files.js";import{pruneInstallTmp as Is}from"../hooks/plugin-installer.js";import{readDaemonSettingsSync as y,setDaemonSettingsDb as As,DEFAULT_SERVER_SETTINGS as Cs}from"./settings.js";import{AuthService as _s}from"./dashboard-auth.js";import{resolveStaticDir as Fs}from"./static.js";const Hs="CLAUDE_CODE_CHILD_SESSION"in process.env;delete process.env.CLAUDE_CODE_CHILD_SESSION;for(const p of De)delete process.env[p];async function $s(){Ts();const p=await Es(x)?x:await Ps(x+1);ae({pid:process.pid,port:p,startedAt:new Date().toISOString()});const t=ge();As(t);const f=y().server?.bindHost??Ds,O=y().server?.tlsPort??Cs.tlsPort,I=new _s;I.initialPassword&&console.log(`[dev] initial dashboard password: ${I.initialPassword}`);const r=new Se(t);Os(r.list().map(e=>e.id)),Is();const a=new ve(t),u=new be(t),h=ke(),le=h.byCapability("events").flatMap(e=>e.events??[]),k=new Ie(new ne(t)),D=new Re(t),o=new ye(t),n=new Ce;{const e=await ss({libraries:u});e.error?console.error(`[dev] builtin market unavailable: ${e.error}`):e.changed&&console.log(`[dev] builtin market ${e.form==="link"?"linked":"copied"} -> ${ts(u.dataRoot)}`)}const{loader:m}=await es({rules:new ne(t),registry:k,states:new T(t),bus:n,libraries:u},r.list());{const e=m.list().filter(s=>s.status==="rejected");console.log(`[dev] plugins loaded: ${m.list().length} (rejected: ${e.length})`);for(const s of e)console.log(`[dev] rejected ${s.id}: ${s.error}`)}m.watchRoots();const Q={list:()=>m.list(),setPluginEnabled:(e,s)=>m.setPluginEnabled(e,s),reloadAll:()=>m.reloadAll(),rescan:()=>m.rescanRoots(r.list(),u)},ce=new os({projects:r,states:new T(t),plugins:Q,libraries:u}),A={run:null},q=new Ae({registry:k,dispatches:D,bus:n,projects:r,sessions:o,plugins:m,pluginStates:new T(t),classify:e=>A.run?A.run(e):Promise.resolve(null),sessionTitleOf:async e=>{const s=a.listBySession(e,1).at(-1)?.source;return W(s)?h.get(s)?.titles?.sessionTitleOf(e)??null:null}}),P=new Fe,pe=new _e({dispatches:D,sessions:o,projects:r,bus:n,resumeSpec:h.get("claude")?.resume,headless:P}),c=new He({sessions:o,projects:r,hookEvents:a,bus:n,headless:P,terminal:ie(()=>y().terminal),blockedByQuestion:e=>w.get(e)!=null,livenessOf:R,sideAnswerStore:{answerById:(e,s,i)=>{$.answerById(e,s,i)}}});Ne(c);const C=new We(t),_=new Je({watches:C,deliverer:c,sessions:o,bus:n,livenessOf:R}),K=new je(t),F=new xe(t),me=new qe({subscriptions:K,sessions:o,bus:n}),H=new Ke(t),G=new Ge(t),d=new us(fs(a),ds(a,e=>o.getBySessionId(e)?.harness??null)),J=new hs(n,e=>Ee(W(e)?e:"claude"),e=>d.transcriptPathOf(e),e=>o.livenessRowOf(e)?.harness??null);J.start();const w=new $e({sessions:o,hookEvents:a,onPending:e=>{n.emit({kind:"question.pending",sessionId:e.sessionId,harness:e.harness,count:e.questions.length,at:e.at})},interruptedAt:e=>{const s=o.getBySessionId(e);return s?d.interruptedAt(e,s.lastSeenAt):null}});w.seedFromDb();const $=new Be(t),V=new Le,B=Ue({rate:V,events:a,sessions:o,projects:r,bus:n}),Y={repo:$,bus:n,settle:e=>{c.interrupt(e.sessionId)}},z=new as(r);z.start();const l=new ps,g=new ms(async()=>({counts:await Rs(r.list()),terminals:await c.sessionTerminals()}),l,{shouldRun:()=>l.hasSubscribers(),graceMs:1e4});g.start();const M=new j(()=>{const e=R(),s={};for(const i of o.listWithCounts()){const b=bs(i,e);b!==null&&(s[i.sessionId]=b)}return{alive:s}},l,{key:"sessionLiveness",shouldRun:()=>l.hasSubscribers()});M.start();const L=new j(()=>{const e={};for(const s of o.listWithCounts()){if(s.turnOpen!==!0)continue;const i=d.interruptedAt(s.sessionId,s.lastSeenAt);i!==null&&(e[s.sessionId]=i)}return{interrupted:e}},l,{key:"sessionInterrupt",intervalMs:5e3,shouldRun:()=>l.hasSubscribers()});L.start(),new j(()=>{const e={};for(const s of r.list())e[s.id]=is(s.path);return e},l,{key:"statusline",intervalMs:5e3,shouldRun:()=>l.hasSubscribers(),invalidateOnly:!0}).start();const ue=new ws(()=>c.listInflightCounts(),l,n);let X=null;const S=Oe({sessions:o,projects:r,harnessOf:e=>{const s=a.listBySession(e,1),i=s[s.length-1]?.source;return W(i)?i:null},surfaceFor:Pe,headless:P,onSyntheticChange:()=>X?.pushSyntheticSessions(Te())});A.run=e=>S.run(e);const de=ze({config:async()=>{const e=y().decision;if(!e?.baseUrl||!e.model)return null;const s=Xe();return s?{baseUrl:e.baseUrl,model:e.model,apiKey:s}:null},fallback:Ye({supports:e=>S.supports(e),extract:e=>S.run(e)})}),v=new Ve({orchestrations:H,runs:G,deliverer:c,sessions:o,bus:n,supportsExtract:e=>S.supports(e),extract:e=>S.run(e),conditionJudge:de,deferWhenUserPresent:!0,ensureOpen:async e=>{const s=a.listBySession(e,1).at(-1)?.id??0,i=await Ze({hookSessions:o,hookEvents:a,projects:r,harnesses:h,sessionProbe:d,terminalRefresher:g},e);if(!i.ok)return i;let b=!1;for(let re=0;re<60;re++){if(a.listBySession(e,20).some(E=>E.id>s&&E.eventType==="SessionStart"))return{ok:!0,ack:"session-start"};R().get(e)===!0&&(b=!0),await new Promise(E=>setTimeout(E,250))}return b?{ok:!0,ack:"registry"}:{ok:!1,error:"session did not report ready within 15s"}}});v.rearm();const Z=setInterval(()=>v.cronTick(),3e4);Z.unref();const fe=new Ss,he=new gs(()=>vs(r.list(),u.list(),fe),l,n,()=>l.hasSubscribers());rs({sessions:o,events:a,dispatches:D,deliverer:c,watches:C,orchestrations:H,watchEngine:_,orchestrationEngine:v,questions:w,sideQuestions:$,probe:d,uploads:F,uploadSessions:Qe,livenessOf:R}),ns();const U=ys({projects:r,rules:k,sessions:o,bus:n,dispatcher:q,watchEngine:_,orchestrationEngine:v,messagePipe:c,questionTracker:w,sideQuestions:{onEvent:e=>{Me(Y,e)}},sessionProbe:d,uploads:F,dashboardRate:V,terminalTopologyKick:()=>{g.refreshNow()}});X=U;const N=Fs(),ee=ls({projects:r,port:p,tlsPort:O,watch:z,hookEvents:a,adapters:le,harnesses:h,libraries:u,staticDir:N,hookRegistry:k,hookDispatches:D,hookSessions:o,hookBus:n,dataBus:l,terminalRefresher:g,interruptRefresher:L,livenessRefresher:M,sessionProbe:d,inflightRefresher:ue,updatesRefresher:he,hookDispatcher:q,hookRunner:pe,messageDeliverer:c,terminal:ie(()=>y().terminal),uploads:F,questionTracker:w,sideQuestions:Y,sessionWatches:C,watchEngine:_,orchestrations:H,orchestrationRuns:G,orchestrationEngine:v,pushSubscriptions:K,pushNotifier:me,onAttach:B.attach,dashboardRefresh:B.attach,hookPlugins:Q,hookMirror:U.mirror,pluginStates:new T(t),toolkit:ce,auth:I}),se=we.createServer(ee);let te=null;cs({port:O,bindHost:f,handler:ee}).then(e=>{te=e,e&&console.log(`[dev] weave daemon tls listening on https://${f}:${e.port}`)});const oe=()=>{g.stop(),M.stop(),L.stop(),P.killAll(),clearInterval(Z),J.stop(),B.stop(),U.stop(),se.close(),te?.server.close(),process.exit(0)};process.on("SIGTERM",oe),process.on("SIGINT",oe),se.listen(p,f,()=>{ae({pid:process.pid,port:p,startedAt:new Date().toISOString(),host:f,tlsPort:O}),console.log(`[dev] weave daemon listening on http://${f}:${p}`),console.log(`[dev] cli/dashboard local url: http://${ks}:${p}`),console.log(`[dev] child-session marker stripped: ${Hs}`),console.log(N?`[dev] static: ${N}`:"[dev] static: (web/dist not built \u2014 run pnpm build:web)")})}$s();
1
+ import 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 U}from"@weavecode/core";import{messagingSurfaceFor as De,narrationSurfaceFor as Ee}from"../surfaces.js";import{syntheticSessionIds as Pe}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 Me}from"../repositories/side-questions.js";import{claimSideAnswer as $e}from"../hooks/side-questions.js";import{DashboardRateCache as Be}from"../hooks/dashboard-rate.js";import{startDashboardPusher as Le}from"./dashboard-pusher.js";import{startPromptFlusher as Ue}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 Ds,isPortFree as Es}from"./port.js";import{writeDaemonState as ne}from"./state.js";import{ensureDataLayout as Ps}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{resolveStaticDir as _s}from"./static.js";const Fs="CLAUDE_CODE_CHILD_SESSION"in process.env;delete process.env.CLAUDE_CODE_CHILD_SESSION;for(const p of ke)delete process.env[p];async function Hs(){Ps();const p=await Es(W)?W:await Ds(W+1);ne({pid:process.pid,port:p,startedAt:new Date().toISOString()});const o=we();Ts(o);const f=R().server?.bindHost??ks,P=R().server?.tlsPort??As.tlsPort,O=new Cs;O.initialPassword&&console.log(`[dev] initial dashboard password: ${O.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??[]),y=new Ie(new oe(o)),k=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:y,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:y,dispatches:k,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 U(s)?h.get(s)?.titles?.sessionTitleOf(e)??null:null}}),D=new _e,le=new Ce({dispatches:k,sessions:t,projects:r,bus:n,resumeSpec:h.get("claude")?.resume,headless:D}),c=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)}}});Ue(c);const T=new Ne(o),A=new Ge({watches:T,deliverer:c,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=>Ee(U(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 Me(o),G=new Be,H=Le({rate:G,events:a,sessions:t,projects:r,bus:n}),J={repo:F,bus:n,settle:e=>{c.interrupt(e.sessionId)}},V=new is(r);V.start();const i=new cs,g=new ps(async()=>({counts:await bs(r.list()),terminals:await c.sessionTerminals()}),i,{shouldRun:()=>i.hasSubscribers(),graceMs:1e4});g.start();const M=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()});M.start();const $=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()});$.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(()=>c.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 U(l)?l:null},surfaceFor:De,headless:D,onSyntheticChange:()=>Y?.pushSyntheticSessions(Pe())});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:c,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:k,deliverer:c,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:y,sessions:t,bus:n,dispatcher:x,watchEngine:A,orchestrationEngine:S,messagePipe:c,questionTracker:w,sideQuestions:{onEvent:e=>{$e(J,e)}},sessionProbe:d,uploads:C,dashboardRate:G,terminalTopologyKick:()=>{g.refreshNow()}});Y=B;const L=_s(),X=as({projects:r,port:p,tlsPort:P,watch:V,hookEvents:a,adapters:ie,harnesses:h,libraries:u,staticDir:L,hookRegistry:y,hookDispatches:k,hookSessions:t,hookBus:n,dataBus:i,terminalRefresher:g,interruptRefresher:$,livenessRefresher:M,sessionProbe:d,inflightRefresher:pe,updatesRefresher:fe,hookDispatcher:x,hookRunner:le,messageDeliverer:c,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:O}),Z=he.createServer(X);let ee=null;ls({port:P,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(),M.stop(),$.stop(),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(p,f,()=>{ne({pid:process.pid,port:p,startedAt:new Date().toISOString(),host:f,tlsPort:P}),console.log(`[dev] weave daemon listening on http://${f}:${p}`),console.log(`[dev] cli/dashboard local url: http://${ys}:${p}`),console.log(`[dev] child-session marker stripped: ${Fs}`),console.log(L?`[dev] static: ${L}`:"[dev] static: (web/dist not built \u2014 run pnpm build:web)")})}Hs();
@@ -1 +1,7 @@
1
- import{startDaemon as m}from"./start.js";m();
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}:
2
+ ${n}
3
+
4
+ `,"utf8")}catch{}process.exit(1)};process.on("uncaughtException",t=>i("uncaughtException",t)),process.on("unhandledRejection",t=>i("unhandledRejection",t));try{m()}catch(t){const o=t instanceof Error?t.stack??t.message:String(t);try{const n=a();s(n,{recursive:!0}),r(c.join(n,"daemon-boot.log"),`[${new Date().toISOString()}] boot crash:
5
+ ${o}
6
+
7
+ `,"utf8")}catch{}process.exit(1)}
@@ -1 +1 @@
1
- import{z as g}from"zod";import{HARNESS_SESSION_CONTROL as x,isHarness as P}from"@weavecode/core";import{aliasOfModel as O,modelAliasTargets as M}from"@weavecode/harness";import{readJson as k,sendJson as n}from"./http.js";import{purgeSession as D}from"../hooks/session-purge.js";import{readDaemonSettingsSync as A,readHooksEnabled as H}from"./settings.js";import{handleOrchestrationRoutes as W}from"./routes/orchestration.js";import{handleHookAdminRoutes as U}from"./routes/hooks-admin.js";import{handleUploadRoutes as N}from"./routes/uploads.js";import{handleSessionControlRoutes as $}from"./routes/session-control.js";import{handlePathRefRoutes as B}from"./routes/path-refs.js";import{handleSessionInsightRoutes as K}from"./routes/session-insights.js";import{handleWatchRoutes as G}from"./routes/watches.js";import{openSessionTerminal as L,transcriptState as Q}from"./session-open.js";import{pidAliveOf as j}from"./claude-liveness.js";import{combinedLivenessOf as E}from"./liveness.js";import{captureSurfaces as _,messagingSurfaces as F,sessionTitleSurfaceFor as V}from"../surfaces.js";import{getDataDir as J}from"../db/paths.js";import{WEAVE_VERSION as z}from"../version.js";const X=g.object({title:g.string().min(1).max(200)}),Y=g.object({text:g.string().max(2e4),fromKind:g.enum(["dashboard","session"]).optional(),fromSessionId:g.string().min(1).nullable().optional(),attachments:g.array(g.string().regex(/^[a-f0-9]{64}$/)).max(8).optional(),images:g.array(g.string().regex(/^[a-f0-9]{64}$/)).max(8).optional(),forceTerminal:g.boolean().optional()});function Z(a,s){return a.queuedPrompt!==null||a.prompt!==null||s}function q(a){const{diag:s,capture:e,eventCount:i}=a,l=[];return!e||e.source==="none"||!e.present?l.push("no-hook-script"):e.weaveOwned?!e.reportsInbox&&s?.inbox.reason!=="no-mechanism"&&l.push("hook-script-stale"):l.push("hook-script-not-weave"),i===0&&l.push("no-events"),s&&(s.alive===!1&&l.push("not-running"),s.inbox.reason==="no-credentials"&&e?.reportsInbox===!0&&l.push("no-inbox-credentials"),s.inbox.reason==="auth-token-required"&&l.push("inbox-token-required"),s.relay.reason==="no-peer-name"&&l.push("no-peer-name"),s.terminal.reason==="no-backend"&&l.push("terminal-no-backend"),s.terminal.reason==="no-pane-env"&&l.push("terminal-no-pane-env"),s.pending>0&&l.push("queued"),s.stalled&&l.push("stalled")),l}export async function handleHooksRoutes(a,s,e,i,l){if(!(i.startsWith("/hooks/")||i==="/dashboard/refresh"||i==="/sessions"||i.startsWith("/sessions/")||i.startsWith("/messaging")||i.startsWith("/webhooks/orchestrate/")||i==="/uploads"||i.startsWith("/uploads/")||i.startsWith("/images/")))return!1;if(await U(a,s,e,i,l))return!0;if(i==="/dashboard/refresh"&&a.method==="POST")return e.dashboardRefresh?.(),n(s,200,{ok:!0}),!0;if(i==="/sessions"&&a.method==="GET"){if(!e.hookSessions)return n(s,503,{error:"Hooks subsystem unavailable"}),!0;const t=l.searchParams.get("projectId"),r=t!=null&&t!==""?Number(t):void 0,o=e.hookSessions.listWithCounts(r),d=E(),h=e.terminalRefresher?.lastSnapshot?.terminals??{},m={};for(const u of o){const p=u.harness??"";p in m||(m[p]=M(x[u.harness]?.modelNames??[]))}return n(s,200,{sessions:o.map(u=>{const p=e.sessionProbe?.currentModel(u.sessionId)??null,S=e.sessionProbe?.transcriptPresent(u.sessionId)??null,c=P(u.harness)?e.harnesses?.get(u.harness)?.resume:void 0;return{...u,pidAlive:j(u,d),canOpenTerminal:!!(c?.supported&&c.openArgs),terminal:h[u.sessionId]??null,interruptedAt:u.turnOpen===!0?e.sessionProbe?.interruptedAt(u.sessionId,u.lastSeenAt)??null:null,model:p,modelAlias:O(m[u.harness??""]??[],p),mode:e.sessionProbe?.currentMode(u.sessionId)??null,effort:e.sessionProbe?.currentEffort(u.sessionId)??null,contextTokens:e.sessionProbe?.currentContextTokens(u.sessionId)??null,transcriptPresent:Q(S,u.hasRun)}}),modelCatalog:m}),!0}const v=i.match(/^\/sessions\/([^/]+)$/);if(v&&a.method==="PATCH"){if(!e.hookSessions)return n(s,503,{error:"Hooks subsystem unavailable"}),!0;const t=decodeURIComponent(v[1]);if(!e.hookSessions.getBySessionId(t))return n(s,404,{error:"Session not found"}),!0;try{const r=X.parse(await k(a)),o=e.hookEvents?.listBySession(t,1),d=o?.[o.length-1]?.source,h=P(d)?V(d):null;if(h){try{await h.setSessionTitle(t,r.title)}catch(p){return n(s,502,{error:p instanceof Error?p.message:"Host rename failed"}),!0}const u=e.hookSessions.setTitle(t,r.title);return u?.projectId!=null&&e.hookMirror?.syncProject(u.projectId),n(s,200,{session:u}),!0}const m=e.hookSessions.setPendingTitle(t,r.title);m?.projectId!=null&&e.hookMirror?.syncProject(m.projectId),n(s,200,{session:m})}catch(r){n(s,400,{error:r instanceof Error?r.message:"Invalid body"})}return!0}if(v&&a.method==="DELETE"){if(!e.hookSessions||!e.hookEvents)return n(s,503,{error:"Hooks subsystem unavailable"}),!0;const t=decodeURIComponent(v[1]),r=e.hookSessions.getBySessionId(t);if(!r)return n(s,404,{error:"Session not found"}),!0;const o=D({sessions:e.hookSessions,events:e.hookEvents,dispatches:e.hookDispatches,deliverer:e.messageDeliverer,watches:e.sessionWatches,orchestrations:e.orchestrations,questions:e.questionTracker,sideQuestions:e.sideQuestions?.repo,probe:e.sessionProbe,uploads:e.uploads},t);return r.projectId!=null&&e.hookMirror?.syncProject(r.projectId),n(s,200,{ok:!0,sessionId:t,...o}),!0}const y=i.match(/^\/sessions\/([^/]+)\/open-terminal$/);if(y&&a.method==="POST"){const t=decodeURIComponent(y[1]);let r;try{const d=await k(a);typeof d?.target=="string"&&d.target&&(r=d.target)}catch{}const o=await L(e,t,r);return o.ok?(n(s,200,{ok:!0,sessionId:o.sessionId,command:o.command,cwd:o.cwd,...o.target?{target:o.target}:{}}),!0):(n(s,o.status,{error:o.error}),!0)}if(await N(a,s,e,i,l))return!0;const R=i.match(/^\/sessions\/([^/]+)\/messages$/);if(R){const t=decodeURIComponent(R[1]);if(a.method==="GET")return e.messageDeliverer?e.hookSessions?.getBySessionId(t)?(n(s,200,{messages:e.messageDeliverer.listVisible(t)}),!0):(n(s,404,{error:"Session not found"}),!0):(n(s,503,{error:"Messaging subsystem unavailable"}),!0);if(a.method==="POST"){if(!e.messageDeliverer||!e.hookSessions)return n(s,503,{error:"Messaging subsystem unavailable"}),!0;let r;try{r=Y.parse(await k(a))}catch(m){return n(s,400,{error:m instanceof Error?m.message:"Invalid body"}),!0}const o=[...r.attachments??[],...r.images??[]];if(!r.text.trim()&&o.length===0)return n(s,400,{error:"Message is empty"}),!0;let d=[];if(o.length>0){const m=e.uploads?.refsOf(o)??null;if(!m)return n(s,404,{error:"Attachment not found"}),!0;d=m}const h=await e.messageDeliverer.send({toSessionId:t,text:r.text,...d.length>0?{attachments:d}:{},...r.forceTerminal===!0?{forceTerminal:!0}:{},mode:"prompt",fromKind:r.fromKind??"dashboard",fromSessionId:r.fromSessionId??null,oneWay:!0});return h.ok?n(s,201,{ok:!0,messageId:h.messageId,status:h.status,message:h.message}):n(s,h.status,{error:h.error}),!0}}if(await K(a,s,e,i,l)||await B(a,s,e,i,l))return!0;const w=i.match(/^\/sessions\/([^/]+)\/messages\/([^/]+)\/resend$/);if(w&&a.method==="POST"){if(!e.messageDeliverer)return n(s,503,{error:"Messaging subsystem unavailable"}),!0;const t=await e.messageDeliverer.resend(decodeURIComponent(w[2]));return t.ok?n(s,200,{ok:!0,messageId:t.messageId,status:t.status,message:t.message}):n(s,t.status,{error:t.error}),!0}const I=i.match(/^\/sessions\/([^/]+)\/messages\/([^/]+)\/dismiss$/);if(I&&a.method==="POST"){if(!e.messageDeliverer)return n(s,503,{error:"Messaging subsystem unavailable"}),!0;const t=e.messageDeliverer.dismiss(decodeURIComponent(I[1]),decodeURIComponent(I[2]));return t.ok?n(s,200,{ok:!0}):n(s,t.status,{error:t.error}),!0}if(await $(a,s,e,i,l)||await G(a,s,e,i)||await W(a,s,e,i,l))return!0;if(i==="/messaging/capabilities"&&a.method==="GET"){const t=e.messageDeliverer?.hasTerminalChannel()??!1;return n(s,200,{capabilities:F().map(({harness:r,surface:o})=>({harness:r,discovery:o.discovery,prompt:Z(o,t),inject:o.inject!==null,headless:o.headless!==null,watch:o.idleSignals.length>0,attachKinds:o.attach?.kinds??[],pathRefs:o.pathRefs!==null,pathRefLines:o.pathRefs?.lines===!0,pathRefKinds:o.pathRefs?.kinds??[],sideQuestion:o.sideQuestion!==null,unsupportedReasons:o.unsupportedReasons??null}))}),!0}if(i==="/messaging/diagnostics"&&a.method==="GET"){if(!e.messageDeliverer||!e.hookSessions)return n(s,503,{error:"Message subsystem unavailable"}),!0;const t=l.searchParams.get("session"),r=l.searchParams.get("project"),o=_(),d=e.projects.list(),h=await Promise.all(d.map(async c=>({id:c.id,name:c.name,path:c.path,captures:await Promise.all(o.map(async({harness:f,surface:b})=>({harness:f,...await b.scriptHealth({projectPath:c.path})})))}))),m=(c,f)=>h.find(b=>b.id===c)?.captures.find(b=>b.harness===f)??null,u=E(),S=e.hookSessions.listWithCounts(t?void 0:r?Number(r):void 0).filter(c=>t?c.sessionId===t:j(c,u)!==!1).map(c=>{const f=e.messageDeliverer.diagnose(c.sessionId),b=m(c.projectId,c.harness??null),T={inbox:f.inbox,queue:f.queue,relay:f.relay,terminal:f.terminal};return{sessionId:c.sessionId,projectId:c.projectId,harness:c.harness??null,title:c.title,lastSeenAt:c.lastSeenAt,eventCount:c.eventCount??0,lastEventType:c.lastEventType??null,alive:f.alive,paneEnvReported:f.paneEnvReported,channels:T,queue:{pending:f.pending,stalled:f.stalled},reachable:Object.values(T).some(C=>C.status==="ready"),hints:q({diag:f,capture:b,eventCount:c.eventCount??0})}});return n(s,200,{daemon:{version:z,platform:process.platform,dataDir:J(),uptimeMs:Math.round(process.uptime()*1e3),terminalPreset:A().terminal.preset,terminalTextChannel:e.messageDeliverer.hasTerminalChannel(),hooksEnabled:H()},projects:h,sessions:S}),!0}return!1}
1
+ import{z as 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 r}from"./http.js";import{purgeSession as D}from"../hooks/session-purge.js";import{readDaemonSettingsSync as A,readHooksEnabled as H}from"./settings.js";import{handleOrchestrationRoutes as W}from"./routes/orchestration.js";import{handleHookAdminRoutes as U}from"./routes/hooks-admin.js";import{handleUploadRoutes as 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{handleSessionInsightRoutes as G}from"./routes/session-insights.js";import{handleWatchRoutes as L}from"./routes/watches.js";import{openSessionTerminal as Q,transcriptState as V}from"./session-open.js";import{pidAliveOf as j}from"./claude-liveness.js";import{combinedLivenessOf as E}from"./liveness.js";import{captureSurfaces as _,messagingSurfaces as z,sessionTitleSurfaceFor as F}from"../surfaces.js";import{getDataDir as J}from"../db/paths.js";import{WEAVE_VERSION as X}from"../version.js";const Y=h.object({title:h.string().min(1).max(200)}),Z=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 q(l,s){return l.queuedPrompt!==null||l.prompt!==null||s}function ee(l){const{diag:s,capture:e,eventCount:i}=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"),i===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,i,u){if(!(i.startsWith("/hooks/")||i==="/dashboard/refresh"||i==="/sessions"||i.startsWith("/sessions/")||i.startsWith("/messaging")||i.startsWith("/webhooks/orchestrate/")||i==="/uploads"||i.startsWith("/uploads/")||i.startsWith("/images/")||i==="/visualizations/fragment"))return!1;if(await U(l,s,e,i,u))return!0;if(i==="/dashboard/refresh"&&l.method==="POST")return e.dashboardRefresh?.(),r(s,200,{ok:!0}),!0;if(i==="/sessions"&&l.method==="GET"){if(!e.hookSessions)return r(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 r(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:V(g,t.hasRun)}}),modelCatalog:b}),!0}const S=i.match(/^\/sessions\/([^/]+)$/);if(S&&l.method==="PATCH"){if(!e.hookSessions)return r(s,503,{error:"Hooks subsystem unavailable"}),!0;const o=decodeURIComponent(S[1]);if(!e.hookSessions.getBySessionId(o))return r(s,404,{error:"Session not found"}),!0;try{const a=Y.parse(await y(l)),n=e.hookEvents?.listBySession(o,1),d=n?.[n.length-1]?.source,m=T(d)?F(d):null;if(m){try{await m.setSessionTitle(o,a.title)}catch(v){return r(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),r(s,200,{session:p}),!0}const f=e.hookSessions.setPendingTitle(o,a.title);f?.projectId!=null&&e.hookMirror?.syncProject(f.projectId),r(s,200,{session:f})}catch(a){r(s,400,{error:a instanceof Error?a.message:"Invalid body"})}return!0}if(S&&l.method==="DELETE"){if(!e.hookSessions||!e.hookEvents)return r(s,503,{error:"Hooks subsystem unavailable"}),!0;const o=decodeURIComponent(S[1]),a=e.hookSessions.getBySessionId(o);if(!a)return r(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),r(s,200,{ok:!0,sessionId:o,...n}),!0}const R=i.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 Q(e,o,a);return n.ok?(r(s,200,{ok:!0,sessionId:n.sessionId,command:n.command,cwd:n.cwd,...n.target?{target:n.target}:{}}),!0):(r(s,n.status,{error:n.error}),!0)}if(await B(l,s,e,i,u))return!0;const w=i.match(/^\/sessions\/([^/]+)\/messages$/);if(w){const o=decodeURIComponent(w[1]);if(l.method==="GET")return e.messageDeliverer?e.hookSessions?.getBySessionId(o)?(r(s,200,{messages:e.messageDeliverer.listVisible(o)}),!0):(r(s,404,{error:"Session not found"}),!0):(r(s,503,{error:"Messaging subsystem unavailable"}),!0);if(l.method==="POST"){if(!e.messageDeliverer||!e.hookSessions)return r(s,503,{error:"Messaging subsystem unavailable"}),!0;let a;try{a=Z.parse(await y(l))}catch(f){return r(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 r(s,400,{error:"Message is empty"}),!0;let d=[];if(n.length>0){const f=e.uploads?.refsOf(n)??null;if(!f)return r(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?r(s,201,{ok:!0,messageId:m.messageId,status:m.status,message:m.message}):r(s,m.status,{error:m.error}),!0}}if(await G(l,s,e,i,u)||await $(l,s,e,i,u)||await K(l,s,e,i,u))return!0;const P=i.match(/^\/sessions\/([^/]+)\/messages\/([^/]+)\/resend$/);if(P&&l.method==="POST"){if(!e.messageDeliverer)return r(s,503,{error:"Messaging subsystem unavailable"}),!0;const o=await e.messageDeliverer.resend(decodeURIComponent(P[2]));return o.ok?r(s,200,{ok:!0,messageId:o.messageId,status:o.status,message:o.message}):r(s,o.status,{error:o.error}),!0}const k=i.match(/^\/sessions\/([^/]+)\/messages\/([^/]+)\/dismiss$/);if(k&&l.method==="POST"){if(!e.messageDeliverer)return r(s,503,{error:"Messaging subsystem unavailable"}),!0;const o=e.messageDeliverer.dismiss(decodeURIComponent(k[1]),decodeURIComponent(k[2]));return o.ok?r(s,200,{ok:!0}):r(s,o.status,{error:o.error}),!0}if(await N(l,s,e,i,u)||await L(l,s,e,i)||await W(l,s,e,i,u))return!0;if(i==="/messaging/capabilities"&&l.method==="GET"){const o=e.messageDeliverer?.hasTerminalChannel()??!1;return r(s,200,{capabilities:z().map(({harness:a,surface:n})=>({harness:a,discovery:n.discovery,prompt:q(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(i==="/messaging/diagnostics"&&l.method==="GET"){if(!e.messageDeliverer||!e.hookSessions)return r(s,503,{error:"Message subsystem unavailable"}),!0;const o=u.searchParams.get("session"),a=u.searchParams.get("project"),n=_(),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:ee({diag:c,capture:g,eventCount:t.eventCount??0})}});return r(s,200,{daemon:{version:X,platform:process.platform,dataDir:J(),uptimeMs:Math.round(process.uptime()*1e3),terminalPreset:A().terminal.preset,terminalTextChannel:e.messageDeliverer.hasTerminalChannel(),hooksEnabled:H()},projects:m,sessions:b}),!0}return!1}
@@ -1 +1 @@
1
- import{spawn as a}from"node:child_process";export function resolveTerminalLaunch(r,e,n=process.platform,o){return terminalBackendFor(e,n).candidates(r,o)}export function resolveExplorerLaunch(r,e=process.platform){return e==="win32"?{command:"explorer.exe",args:[r]}:e==="darwin"?{command:"open",args:[r]}:{command:"xdg-open",args:[r]}}export function trySpawn(r){return new Promise(e=>{let n;try{n=a(r.command,r.args,{cwd:r.cwd,shell:r.shell,detached:!0,stdio:"ignore"})}catch{e(!1);return}n.on("error",()=>e(!1)),n.on("spawn",()=>{n.unref(),e(!0)})})}export async function openInExplorer(r){const e=resolveExplorerLaunch(r);if(!await trySpawn(e))throw new Error(`Failed to open file manager (${e.command})`)}export async function openInTerminal(r,e){await terminalBackendFor(e).open(r)}
1
+ import{spawn as a}from"node:child_process";export function resolveTerminalLaunch(n,e,r=process.platform,o){return terminalBackendFor(e,r).candidates(n,o)}export function resolveExplorerLaunch(n,e=process.platform){return e==="win32"?{command:"explorer.exe",args:[n]}:e==="darwin"?{command:"open",args:[n]}:{command:"xdg-open",args:[n]}}export function trySpawn(n){return new Promise(e=>{let r;try{r=a(n.command,n.args,{cwd:n.cwd,shell:n.shell,detached:!0,stdio:"ignore"})}catch{e(!1);return}r.on("error",()=>e(!1)),r.on("spawn",()=>{r.unref(),e(!0)})})}export async function openInExplorer(n){const e=resolveExplorerLaunch(n);if(!await trySpawn(e))throw new Error(`Failed to open file manager (${e.command})`)}export async function openInTerminal(n,e){await terminalBackendFor(e).open(n)}
@@ -51,6 +51,8 @@ export declare function promptTerminalChannel(settings: () => TerminalSettings):
51
51
  locateScreens(envs: Record<string, Record<string, string>>): Promise<Record<string, SessionTerminal | null>>;
52
52
  sendText(paneId: string, text: string): Promise<void>;
53
53
  sendKeys(paneId: string, keys: string): Promise<void>;
54
+ /** 读 pane 可视屏(中断后的读屏确认:宿主吞掉 ESC 时才补打)。 */
55
+ getPaneText(paneId: string): Promise<string | null>;
54
56
  closePane(paneId: string): Promise<void>;
55
57
  };
56
58
  /**
@@ -1 +1 @@
1
- import{TERMINAL_LOCATOR_ENV as h}from"@weavecode/core";import{readDaemonSettings as B}from"./settings.js";import{normalizeDirKey as P}from"./opener/wezterm-mux.js";import{KonsoleBackend as E}from"./opener/backend-konsole.js";import{ItermBackend as A}from"./opener/backend-iterm.js";import{GhosttyBackend as I}from"./opener/backend-ghostty.js";import{TerminalAppBackend as k}from"./opener/backend-terminal-app.js";import{WtBackend as T}from"./opener/backend-wt.js";import{WeztermBackend as x}from"./opener/backend-wezterm.js";import{CandidatesBackend as u,CustomBackend as b,PRESET_CANDIDATES as w,TerminalBackend as S,trySpawn as W}from"./opener/backend.js";export{parseTerminalAppDump,parseTerminalAppTargetId,parsePsRootPids,parseLsofCwds,pickTerminalAppWindow,terminalAppTargets}from"./opener/pty-terminals.js";export{winRaiseEncodedScript}from"./opener/win-raise.js";export{parseWtPaneId,parseWtProcDump,parseWtTargetId,wtInjectEncodedScript,wtPanePidFromEnv,wtPanes,wtWindowSlug}from"./opener/wt.js";export{quotePath}from"./opener/shared.js";export{attachTargetsFromMuxes,countWindowsByDir,listAttachTargets,normalizeDirKey,parseAttachTargetId,parseWeztermPanes,planWeztermNewWindow,planWeztermReuse,sessionScreensFromEnvs,SocketProbeGate,weztermActiveWorkspaceOf,weztermCliArgs,weztermMuxKey,weztermPaneFromEnv,weztermSocketCandidates}from"./opener/wezterm-mux.js";export{planWeztermGrid}from"./opener/wezterm-mux.js";export{konsolePaneFromEnv,parseKonsolePaneId,qtKeyOf}from"./opener/backend-konsole.js";export{applescriptString,itermPaneFromEnv,parseItermPaneId}from"./opener/backend-iterm.js";export{parsePromptPaneId,runInWeztermAt}from"./opener/backend-wezterm.js";export{CandidatesBackend,CustomBackend,PRESET_CANDIDATES,TerminalBackend,trySpawn}from"./opener/backend.js";class z extends S{parts;constructor(e){super("auto",!0,e,e!=="win32"&&e!=="darwin");const a={win32:["wt","powershell","cmd"],darwin:["terminal","iterm"]}[e]??["gnome","konsole"];this.parts=a.map(s=>new u(s,e,w[s]))}candidates(e,n){return this.parts.flatMap(a=>n&&a.preset==="iterm"?[]:a.candidates(e,n))}attachBackend(){return this.platform==="darwin"?new k(this.platform):this.platform==="win32"?new T(this.platform):new x(this.platform)}countWindows(e){return this.attachBackend().countWindows(e)}listTargets(e){return this.attachBackend().listTargets(e)}runAt(e,n,a){return this.attachBackend().runAt(e,n,a)}focusTarget(e,n){return this.attachBackend().focusTarget(e,n)}listPromptPanes(){return this.attachBackend().listPromptPanes()}locatePane(e){return this.attachBackend().locatePane(e)}locateScreens(e){return this.attachBackend().locateScreens(e)}sendPromptText(e,n){return this.attachBackend().sendPromptText(e,n)}sendKeys(e,n){return this.attachBackend().sendKeys(e,n)}getPaneText(e){return this.attachBackend().getPaneText(e)}closePane(e){return this.attachBackend().closePane(e)}}const g={auto:(t,e)=>new z(e),wt:(t,e)=>new T(e),powershell:(t,e)=>new u("powershell",e,w.powershell),cmd:(t,e)=>new u("cmd",e,w.cmd),terminal:(t,e)=>new k(e),iterm:(t,e)=>new A(e),gnome:(t,e)=>new u("gnome",e,w.gnome),konsole:(t,e)=>new E(e),ghostty:(t,e)=>new I(e),wezterm:(t,e)=>new x(e),custom:(t,e)=>new b(t,e)};export function terminalBackendFor(t,e=process.platform){return(g[t.preset]??g.auto)(t,e)}export function locatorPresetOf(t){for(const[e,n]of Object.entries(h))if(n.every(a=>t[a]))return e;return null}export function promptTerminalChannel(t){const e=r=>terminalBackendFor({...t(),preset:r}),n=()=>e(t().preset),a=()=>Object.keys(h).map(r=>e(r)),s=r=>{const o=locatorPresetOf(r);return o?e(o):null},c=r=>a().find(o=>o.ownsPaneId(r))??null;return{available:()=>a().some(r=>r.textAddressable),listPanes:async()=>{const r=n();return r.textAddressable?await r.listPromptPanes():[]},locatePane:async r=>await s(r)?.locatePane(r)??null,locateScreens:async r=>{const o={},i=new Map;for(const[l,m]of Object.entries(r)){const p=locatorPresetOf(m);if(!p){o[l]=null;continue}const d=i.get(p)??{};d[l]=m,i.set(p,d)}for(const[l,m]of i){const p=e(l);if(!p.locateScreens){for(const f of Object.keys(m))o[f]=null;continue}const d=await p.locateScreens(m);for(const[f,y]of Object.entries(d))o[f]=y}return o},sendText:async(r,o)=>{const i=c(r);if(!i)throw new Error(`Invalid prompt pane "${r}"`);await i.sendPromptText(r,o)},sendKeys:async(r,o)=>{const i=c(r);if(!i)throw new Error(`Invalid prompt pane "${r}"`);await i.sendKeys(r,o)},closePane:async r=>{const o=c(r);if(!o)throw new Error(`Invalid prompt pane "${r}"`);await o.closePane(r)}}}export async function runInTerminal(t,e,n){return terminalBackendFor(n).run(t,e)}export async function countOpenTerminals(t,e){return terminalBackendFor(e).countWindows(t)}export function panesAtDir(t,e,n=process.platform){const a=P(e,n);return t.filter(s=>s.cwd!=null&&P(s.cwd,n)===a)}export async function listProjectPanes(t,e,n=process.platform){const a=terminalBackendFor(e,n),s=panesAtDir(await a.listPromptPanes(),t,n);if(s.length===0&&((await a.countWindows([t])).get(t)??0)>0)throw new Error(`Terminal preset "${a.preset}" cannot close open panes remotely \u2014 pick wezterm in settings`);return s}export async function closeTerminalsIn(t,e,n,a=process.platform){const s=terminalBackendFor(e,a),c=new Set(n),r=(await listProjectPanes(t,e,a)).filter(o=>c.has(o.id));for(const o of r)await s.closePane(o.id);return r.length}export async function readTerminalCounts(t,e=void 0){const n=await B(),s=await(e?.countTerminals??countOpenTerminals)(t.map(c=>c.path),n.terminal);return Object.fromEntries(t.map(c=>[c.id,s.get(c.path)??0]))}export function resolveTerminalLaunch(t,e,n=process.platform,a){return terminalBackendFor(e,n).candidates(t,a)}export function resolveExplorerLaunch(t,e=process.platform){return e==="win32"?{command:"explorer.exe",args:[t]}:e==="darwin"?{command:"open",args:[t]}:{command:"xdg-open",args:[t]}}export async function openInExplorer(t){const e=resolveExplorerLaunch(t);if(!await W(e))throw new Error(`Failed to open file manager (${e.command})`)}export async function openInTerminal(t,e){await terminalBackendFor(e).open(t)}export const defaultProjectOpener={openExplorer:openInExplorer,openTerminal:openInTerminal,runInTerminal,countTerminals:countOpenTerminals,closeTerminals:(t,e,n)=>closeTerminalsIn(t,e,n),listPanes:(t,e)=>listProjectPanes(t,e),listTerminals:(t,e)=>terminalBackendFor(e).listTargets(t),runInTerminalAt:(t,e,n,a)=>terminalBackendFor(a).runAt(t,e,n),focusTerminal:(t,e,n)=>terminalBackendFor(n).focusTarget(t,e)};
1
+ import{TERMINAL_LOCATOR_ENV as h}from"@weavecode/core";import{readDaemonSettings as B}from"./settings.js";import{normalizeDirKey as P}from"./opener/wezterm-mux.js";import{KonsoleBackend as E}from"./opener/backend-konsole.js";import{ItermBackend as A}from"./opener/backend-iterm.js";import{GhosttyBackend as b}from"./opener/backend-ghostty.js";import{TerminalAppBackend as k}from"./opener/backend-terminal-app.js";import{WtBackend as T}from"./opener/backend-wt.js";import{WeztermBackend as x}from"./opener/backend-wezterm.js";import{CandidatesBackend as u,CustomBackend as I,PRESET_CANDIDATES as w,TerminalBackend as S,trySpawn as W}from"./opener/backend.js";export{parseTerminalAppDump,parseTerminalAppTargetId,parsePsRootPids,parseLsofCwds,pickTerminalAppWindow,terminalAppTargets}from"./opener/pty-terminals.js";export{winRaiseEncodedScript}from"./opener/win-raise.js";export{parseWtPaneId,parseWtProcDump,parseWtTargetId,wtInjectEncodedScript,wtPanePidFromEnv,wtPanes,wtWindowSlug}from"./opener/wt.js";export{quotePath}from"./opener/shared.js";export{attachTargetsFromMuxes,countWindowsByDir,listAttachTargets,normalizeDirKey,parseAttachTargetId,parseWeztermPanes,planWeztermNewWindow,planWeztermReuse,sessionScreensFromEnvs,SocketProbeGate,weztermActiveWorkspaceOf,weztermCliArgs,weztermMuxKey,weztermPaneFromEnv,weztermSocketCandidates}from"./opener/wezterm-mux.js";export{planWeztermGrid}from"./opener/wezterm-mux.js";export{konsolePaneFromEnv,parseKonsolePaneId,qtKeyOf}from"./opener/backend-konsole.js";export{applescriptString,itermPaneFromEnv,parseItermPaneId}from"./opener/backend-iterm.js";export{parsePromptPaneId,runInWeztermAt}from"./opener/backend-wezterm.js";export{CandidatesBackend,CustomBackend,PRESET_CANDIDATES,TerminalBackend,trySpawn}from"./opener/backend.js";class v extends S{parts;constructor(e){super("auto",!0,e,e!=="win32"&&e!=="darwin");const a={win32:["wt","powershell","cmd"],darwin:["terminal","iterm"]}[e]??["gnome","konsole"];this.parts=a.map(s=>new u(s,e,w[s]))}candidates(e,r){return this.parts.flatMap(a=>r&&a.preset==="iterm"?[]:a.candidates(e,r))}attachBackend(){return this.platform==="darwin"?new k(this.platform):this.platform==="win32"?new T(this.platform):new x(this.platform)}countWindows(e){return this.attachBackend().countWindows(e)}listTargets(e){return this.attachBackend().listTargets(e)}runAt(e,r,a){return this.attachBackend().runAt(e,r,a)}focusTarget(e,r){return this.attachBackend().focusTarget(e,r)}listPromptPanes(){return this.attachBackend().listPromptPanes()}locatePane(e){return this.attachBackend().locatePane(e)}locateScreens(e){return this.attachBackend().locateScreens(e)}sendPromptText(e,r){return this.attachBackend().sendPromptText(e,r)}sendKeys(e,r){return this.attachBackend().sendKeys(e,r)}getPaneText(e){return this.attachBackend().getPaneText(e)}closePane(e){return this.attachBackend().closePane(e)}}const g={auto:(t,e)=>new v(e),wt:(t,e)=>new T(e),powershell:(t,e)=>new u("powershell",e,w.powershell),cmd:(t,e)=>new u("cmd",e,w.cmd),terminal:(t,e)=>new k(e),iterm:(t,e)=>new A(e),gnome:(t,e)=>new u("gnome",e,w.gnome),konsole:(t,e)=>new E(e),ghostty:(t,e)=>new b(e),wezterm:(t,e)=>new x(e),custom:(t,e)=>new I(t,e)};export function terminalBackendFor(t,e=process.platform){return(g[t.preset]??g.auto)(t,e)}export function locatorPresetOf(t){for(const[e,r]of Object.entries(h))if(r.every(a=>t[a]))return e;return null}export function promptTerminalChannel(t){const e=n=>terminalBackendFor({...t(),preset:n}),r=()=>e(t().preset),a=()=>Object.keys(h).map(n=>e(n)),s=n=>{const o=locatorPresetOf(n);return o?e(o):null},c=n=>a().find(o=>o.ownsPaneId(n))??null;return{available:()=>a().some(n=>n.textAddressable),listPanes:async()=>{const n=r();return n.textAddressable?await n.listPromptPanes():[]},locatePane:async n=>await s(n)?.locatePane(n)??null,locateScreens:async n=>{const o={},i=new Map;for(const[l,m]of Object.entries(n)){const p=locatorPresetOf(m);if(!p){o[l]=null;continue}const d=i.get(p)??{};d[l]=m,i.set(p,d)}for(const[l,m]of i){const p=e(l);if(!p.locateScreens){for(const f of Object.keys(m))o[f]=null;continue}const d=await p.locateScreens(m);for(const[f,y]of Object.entries(d))o[f]=y}return o},sendText:async(n,o)=>{const i=c(n);if(!i)throw new Error(`Invalid prompt pane "${n}"`);await i.sendPromptText(n,o)},sendKeys:async(n,o)=>{const i=c(n);if(!i)throw new Error(`Invalid prompt pane "${n}"`);await i.sendKeys(n,o)},getPaneText:async n=>{const o=c(n);if(!o)throw new Error(`Invalid prompt pane "${n}"`);return o.getPaneText(n)},closePane:async n=>{const o=c(n);if(!o)throw new Error(`Invalid prompt pane "${n}"`);await o.closePane(n)}}}export async function runInTerminal(t,e,r){return terminalBackendFor(r).run(t,e)}export async function countOpenTerminals(t,e){return terminalBackendFor(e).countWindows(t)}export function panesAtDir(t,e,r=process.platform){const a=P(e,r);return t.filter(s=>s.cwd!=null&&P(s.cwd,r)===a)}export async function listProjectPanes(t,e,r=process.platform){const a=terminalBackendFor(e,r),s=panesAtDir(await a.listPromptPanes(),t,r);if(s.length===0&&((await a.countWindows([t])).get(t)??0)>0)throw new Error(`Terminal preset "${a.preset}" cannot close open panes remotely \u2014 pick wezterm in settings`);return s}export async function closeTerminalsIn(t,e,r,a=process.platform){const s=terminalBackendFor(e,a),c=new Set(r),n=(await listProjectPanes(t,e,a)).filter(o=>c.has(o.id));for(const o of n)await s.closePane(o.id);return n.length}export async function readTerminalCounts(t,e=void 0){const r=await B(),s=await(e?.countTerminals??countOpenTerminals)(t.map(c=>c.path),r.terminal);return Object.fromEntries(t.map(c=>[c.id,s.get(c.path)??0]))}export function resolveTerminalLaunch(t,e,r=process.platform,a){return terminalBackendFor(e,r).candidates(t,a)}export function resolveExplorerLaunch(t,e=process.platform){return e==="win32"?{command:"explorer.exe",args:[t]}:e==="darwin"?{command:"open",args:[t]}:{command:"xdg-open",args:[t]}}export async function openInExplorer(t){const e=resolveExplorerLaunch(t);if(!await W(e))throw new Error(`Failed to open file manager (${e.command})`)}export async function openInTerminal(t,e){await terminalBackendFor(e).open(t)}export const defaultProjectOpener={openExplorer:openInExplorer,openTerminal:openInTerminal,runInTerminal,countTerminals:countOpenTerminals,closeTerminals:(t,e,r)=>closeTerminalsIn(t,e,r),listPanes:(t,e)=>listProjectPanes(t,e),listTerminals:(t,e)=>terminalBackendFor(e).listTargets(t),runInTerminalAt:(t,e,r,a)=>terminalBackendFor(a).runAt(t,e,r),focusTerminal:(t,e,r)=>terminalBackendFor(r).focusTarget(t,e)};
@@ -1 +1 @@
1
- import{z as a}from"zod";import{readJson as g,sendJson as s}from"../http.js";import{composeAnswerAtoms as C}from"../../hooks/answer-keys.js";import{readSideQuestions as O}from"../../hooks/side-questions.js";const Q=a.object({question:a.string().min(1).max(4e3)}),U=a.object({model:a.string().min(1).max(128)}),$=a.object({level:a.string().min(1).max(32)}),j=a.object({answers:a.array(a.object({questionKey:a.string().min(1),options:a.array(a.number().int().min(0)).max(32),text:a.string().max(2e3).optional()})).min(1)}),A=1200;async function P(i,r){await new Promise(u=>setTimeout(u,A));const e=i();return e!==null&&e>r}export async function handleSessionControlRoutes(i,r,e,u,b){const h=u.match(/^\/sessions\/([^/]+)\/interrupt$/);if(h&&i.method==="POST"){if(!e.messageDeliverer)return s(r,503,{error:"Messaging subsystem unavailable"}),!0;const t=decodeURIComponent(h[1]),o=e.sessionProbe,n=e.hookSessions?.getBySessionId(t)??null,c=!!o&&!!n&&o.transcriptPresent(t)!==null,m=()=>c?o.interruptedAt(t,n.lastSeenAt)??null:null,l=m()??0,f=await e.messageDeliverer.interrupt(t);if(!f.ok)return s(r,f.status,{error:f.error}),!0;let d=null;if(c&&(d=await P(m,l),d===!1)){const D=await e.messageDeliverer.interrupt(t,"heuristic",f.paneId);D.ok&&D.sent&&(d=await P(m,l))}return setTimeout(()=>e.interruptRefresher?.tick(),1500),s(r,200,{ok:!0,sessionId:t,interrupted:d}),!0}const k=u.match(/^\/sessions\/([^/]+)\/close-pane$/);if(k&&i.method==="POST"){if(!e.messageDeliverer)return s(r,503,{error:"Messaging subsystem unavailable"}),!0;const t=decodeURIComponent(k[1]),o=await e.messageDeliverer.closePane(t);return o.ok?(setTimeout(()=>{e.livenessRefresher?.tick(),e.terminalRefresher?.refreshNow()},600),s(r,200,{ok:!0,sessionId:t}),!0):(s(r,o.status,{error:o.error}),!0)}const v=u.match(/^\/sessions\/([^/]+)\/mode$/);if(v&&i.method==="POST"){if(!e.messageDeliverer)return s(r,503,{error:"Messaging subsystem unavailable"}),!0;const t=decodeURIComponent(v[1]),o=await e.messageDeliverer.cycleMode(t);return o.ok?(s(r,200,{ok:!0,sessionId:t}),!0):(s(r,o.status,{error:o.error}),!0)}const I=u.match(/^\/sessions\/([^/]+)\/enter$/);if(I&&i.method==="POST"){if(!e.messageDeliverer)return s(r,503,{error:"Messaging subsystem unavailable"}),!0;const t=decodeURIComponent(I[1]),o=await e.messageDeliverer.pressEnter(t);return o.ok?(s(r,200,{ok:!0,sessionId:t}),!0):(s(r,o.status,{error:o.error}),!0)}const w=u.match(/^\/sessions\/([^/]+)\/ctrl-c$/);if(w&&i.method==="POST"){if(!e.messageDeliverer)return s(r,503,{error:"Messaging subsystem unavailable"}),!0;const t=decodeURIComponent(w[1]),o=await e.messageDeliverer.pressCtrlC(t);return o.ok?(s(r,200,{ok:!0,sessionId:t}),!0):(s(r,o.status,{error:o.error}),!0)}const y=u.match(/^\/sessions\/([^/]+)\/model$/);if(y&&i.method==="POST"){if(!e.messageDeliverer)return s(r,503,{error:"Messaging subsystem unavailable"}),!0;const t=decodeURIComponent(y[1]),o=U.parse(await g(i)),n=await e.messageDeliverer.setModel(t,o.model);return n.ok?(setTimeout(()=>e.interruptRefresher?.tick(),1500),s(r,200,{ok:!0,sessionId:t}),!0):(s(r,n.status,{error:n.error}),!0)}const M=u.match(/^\/sessions\/([^/]+)\/effort$/);if(M&&i.method==="POST"){if(!e.messageDeliverer)return s(r,503,{error:"Messaging subsystem unavailable"}),!0;const t=decodeURIComponent(M[1]),o=$.parse(await g(i)),n=await e.messageDeliverer.setEffort(t,o.level);return n.ok?(s(r,200,{ok:!0,sessionId:t}),!0):(s(r,n.status,{error:n.error}),!0)}if(u==="/messaging/questions"&&i.method==="GET")return e.questionTracker?(s(r,200,{questions:e.questionTracker.snapshot()}),!0):(s(r,503,{error:"Question tracking unavailable"}),!0);const T=u.match(/^\/sessions\/([^/]+)\/answer$/);if(T&&i.method==="POST"){if(!e.questionTracker||!e.messageDeliverer)return s(r,503,{error:"Question tracking unavailable"}),!0;const t=decodeURIComponent(T[1]);let o;try{o=j.parse(await g(i))}catch(l){return s(r,400,{error:l instanceof Error?l.message:"Invalid body"}),!0}const n=e.questionTracker.get(t);if(!n)return s(r,409,{error:"Session has no pending question"}),!0;const c=C(n.questions,o.answers);if(!c.ok)return s(r,400,{error:c.error}),!0;const m=await e.messageDeliverer.answer(t,c.atoms);return m.ok?(e.questionTracker.markAnswered(t),s(r,200,{ok:!0,sessionId:t}),!0):(s(r,m.status,{error:m.error}),!0)}const S=u.match(/^\/sessions\/([^/]+)\/side-question$/);if(S&&i.method==="POST"){if(!e.messageDeliverer||!e.sideQuestions)return s(r,503,{error:"Messaging subsystem unavailable"}),!0;const t=decodeURIComponent(S[1]);let o;try{o=Q.parse(await g(i))}catch(m){return s(r,400,{error:m instanceof Error?m.message:"Invalid body"}),!0}const n=await e.messageDeliverer.askSideQuestion(t,o.question);if(!n.ok)return s(r,n.status,{error:n.error}),!0;const c=e.sideQuestions.repo.insert({sessionId:t,projectId:e.hookSessions?.getBySessionId(t)?.projectId??null,question:n.question});return s(r,200,{ok:!0,sideQuestion:c}),!0}const R=u.match(/^\/sessions\/([^/]+)\/side-questions$/);if(R&&i.method==="GET"){if(!e.sideQuestions)return s(r,503,{error:"Messaging subsystem unavailable"}),!0;const t=decodeURIComponent(R[1]),o=Number(b.searchParams.get("limit")),n=Number(b.searchParams.get("beforeId")),c=O(e.sideQuestions,t,{limit:Number.isFinite(o)&&o>0?Math.min(o,100):20,beforeId:Number.isFinite(n)&&n>0?n:void 0});return s(r,200,{sideQuestions:c}),!0}return!1}
1
+ import{z as u}from"zod";import{readJson as l,sendJson as r}from"../http.js";import{composeAnswerAtoms as D}from"../../hooks/answer-keys.js";import{readSideQuestions as R}from"../../hooks/side-questions.js";const S=u.object({question:u.string().min(1).max(4e3)}),C=u.object({model:u.string().min(1).max(128)}),P=u.object({level:u.string().min(1).max(32)}),Q=u.object({answers:u.array(u.object({questionKey:u.string().min(1),options:u.array(u.number().int().min(0)).max(32),text:u.string().max(2e3).optional()})).min(1)});export async function handleSessionControlRoutes(i,e,s,a,f){const d=a.match(/^\/sessions\/([^/]+)\/interrupt$/);if(d&&i.method==="POST"){if(!s.messageDeliverer)return r(e,503,{error:"Messaging subsystem unavailable"}),!0;const o=decodeURIComponent(d[1]),t=await s.messageDeliverer.interrupt(o);return t.ok?(setTimeout(()=>s.interruptRefresher?.tick(),1500),setTimeout(()=>s.interruptRefresher?.tick(),12e3),r(e,200,{ok:!0,sessionId:o,confirmed:t.confirmed}),!0):(r(e,t.status,{error:t.error}),!0)}const g=a.match(/^\/sessions\/([^/]+)\/close-pane$/);if(g&&i.method==="POST"){if(!s.messageDeliverer)return r(e,503,{error:"Messaging subsystem unavailable"}),!0;const o=decodeURIComponent(g[1]),t=await s.messageDeliverer.closePane(o);return t.ok?(setTimeout(()=>{s.livenessRefresher?.tick(),s.terminalRefresher?.refreshNow()},600),r(e,200,{ok:!0,sessionId:o}),!0):(r(e,t.status,{error:t.error}),!0)}const b=a.match(/^\/sessions\/([^/]+)\/mode$/);if(b&&i.method==="POST"){if(!s.messageDeliverer)return r(e,503,{error:"Messaging subsystem unavailable"}),!0;const o=decodeURIComponent(b[1]),t=await s.messageDeliverer.cycleMode(o);return t.ok?(r(e,200,{ok:!0,sessionId:o}),!0):(r(e,t.status,{error:t.error}),!0)}const h=a.match(/^\/sessions\/([^/]+)\/enter$/);if(h&&i.method==="POST"){if(!s.messageDeliverer)return r(e,503,{error:"Messaging subsystem unavailable"}),!0;const o=decodeURIComponent(h[1]),t=await s.messageDeliverer.pressEnter(o);return t.ok?(r(e,200,{ok:!0,sessionId:o}),!0):(r(e,t.status,{error:t.error}),!0)}const v=a.match(/^\/sessions\/([^/]+)\/ctrl-c$/);if(v&&i.method==="POST"){if(!s.messageDeliverer)return r(e,503,{error:"Messaging subsystem unavailable"}),!0;const o=decodeURIComponent(v[1]),t=await s.messageDeliverer.pressCtrlC(o);return t.ok?(r(e,200,{ok:!0,sessionId:o}),!0):(r(e,t.status,{error:t.error}),!0)}const k=a.match(/^\/sessions\/([^/]+)\/model$/);if(k&&i.method==="POST"){if(!s.messageDeliverer)return r(e,503,{error:"Messaging subsystem unavailable"}),!0;const o=decodeURIComponent(k[1]),t=C.parse(await l(i)),n=await s.messageDeliverer.setModel(o,t.model);return n.ok?(setTimeout(()=>s.interruptRefresher?.tick(),1500),r(e,200,{ok:!0,sessionId:o}),!0):(r(e,n.status,{error:n.error}),!0)}const y=a.match(/^\/sessions\/([^/]+)\/effort$/);if(y&&i.method==="POST"){if(!s.messageDeliverer)return r(e,503,{error:"Messaging subsystem unavailable"}),!0;const o=decodeURIComponent(y[1]),t=P.parse(await l(i)),n=await s.messageDeliverer.setEffort(o,t.level);return n.ok?(r(e,200,{ok:!0,sessionId:o}),!0):(r(e,n.status,{error:n.error}),!0)}if(a==="/messaging/questions"&&i.method==="GET")return s.questionTracker?(r(e,200,{questions:s.questionTracker.snapshot()}),!0):(r(e,503,{error:"Question tracking unavailable"}),!0);const I=a.match(/^\/sessions\/([^/]+)\/answer$/);if(I&&i.method==="POST"){if(!s.questionTracker||!s.messageDeliverer)return r(e,503,{error:"Question tracking unavailable"}),!0;const o=decodeURIComponent(I[1]);let t;try{t=Q.parse(await l(i))}catch(T){return r(e,400,{error:T instanceof Error?T.message:"Invalid body"}),!0}const n=s.questionTracker.get(o);if(!n)return r(e,409,{error:"Session has no pending question"}),!0;const c=D(n.questions,t.answers);if(!c.ok)return r(e,400,{error:c.error}),!0;const m=await s.messageDeliverer.answer(o,c.atoms);return m.ok?(s.questionTracker.markAnswered(o),r(e,200,{ok:!0,sessionId:o}),!0):(r(e,m.status,{error:m.error}),!0)}const w=a.match(/^\/sessions\/([^/]+)\/side-question$/);if(w&&i.method==="POST"){if(!s.messageDeliverer||!s.sideQuestions)return r(e,503,{error:"Messaging subsystem unavailable"}),!0;const o=decodeURIComponent(w[1]);let t;try{t=S.parse(await l(i))}catch(m){return r(e,400,{error:m instanceof Error?m.message:"Invalid body"}),!0}const n=await s.messageDeliverer.askSideQuestion(o,t.question);if(!n.ok)return r(e,n.status,{error:n.error}),!0;const c=s.sideQuestions.repo.insert({sessionId:o,projectId:s.hookSessions?.getBySessionId(o)?.projectId??null,question:n.question});return r(e,200,{ok:!0,sideQuestion:c}),!0}const M=a.match(/^\/sessions\/([^/]+)\/side-questions$/);if(M&&i.method==="GET"){if(!s.sideQuestions)return r(e,503,{error:"Messaging subsystem unavailable"}),!0;const o=decodeURIComponent(M[1]),t=Number(f.searchParams.get("limit")),n=Number(f.searchParams.get("beforeId")),c=R(s.sideQuestions,o,{limit:Number.isFinite(t)&&t>0?Math.min(t,100):20,beforeId:Number.isFinite(n)&&n>0?n:void 0});return r(e,200,{sideQuestions:c}),!0}return!1}
@@ -1 +1 @@
1
- import{readFileSync as C}from"node:fs";import y from"node:path";import{isHarness as _}from"@weavecode/core";import{sendJson as i}from"../http.js";import{blockingPromptFor as R,commandsSurfaceFor as j,editSurfaceFor as F,narrationSurfaceFor as N}from"../../surfaces.js";function E(o,t,n){if(!t.hookSessions||!t.hookEvents)return i(o,503,{error:"Hooks subsystem unavailable"}),null;const r=t.hookSessions.getBySessionId(n);if(!r)return i(o,404,{error:"Session not found"}),null;if(r.projectId==null)return i(o,400,{error:"Session is not bound to a project"}),null;const f=t.projects.getById(r.projectId);return f||(i(o,404,{error:"Project not found"}),null)}function S(o,t){if(!o.hookEvents)return null;const n=o.hookEvents.listBySession(t,1),r=n[n.length-1]?.source;return _(r)?r:null}const v=20,O=2e5;function H(o){try{const t=JSON.parse(o);return[typeof t.toolName=="string"?t.toolName:null,t.toolInput??null,t.toolResponse??null]}catch{return[null,null,null]}}function w(o){if(!o)return null;try{const t=C(o,"utf8");return t.trim()?t:null}catch{return null}}const x=2e5,B=4e6;function G(o,t){const n=y.relative(t,o);return(!!n&&!n.startsWith("..")&&!y.isAbsolute(n)?n:o).split(y.sep).join("/")}function M(o){if(!o)return null;const t=Date.parse(o);return Number.isFinite(t)?t:null}function U(o,t,n){if(t===null&&n===null)return!0;if(!o)return!1;const r=Date.parse(o);return!(!Number.isFinite(r)||t!==null&&r<=t||n!==null&&r>n)}function $(o,t){const n=[],r=new Map;let f=B,I=0,h=!1;for(const c of o){const d=c.hunk.before.slice(0,x),p=c.hunk.after.slice(0,x),P=d.length<c.hunk.before.length||p.length<c.hunk.after.length;P&&(h=!0);const e=d.length+p.length;if(e>f){h=!0;continue}f-=e;const s=G(c.path,t);let u=r.get(s);u||(u={path:s,hunks:[]},r.set(s,u),n.push(u)),u.hunks.push({before:d,after:p,at:c.at,...P?{clamped:!0}:{}}),I++}return{files:n,hunks:I,truncated:h}}export async function handleSessionInsightRoutes(o,t,n,r,f){const I=r.match(/^\/sessions\/([^/]+)\/plan$/);if(I&&o.method==="GET"){const e=decodeURIComponent(I[1]);if(!n.hookEvents)return i(t,503,{error:"Hook ingestion unavailable"}),!0;const s=n.hookEvents.listBySession(e,1),u=s[s.length-1]?.source,l=_(u)?R(u)?.plan??null:null;if(!l)return i(t,200,{plan:null}),!0;const m=g=>g.flatMap(T=>{const A=l.draftOf(...H(T.payload));return A?[{row:T,draft:A}]:[]}),[a]=m(n.hookEvents.listByTools(e,[l.tool],null,v));if(!a)return i(t,200,{plan:null}),!0;const[k]=m(n.hookEvents.listByTools(e,l.writeTools,l.fileHint,v)).filter(g=>g.row.id<a.row.id),b=a.draft.text??w(a.draft.filePath)??k?.draft.text??w(k?.draft.filePath??null);return b?(i(t,200,{plan:{eventId:a.row.id,at:a.row.createdAt,text:b.slice(0,O)}}),!0):(i(t,200,{plan:null}),!0)}const h=r.match(/^\/sessions\/([^/]+)\/pre-question$/);if(h&&o.method==="GET"){const e=decodeURIComponent(h[1]);if(!E(t,n,e))return!0;const s=S(n,e),l=await(s?R(s):null)?.preQuestion?.(n.sessionProbe?.transcriptPathOf(e)??null);return i(t,200,{preQuestion:l??null}),!0}const c=r.match(/^\/sessions\/([^/]+)\/narration$/);if(c&&o.method==="GET"){const e=decodeURIComponent(c[1]);if(!E(t,n,e))return!0;const s=S(n,e),u=s?N(s):null;if(!u)return i(t,200,{supported:!1,narration:null}),!0;const l=await u.sessionNarration({sessionId:e,transcriptPath:n.sessionProbe?.transcriptPathOf(e)??null});return i(t,200,{supported:l!==null,narration:l}),!0}const d=r.match(/^\/sessions\/([^/]+)\/commands$/);if(d&&o.method==="GET"){const e=decodeURIComponent(d[1]),s=E(t,n,e);if(!s)return!0;const u=S(n,e),l=u?j(u):null;return l?(i(t,200,{supported:!0,commands:await l.list({projectPath:s.path})}),!0):(i(t,200,{supported:!1,commands:[]}),!0)}const p=r.match(/^\/sessions\/([^/]+)\/command-executions$/);if(p&&o.method==="GET"){const e=decodeURIComponent(p[1]);if(!E(t,n,e))return!0;const s=S(n,e),u=s?j(s):null;if(!u)return i(t,200,{supported:!1,executions:null}),!0;const l=await u.executions(n.sessionProbe?.transcriptPathOf(e)??null);return i(t,200,{supported:l!==null,executions:l}),!0}const P=r.match(/^\/sessions\/([^/]+)\/edits$/);if(P&&o.method==="GET"){const e=decodeURIComponent(P[1]),s=E(t,n,e);if(!s)return!0;const u=S(n,e),l=u?F(u):null;if(!l)return i(t,200,{files:null,hunks:0,truncated:!1,reason:"unsupported"}),!0;const m=await l.sessionEdits({sessionId:e,transcriptPath:n.sessionProbe?.transcriptPathOf(e)??null});if(!m)return i(t,200,{files:null,hunks:0,truncated:!1,reason:"unreadable"}),!0;const a=M(f.searchParams.get("since")),k=M(f.searchParams.get("until")),b=a!==null||k!==null?m.filter(g=>U(g.at,a,k)):m;return i(t,200,$(b,s.path)),!0}return!1}
1
+ import{readFileSync as U}from"node:fs";import T from"node:path";import{isHarness as j}from"@weavecode/core";import{sendJson as c}from"../http.js";import{blockingPromptFor as v,commandsSurfaceFor as x,editSurfaceFor as $,narrationSurfaceFor as D,rewindSurfaceFor as L}from"../../surfaces.js";function g(o,t,n){if(!t.hookSessions||!t.hookEvents)return c(o,503,{error:"Hooks subsystem unavailable"}),null;const u=t.hookSessions.getBySessionId(n);if(!u)return c(o,404,{error:"Session not found"}),null;if(u.projectId==null)return c(o,400,{error:"Session is not bound to a project"}),null;const f=t.projects.getById(u.projectId);return f||(c(o,404,{error:"Project not found"}),null)}function k(o,t){if(!o.hookEvents)return null;const n=o.hookEvents.listBySession(t,1),u=n[n.length-1]?.source;return j(u)?u:null}const F=20,X=2e3,Q=200,C=new Map,W=2e5;function z(o){try{const t=JSON.parse(o);return[typeof t.toolName=="string"?t.toolName:null,t.toolInput??null,t.toolResponse??null]}catch{return[null,null,null]}}function H(o){if(!o)return null;try{const t=U(o,"utf8");return t.trim()?t:null}catch{return null}}const B=2e5,J=4e6;function K(o,t){const n=T.relative(t,o);return(!!n&&!n.startsWith("..")&&!T.isAbsolute(n)?n:o).split(T.sep).join("/")}function G(o){if(!o)return null;const t=Date.parse(o);return Number.isFinite(t)?t:null}function V(o,t,n){if(t===null&&n===null)return!0;if(!o)return!1;const u=Date.parse(o);return!(!Number.isFinite(u)||t!==null&&u<=t||n!==null&&u>n)}function Y(o,t){const n=[],u=new Map;let f=J,w=0,d=!1;for(const l of o){const h=l.hunk.before.slice(0,B),p=l.hunk.after.slice(0,B),E=h.length<l.hunk.before.length||p.length<l.hunk.after.length;E&&(d=!0);const S=h.length+p.length;if(S>f){d=!0;continue}f-=S;const e=K(l.path,t);let s=u.get(e);s||(s={path:e,hunks:[]},u.set(e,s),n.push(s)),s.hunks.push({before:h,after:p,at:l.at,...E?{clamped:!0}:{}}),w++}return{files:n,hunks:w,truncated:d}}export async function handleSessionInsightRoutes(o,t,n,u,f){const w=u.match(/^\/sessions\/([^/]+)\/plan$/);if(w&&o.method==="GET"){const e=decodeURIComponent(w[1]);if(!n.hookEvents)return c(t,503,{error:"Hook ingestion unavailable"}),!0;const s=n.hookEvents.listBySession(e,1),i=s[s.length-1]?.source,r=j(i)?v(i)?.plan??null:null;if(!r)return c(t,200,{plan:null}),!0;const m=a=>a.flatMap(M=>{const y=r.draftOf(...z(M.payload));return y?[{row:M,draft:y}]:[]}),I=s[s.length-1]?.id??0,b=n.hookEvents,A=C.get(e);if(A&&A.latestId===I)return c(t,200,{plan:A.plan}),!0;const _=a=>(C.size>=Q&&C.clear(),C.set(e,{latestId:I,plan:a}),c(t,200,{plan:a}),!0),R=(a,M)=>{const y=b.listByTools(e,a,M,F,I-X);return y.length>0?y:b.listByTools(e,a,M,F)},[P]=m(R([r.tool],null));if(!P)return _(null);const[N]=m(R(r.writeTools,r.fileHint)).filter(a=>a.row.id<P.row.id),O=P.draft.text??H(P.draft.filePath)??N?.draft.text??H(N?.draft.filePath??null);return _(O?{eventId:P.row.id,at:P.row.createdAt,text:O.slice(0,W)}:null)}const d=u.match(/^\/sessions\/([^/]+)\/pre-question$/);if(d&&o.method==="GET"){const e=decodeURIComponent(d[1]);if(!g(t,n,e))return!0;const s=k(n,e),r=await(s?v(s):null)?.preQuestion?.(n.sessionProbe?.transcriptPathOf(e)??null);return c(t,200,{preQuestion:r??null}),!0}const l=u.match(/^\/sessions\/([^/]+)\/narration$/);if(l&&o.method==="GET"){const e=decodeURIComponent(l[1]);if(!g(t,n,e))return!0;const s=k(n,e),i=s?D(s):null;if(!i)return c(t,200,{supported:!1,narration:null}),!0;const r=await i.sessionNarration({sessionId:e,transcriptPath:n.sessionProbe?.transcriptPathOf(e)??null});return c(t,200,{supported:r!==null,narration:r}),!0}const h=u.match(/^\/sessions\/([^/]+)\/rewinds$/);if(h&&o.method==="GET"){const e=decodeURIComponent(h[1]);if(!g(t,n,e))return!0;const s=k(n,e),i=s?L(s):null;if(!i)return c(t,200,{supported:!1,rewinds:null}),!0;const r=await i.sessionRewinds({sessionId:e,transcriptPath:n.sessionProbe?.transcriptPathOf(e)??null});return c(t,200,{supported:r!==null,rewinds:r}),!0}const p=u.match(/^\/sessions\/([^/]+)\/commands$/);if(p&&o.method==="GET"){const e=decodeURIComponent(p[1]),s=g(t,n,e);if(!s)return!0;const i=k(n,e),r=i?x(i):null;return r?(c(t,200,{supported:!0,commands:await r.list({projectPath:s.path}),inputModes:r.inputModes}),!0):(c(t,200,{supported:!1,commands:[],inputModes:[]}),!0)}const E=u.match(/^\/sessions\/([^/]+)\/command-executions$/);if(E&&o.method==="GET"){const e=decodeURIComponent(E[1]);if(!g(t,n,e))return!0;const s=k(n,e),i=s?x(s):null;if(!i)return c(t,200,{supported:!1,executions:null}),!0;const r=await i.executions(n.sessionProbe?.transcriptPathOf(e)??null);return c(t,200,{supported:r!==null,executions:r}),!0}const S=u.match(/^\/sessions\/([^/]+)\/edits$/);if(S&&o.method==="GET"){const e=decodeURIComponent(S[1]),s=g(t,n,e);if(!s)return!0;const i=k(n,e),r=i?$(i):null;if(!r)return c(t,200,{files:null,hunks:0,truncated:!1,reason:"unsupported"}),!0;const m=await r.sessionEdits({sessionId:e,transcriptPath:n.sessionProbe?.transcriptPathOf(e)??null});if(!m)return c(t,200,{files:null,hunks:0,truncated:!1,reason:"unreadable"}),!0;const I=G(f.searchParams.get("since")),b=G(f.searchParams.get("until")),A=I!==null||b!==null?m.filter(_=>V(_.at,I,b)):m;return c(t,200,Y(A,s.path)),!0}return!1}
@@ -1 +1 @@
1
- import{createReadStream as B}from"node:fs";import{z as d}from"zod";import{readJson as p,readRawBody as E,sendJson as r}from"../http.js";import{isImageMediaType as I,maxUploadBytes as g}from"../../repositories/uploads.js";import{defaultUploadSessions as S}from"../upload-sessions.js";const w=d.object({name:d.string().min(1).max(200),mediaType:d.string().min(1).max(100),data:d.string().min(1),projectId:d.number().int().positive().optional()}),j=d.object({name:d.string().min(1).max(200),mediaType:d.string().min(1).max(100),size:d.number().int().positive(),projectId:d.number().int().positive().optional()});function z(i,e){return(I(e)?i?.images:i?.files)??null}const x=16*1024*1024;function y(i,e){return{id:e.id,name:e.name,mediaType:e.mediaType,size:e.size,path:i.uploads.filePath(e.id,e.mediaType,e.name,e.dir??i.uploads.defaultDir)}}function T(i,e,o){if(!i.projects.getById(e))return null;const c=i.projects.getMeta(e);return z(c?.storage,o)}export async function handleUploadRoutes(i,e,o,s,c){const l=o.uploadSessions??S;if(s==="/uploads/begin"&&i.method==="POST"){if(!o.uploads)return r(e,503,{error:"Upload subsystem unavailable"}),!0;let t;try{t=j.parse(await p(i))}catch(n){return r(e,400,{error:n instanceof Error?n.message:"Invalid body"}),!0}if(t.size>g(t.mediaType))return r(e,413,{error:"File too large"}),!0;const a=t.projectId?T(o,t.projectId,t.mediaType):null,u=await l.begin({...t,dir:a});return r(e,201,{uploadId:u.id,received:0,size:u.size}),!0}const f=s.match(/^\/uploads\/([0-9a-f-]{36})\/finish$/);if(f&&i.method==="POST"){if(!o.uploads)return r(e,503,{error:"Upload subsystem unavailable"}),!0;const t=await l.finish(f[1]);if(!t)return r(e,409,{error:"Upload incomplete"}),!0;const a=await o.uploads.adoptFromFile(t);return await l.abort(f[1]),r(e,201,{upload:y(o,a)}),!0}const b=s.match(/^\/uploads\/([0-9a-f-]{36})$/);if(b){const t=b[1];if(i.method==="GET"){const a=await l.get(t);return a?(r(e,200,{received:a.received,size:a.size,name:a.name,mediaType:a.mediaType}),!0):(r(e,404,{error:"Upload not found"}),!0)}if(i.method==="PUT"){const a=Number(c.searchParams.get("offset")??"");if(!Number.isInteger(a)||a<0)return r(e,400,{error:"Invalid offset"}),!0;const u=await E(i,x).catch(()=>null);if(!u)return r(e,413,{error:"Chunk too large"}),!0;const n=await l.append(t,a,u);return n.kind==="missing"?(r(e,404,{error:"Upload not found"}),!0):n.kind==="conflict"?(r(e,409,{received:n.received}),!0):n.kind==="overflow"?(r(e,413,{received:n.received,error:"Exceeds declared size"}),!0):(r(e,200,{received:n.received}),!0)}if(i.method==="DELETE")return await l.abort(t),r(e,200,{ok:!0}),!0}if(s==="/uploads"&&i.method==="POST"){if(!o.uploads)return r(e,503,{error:"Upload subsystem unavailable"}),!0;let t;try{t=w.parse(await p(i))}catch(n){return r(e,400,{error:n instanceof Error?n.message:"Invalid body"}),!0}const a=Buffer.from(t.data,"base64");if(a.length===0)return r(e,400,{error:"Empty upload"}),!0;if(a.length>g(t.mediaType))return r(e,413,{error:"File too large"}),!0;const u=o.uploads.save({name:t.name,mediaType:t.mediaType,bytes:a,dir:t.projectId?T(o,t.projectId,t.mediaType):null});return r(e,201,{upload:y(o,u)}),!0}const m=s.match(/^\/sessions\/([^/]+)\/uploads$/);if(m&&i.method==="GET"){if(!o.uploads)return r(e,503,{error:"Upload subsystem unavailable"}),!0;const t=o.uploads.uploadsBySession(decodeURIComponent(m[1]));return r(e,200,{uploads:(t??[]).map(a=>({...y(o,a),createdAt:a.createdAt})),totalBytes:(t??[]).reduce((a,u)=>a+u.size,0)}),!0}if(m&&i.method==="DELETE"){if(!o.uploads)return r(e,503,{error:"Upload subsystem unavailable"}),!0;const t=o.uploads.uploadsBySession(decodeURIComponent(m[1]));if(!t)return r(e,200,{removed:0,freedBytes:0}),!0;const a=t.reduce((n,U)=>n+U.size,0),u=o.uploads.removeMany(t.map(n=>n.id));return o.dataBus?.emit({key:"sessions"}),r(e,200,{removed:u,freedBytes:a}),!0}if(s==="/uploads/unreferenced"&&i.method==="GET")return o.uploads?(r(e,200,o.uploads.unreferencedStats()),!0):(r(e,503,{error:"Upload subsystem unavailable"}),!0);if(s==="/uploads/overview"&&i.method==="GET")return o.uploads?(r(e,200,o.uploads.overview()),!0):(r(e,503,{error:"Upload subsystem unavailable"}),!0);const h=d.object({ids:d.array(d.string().regex(/^[a-f0-9]{64}$/)).min(1).max(500)});if(s==="/uploads/remove"&&i.method==="POST"){if(!o.uploads)return r(e,503,{error:"Upload subsystem unavailable"}),!0;let t;try{t=h.parse(await p(i))}catch(u){return r(e,400,{error:u instanceof Error?u.message:"Invalid body"}),!0}const a=o.uploads.removeMany(t.ids);return o.dataBus?.emit({key:"sessions"}),r(e,200,{removed:a}),!0}if(s==="/uploads/usage"&&i.method==="GET")return o.uploads?(r(e,200,{sessions:o.uploads.usageBySession()}),!0):(r(e,503,{error:"Upload subsystem unavailable"}),!0);if(s==="/uploads/unreferenced"&&i.method==="POST"){if(!o.uploads)return r(e,503,{error:"Upload subsystem unavailable"}),!0;let t={done:0,total:0};const a=o.uploads.cleanupUnreferenced((u,n)=>{t={done:u,total:n}});return o.dataBus?.emit({key:"sessions"}),r(e,200,{removed:a,...t}),!0}const v=s.match(/^\/images\/([a-f0-9]{64})$/);if(v&&i.method==="GET"){if(!o.uploads)return r(e,503,{error:"Upload subsystem unavailable"}),!0;const t=o.uploads.fileStatOf(v[1]);if(!t)return r(e,404,{error:"Image not found"}),!0;e.writeHead(200,{"content-type":t.row.mediaType,"content-length":String(t.size),"cache-control":"private, max-age=31536000, immutable"});const a=B(t.file);return a.on("error",()=>{typeof e.destroy=="function"&&e.destroy()}),a.pipe(e),!0}return!1}
1
+ import{createReadStream as B}from"node:fs";import{z as s}from"zod";import{readJson as p,readRawBody as E,sendJson as r}from"../http.js";import{isImageMediaType as w,maxUploadBytes as g}from"../../repositories/uploads.js";import{defaultUploadSessions as I}from"../upload-sessions.js";const S=s.object({name:s.string().min(1).max(200),mediaType:s.string().min(1).max(100),data:s.string().min(1),projectId:s.number().int().positive().optional()}),j=s.object({name:s.string().min(1).max(200),mediaType:s.string().min(1).max(100),size:s.number().int().positive(),projectId:s.number().int().positive().optional()});function z(i,e){return(w(e)?i?.images:i?.files)??null}const x=16*1024*1024;function y(i,e){return{id:e.id,name:e.name,mediaType:e.mediaType,size:e.size,path:i.uploads.pathOf(e)}}function h(i,e,o){if(!i.projects.getById(e))return null;const m=i.projects.getMeta(e);return z(m?.storage,o)}export async function handleUploadRoutes(i,e,o,d,m){const l=o.uploadSessions??I;if(d==="/uploads/begin"&&i.method==="POST"){if(!o.uploads)return r(e,503,{error:"Upload subsystem unavailable"}),!0;let t;try{t=j.parse(await p(i))}catch(n){return r(e,400,{error:n instanceof Error?n.message:"Invalid body"}),!0}if(t.size>g(t.mediaType))return r(e,413,{error:"File too large"}),!0;const a=t.projectId?h(o,t.projectId,t.mediaType):null,u=await l.begin({...t,dir:a});return r(e,201,{uploadId:u.id,received:0,size:u.size}),!0}const f=d.match(/^\/uploads\/([0-9a-f-]{36})\/finish$/);if(f&&i.method==="POST"){if(!o.uploads)return r(e,503,{error:"Upload subsystem unavailable"}),!0;const t=await l.finish(f[1]);if(!t)return r(e,409,{error:"Upload incomplete"}),!0;const a=await o.uploads.adoptFromFile(t);return await l.abort(f[1]),r(e,201,{upload:y(o,a)}),!0}const b=d.match(/^\/uploads\/([0-9a-f-]{36})$/);if(b){const t=b[1];if(i.method==="GET"){const a=await l.get(t);return a?(r(e,200,{received:a.received,size:a.size,name:a.name,mediaType:a.mediaType}),!0):(r(e,404,{error:"Upload not found"}),!0)}if(i.method==="PUT"){const a=Number(m.searchParams.get("offset")??"");if(!Number.isInteger(a)||a<0)return r(e,400,{error:"Invalid offset"}),!0;const u=await E(i,x).catch(()=>null);if(!u)return r(e,413,{error:"Chunk too large"}),!0;const n=await l.append(t,a,u);return n.kind==="missing"?(r(e,404,{error:"Upload not found"}),!0):n.kind==="conflict"?(r(e,409,{received:n.received}),!0):n.kind==="overflow"?(r(e,413,{received:n.received,error:"Exceeds declared size"}),!0):(r(e,200,{received:n.received}),!0)}if(i.method==="DELETE")return await l.abort(t),r(e,200,{ok:!0}),!0}if(d==="/uploads"&&i.method==="POST"){if(!o.uploads)return r(e,503,{error:"Upload subsystem unavailable"}),!0;let t;try{t=S.parse(await p(i))}catch(n){return r(e,400,{error:n instanceof Error?n.message:"Invalid body"}),!0}const a=Buffer.from(t.data,"base64");if(a.length===0)return r(e,400,{error:"Empty upload"}),!0;if(a.length>g(t.mediaType))return r(e,413,{error:"File too large"}),!0;const u=o.uploads.save({name:t.name,mediaType:t.mediaType,bytes:a,dir:t.projectId?h(o,t.projectId,t.mediaType):null});return r(e,201,{upload:y(o,u)}),!0}const c=d.match(/^\/sessions\/([^/]+)\/uploads$/);if(c&&i.method==="GET"){if(!o.uploads)return r(e,503,{error:"Upload subsystem unavailable"}),!0;const t=o.uploads.uploadsBySession(decodeURIComponent(c[1]));return r(e,200,{uploads:(t??[]).map(a=>({...y(o,a),createdAt:a.createdAt})),totalBytes:(t??[]).reduce((a,u)=>a+u.size,0)}),!0}if(c&&i.method==="DELETE"){if(!o.uploads)return r(e,503,{error:"Upload subsystem unavailable"}),!0;const t=o.uploads.uploadsBySession(decodeURIComponent(c[1]));if(!t)return r(e,200,{removed:0,freedBytes:0}),!0;const a=t.reduce((n,U)=>n+U.size,0),u=o.uploads.removeMany(t.map(n=>n.id));return o.dataBus?.emit({key:"sessions"}),r(e,200,{removed:u,freedBytes:a}),!0}if(d==="/uploads/unreferenced"&&i.method==="GET")return o.uploads?(r(e,200,o.uploads.unreferencedStats()),!0):(r(e,503,{error:"Upload subsystem unavailable"}),!0);if(d==="/uploads/overview"&&i.method==="GET")return o.uploads?(r(e,200,o.uploads.overview()),!0):(r(e,503,{error:"Upload subsystem unavailable"}),!0);const T=s.object({ids:s.array(s.string().regex(/^[a-f0-9]{64}$/)).min(1).max(500)});if(d==="/uploads/remove"&&i.method==="POST"){if(!o.uploads)return r(e,503,{error:"Upload subsystem unavailable"}),!0;let t;try{t=T.parse(await p(i))}catch(u){return r(e,400,{error:u instanceof Error?u.message:"Invalid body"}),!0}const a=o.uploads.removeMany(t.ids);return o.dataBus?.emit({key:"sessions"}),r(e,200,{removed:a}),!0}if(d==="/uploads/usage"&&i.method==="GET")return o.uploads?(r(e,200,{sessions:o.uploads.usageBySession()}),!0):(r(e,503,{error:"Upload subsystem unavailable"}),!0);if(d==="/uploads/unreferenced"&&i.method==="POST"){if(!o.uploads)return r(e,503,{error:"Upload subsystem unavailable"}),!0;let t={done:0,total:0};const a=o.uploads.cleanupUnreferenced((u,n)=>{t={done:u,total:n}});return o.dataBus?.emit({key:"sessions"}),r(e,200,{removed:a,...t}),!0}const v=d.match(/^\/images\/([a-f0-9]{64})$/);if(v&&i.method==="GET"){if(!o.uploads)return r(e,503,{error:"Upload subsystem unavailable"}),!0;const t=o.uploads.fileStatOf(v[1]);if(!t)return r(e,404,{error:"Image not found"}),!0;e.writeHead(200,{"content-type":t.row.mediaType,"content-length":String(t.size),"cache-control":"private, max-age=31536000, immutable"});const a=B(t.file);return a.on("error",()=>{typeof e.destroy=="function"&&e.destroy()}),a.pipe(e),!0}return!1}
@@ -0,0 +1,3 @@
1
+ import type { IncomingMessage, ServerResponse } from 'node:http';
2
+ import type { WeaveServerDeps } from '../server.js';
3
+ export declare function handleVisualizationRoutes(req: IncomingMessage, res: ServerResponse, deps: WeaveServerDeps, pathname: string, url: URL): Promise<boolean>;
@@ -0,0 +1 @@
1
+ import t from"node:path";import f from"node:os";import{promises as c}from"node:fs";import{HARNESS_DIRS as u,VISUALIZATION_PROTOCOL as g}from"@weavecode/core";import{sendJson as e}from"../http.js";import{isInsideDir as j}from"../../market/resolve.js";function w(s){const r=f.homedir(),o=[t.join(r,u.codex.userDir,"visualizations"),t.join(r,u.claude.userDir),t.join(r,u.codex.userDir,"plugins"),t.join(f.tmpdir(),"weave")];for(const a of s.projects.list())o.push(a.path);return o}export async function handleVisualizationRoutes(s,r,o,a,p){if(a!=="/visualizations/fragment"||s.method!=="GET")return!1;const n=p.searchParams.get("path")??"",i=t.resolve(n);if(!n||!t.isAbsolute(n))return e(r,400,{error:'Missing or relative "path" query parameter'}),!0;const l=w(o);if(!l.some(d=>j(i,d)))return e(r,403,{error:`Fragment path is outside the allowed roots: ${l.join(", ")}`}),!0;if(t.extname(i).toLowerCase()!==".html")return e(r,403,{error:"Only .html fragments are served"}),!0;let m;try{m=await c.stat(i)}catch{return e(r,404,{error:"Fragment file not found"}),!0}if(!m.isFile())return e(r,404,{error:"Fragment path is not a file"}),!0;if(m.size>g.maxFragmentBytes)return e(r,413,{error:"Fragment exceeds the 1 MB size limit"}),!0;const h=await c.readFile(i,"utf8");return r.setHeader("cache-control","no-store"),e(r,200,{html:h}),!0}
@@ -1,4 +1,4 @@
1
- import y from"node:http";import{WEAVE_VERSION as S}from"../version.js";import{isHarness as R}from"@weavecode/core";import h from"node:fs";import d from"node:path";import{SseHub as E}from"./sse-hub.js";import{importPromptImagesOnce as H,needsImageImport as N}from"./prompt-images.js";import{sendJson as u}from"./http.js";import{FingerprintCache as P}from"../install/fingerprint.js";import{ApiLogger as j}from"./api-log.js";import{handleHooksRoutes as k}from"./hooks-routes.js";import{handleMcpRequest as x}from"./mcp-orchestration.js";import{handleToolkitRoutes as I}from"./toolkit-routes.js";import{handleCaptureRoutes as T}from"./capture-routes.js";import{handleConfigRoutes as A}from"./config-routes.js";import{handleMarketRoutes as O}from"./routes/market.js";import{handleProjectRoutes as W}from"./routes/projects.js";import{handleSettingsRoutes as M}from"./routes/settings-statusline.js";import{handleSearchRoutes as C}from"./routes/search.js";import{handleProjectFileRoutes as B}from"./routes/project-files.js";import{DAEMON_HOST as J}from"./port.js";import{handleAuthRoutes as L}from"./auth-routes.js";import{handleAiRoutes as $}from"./ai-routes.js";export const DAEMON_VERSION=S;export function weaveRequestHandler(t){const n=t.fingerprintCache??new P,e=t.apiLog??new j,r=t.sseHub??new E(t),i={...t,fingerprintCache:n,apiLog:e,sseHub:r};return(s,o)=>{e.begin(s,o),D(s,o,i)}}export function createWeaveServer(t){return y.createServer(weaveRequestHandler(t))}async function D(t,n,e){const r=new URL(t.url??"/",`http://${J}`);let i=r.pathname;if(i.startsWith("/api/")?i=i.slice(4):i==="/api"&&(i="/"),i==="/health"&&t.method==="GET"){u(n,200,{service:"weave-daemon",version:DAEMON_VERSION,pid:process.pid,port:e.port,uptimeMs:Math.round(process.uptime()*1e3)});return}if(await L(t,n,e,i)||await $(t,n,e,i))return;if(e.auth&&!G(t,i,e)&&!e.auth.isAuthenticated(t.headers)){u(n,401,{error:"Unauthorized"});return}if(i==="/mcp"){await x(t,n,{port:e.port,token:e.auth?.getLocalToken()??null});return}if(i==="/api-logs"&&t.method==="GET"){if(!e.apiLog){u(n,503,{error:"API log unavailable"});return}const o=r.searchParams.get("status"),c=r.searchParams.get("limit"),a=await e.apiLog.query({from:r.searchParams.get("from")??void 0,to:r.searchParams.get("to")??void 0,path:r.searchParams.get("path")??void 0,method:r.searchParams.get("method")??void 0,status:o==null?void 0:Number(o),limit:c==null?void 0:Number(c)});u(n,200,a);return}if(await k(t,n,e,i,r)||await I(t,n,e,i,r)||await T(t,n,e,i)||await A(t,n,e,i,r))return;const s=i.match(/^\/projects\/(\d+)\/hooks$/);if(s&&t.method==="GET"){if(!e.hookEvents){u(n,503,{error:"Hook ingestion unavailable"});return}const o=Number(s[1]),c=Q(r.searchParams.get("limit")),a=r.searchParams.get("sessionId"),p=r.searchParams.get("beforeId"),m=p?Number(p):void 0,v=(r.searchParams.get("types")??"").split(",").map(f=>f.trim()).filter(Boolean);if(a){const f=e.hookEvents.listBySession(a,c??300,m,v);let b=e.uploads?.imagesBySession(a);if(N(f,b)){const l=e.projects.getMeta(o);await H({hookEvents:e.hookEvents,uploads:e.uploads,sessionProbe:e.sessionProbe,uploadDir:l?.storage?.images??null},a,K(f))&&(b=e.uploads?.imagesBySession(a))}u(n,200,{events:f.map(l=>{const w=b?.get(l.id);return w?.length?{...l,images:w.map(g=>({id:g.id,name:g.name,mediaType:g.mediaType,size:g.size}))}:l})});return}u(n,200,{events:e.hookEvents.listByProject(o,c)});return}if(!await O(t,n,e,i,r)&&!await M(t,n,e,i,r)&&!await C(t,n,e,i,r)&&!await B(t,n,e,i,r)){if(i==="/events"&&t.method==="GET"){z(t,n,e,r);return}if(!await W(t,n,e,i)){if(t.method==="GET"&&e.staticDir){V(n,i,e.staticDir);return}u(n,404,{error:"Not found"})}}}const F=25e3;function z(t,n,e,r){const i=e.sseHub;if(!i||!e.watch&&!e.hookBus&&!e.dataBus){n.statusCode=503,n.setHeader("content-type","application/json"),n.end(JSON.stringify({error:"Event stream unavailable"}));return}const s=t.headers["last-event-id"],o=(Array.isArray(s)?s[0]:s)??r.searchParams.get("since")??null,c=i.replay(o);n.writeHead(200,{"content-type":"text/event-stream","cache-control":"no-cache",connection:"keep-alive","x-accel-buffering":"no"}),n.write(`: connected
1
+ import y from"node:http";import{WEAVE_VERSION as S}from"../version.js";import{isHarness as R}from"@weavecode/core";import h from"node:fs";import d from"node:path";import{SseHub as E}from"./sse-hub.js";import{importPromptImagesOnce as H,needsImageImport as N}from"./prompt-images.js";import{sendJson as u}from"./http.js";import{FingerprintCache as j}from"../install/fingerprint.js";import{ApiLogger as k}from"./api-log.js";import{handleHooksRoutes as P}from"./hooks-routes.js";import{handleMcpRequest as x}from"./mcp-orchestration.js";import{handleToolkitRoutes as I}from"./toolkit-routes.js";import{handleCaptureRoutes as W}from"./capture-routes.js";import{handleConfigRoutes as T}from"./config-routes.js";import{handleMarketRoutes as A}from"./routes/market.js";import{handleProjectRoutes as O}from"./routes/projects.js";import{handleSettingsRoutes as M}from"./routes/settings-statusline.js";import{handleSearchRoutes as C}from"./routes/search.js";import{handleProjectFileRoutes as B}from"./routes/project-files.js";import{DAEMON_HOST as J}from"./port.js";import{handleAuthRoutes as L}from"./auth-routes.js";import{handleAiRoutes as $}from"./ai-routes.js";export const DAEMON_VERSION=S;export function weaveRequestHandler(t){const n=t.fingerprintCache??new j,e=t.apiLog??new k,r=t.sseHub??new E(t),i={...t,fingerprintCache:n,apiLog:e,sseHub:r};return(s,o)=>{e.begin(s,o),D(s,o,i)}}export function createWeaveServer(t){return y.createServer(weaveRequestHandler(t))}async function D(t,n,e){const r=new URL(t.url??"/",`http://${J}`);let i=r.pathname;if(i.startsWith("/api/")?i=i.slice(4):i==="/api"&&(i="/"),i==="/health"&&t.method==="GET"){u(n,200,{service:"weave-daemon",version:DAEMON_VERSION,pid:process.pid,port:e.port,uptimeMs:Math.round(process.uptime()*1e3)});return}if(await L(t,n,e,i)||await $(t,n,e,i))return;if(e.auth&&!G(t,i,e)&&!e.auth.isAuthenticated(t.headers)){u(n,401,{error:"Unauthorized"});return}if(i==="/mcp"){await x(t,n,{port:e.port,token:e.auth?.getLocalToken()??null});return}if(i==="/api-logs"&&t.method==="GET"){if(!e.apiLog){u(n,503,{error:"API log unavailable"});return}const o=r.searchParams.get("status"),c=r.searchParams.get("limit"),a=await e.apiLog.query({from:r.searchParams.get("from")??void 0,to:r.searchParams.get("to")??void 0,path:r.searchParams.get("path")??void 0,method:r.searchParams.get("method")??void 0,status:o==null?void 0:Number(o),limit:c==null?void 0:Number(c)});u(n,200,a);return}if(await P(t,n,e,i,r)||await I(t,n,e,i,r)||await W(t,n,e,i)||await T(t,n,e,i,r))return;const s=i.match(/^\/projects\/(\d+)\/hooks$/);if(s&&t.method==="GET"){if(!e.hookEvents){u(n,503,{error:"Hook ingestion unavailable"});return}const o=Number(s[1]),c=Q(r.searchParams.get("limit")),a=r.searchParams.get("sessionId"),p=r.searchParams.get("beforeId"),m=p?Number(p):void 0,v=(r.searchParams.get("types")??"").split(",").map(f=>f.trim()).filter(Boolean);if(a){const f=e.hookEvents.listBySession(a,c??300,m,v);let b=e.uploads?.imagesBySession(a);if(N(f,b)){const l=e.projects.getMeta(o);await H({hookEvents:e.hookEvents,uploads:e.uploads,sessionProbe:e.sessionProbe,uploadDir:l?.storage?.images??null},a,K(f))&&(b=e.uploads?.imagesBySession(a))}u(n,200,{events:f.map(l=>{const w=b?.get(l.id);return w?.length?{...l,images:w.map(g=>({id:g.id,name:g.name,mediaType:g.mediaType,size:g.size}))}:l})});return}u(n,200,{events:e.hookEvents.listByProject(o,c)});return}if(!await A(t,n,e,i,r)&&!await M(t,n,e,i,r)&&!await C(t,n,e,i,r)&&!await B(t,n,e,i,r)){if(i==="/events"&&t.method==="GET"){z(t,n,e,r);return}if(!await O(t,n,e,i)){if(t.method==="GET"&&e.staticDir){V(n,i,e.staticDir);return}u(n,404,{error:"Not found"})}}}const F=25e3;function z(t,n,e,r){const i=e.sseHub;if(!i||!e.watch&&!e.hookBus&&!e.dataBus){n.statusCode=503,n.setHeader("content-type","application/json"),n.end(JSON.stringify({error:"Event stream unavailable"}));return}const s=t.headers["last-event-id"],o=(Array.isArray(s)?s[0]:s)??r.searchParams.get("since")??null,c=i.replay(o);n.writeHead(200,{"content-type":"text/event-stream","cache-control":"no-cache",connection:"keep-alive","x-accel-buffering":"no"}),n.write(`: connected
2
2
 
3
3
  `);const a=setInterval(()=>{n.writableEnded||n.write(`data: ${JSON.stringify({type:"ping"})}
4
4
 
@@ -10,4 +10,4 @@ data: ${m.data}
10
10
  `);const p=i.subscribe(m=>{n.write(`id: ${m.id}
11
11
  data: ${m.data}
12
12
 
13
- `)});e.inflightRefresher?.refreshNow(),e.terminalRefresher?.onSubscriberJoin(),e.updatesRefresher?.onSubscriberJoin(),t.on("close",()=>{clearInterval(a),p()})}function G(t,n,e){if(n==="/health"||n.startsWith("/webhooks/orchestrate/"))return!0;if(t.method!=="GET")return!1;if((t.headers.accept??"").includes("text/html"))return!0;if(!e.staticDir)return!1;const r=d.normalize(n).replace(/^([/\\]\.\.[/\\])+/,""),i=d.join(e.staticDir,r);return i.startsWith(e.staticDir)&&h.existsSync(i)&&h.statSync(i).isFile()}function _(t,n){t.setHeader("cache-control",n.startsWith("/assets/")?"public, max-age=31536000, immutable":"no-cache")}function V(t,n,e){const r=d.normalize(n).replace(/^([/\\]\.\.[/\\])+/,""),i=d.join(e,r);if(!i.startsWith(e)){t.statusCode=403,t.setHeader("content-type","application/json"),t.end(JSON.stringify({error:"Forbidden"}));return}h.stat(i,(s,o)=>{if(!s&&o.isFile()){t.setHeader("content-type",U(i)),_(t,n),t.setHeader("content-length",String(o.size)),h.createReadStream(i).pipe(t);return}h.readFile(d.join(e,"index.html"),(c,a)=>{if(c){t.statusCode=404,t.setHeader("content-type","application/json"),t.end(JSON.stringify({error:"Not found"}));return}t.setHeader("content-type","text/html"),t.setHeader("cache-control","no-cache"),t.end(a)})})}function U(t){return t.endsWith(".js")?"text/javascript":t.endsWith(".css")?"text/css":t.endsWith(".html")?"text/html":t.endsWith(".svg")?"image/svg+xml":t.endsWith(".json")?"application/json":"application/octet-stream"}function K(t){for(let n=t.length-1;n>=0;n--){const e=t[n].source;if(R(e))return e}return null}function Q(t){const n=Number(t??"100");return!Number.isFinite(n)||n<=0?100:Math.min(Math.floor(n),500)}
13
+ `)});e.inflightRefresher?.refreshNow(),e.terminalRefresher?.onSubscriberJoin(),e.updatesRefresher?.onSubscriberJoin(),t.on("close",()=>{clearInterval(a),p()})}function G(t,n,e){if(n==="/health"||n.startsWith("/webhooks/orchestrate/"))return!0;if(t.method!=="GET")return!1;if((t.headers.accept??"").includes("text/html"))return!0;if(!e.staticDir)return!1;const r=d.normalize(n).replace(/^([/\\]\.\.[/\\])+/,""),i=d.join(e.staticDir,r);return i.startsWith(e.staticDir)&&h.existsSync(i)&&h.statSync(i).isFile()}function _(t,n){t.setHeader("cache-control",n.startsWith("/assets/")?"public, max-age=31536000, immutable":"no-cache")}function V(t,n,e){const r=d.normalize(n).replace(/^([/\\]\.\.[/\\])+/,""),i=d.join(e,r);if(!i.startsWith(e)){t.statusCode=403,t.setHeader("content-type","application/json"),t.end(JSON.stringify({error:"Forbidden"}));return}h.stat(i,(s,o)=>{if(!s&&o.isFile()){t.setHeader("content-type",U(i)),_(t,n),t.setHeader("content-length",String(o.size)),h.createReadStream(i).pipe(t);return}h.readFile(d.join(e,"index.html"),(c,a)=>{if(c){t.statusCode=404,t.setHeader("content-type","application/json"),t.end(JSON.stringify({error:"Not found"}));return}t.setHeader("content-type","text/html"),t.setHeader("cache-control","no-cache"),t.end(a)})})}function U(t){return t.endsWith(".js")?"text/javascript":t.endsWith(".css")?"text/css":t.endsWith(".html")?"text/html":t.endsWith(".svg")?"image/svg+xml":t.endsWith(".png")?"image/png":t.endsWith(".json")?"application/json":t.endsWith(".webmanifest")?"application/manifest+json":"application/octet-stream"}function K(t){for(let n=t.length-1;n>=0;n--){const e=t[n].source;if(R(e))return e}return null}function Q(t){const n=Number(t??"100");return!Number.isFinite(n)||n<=0?100:Math.min(Math.floor(n),500)}
@@ -33,3 +33,20 @@ export declare function scheduleBootstrapInjection(deps: Pick<WeaveServerDeps, '
33
33
  * 路由与编排引擎的「目标会话没开就拉起来」共用这一份:判据、能力面取法与错误码只有一处。
34
34
  */
35
35
  export declare function openSessionTerminal(deps: SessionOpenDeps, sessionId: string, target?: string): Promise<SessionOpenResult>;
36
+ /** ensureOpen 的返回(与编排引擎 `deps.ensureOpen` 的形状逐字一致,两边共用一份)。 */
37
+ export type EnsureOpenResult = {
38
+ ok: true;
39
+ ack?: 'session-start' | 'registry';
40
+ } | {
41
+ ok: false;
42
+ error: string;
43
+ };
44
+ /**
45
+ * 「判死会话先拉起再投递」的共享工厂:`openSessionTerminal` spawn + 等「真进了
46
+ * 会话」(SessionStart 事件 id 超过拉起前基线;注册表出现 pid 只算弱信号)。
47
+ * 编排引擎的「目标会话没开就拉起来」用这一份——判据、预算、错误口径只有一处。
48
+ * **单飞**:同一会话被并发投递时只拉起一次(后到的搭同一班车的结果)。
49
+ */
50
+ export declare function createEnsureOpen(deps: SessionOpenDeps & {
51
+ livenessOf?: () => Map<string, boolean>;
52
+ }): (sessionId: string) => Promise<EnsureOpenResult>;
@@ -1 +1 @@
1
- import{stat as w}from"node:fs/promises";import{isHarness as T}from"@weavecode/core";import{readDaemonSettings as g}from"./settings.js";import{defaultProjectOpener as v,terminalBackendFor as y}from"./opener.js";import{messagingSurfaceFor as O}from"../surfaces.js";const m=8e3,P=11e3,E=14e3;export function transcriptState(t,e){return t!==!1?t:e===!0?!1:null}function p(t,e,n,r){!r||O(e).paneEnvSource!=="launch"||t.messageDeliverer?.notePaneEnv(n,r.env)}export function scheduleBootstrapInjection(t,e,n){const r=t.terminal;r&&(async()=>{await new Promise(s=>setTimeout(s,m));const a=await r.locatePane?.(e.env).catch(()=>null)??null;if(!a)return;const o=async()=>{try{await r.sendText(a,n)}catch{return}};await o(),setTimeout(()=>{r.sendKeys(a,"\r").catch(()=>{})},P-m),setTimeout(()=>{o()},E-m)})()}export async function openSessionTerminal(t,e,n){if(!t.hookSessions)return{ok:!1,status:503,error:"Hooks subsystem unavailable"};const r=t.hookSessions.getBySessionId(e);if(!r)return{ok:!1,status:404,error:"Session not found"};if(!t.hookEvents)return{ok:!1,status:503,error:"Hook ingestion unavailable"};const a=t.hookEvents.listBySession(e,1),o=a[a.length-1]?.source;if(!T(o))return{ok:!1,status:400,error:"Session has no hook events to determine its harness"};const s=t.harnesses?.get(o)?.resume;if(!s?.supported||!s.openArgs)return{ok:!1,status:501,error:`Harness "${o}" does not support interactive resume`};if(!r.projectId)return{ok:!1,status:400,error:"Session is not bound to a project"};const i=t.projects?.getById(r.projectId);if(!i)return{ok:!1,status:404,error:"Project not found"};const k=t.sessionProbe?.transcriptPresent(e)??null;if(transcriptState(k,t.hookSessions.hasRunOf(e))===!1)return{ok:!1,status:409,error:"Session transcript is missing \u2014 nothing to resume"};const h=t.opener??v;try{if(!(await w(i.path)).isDirectory())throw new Error(`Not a directory: ${i.path}`);const c=await g(),f=[s.bin,...s.launchArgs??[],...s.openArgs(e)];if(n){if(!y(c.terminal).enumerable)throw new Error(`Terminal preset "${c.terminal.preset}" cannot attach to a chosen pane \u2014 pick wezterm, wt or Terminal.app in settings`);const u=h.runInTerminalAt;if(!u)throw new Error("Targeted attach is unavailable");const S=await u(i.path,f,n,c.terminal);p(t,o,e,S)}else{const u=await h.runInTerminal(i.path,f,c.terminal);p(t,o,e,u)}return setTimeout(()=>{t.terminalRefresher?.refreshNow()},600),{ok:!0,sessionId:e,command:f.join(" "),cwd:i.path,...n?{target:n}:{}}}catch(l){return{ok:!1,status:400,error:l instanceof Error?l.message:"Open failed"}}}
1
+ import{stat as g}from"node:fs/promises";import{isHarness as w}from"@weavecode/core";import{readDaemonSettings as S}from"./settings.js";import{defaultProjectOpener as T,terminalBackendFor as y}from"./opener.js";import{combinedLivenessOf as E}from"./liveness.js";import{messagingSurfaceFor as O}from"../surfaces.js";const h=8e3,P=11e3,b=14e3;export function transcriptState(e,r){return e!==!1?e:r===!0?!1:null}function k(e,r,s,t){!t||O(r).paneEnvSource!=="launch"||e.messageDeliverer?.notePaneEnv(s,t.env)}export function scheduleBootstrapInjection(e,r,s){const t=e.terminal;t&&(async()=>{await new Promise(a=>setTimeout(a,h));const o=await t.locatePane?.(r.env).catch(()=>null)??null;if(!o)return;const n=async()=>{try{await t.sendText(o,s)}catch{return}};await n(),setTimeout(()=>{t.sendKeys(o,"\r").catch(()=>{})},P-h),setTimeout(()=>{n()},b-h)})()}export async function openSessionTerminal(e,r,s){if(!e.hookSessions)return{ok:!1,status:503,error:"Hooks subsystem unavailable"};const t=e.hookSessions.getBySessionId(r);if(!t)return{ok:!1,status:404,error:"Session not found"};if(!e.hookEvents)return{ok:!1,status:503,error:"Hook ingestion unavailable"};const o=e.hookEvents.listBySession(r,1),n=o[o.length-1]?.source;if(!w(n))return{ok:!1,status:400,error:"Session has no hook events to determine its harness"};const a=e.harnesses?.get(n)?.resume;if(!a?.supported||!a.openArgs)return{ok:!1,status:501,error:`Harness "${n}" does not support interactive resume`};if(!t.projectId)return{ok:!1,status:400,error:"Session is not bound to a project"};const i=e.projects?.getById(t.projectId);if(!i)return{ok:!1,status:404,error:"Project not found"};const p=e.sessionProbe?.transcriptPresent(r)??null;if(transcriptState(p,e.hookSessions.hasRunOf(r))===!1)return{ok:!1,status:409,error:"Session transcript is missing \u2014 nothing to resume"};const c=e.opener??T;try{if(!(await g(i.path)).isDirectory())throw new Error(`Not a directory: ${i.path}`);const u=await S(),m=[a.bin,...a.launchArgs??[],...a.openArgs(r)];if(s){if(!y(u.terminal).enumerable)throw new Error(`Terminal preset "${u.terminal.preset}" cannot attach to a chosen pane \u2014 pick wezterm, wt or Terminal.app in settings`);const l=c.runInTerminalAt;if(!l)throw new Error("Targeted attach is unavailable");const v=await l(i.path,m,s,u.terminal);k(e,n,r,v)}else{const l=await c.runInTerminal(i.path,m,u.terminal);k(e,n,r,l)}return setTimeout(()=>{e.terminalRefresher?.refreshNow()},600),{ok:!0,sessionId:r,command:m.join(" "),cwd:i.path,...s?{target:s}:{}}}catch(f){return{ok:!1,status:400,error:f instanceof Error?f.message:"Open failed"}}}export function createEnsureOpen(e){const r=new Map,s=async t=>{if(!e.hookEvents)return{ok:!1,error:"Hook ingestion unavailable"};const o=e.hookEvents.listBySession(t,1).at(-1)?.id??0,n=await openSessionTerminal(e,t);if(!n.ok)return{ok:!1,error:n.error};let a=!1;for(let i=0;i<60;i++){if(e.hookEvents.listBySession(t,20).some(c=>c.id>o&&c.eventType==="SessionStart"))return{ok:!0,ack:"session-start"};(e.livenessOf?.()??E()).get(t)===!0&&(a=!0),await new Promise(c=>setTimeout(c,250))}return a?{ok:!0,ack:"registry"}:{ok:!1,error:"session did not report ready within 15s"}};return t=>{const o=r.get(t);if(o)return o;const n=s(t).finally(()=>r.delete(t));return r.set(t,n),n}}
@@ -96,11 +96,12 @@ export declare class SessionProbe {
96
96
  */
97
97
  transcriptPresent(sessionId: string): boolean | null;
98
98
  /**
99
- * 单会话的中断时刻(ms):转录最后一条中断标记**晚于**最后一条 hook 事件才算
100
- * ——之后任何事件(用户又发了一条、工具收尾)都会把它盖过去,故是自愈的;
101
- * 未知路径/读不到/没标记一律 null(不猜)。
99
+ * 单会话的中断时刻(ms):转录最后一条中断标记**晚于**最后一条主回合事件才算
100
+ * ——之后任何主回合事件(用户又发了一条、工具收尾)都会把它盖过去,故是自愈的;
101
+ * 未知路径/读不到/没标记一律 null(不猜)。基准由调用方给(`lastMainEventAtOf`
102
+ * ,排除 SubagentStop——后台子代理收尾与主回合无关,中断后异步到达不该盖掉它)。
102
103
  */
103
- interruptedAt(sessionId: string, lastSeenAt: string): number | null;
104
+ interruptedAt(sessionId: string, lastMainEventAt: string): number | null;
104
105
  /** 最近一轮真跑过的模型(转录 `message.model`);未知/读不到一律 null(不猜)。 */
105
106
  currentModel(sessionId: string): string | null;
106
107
  /**