@weavecode/weave 0.1.8 → 0.1.9

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (351) hide show
  1. package/node_modules/@modelcontextprotocol/sdk/node_modules/@hono/node-server/dist/index.cjs +31 -6
  2. package/node_modules/@modelcontextprotocol/sdk/node_modules/@hono/node-server/dist/index.mjs +31 -6
  3. package/node_modules/@modelcontextprotocol/sdk/node_modules/@hono/node-server/package.json +1 -1
  4. package/node_modules/@modelcontextprotocol/sdk/node_modules/express-rate-limit/dist/index.cjs +1 -1
  5. package/node_modules/@modelcontextprotocol/sdk/node_modules/express-rate-limit/dist/index.mjs +1 -1
  6. package/node_modules/@modelcontextprotocol/sdk/node_modules/express-rate-limit/node_modules/ip-address/README.md +39 -39
  7. package/node_modules/@modelcontextprotocol/sdk/node_modules/express-rate-limit/node_modules/ip-address/dist/ipv6.js +1 -1
  8. package/node_modules/@modelcontextprotocol/sdk/node_modules/express-rate-limit/node_modules/ip-address/package.json +1 -1
  9. package/node_modules/@modelcontextprotocol/sdk/node_modules/express-rate-limit/package.json +1 -1
  10. package/node_modules/@weavecode/cli/dist/cli.js +4 -4
  11. package/node_modules/@weavecode/cli/dist/commands/chpass.js +1 -1
  12. package/node_modules/@weavecode/cli/dist/commands/daemon-auth.js +1 -1
  13. package/node_modules/@weavecode/cli/dist/commands/daemon.js +2 -2
  14. package/node_modules/@weavecode/cli/dist/commands/dashboard.js +2 -2
  15. package/node_modules/@weavecode/cli/dist/commands/doctor.js +1 -1
  16. package/node_modules/@weavecode/cli/dist/commands/init.js +1 -1
  17. package/node_modules/@weavecode/cli/dist/commands/msg.js +2 -2
  18. package/node_modules/@weavecode/cli/dist/commands/scan.js +1 -1
  19. package/node_modules/@weavecode/cli/dist/commands/status.js +2 -2
  20. package/node_modules/@weavecode/cli/dist/commands/uninstall.js +1 -1
  21. package/node_modules/@weavecode/cli/dist/i18n/dict/en.js +2 -2
  22. package/node_modules/@weavecode/cli/dist/i18n/dict/zh.d.ts +7 -0
  23. package/node_modules/@weavecode/cli/dist/i18n/dict/zh.js +3 -3
  24. package/node_modules/@weavecode/cli/dist/i18n/index.js +1 -1
  25. package/node_modules/@weavecode/cli/dist/i18n/t.js +1 -1
  26. package/node_modules/@weavecode/cli/dist/init/claudemd-gen.js +5 -5
  27. package/node_modules/@weavecode/cli/dist/init/executor.js +3 -3
  28. package/node_modules/@weavecode/cli/dist/init/git-commit.js +2 -2
  29. package/node_modules/@weavecode/cli/dist/init/git-exclude.d.ts +20 -0
  30. package/node_modules/@weavecode/cli/dist/init/git-exclude.js +7 -0
  31. package/node_modules/@weavecode/cli/dist/init/harnesses/claude.js +7 -7
  32. package/node_modules/@weavecode/cli/dist/init/harnesses/codex.js +1 -1
  33. package/node_modules/@weavecode/cli/dist/init/instruction-files.d.ts +14 -0
  34. package/node_modules/@weavecode/cli/dist/init/instruction-files.js +1 -0
  35. package/node_modules/@weavecode/cli/dist/init/instruction-link.js +1 -1
  36. package/node_modules/@weavecode/cli/dist/init/plugin-templates.js +1 -1
  37. package/node_modules/@weavecode/cli/dist/init/prompt.js +4 -4
  38. package/node_modules/@weavecode/cli/dist/init/provision.js +1 -1
  39. package/node_modules/@weavecode/cli/dist/init/uninstall.js +6 -6
  40. package/node_modules/@weavecode/cli/dist/init/wiring.js +1 -1
  41. package/node_modules/@weavecode/cli/dist/parser.js +1 -1
  42. package/node_modules/@weavecode/cli/dist/statusline/ansi.js +1 -1
  43. package/node_modules/@weavecode/cli/dist/statusline/mock-input.js +1 -1
  44. package/node_modules/@weavecode/cli/dist/statusline/preview.js +2 -2
  45. package/node_modules/@weavecode/cli/package.json +5 -5
  46. package/node_modules/@weavecode/core/dist/harness-checks.js +1 -1
  47. package/node_modules/@weavecode/core/dist/harness.d.ts +37 -0
  48. package/node_modules/@weavecode/core/dist/harness.js +1 -1
  49. package/node_modules/@weavecode/core/dist/index.d.ts +1 -1
  50. package/node_modules/@weavecode/core/dist/index.js +1 -1
  51. package/node_modules/@weavecode/core/dist/platform.js +1 -1
  52. package/node_modules/@weavecode/core/dist/types.d.ts +4 -4
  53. package/node_modules/@weavecode/core/dist/types.js +1 -1
  54. package/node_modules/@weavecode/core/dist/utils/fs.js +1 -1
  55. package/node_modules/@weavecode/core/package.json +1 -1
  56. package/node_modules/@weavecode/harness/dist/claude/assets.js +3 -3
  57. package/node_modules/@weavecode/harness/dist/claude/capture.js +9 -9
  58. package/node_modules/@weavecode/harness/dist/claude/commands.js +3 -3
  59. package/node_modules/@weavecode/harness/dist/claude/config.js +2 -2
  60. package/node_modules/@weavecode/harness/dist/claude/detect.js +1 -1
  61. package/node_modules/@weavecode/harness/dist/claude/edits.js +1 -1
  62. package/node_modules/@weavecode/harness/dist/claude/event-source.js +1 -1
  63. package/node_modules/@weavecode/harness/dist/claude/images.js +2 -2
  64. package/node_modules/@weavecode/harness/dist/claude/index.js +1 -1
  65. package/node_modules/@weavecode/harness/dist/claude/liveness.js +1 -1
  66. package/node_modules/@weavecode/harness/dist/claude/mcp-gen.js +1 -1
  67. package/node_modules/@weavecode/harness/dist/claude/messaging.js +2 -2
  68. package/node_modules/@weavecode/harness/dist/claude/model-aliases.js +1 -1
  69. package/node_modules/@weavecode/harness/dist/claude/narration.js +1 -1
  70. package/node_modules/@weavecode/harness/dist/claude/peers.js +1 -1
  71. package/node_modules/@weavecode/harness/dist/claude/plan.js +1 -1
  72. package/node_modules/@weavecode/harness/dist/claude/plugins.js +4 -4
  73. package/node_modules/@weavecode/harness/dist/claude/prompt-inbox.js +1 -1
  74. package/node_modules/@weavecode/harness/dist/claude/prompt.js +3 -3
  75. package/node_modules/@weavecode/harness/dist/claude/questions.js +2 -2
  76. package/node_modules/@weavecode/harness/dist/claude/resume.js +1 -1
  77. package/node_modules/@weavecode/harness/dist/claude/rewind.js +1 -1
  78. package/node_modules/@weavecode/harness/dist/claude/settings-gen.js +1 -1
  79. package/node_modules/@weavecode/harness/dist/claude/side-question.js +2 -2
  80. package/node_modules/@weavecode/harness/dist/claude/statusline/generator.d.ts +6 -0
  81. package/node_modules/@weavecode/harness/dist/claude/statusline/generator.js +21 -14
  82. package/node_modules/@weavecode/harness/dist/claude/statusline/git-cache.js +1 -1
  83. package/node_modules/@weavecode/harness/dist/claude/statusline/surface.js +2 -2
  84. package/node_modules/@weavecode/harness/dist/claude/transcript-cursor.js +2 -2
  85. package/node_modules/@weavecode/harness/dist/claude/transcript.js +7 -7
  86. package/node_modules/@weavecode/harness/dist/codex/assets.js +1 -1
  87. package/node_modules/@weavecode/harness/dist/codex/capture.js +2 -2
  88. package/node_modules/@weavecode/harness/dist/codex/commands.js +4 -4
  89. package/node_modules/@weavecode/harness/dist/codex/config.js +2 -2
  90. package/node_modules/@weavecode/harness/dist/codex/detect.js +1 -1
  91. package/node_modules/@weavecode/harness/dist/codex/event-source.js +2 -2
  92. package/node_modules/@weavecode/harness/dist/codex/images.js +1 -1
  93. package/node_modules/@weavecode/harness/dist/codex/index.js +1 -1
  94. package/node_modules/@weavecode/harness/dist/codex/liveness.js +1 -1
  95. package/node_modules/@weavecode/harness/dist/codex/mcp.js +1 -1
  96. package/node_modules/@weavecode/harness/dist/codex/messaging.js +2 -2
  97. package/node_modules/@weavecode/harness/dist/codex/narration.js +1 -1
  98. package/node_modules/@weavecode/harness/dist/codex/plugin-state.js +1 -1
  99. package/node_modules/@weavecode/harness/dist/codex/plugins.js +3 -3
  100. package/node_modules/@weavecode/harness/dist/codex/provision.js +1 -1
  101. package/node_modules/@weavecode/harness/dist/codex/questions.js +2 -2
  102. package/node_modules/@weavecode/harness/dist/codex/rollout.js +5 -5
  103. package/node_modules/@weavecode/harness/dist/codex/side-question.js +4 -4
  104. package/node_modules/@weavecode/harness/dist/codex/titles.js +4 -4
  105. package/node_modules/@weavecode/harness/dist/codex/toml.js +13 -13
  106. package/node_modules/@weavecode/harness/dist/codex/transcript.js +2 -2
  107. package/node_modules/@weavecode/harness/dist/driver.js +1 -1
  108. package/node_modules/@weavecode/harness/dist/init/generated.js +2 -2
  109. package/node_modules/@weavecode/harness/dist/init/pipeline.js +1 -1
  110. package/node_modules/@weavecode/harness/dist/registry-wiring.js +1 -1
  111. package/node_modules/@weavecode/harness/dist/shared/install-link.js +1 -1
  112. package/node_modules/@weavecode/harness/dist/shared/json-cap.js +1 -1
  113. package/node_modules/@weavecode/harness/dist/zcode/assets.js +1 -1
  114. package/node_modules/@weavecode/harness/dist/zcode/capture.js +3 -3
  115. package/node_modules/@weavecode/harness/dist/zcode/mcp.js +2 -2
  116. package/node_modules/@weavecode/harness/package.json +2 -2
  117. package/node_modules/@weavecode/server/dist/config/dotted.js +1 -1
  118. package/node_modules/@weavecode/server/dist/config/profiles.js +2 -2
  119. package/node_modules/@weavecode/server/dist/daemon/ai-config.js +2 -2
  120. package/node_modules/@weavecode/server/dist/daemon/ai-context.js +6 -6
  121. package/node_modules/@weavecode/server/dist/daemon/ai-routes.js +4 -4
  122. package/node_modules/@weavecode/server/dist/daemon/api-log.js +3 -3
  123. package/node_modules/@weavecode/server/dist/daemon/auth-routes.js +1 -1
  124. package/node_modules/@weavecode/server/dist/daemon/auto-start.js +3 -3
  125. package/node_modules/@weavecode/server/dist/daemon/capture-routes.js +1 -1
  126. package/node_modules/@weavecode/server/dist/daemon/config-routes.js +1 -1
  127. package/node_modules/@weavecode/server/dist/daemon/cron.js +1 -1
  128. package/node_modules/@weavecode/server/dist/daemon/dashboard-auth.js +2 -2
  129. package/node_modules/@weavecode/server/dist/daemon/dashboard-pusher.js +1 -1
  130. package/node_modules/@weavecode/server/dist/daemon/decision-config.js +2 -2
  131. package/node_modules/@weavecode/server/dist/daemon/dev-entry.js +1 -1
  132. package/node_modules/@weavecode/server/dist/daemon/entry.js +2 -2
  133. package/node_modules/@weavecode/server/dist/daemon/fs-browser.js +1 -1
  134. package/node_modules/@weavecode/server/dist/daemon/hook-pipeline.js +1 -1
  135. package/node_modules/@weavecode/server/dist/daemon/hooks-routes.js +1 -1
  136. package/node_modules/@weavecode/server/dist/daemon/http.js +1 -1
  137. package/node_modules/@weavecode/server/dist/daemon/liveness.js +1 -1
  138. package/node_modules/@weavecode/server/dist/daemon/mcp-orchestration.js +1 -1
  139. package/node_modules/@weavecode/server/dist/daemon/narration-watcher.js +2 -2
  140. package/node_modules/@weavecode/server/dist/daemon/opener/backend-ghostty.js +1 -1
  141. package/node_modules/@weavecode/server/dist/daemon/opener/backend-iterm.js +1 -1
  142. package/node_modules/@weavecode/server/dist/daemon/opener/backend-konsole.js +2 -2
  143. package/node_modules/@weavecode/server/dist/daemon/opener/backend-terminal-app.js +1 -1
  144. package/node_modules/@weavecode/server/dist/daemon/opener/backend-wezterm.js +1 -1
  145. package/node_modules/@weavecode/server/dist/daemon/opener/backend-wt.js +1 -1
  146. package/node_modules/@weavecode/server/dist/daemon/opener/backend.js +1 -1
  147. package/node_modules/@weavecode/server/dist/daemon/opener/launch.js +1 -1
  148. package/node_modules/@weavecode/server/dist/daemon/opener/pty-terminals.js +1 -1
  149. package/node_modules/@weavecode/server/dist/daemon/opener/shared.js +1 -1
  150. package/node_modules/@weavecode/server/dist/daemon/opener/wezterm-mux.js +1 -1
  151. package/node_modules/@weavecode/server/dist/daemon/opener/wt.js +3 -3
  152. package/node_modules/@weavecode/server/dist/daemon/opener.js +1 -1
  153. package/node_modules/@weavecode/server/dist/daemon/pet-seed.d.ts +4 -6
  154. package/node_modules/@weavecode/server/dist/daemon/pet-seed.js +2 -1
  155. package/node_modules/@weavecode/server/dist/daemon/pet-window.js +1 -1
  156. package/node_modules/@weavecode/server/dist/daemon/port.js +1 -1
  157. package/node_modules/@weavecode/server/dist/daemon/project-files.js +2 -2
  158. package/node_modules/@weavecode/server/dist/daemon/project-harnesses.js +2 -2
  159. package/node_modules/@weavecode/server/dist/daemon/project-updates-refresher.js +1 -1
  160. package/node_modules/@weavecode/server/dist/daemon/prompt-images.js +1 -1
  161. package/node_modules/@weavecode/server/dist/daemon/routes/hooks-admin.js +1 -1
  162. package/node_modules/@weavecode/server/dist/daemon/routes/installations.d.ts +29 -0
  163. package/node_modules/@weavecode/server/dist/daemon/routes/installations.js +1 -0
  164. package/node_modules/@weavecode/server/dist/daemon/routes/market.js +1 -1
  165. package/node_modules/@weavecode/server/dist/daemon/routes/orchestration.js +1 -1
  166. package/node_modules/@weavecode/server/dist/daemon/routes/path-refs.js +1 -1
  167. package/node_modules/@weavecode/server/dist/daemon/routes/pets.js +1 -1
  168. package/node_modules/@weavecode/server/dist/daemon/routes/project-files.js +1 -1
  169. package/node_modules/@weavecode/server/dist/daemon/routes/projects.js +1 -1
  170. package/node_modules/@weavecode/server/dist/daemon/routes/search.js +1 -1
  171. package/node_modules/@weavecode/server/dist/daemon/routes/session-control.js +1 -1
  172. package/node_modules/@weavecode/server/dist/daemon/routes/session-insights.js +1 -1
  173. package/node_modules/@weavecode/server/dist/daemon/routes/settings-statusline.js +1 -1
  174. package/node_modules/@weavecode/server/dist/daemon/routes/uploads.js +1 -1
  175. package/node_modules/@weavecode/server/dist/daemon/routes/visualizations.js +2 -2
  176. package/node_modules/@weavecode/server/dist/daemon/routes/watches.js +1 -1
  177. package/node_modules/@weavecode/server/dist/daemon/server.d.ts +2 -0
  178. package/node_modules/@weavecode/server/dist/daemon/server.js +8 -8
  179. package/node_modules/@weavecode/server/dist/daemon/session-open.js +1 -1
  180. package/node_modules/@weavecode/server/dist/daemon/session-probe.js +1 -1
  181. package/node_modules/@weavecode/server/dist/daemon/settings.js +2 -2
  182. package/node_modules/@weavecode/server/dist/daemon/snapshot-refresher.js +1 -1
  183. package/node_modules/@weavecode/server/dist/daemon/sse-hub.js +1 -1
  184. package/node_modules/@weavecode/server/dist/daemon/start.js +1 -1
  185. package/node_modules/@weavecode/server/dist/daemon/state.js +2 -2
  186. package/node_modules/@weavecode/server/dist/daemon/static.js +1 -1
  187. package/node_modules/@weavecode/server/dist/daemon/terminal-topology-refresher.js +1 -1
  188. package/node_modules/@weavecode/server/dist/daemon/tls.js +1 -1
  189. package/node_modules/@weavecode/server/dist/daemon/toolkit-routes.js +1 -1
  190. package/node_modules/@weavecode/server/dist/daemon/upload-sessions.js +1 -1
  191. package/node_modules/@weavecode/server/dist/db/db.js +2 -2
  192. package/node_modules/@weavecode/server/dist/db/layout.d.ts +5 -0
  193. package/node_modules/@weavecode/server/dist/db/layout.js +2 -1
  194. package/node_modules/@weavecode/server/dist/db/paths.d.ts +5 -0
  195. package/node_modules/@weavecode/server/dist/db/paths.js +1 -1
  196. package/node_modules/@weavecode/server/dist/hooks/answer-keys.js +1 -1
  197. package/node_modules/@weavecode/server/dist/hooks/dashboard-rate.js +1 -1
  198. package/node_modules/@weavecode/server/dist/hooks/decision-judge.js +1 -1
  199. package/node_modules/@weavecode/server/dist/hooks/delivery/ack-gate.js +1 -1
  200. package/node_modules/@weavecode/server/dist/hooks/delivery/channels.js +1 -1
  201. package/node_modules/@weavecode/server/dist/hooks/delivery/keys.js +1 -1
  202. package/node_modules/@weavecode/server/dist/hooks/delivery/queue.js +1 -1
  203. package/node_modules/@weavecode/server/dist/hooks/delivery/relay.js +1 -1
  204. package/node_modules/@weavecode/server/dist/hooks/delivery/send.js +2 -2
  205. package/node_modules/@weavecode/server/dist/hooks/delivery/views.js +1 -1
  206. package/node_modules/@weavecode/server/dist/hooks/dispatcher.js +6 -6
  207. package/node_modules/@weavecode/server/dist/hooks/edge-extract.js +1 -1
  208. package/node_modules/@weavecode/server/dist/hooks/handlers/webhook.js +1 -1
  209. package/node_modules/@weavecode/server/dist/hooks/headless-runner.js +2 -2
  210. package/node_modules/@weavecode/server/dist/hooks/inbox-socket.js +2 -2
  211. package/node_modules/@weavecode/server/dist/hooks/inbox-worker.js +3 -3
  212. package/node_modules/@weavecode/server/dist/hooks/match.js +1 -1
  213. package/node_modules/@weavecode/server/dist/hooks/message-deliverer.js +5 -5
  214. package/node_modules/@weavecode/server/dist/hooks/mirror.js +4 -4
  215. package/node_modules/@weavecode/server/dist/hooks/orchestration-engine.js +7 -7
  216. package/node_modules/@weavecode/server/dist/hooks/orchestration-graph.js +1 -1
  217. package/node_modules/@weavecode/server/dist/hooks/plugin-installer.js +3 -3
  218. package/node_modules/@weavecode/server/dist/hooks/plugin-loader.js +1 -1
  219. package/node_modules/@weavecode/server/dist/hooks/plugin-project-state.js +1 -1
  220. package/node_modules/@weavecode/server/dist/hooks/prompt-flusher.js +1 -1
  221. package/node_modules/@weavecode/server/dist/hooks/promptbox.js +8 -8
  222. package/node_modules/@weavecode/server/dist/hooks/push-notify.js +2 -2
  223. package/node_modules/@weavecode/server/dist/hooks/question-tracker.js +1 -1
  224. package/node_modules/@weavecode/server/dist/hooks/registry.js +1 -1
  225. package/node_modules/@weavecode/server/dist/hooks/resume-runner.js +1 -1
  226. package/node_modules/@weavecode/server/dist/hooks/session-purge.js +1 -1
  227. package/node_modules/@weavecode/server/dist/hooks/side-questions.js +1 -1
  228. package/node_modules/@weavecode/server/dist/hooks/synthetic-sessions.js +1 -1
  229. package/node_modules/@weavecode/server/dist/hooks/toolkit-scan.js +1 -1
  230. package/node_modules/@weavecode/server/dist/hooks/toolkit.js +5 -5
  231. package/node_modules/@weavecode/server/dist/hooks/watch-engine.js +1 -1
  232. package/node_modules/@weavecode/server/dist/install/apply-update.js +1 -1
  233. package/node_modules/@weavecode/server/dist/install/capabilities.js +1 -1
  234. package/node_modules/@weavecode/server/dist/install/codex-toml.js +1 -1
  235. package/node_modules/@weavecode/server/dist/install/file-assets.js +1 -1
  236. package/node_modules/@weavecode/server/dist/install/fingerprint.js +1 -1
  237. package/node_modules/@weavecode/server/dist/install/global-config.js +1 -1
  238. package/node_modules/@weavecode/server/dist/install/global-file-assets.js +1 -1
  239. package/node_modules/@weavecode/server/dist/install/init-files.d.ts +0 -9
  240. package/node_modules/@weavecode/server/dist/install/init-files.js +2 -2
  241. package/node_modules/@weavecode/server/dist/install/install-ledger.js +1 -1
  242. package/node_modules/@weavecode/server/dist/install/installer.js +1 -1
  243. package/node_modules/@weavecode/server/dist/install/library-index.js +1 -1
  244. package/node_modules/@weavecode/server/dist/install/mcp-rows.js +1 -1
  245. package/node_modules/@weavecode/server/dist/install/plugin-install.js +1 -1
  246. package/node_modules/@weavecode/server/dist/install/plugin-rows.js +1 -1
  247. package/node_modules/@weavecode/server/dist/install/plugin-templates.js +1 -1
  248. package/node_modules/@weavecode/server/dist/install/project-config.js +1 -1
  249. package/node_modules/@weavecode/server/dist/install/reader.js +1 -1
  250. package/node_modules/@weavecode/server/dist/install/scan-cache.js +1 -1
  251. package/node_modules/@weavecode/server/dist/install/scanner.js +1 -1
  252. package/node_modules/@weavecode/server/dist/install/settings-mcp.js +2 -2
  253. package/node_modules/@weavecode/server/dist/install/updates.js +1 -1
  254. package/node_modules/@weavecode/server/dist/market/builtin.js +1 -1
  255. package/node_modules/@weavecode/server/dist/market/identity.js +1 -1
  256. package/node_modules/@weavecode/server/dist/market/import.js +2 -2
  257. package/node_modules/@weavecode/server/dist/market/refresh.js +1 -1
  258. package/node_modules/@weavecode/server/dist/market/resolve.js +1 -1
  259. package/node_modules/@weavecode/server/dist/market/updates.js +1 -1
  260. package/node_modules/@weavecode/server/dist/registry.js +2 -2
  261. package/node_modules/@weavecode/server/dist/repositories/hook-dispatches.js +4 -4
  262. package/node_modules/@weavecode/server/dist/repositories/hook-events.js +6 -6
  263. package/node_modules/@weavecode/server/dist/repositories/hook-rules.js +4 -4
  264. package/node_modules/@weavecode/server/dist/repositories/libraries.js +1 -1
  265. package/node_modules/@weavecode/server/dist/repositories/orchestrations.js +7 -7
  266. package/node_modules/@weavecode/server/dist/repositories/plugin-states.js +1 -1
  267. package/node_modules/@weavecode/server/dist/repositories/projects.js +1 -1
  268. package/node_modules/@weavecode/server/dist/repositories/push-subscriptions.js +2 -2
  269. package/node_modules/@weavecode/server/dist/repositories/session-watches.js +4 -4
  270. package/node_modules/@weavecode/server/dist/repositories/sessions.js +2 -2
  271. package/node_modules/@weavecode/server/dist/repositories/uploads.js +11 -11
  272. package/node_modules/@weavecode/server/dist/statusline/cache-sweeper.js +1 -1
  273. package/node_modules/@weavecode/server/dist/statusline/generator.js +1 -1
  274. package/node_modules/@weavecode/server/dist/statusline/manager.js +3 -3
  275. package/node_modules/@weavecode/server/dist/surfaces.js +1 -1
  276. package/node_modules/@weavecode/server/dist/watch/cache.js +1 -1
  277. package/node_modules/@weavecode/server/dist/watch/classifier.js +1 -1
  278. package/node_modules/@weavecode/server/dist/watch/plugin-mods.js +1 -1
  279. package/node_modules/@weavecode/server/dist/watch/sync-scheduler.js +1 -1
  280. package/node_modules/@weavecode/server/dist/watch/watch-service.js +1 -1
  281. package/node_modules/@weavecode/server/package.json +4 -4
  282. package/node_modules/@weavecode/server/web/dist/assets/{abnfDiagram-WEYOIA3C-t5OQjhuS.js → abnfDiagram-WEYOIA3C-S1lL1V_n.js} +1 -1
  283. package/node_modules/@weavecode/server/web/dist/assets/{arc-De-uH_Q9.js → arc-CoTNHyHV.js} +1 -1
  284. package/node_modules/@weavecode/server/web/dist/assets/{architectureDiagram-ZHVYKT53-ImPclD43.js → architectureDiagram-ZHVYKT53-C6ttfnzW.js} +1 -1
  285. package/node_modules/@weavecode/server/web/dist/assets/{blockDiagram-RJAE7QA3-B5xEQs6X.js → blockDiagram-RJAE7QA3-CYr3Cpu9.js} +1 -1
  286. package/node_modules/@weavecode/server/web/dist/assets/{c4Diagram-XDPPPE54-DP8MjIgJ.js → c4Diagram-XDPPPE54-BFS7PhLD.js} +1 -1
  287. package/node_modules/@weavecode/server/web/dist/assets/channel-DxQHp3Yc.js +1 -0
  288. package/node_modules/@weavecode/server/web/dist/assets/{chunk-2E7WHVMD-C3UFIDyj.js → chunk-2E7WHVMD-DJ7X_Shu.js} +1 -1
  289. package/node_modules/@weavecode/server/web/dist/assets/{chunk-2Q5K7J3B-Bgw-3YfG.js → chunk-2Q5K7J3B-B8nr2rdz.js} +1 -1
  290. package/node_modules/@weavecode/server/web/dist/assets/{chunk-4EMNKR2T-Dy_Wq9qn.js → chunk-4EMNKR2T-DmnZmUMU.js} +1 -1
  291. package/node_modules/@weavecode/server/web/dist/assets/{chunk-55XCU76K-D32C0DXX.js → chunk-55XCU76K-Xz9a8dmp.js} +1 -1
  292. package/node_modules/@weavecode/server/web/dist/assets/{chunk-5VM5RSS4-Dpmi-9Gi.js → chunk-5VM5RSS4-Dg9mg7pf.js} +1 -1
  293. package/node_modules/@weavecode/server/web/dist/assets/{chunk-JWPE2WC7-CEYXaZDX.js → chunk-JWPE2WC7-CmjTZO8o.js} +1 -1
  294. package/node_modules/@weavecode/server/web/dist/assets/{chunk-VQ5W62QI-A616Pgzo.js → chunk-VQ5W62QI-D3YDdJ3E.js} +1 -1
  295. package/node_modules/@weavecode/server/web/dist/assets/{chunk-XXDRQBXY-CnxFMLWV.js → chunk-XXDRQBXY-s1OG9sqW.js} +1 -1
  296. package/node_modules/@weavecode/server/web/dist/assets/{chunk-ZCHMQSOR-BhjCTig8.js → chunk-ZCHMQSOR-C3hINQU3.js} +2 -2
  297. package/node_modules/@weavecode/server/web/dist/assets/{classDiagram-v2-4MYWR3UA-rzlq5tPv.js → classDiagram-v2-4MYWR3UA-BTsbYrVl.js} +1 -1
  298. package/node_modules/@weavecode/server/web/dist/assets/{cose-bilkent-JH36ORCC-CxWQXzj8.js → cose-bilkent-JH36ORCC-C0W8Y-jI.js} +1 -1
  299. package/node_modules/@weavecode/server/web/dist/assets/{cynefin-EF2NZ3EQ-AFHjx2wU.js → cynefin-EF2NZ3EQ-stAu4Rh-.js} +1 -1
  300. package/node_modules/@weavecode/server/web/dist/assets/{cynefinDiagram-WF24UDRP-Bp_Oaf9U.js → cynefinDiagram-WF24UDRP-CqYibiiv.js} +1 -1
  301. package/node_modules/@weavecode/server/web/dist/assets/{dagre-NK4GIZVX-7oUPIU35.js → dagre-NK4GIZVX-qqcoJAqB.js} +1 -1
  302. package/node_modules/@weavecode/server/web/dist/assets/{diagram-CBK3MWTC-D_rS_rSY.js → diagram-CBK3MWTC-D0YTopb7.js} +1 -1
  303. package/node_modules/@weavecode/server/web/dist/assets/{diagram-I5XIIV2D-Duc_cKMb.js → diagram-I5XIIV2D-Csvw6aYr.js} +1 -1
  304. package/node_modules/@weavecode/server/web/dist/assets/{diagram-ODIL2UCW-DA0XFVXm.js → diagram-ODIL2UCW-Dl0tYLkF.js} +1 -1
  305. package/node_modules/@weavecode/server/web/dist/assets/{diagram-PFBEJUXE-D1U0Xhtt.js → diagram-PFBEJUXE-BCPSWZPe.js} +1 -1
  306. package/node_modules/@weavecode/server/web/dist/assets/{diagram-RJA3I4VV-CbDFY871.js → diagram-RJA3I4VV-ETg-BrAJ.js} +1 -1
  307. package/node_modules/@weavecode/server/web/dist/assets/{diagram-TYUNFSNR-jPg9AxQv.js → diagram-TYUNFSNR-_M6ZxBG7.js} +1 -1
  308. package/node_modules/@weavecode/server/web/dist/assets/{ebnfDiagram-V4P3TTPT-ZHfGTB0N.js → ebnfDiagram-V4P3TTPT-C-e_W7qx.js} +1 -1
  309. package/node_modules/@weavecode/server/web/dist/assets/{elk-QONTBCTQ-C-ESJrUi.js → elk-QONTBCTQ-B5TBharB.js} +1 -1
  310. package/node_modules/@weavecode/server/web/dist/assets/{erDiagram-KYQIGQAA-DGK7TeHj.js → erDiagram-KYQIGQAA-D08rj2pv.js} +1 -1
  311. package/node_modules/@weavecode/server/web/dist/assets/{flowDiagram-IUGLLWBU-CVV4rL8v.js → flowDiagram-IUGLLWBU-BALTxsKh.js} +1 -1
  312. package/node_modules/@weavecode/server/web/dist/assets/{ganttDiagram-R7GPNTJY-CuAwNvbm.js → ganttDiagram-R7GPNTJY-Cts193jT.js} +1 -1
  313. package/node_modules/@weavecode/server/web/dist/assets/{gitGraphDiagram-PDYL7XHY-D_15Wtf-.js → gitGraphDiagram-PDYL7XHY-L9qYUX0v.js} +1 -1
  314. package/node_modules/@weavecode/server/web/dist/assets/{infoDiagram-MVDRKAX5-ClqhbrCa.js → infoDiagram-MVDRKAX5-Bv47rgU0.js} +1 -1
  315. package/node_modules/@weavecode/server/web/dist/assets/{ishikawaDiagram-HPEHV2GE-CUJ891JX.js → ishikawaDiagram-HPEHV2GE-Da8_s6cs.js} +1 -1
  316. package/node_modules/@weavecode/server/web/dist/assets/{journeyDiagram-BOSHW7O7-B4skiMu-.js → journeyDiagram-BOSHW7O7-Bj3CjZOf.js} +1 -1
  317. package/node_modules/@weavecode/server/web/dist/assets/{kanban-definition-FNSA4HC5-UNGJR_y_.js → kanban-definition-FNSA4HC5-D1hicmMu.js} +1 -1
  318. package/node_modules/@weavecode/server/web/dist/assets/{linear-BEB-UwbR.js → linear-CWQg2iA1.js} +1 -1
  319. package/node_modules/@weavecode/server/web/dist/assets/main-XLn3EZFh.css +11 -0
  320. package/node_modules/@weavecode/server/web/dist/assets/main-bsb0lQoL.js +1096 -0
  321. package/node_modules/@weavecode/server/web/dist/assets/{mermaid.core-knGXJfjz.js → mermaid.core-C-wP0Zg2.js} +4 -4
  322. package/node_modules/@weavecode/server/web/dist/assets/{mindmap-definition-6OY57UG3-CEldbr3a.js → mindmap-definition-6OY57UG3-Dk0VKqre.js} +1 -1
  323. package/node_modules/@weavecode/server/web/dist/assets/{pegDiagram-ECIUJNBX-cNCkGLx3.js → pegDiagram-ECIUJNBX-Bp1K_F9z.js} +1 -1
  324. package/node_modules/@weavecode/server/web/dist/assets/pet-J6izA90s.js +1 -0
  325. package/node_modules/@weavecode/server/web/dist/assets/{pieDiagram-GNMPY74T-CfMEFiQD.js → pieDiagram-GNMPY74T-BZ4rGy3t.js} +1 -1
  326. package/node_modules/@weavecode/server/web/dist/assets/{quadrantDiagram-D57K4MC3-knmi2rwP.js → quadrantDiagram-D57K4MC3-B4N5KRsR.js} +1 -1
  327. package/node_modules/@weavecode/server/web/dist/assets/{railroadDiagram-Y72NRBL7-BJ7AzhEo.js → railroadDiagram-Y72NRBL7-C8nx8oHf.js} +1 -1
  328. package/node_modules/@weavecode/server/web/dist/assets/{requirementDiagram-EQYSW5RA-Dte2LGQM.js → requirementDiagram-EQYSW5RA-VSH57d0d.js} +1 -1
  329. package/node_modules/@weavecode/server/web/dist/assets/{sankeyDiagram-SY24JHO5-3noLaWgd.js → sankeyDiagram-SY24JHO5-jUb1hcya.js} +1 -1
  330. package/node_modules/@weavecode/server/web/dist/assets/{sequenceDiagram-BLEHNHQU-CclOWTTc.js → sequenceDiagram-BLEHNHQU-E2BioCNi.js} +1 -1
  331. package/node_modules/@weavecode/server/web/dist/assets/{sizeCapture-INFHLROL-B82sbLhA.js → sizeCapture-INFHLROL-BdKrbRmI.js} +1 -1
  332. package/node_modules/@weavecode/server/web/dist/assets/{stateDiagram-v2-A6IESKWZ-BXfVDwSN.js → stateDiagram-v2-A6IESKWZ-tFz7uNM7.js} +1 -1
  333. package/node_modules/@weavecode/server/web/dist/assets/{swimlanes-B3ENRKFQ-D4lKZaeV.js → swimlanes-B3ENRKFQ-B9BAPDWw.js} +1 -1
  334. package/node_modules/@weavecode/server/web/dist/assets/swimlanesDiagram-AYQRV4AK-DQ2NPLl9.js +8 -0
  335. package/node_modules/@weavecode/server/web/dist/assets/{timeline-definition-JXYKGLGB-D6H6zP5b.js → timeline-definition-JXYKGLGB-CofNnFTK.js} +1 -1
  336. package/node_modules/@weavecode/server/web/dist/assets/{usecaseDiagram-WPOLBNNX-D2J2bKo_.js → usecaseDiagram-WPOLBNNX-DOvjhJjJ.js} +1 -1
  337. package/node_modules/@weavecode/server/web/dist/assets/{vennDiagram-Q3Y3IDCW-pdRbIkpB.js → vennDiagram-Q3Y3IDCW-BcFHWnhS.js} +1 -1
  338. package/node_modules/@weavecode/server/web/dist/assets/{wardleyDiagram-IVAIDKWA-Cyd2QPMf.js → wardleyDiagram-IVAIDKWA-Bz2aqRAs.js} +1 -1
  339. package/node_modules/@weavecode/server/web/dist/assets/{xychartDiagram-4URNHDU4-Bd4BkwVM.js → xychartDiagram-4URNHDU4-DpNF6Vsq.js} +1 -1
  340. package/node_modules/@weavecode/server/web/dist/index.html +2 -2
  341. package/node_modules/@weavecode/server/web/dist/pet.html +80 -10
  342. package/node_modules/@weavecode/templates/dist/resources/pets/weave-spider/pet.json +1 -1
  343. package/node_modules/@weavecode/templates/dist/resources/pets/weave-spider/spritesheet.png +0 -0
  344. package/node_modules/@weavecode/templates/package.json +2 -2
  345. package/package.json +6 -6
  346. package/scripts/preinstall.mjs +60 -22
  347. package/node_modules/@weavecode/server/web/dist/assets/channel-C0RGiobt.js +0 -1
  348. package/node_modules/@weavecode/server/web/dist/assets/main-B_0jS_Gz.js +0 -1096
  349. package/node_modules/@weavecode/server/web/dist/assets/main-Czzlavi4.css +0 -11
  350. package/node_modules/@weavecode/server/web/dist/assets/pet-DJCpIDM5.js +0 -1
  351. package/node_modules/@weavecode/server/web/dist/assets/swimlanesDiagram-AYQRV4AK-DbdFh_d6.js +0 -8
@@ -169,16 +169,27 @@ const newHeadersFromIncoming = (incoming) => globalThis.Headers === GlobalHeader
169
169
  const reValidRequestUrl = /^\/[!#$&-;=?-\[\]_a-z~]*$/;
170
170
  const reDotSegment = /\/\.\.?(?:[/?#]|$)/;
171
171
  const reValidHost = /^[a-z0-9._-]+(?::(?:[1-5]\d{3,4}|[6-9]\d{3}))?$/;
172
+ const validateRequestTarget = (target) => {
173
+ const backslash = target.indexOf("\\");
174
+ if (backslash !== -1) {
175
+ const query = target.indexOf("?");
176
+ if (query === -1 || backslash < query) throw new RequestError("Backslash in request path");
177
+ }
178
+ };
172
179
  const buildUrl = (scheme, host, incomingUrl) => {
173
180
  const url = `${scheme}://${host}${incomingUrl}`;
174
181
  if (!reValidHost.test(host)) {
182
+ validateRequestTarget(incomingUrl);
175
183
  const urlObj = new URL(url);
176
184
  if (urlObj.hostname.length !== host.length && urlObj.hostname !== (host.includes(":") ? host.replace(/:\d+$/, "") : host).toLowerCase()) throw new RequestError("Invalid host header");
177
185
  return urlObj.href;
178
186
  } else if (incomingUrl.length === 0) return url + "/";
179
187
  else {
180
188
  if (incomingUrl.charCodeAt(0) !== 47) throw new RequestError("Invalid URL");
181
- if (!reValidRequestUrl.test(incomingUrl) || reDotSegment.test(incomingUrl)) return new URL(url).href;
189
+ if (!reValidRequestUrl.test(incomingUrl) || reDotSegment.test(incomingUrl)) {
190
+ validateRequestTarget(incomingUrl);
191
+ return new URL(url).href;
192
+ }
182
193
  return url;
183
194
  }
184
195
  };
@@ -591,6 +602,7 @@ const newRequest = (incoming, defaultHostname) => {
591
602
  if (incomingUrl[0] !== "/" && (incomingUrl.startsWith("http://") || incomingUrl.startsWith("https://"))) {
592
603
  if (incoming instanceof node_http2.Http2ServerRequest) throw new RequestError("Absolute URL for :path is not allowed in HTTP/2");
593
604
  try {
605
+ validateRequestTarget(incomingUrl);
594
606
  req[urlKey] = new URL(incomingUrl).href;
595
607
  } catch (e) {
596
608
  throw new RequestError("Invalid absolute URL", { cause: e });
@@ -1143,6 +1155,7 @@ const appendResponseHeaders = (headers, responseHeaders) => {
1143
1155
  });
1144
1156
  };
1145
1157
  const rejectUpgradeRequest = (socket, status, responseHeaders) => {
1158
+ if (socket.destroyed) return;
1146
1159
  const responseLines = ["Connection: close", "Content-Length: 0"];
1147
1160
  appendResponseHeaders(responseLines, responseHeaders);
1148
1161
  socket.end(`HTTP/1.1 ${status.toString()} ${node_http.STATUS_CODES[status] ?? ""}\r\n${responseLines.join("\r\n")}\r\n\r
@@ -1150,7 +1163,12 @@ const rejectUpgradeRequest = (socket, status, responseHeaders) => {
1150
1163
  };
1151
1164
  const createUpgradeRequest = (request) => {
1152
1165
  const protocol = request.socket.encrypted ? "https" : "http";
1153
- const url = new URL(request.url ?? "/", `${protocol}://${request.headers.host ?? "localhost"}`);
1166
+ const incomingUrl = request.url ?? "/";
1167
+ let url;
1168
+ if (incomingUrl[0] !== "/" && (incomingUrl.startsWith("http://") || incomingUrl.startsWith("https://"))) {
1169
+ validateRequestTarget(incomingUrl);
1170
+ url = new URL(incomingUrl).href;
1171
+ } else url = buildUrl(protocol, request.headers.host ?? "localhost", incomingUrl);
1154
1172
  const headers = new Headers();
1155
1173
  for (const key in request.headers) {
1156
1174
  const value = request.headers[key];
@@ -1187,6 +1205,10 @@ const setupWebSocket = (options) => {
1187
1205
  };
1188
1206
  server.on("upgrade", async (request, socket, head) => {
1189
1207
  if (request.headers.upgrade?.toLowerCase() !== "websocket") return;
1208
+ const ignoreSocketError = () => {};
1209
+ const reclaimWaiterOnClose = () => rejectWaiter(request);
1210
+ socket.on("error", ignoreSocketError);
1211
+ socket.once("close", reclaimWaiterOnClose);
1190
1212
  const env = {
1191
1213
  incoming: request,
1192
1214
  outgoing: void 0,
@@ -1201,8 +1223,12 @@ const setupWebSocket = (options) => {
1201
1223
  status = response.status;
1202
1224
  responseHeaders = response.headers;
1203
1225
  }
1204
- } catch {
1205
- if (server.listenerCount("upgrade") === 1) rejectUpgradeRequest(socket, 500);
1226
+ } catch (error) {
1227
+ if (server.listenerCount("upgrade") === 1) rejectUpgradeRequest(socket, error instanceof RequestError ? 400 : 500);
1228
+ return;
1229
+ }
1230
+ if (socket.destroyed) {
1231
+ rejectWaiter(request);
1206
1232
  return;
1207
1233
  }
1208
1234
  const waiter = waiterMap.get(request);
@@ -1214,12 +1240,11 @@ const setupWebSocket = (options) => {
1214
1240
  const addResponseHeaders = (headers) => {
1215
1241
  appendResponseHeaders(headers, responseHeaders);
1216
1242
  };
1217
- const reclaimWaiterOnClose = () => rejectWaiter(request);
1218
- socket.once("close", reclaimWaiterOnClose);
1219
1243
  wss.on("headers", addResponseHeaders);
1220
1244
  try {
1221
1245
  wss.handleUpgrade(request, socket, head, (ws) => {
1222
1246
  socket.off("close", reclaimWaiterOnClose);
1247
+ socket.off("error", ignoreSocketError);
1223
1248
  wss.emit("connection", ws, request);
1224
1249
  });
1225
1250
  } finally {
@@ -168,16 +168,27 @@ const newHeadersFromIncoming = (incoming) => globalThis.Headers === GlobalHeader
168
168
  const reValidRequestUrl = /^\/[!#$&-;=?-\[\]_a-z~]*$/;
169
169
  const reDotSegment = /\/\.\.?(?:[/?#]|$)/;
170
170
  const reValidHost = /^[a-z0-9._-]+(?::(?:[1-5]\d{3,4}|[6-9]\d{3}))?$/;
171
+ const validateRequestTarget = (target) => {
172
+ const backslash = target.indexOf("\\");
173
+ if (backslash !== -1) {
174
+ const query = target.indexOf("?");
175
+ if (query === -1 || backslash < query) throw new RequestError("Backslash in request path");
176
+ }
177
+ };
171
178
  const buildUrl = (scheme, host, incomingUrl) => {
172
179
  const url = `${scheme}://${host}${incomingUrl}`;
173
180
  if (!reValidHost.test(host)) {
181
+ validateRequestTarget(incomingUrl);
174
182
  const urlObj = new URL(url);
175
183
  if (urlObj.hostname.length !== host.length && urlObj.hostname !== (host.includes(":") ? host.replace(/:\d+$/, "") : host).toLowerCase()) throw new RequestError("Invalid host header");
176
184
  return urlObj.href;
177
185
  } else if (incomingUrl.length === 0) return url + "/";
178
186
  else {
179
187
  if (incomingUrl.charCodeAt(0) !== 47) throw new RequestError("Invalid URL");
180
- if (!reValidRequestUrl.test(incomingUrl) || reDotSegment.test(incomingUrl)) return new URL(url).href;
188
+ if (!reValidRequestUrl.test(incomingUrl) || reDotSegment.test(incomingUrl)) {
189
+ validateRequestTarget(incomingUrl);
190
+ return new URL(url).href;
191
+ }
181
192
  return url;
182
193
  }
183
194
  };
@@ -590,6 +601,7 @@ const newRequest = (incoming, defaultHostname) => {
590
601
  if (incomingUrl[0] !== "/" && (incomingUrl.startsWith("http://") || incomingUrl.startsWith("https://"))) {
591
602
  if (incoming instanceof Http2ServerRequest) throw new RequestError("Absolute URL for :path is not allowed in HTTP/2");
592
603
  try {
604
+ validateRequestTarget(incomingUrl);
593
605
  req[urlKey] = new URL(incomingUrl).href;
594
606
  } catch (e) {
595
607
  throw new RequestError("Invalid absolute URL", { cause: e });
@@ -1142,6 +1154,7 @@ const appendResponseHeaders = (headers, responseHeaders) => {
1142
1154
  });
1143
1155
  };
1144
1156
  const rejectUpgradeRequest = (socket, status, responseHeaders) => {
1157
+ if (socket.destroyed) return;
1145
1158
  const responseLines = ["Connection: close", "Content-Length: 0"];
1146
1159
  appendResponseHeaders(responseLines, responseHeaders);
1147
1160
  socket.end(`HTTP/1.1 ${status.toString()} ${STATUS_CODES[status] ?? ""}\r\n${responseLines.join("\r\n")}\r\n\r
@@ -1149,7 +1162,12 @@ const rejectUpgradeRequest = (socket, status, responseHeaders) => {
1149
1162
  };
1150
1163
  const createUpgradeRequest = (request) => {
1151
1164
  const protocol = request.socket.encrypted ? "https" : "http";
1152
- const url = new URL(request.url ?? "/", `${protocol}://${request.headers.host ?? "localhost"}`);
1165
+ const incomingUrl = request.url ?? "/";
1166
+ let url;
1167
+ if (incomingUrl[0] !== "/" && (incomingUrl.startsWith("http://") || incomingUrl.startsWith("https://"))) {
1168
+ validateRequestTarget(incomingUrl);
1169
+ url = new URL(incomingUrl).href;
1170
+ } else url = buildUrl(protocol, request.headers.host ?? "localhost", incomingUrl);
1153
1171
  const headers = new Headers();
1154
1172
  for (const key in request.headers) {
1155
1173
  const value = request.headers[key];
@@ -1186,6 +1204,10 @@ const setupWebSocket = (options) => {
1186
1204
  };
1187
1205
  server.on("upgrade", async (request, socket, head) => {
1188
1206
  if (request.headers.upgrade?.toLowerCase() !== "websocket") return;
1207
+ const ignoreSocketError = () => {};
1208
+ const reclaimWaiterOnClose = () => rejectWaiter(request);
1209
+ socket.on("error", ignoreSocketError);
1210
+ socket.once("close", reclaimWaiterOnClose);
1189
1211
  const env = {
1190
1212
  incoming: request,
1191
1213
  outgoing: void 0,
@@ -1200,8 +1222,12 @@ const setupWebSocket = (options) => {
1200
1222
  status = response.status;
1201
1223
  responseHeaders = response.headers;
1202
1224
  }
1203
- } catch {
1204
- if (server.listenerCount("upgrade") === 1) rejectUpgradeRequest(socket, 500);
1225
+ } catch (error) {
1226
+ if (server.listenerCount("upgrade") === 1) rejectUpgradeRequest(socket, error instanceof RequestError ? 400 : 500);
1227
+ return;
1228
+ }
1229
+ if (socket.destroyed) {
1230
+ rejectWaiter(request);
1205
1231
  return;
1206
1232
  }
1207
1233
  const waiter = waiterMap.get(request);
@@ -1213,12 +1239,11 @@ const setupWebSocket = (options) => {
1213
1239
  const addResponseHeaders = (headers) => {
1214
1240
  appendResponseHeaders(headers, responseHeaders);
1215
1241
  };
1216
- const reclaimWaiterOnClose = () => rejectWaiter(request);
1217
- socket.once("close", reclaimWaiterOnClose);
1218
1242
  wss.on("headers", addResponseHeaders);
1219
1243
  try {
1220
1244
  wss.handleUpgrade(request, socket, head, (ws) => {
1221
1245
  socket.off("close", reclaimWaiterOnClose);
1246
+ socket.off("error", ignoreSocketError);
1222
1247
  wss.emit("connection", ws, request);
1223
1248
  });
1224
1249
  } finally {
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@hono/node-server",
3
- "version": "2.1.5",
3
+ "version": "2.1.6",
4
4
  "description": "Node.js Adapter for Hono",
5
5
  "main": "dist/index.mjs",
6
6
  "type": "module",
@@ -1061,7 +1061,7 @@ var rateLimit = (passedOptions) => {
1061
1061
  const retryAfter = await retrieveRetryAfter;
1062
1062
  setRetryAfterHeader(response, info, config.windowMs, retryAfter);
1063
1063
  }
1064
- config.handler(request, response, next, options);
1064
+ await config.handler(request, response, next, options);
1065
1065
  return;
1066
1066
  }
1067
1067
  next();
@@ -1018,7 +1018,7 @@ var rateLimit = (passedOptions) => {
1018
1018
  const retryAfter = await retrieveRetryAfter;
1019
1019
  setRetryAfterHeader(response, info, config.windowMs, retryAfter);
1020
1020
  }
1021
- config.handler(request, response, next, options);
1021
+ await config.handler(request, response, next, options);
1022
1022
  return;
1023
1023
  }
1024
1024
  next();
@@ -186,9 +186,9 @@ A few terms used throughout the API can be confusing if you haven't worked deepl
186
186
  - `static fromWildcard(input: string): Address6` — Construct an `Address6` from a wildcard pattern with trailing `*` groups. The number of trailing wildcards determines the prefix length: each `*` represents 16 bits. `::` is expanded to zero groups (not wildcards) before evaluating trailing wildcards. Only trailing whole-group wildcards are supported. Partial-group wildcards (e.g. `2001:db8::0*`) and interior wildcards (e.g. `*::1`) throw `AddressError`. [src](https://github.com/beaugunderson/ip-address/blob/main/src/ipv6.ts#L331)
187
187
  - `static fromAddress4(address: string): Address6` — Create an IPv6-mapped address given an IPv4 address [src](https://github.com/beaugunderson/ip-address/blob/main/src/ipv6.ts#L392)
188
188
  - `static fromArpa(arpaFormAddress: string): Address6` — Return an address from ip6.arpa form. A full 32-nibble name gives a /128 address; a shorter name, as used for a delegated reverse zone, gives the network it covers, with a subnet mask of four bits per nibble, so `fromArpa(x.reverseForm())` round-trips reverseForm for any prefix. [src](https://github.com/beaugunderson/ip-address/blob/main/src/ipv6.ts#L412)
189
- - `static fromAddress4Nat64(address: string, prefix?: string): Address6` — Embed an IPv4 address into a NAT64 IPv6 address using the encoding defined by [RFC 6052](https://datatracker.ietf.org/doc/html/rfc6052). The default prefix is the well-known prefix `64:ff9b::/96`. The prefix length must be one of 32, 40, 48, 56, 64, or 96; for prefixes shorter than /64 the IPv4 octets are split around the reserved bits 64–71. [src](https://github.com/beaugunderson/ip-address/blob/main/src/ipv6.ts#L1119)
190
- - `static fromByteArray(bytes: number[]): Address6` — Convert a byte array to an Address6 object. Accepts unsigned bytes (0 to 255) or signed bytes (-128 to 127, as an `Int8Array` or a Java `byte[]` holds them), folding signed values to their unsigned equivalent. Throws `AddressError` unless given exactly 16 integers from -128 to 255. To convert from a Node.js `Buffer`, spread it: `Address6.fromByteArray([...buf])`. [src](https://github.com/beaugunderson/ip-address/blob/main/src/ipv6.ts#L1234)
191
- - `static fromUnsignedByteArray(bytes: number[]): Address6` — Convert an unsigned byte array to an Address6 object. Throws `AddressError` unless given exactly 16 integers from 0 to 255. To convert from a Node.js `Buffer`, spread it: `Address6.fromUnsignedByteArray([...buf])`. [src](https://github.com/beaugunderson/ip-address/blob/main/src/ipv6.ts#L1251)
189
+ - `static fromAddress4Nat64(address: string, prefix?: string): Address6` — Embed an IPv4 address into a NAT64 IPv6 address using the encoding defined by [RFC 6052](https://datatracker.ietf.org/doc/html/rfc6052). The default prefix is the well-known prefix `64:ff9b::/96`. The prefix length must be one of 32, 40, 48, 56, 64, or 96; for prefixes shorter than /64 the IPv4 octets are split around the reserved bits 64–71. [src](https://github.com/beaugunderson/ip-address/blob/main/src/ipv6.ts#L1122)
190
+ - `static fromByteArray(bytes: number[]): Address6` — Convert a byte array to an Address6 object. Accepts unsigned bytes (0 to 255) or signed bytes (-128 to 127, as an `Int8Array` or a Java `byte[]` holds them), folding signed values to their unsigned equivalent. Throws `AddressError` unless given exactly 16 integers from -128 to 255. To convert from a Node.js `Buffer`, spread it: `Address6.fromByteArray([...buf])`. [src](https://github.com/beaugunderson/ip-address/blob/main/src/ipv6.ts#L1237)
191
+ - `static fromUnsignedByteArray(bytes: number[]): Address6` — Convert an unsigned byte array to an Address6 object. Throws `AddressError` unless given exactly 16 integers from 0 to 255. To convert from a Node.js `Buffer`, spread it: `Address6.fromUnsignedByteArray([...buf])`. [src](https://github.com/beaugunderson/ip-address/blob/main/src/ipv6.ts#L1254)
192
192
 
193
193
  **Instance methods**
194
194
 
@@ -215,39 +215,39 @@ A few terms used throughout the API can be confusing if you haven't worked deepl
215
215
  - `binaryZeroPad(): string` — Return a zero-padded base-2 string representation of the address [src](https://github.com/beaugunderson/ip-address/blob/main/src/ipv6.ts#L783)
216
216
  - `parse4in6(address: string): string` — Parses a v4-in-v6 string (e.g. `::ffff:192.168.0.1`) by extracting the trailing IPv4 address into `this.address4` / `this.parsedAddress4` and returning the address with the v4 portion converted to two v6 groups. Used internally by `parse()`. [src](https://github.com/beaugunderson/ip-address/blob/main/src/ipv6.ts#L797)
217
217
  - `parse(address: string): string[]` — Parses an IPv6 address string into its 8 hexadecimal groups (expanding any `::` elision and any trailing v4-in-v6 portion) and stores the result on `this.parsedAddress`. Called automatically by the constructor; you typically don't need to call it directly. Throws `AddressError` if the input is malformed. [src](https://github.com/beaugunderson/ip-address/blob/main/src/ipv6.ts#L854)
218
- - `canonicalForm(): string` — Returns the canonical (fully expanded) form of the address: all 8 groups, each padded to 4 hex digits, with no `::` collapsing (e.g. `2001:0db8:0000:0000:0000:0000:0000:0001`). Useful for sorting and byte-exact comparison. [src](https://github.com/beaugunderson/ip-address/blob/main/src/ipv6.ts#L934)
219
- - `decimal(): string` — Return the decimal form of the address [src](https://github.com/beaugunderson/ip-address/blob/main/src/ipv6.ts#L942)
220
- - `bigInt(): bigint` — Return the address as a BigInt [src](https://github.com/beaugunderson/ip-address/blob/main/src/ipv6.ts#L950)
221
- - `to4(): Address4` — Return the last two groups of this address as an IPv4 address string. If this address carries a CIDR prefix that covers the trailing 32 bits (i.e. `subnetMask >= 96`), the resulting `Address4` inherits the corresponding v4 prefix (`subnetMask - 96`); otherwise it defaults to `/32`. [src](https://github.com/beaugunderson/ip-address/blob/main/src/ipv6.ts#L965)
222
- - `to4in6(): string` — Return the v4-in-v6 form of the address [src](https://github.com/beaugunderson/ip-address/blob/main/src/ipv6.ts#L989)
223
- - `inspectTeredo(): TeredoProperties` — Decodes the Teredo tunneling fields embedded in this address. Returns the Teredo prefix, server IPv4, client IPv4, raw flag bits, cone-NAT flag, UDP port, and Microsoft-format flag breakdown (reserved, universal/local, group/individual, nonce). Only meaningful for addresses in `2001::/32`. [src](https://github.com/beaugunderson/ip-address/blob/main/src/ipv6.ts#L1010)
224
- - `inspect6to4(): SixToFourProperties` — Decodes the 6to4 tunneling fields embedded in this address. Returns the 6to4 prefix and the embedded IPv4 gateway address. Only meaningful for addresses in `2002::/16`. [src](https://github.com/beaugunderson/ip-address/blob/main/src/ipv6.ts#L1073)
225
- - `to6to4(): Address6 | null` — Return a v6 6to4 address from a v6 v4inv6 address [src](https://github.com/beaugunderson/ip-address/blob/main/src/ipv6.ts#L1093)
226
- - `toAddress4Nat64(prefix?: string): Address4 | null` — Extract the embedded IPv4 address from a NAT64 IPv6 address using the encoding defined by [RFC 6052](https://datatracker.ietf.org/doc/html/rfc6052). The default prefix is the well-known prefix `64:ff9b::/96`. Returns `null` if this address is not contained within the given prefix. [src](https://github.com/beaugunderson/ip-address/blob/main/src/ipv6.ts#L1162)
227
- - `toByteArray(): number[]` — Return a byte array. To get a Node.js `Buffer`, wrap the result: `Buffer.from(address.toByteArray())`. [src](https://github.com/beaugunderson/ip-address/blob/main/src/ipv6.ts#L1197)
228
- - `toUnsignedByteArray(): number[]` — Return an unsigned byte array. To get a Node.js `Buffer`, wrap the result: `Buffer.from(address.toUnsignedByteArray())`. [src](https://github.com/beaugunderson/ip-address/blob/main/src/ipv6.ts#L1216)
229
- - `isCanonical(): boolean` — Returns true if the address is in the canonical form, false otherwise [src](https://github.com/beaugunderson/ip-address/blob/main/src/ipv6.ts#L1298)
230
- - `isLinkLocal(): boolean` — Returns true if the address is a link-local unicast address in `fe80::/10` ([RFC 4291 §2.4](https://datatracker.ietf.org/doc/html/rfc4291#section-2.4)) or an IPv4-mapped / NAT64 address whose embedded IPv4 address is link-local (`169.254.0.0/16`, e.g. `::ffff:169.254.169.254`), false otherwise. [src](https://github.com/beaugunderson/ip-address/blob/main/src/ipv6.ts#L1309)
231
- - `isMulticast(): boolean` — Returns true if the address is a multicast address, false otherwise [src](https://github.com/beaugunderson/ip-address/blob/main/src/ipv6.ts#L1322)
232
- - `is4(): boolean` — Returns true if the address was written in v4-in-v6 dotted-quad notation (e.g. `::ffff:127.0.0.1`), false otherwise. This is a notation-level flag and does not reflect whether the address bits lie in the IPv4-mapped (`::ffff:0:0/96`) subnet — for that, see isMapped4. [src](https://github.com/beaugunderson/ip-address/blob/main/src/ipv6.ts#L1339)
233
- - `isMapped4(): boolean` — Returns true if the address is an IPv4-mapped IPv6 address in `::ffff:0:0/96` ([RFC 4291 §2.5.5.2](https://datatracker.ietf.org/doc/html/rfc4291#section-2.5.5.2)), false otherwise. Unlike is4, this checks the underlying address bits rather than the textual notation, so `::ffff:127.0.0.1` and `::ffff:7f00:1` both return true. [src](https://github.com/beaugunderson/ip-address/blob/main/src/ipv6.ts#L1351)
234
- - `embeddedIPv4(): Address4 | null` — If this address embeds a routable IPv4 address — i.e. it is IPv4-mapped (`::ffff:0:0/96`) or sits in the NAT64 well-known prefix (`64:ff9b::/96`, [RFC 6052](https://datatracker.ietf.org/doc/html/rfc6052)) — return that embedded address as an Address4; otherwise return null. The special-property checks (`isLoopback`, `isLinkLocal`, `isMulticast`, `isUnspecified`, `isPrivate`, `isCGNAT`, `isBroadcast`) call this first and delegate to the embedded Address4 when present, so a literal such as `::ffff:127.0.0.1` is classified by what it actually reaches (loopback) rather than by its IPv6 wrapper (which `getType()` reports as IPv4-mapped). This matters wherever the checks back a trust-boundary decision (e.g. an SSRF allow/deny filter): without normalization, `::ffff:10.0.0.1`, `::ffff:169.254.169.254`, `64:ff9b::7f00:1`, etc. would all read as non-internal. [src](https://github.com/beaugunderson/ip-address/blob/main/src/ipv6.ts#L1372)
235
- - `isTeredo(): boolean` — Returns true if the address is a Teredo address, false otherwise [src](https://github.com/beaugunderson/ip-address/blob/main/src/ipv6.ts#L1384)
236
- - `is6to4(): boolean` — Returns true if the address is a 6to4 address, false otherwise [src](https://github.com/beaugunderson/ip-address/blob/main/src/ipv6.ts#L1392)
237
- - `isLoopback(): boolean` — Returns true if the address is a loopback address, false otherwise [src](https://github.com/beaugunderson/ip-address/blob/main/src/ipv6.ts#L1400)
238
- - `isULA(): boolean` — Returns true if the address is a Unique Local Address in `fc00::/7` ([RFC 4193](https://datatracker.ietf.org/doc/html/rfc4193)). ULAs are the IPv6 equivalent of IPv4 [RFC 1918](https://datatracker.ietf.org/doc/html/rfc1918) private addresses. [src](https://github.com/beaugunderson/ip-address/blob/main/src/ipv6.ts#L1413)
239
- - `isPrivate(): boolean` — Returns true if the address is private, i.e. a Unique Local Address in `fc00::/7` ([RFC 4193](https://datatracker.ietf.org/doc/html/rfc4193)), an address in the NAT64 local-use range `64:ff9b:1::/48` ([RFC 8215](https://datatracker.ietf.org/doc/html/rfc8215)), or an IPv4-mapped / NAT64 well-known address whose embedded IPv4 address is in one of the [RFC 1918](https://datatracker.ietf.org/doc/html/rfc1918) private ranges (e.g. `::ffff:10.0.0.1`). This is the IPv6 counterpart to Address4.isPrivate; use it instead of isULA when you need to catch mapped RFC 1918 addresses as well as native ULAs. The local-use NAT64 range is reported private as a whole rather than by its embedded IPv4 address: an operator may carve a prefix of any RFC 6052 length out of `64:ff9b:1::/48`, so the same bits decode to different IPv4 addresses under different deployments and no single decoding is correct. Use toAddress4Nat64 with the deployment's prefix to decode one. [src](https://github.com/beaugunderson/ip-address/blob/main/src/ipv6.ts#L1435)
240
- - `isCGNAT(): boolean` — Returns true if the address is an IPv4-mapped / NAT64 address whose embedded IPv4 address is in the carrier-grade NAT range `100.64.0.0/10` ([RFC 6598](https://datatracker.ietf.org/doc/html/rfc6598)), false otherwise. There is no native IPv6 CGNAT range, so this only ever returns true for an embedded IPv4 address (e.g. `::ffff:100.64.0.1`). [src](https://github.com/beaugunderson/ip-address/blob/main/src/ipv6.ts#L1452)
241
- - `isBroadcast(): boolean` — Returns true if the address is an IPv4-mapped / NAT64 address whose embedded IPv4 address is the limited broadcast address `255.255.255.255` ([RFC 919](https://datatracker.ietf.org/doc/html/rfc919)), false otherwise. There is no IPv6 broadcast, so this only ever returns true for an embedded IPv4 address (e.g. `::ffff:255.255.255.255`). [src](https://github.com/beaugunderson/ip-address/blob/main/src/ipv6.ts#L1469)
242
- - `isUnspecified(): boolean` — Returns true if the address is the unspecified address `::`. [src](https://github.com/beaugunderson/ip-address/blob/main/src/ipv6.ts#L1482)
243
- - `isDocumentation(): boolean` — Returns true if the address is in the documentation prefix `2001:db8::/32` ([RFC 3849](https://datatracker.ietf.org/doc/html/rfc3849)). [src](https://github.com/beaugunderson/ip-address/blob/main/src/ipv6.ts#L1495)
244
- - `isBenchmarking(): boolean` — Returns true if the address is in the benchmarking range `2001:2::/48` ([RFC 5180](https://datatracker.ietf.org/doc/html/rfc5180)) or is an IPv4-mapped / NAT64 address whose embedded IPv4 address is in `198.18.0.0/15`, false otherwise. [src](https://github.com/beaugunderson/ip-address/blob/main/src/ipv6.ts#L1506)
245
- - `isGlobal(): boolean` — Returns true if the address is globally reachable: inside the global unicast allocation `2000::/3` (the only range the [IANA IPv6 Address Space Registry](https://www.iana.org/assignments/ipv6-address-space/) assigns for global unicast; everything else is reserved, ULA, link-local, or multicast) and not in any block the [IANA IPv6 Special-Purpose Address Registry](https://www.iana.org/assignments/iana-ipv6-special-registry/) marks as not globally reachable. An IPv4-mapped or NAT64 well-known address answers for its embedded IPv4 address, so `::ffff:10.0.0.1` and `64:ff9b::7f00:1` are not global. Teredo (`2001::/32`) and 6to4 (`2002::/16`) are not global either: the registry lists them as N/A and a packet to one needs a relay. This covers everything the individual classifiers name and the blocks they do not: the discard-only prefix `100::/64`, the IETF protocol assignments in `2001::/23`, the deprecated site-local `fec0::/10` and IPv4-compatible `::/96` ranges, and unallocated space such as `4000::/3`. It is the single predicate to use where a request must not reach an internal or special-purpose destination; see SECURITY.md. [src](https://github.com/beaugunderson/ip-address/blob/main/src/ipv6.ts#L1535)
246
- - `href(optionalPort?: string | number): string` — Returns the address as an HTTP URL with the host bracketed, e.g. `http://[2001:db8::1]/`. If `optionalPort` is provided it is appended, e.g. `http://[2001:db8::1]:8080/`. [src](https://github.com/beaugunderson/ip-address/blob/main/src/ipv6.ts#L1554)
247
- - `link(options?: { className?: string; prefix?: string; v4?: boolean }): string` — Returns an HTML `<a>` element whose `href` encodes the address in a URL hash fragment (default prefix `/#address=`). Useful for linking between pages of an address-inspector UI. [src](https://github.com/beaugunderson/ip-address/blob/main/src/ipv6.ts#L1572)
248
- - `group(): string` — Groups an address. Returns an HTML fragment: each group is wrapped in a `<span>` carrying the group classes an address-inspector UI hovers on. The address content is HTML-escaped; anything you concatenate around it is your responsibility. [src](https://github.com/beaugunderson/ip-address/blob/main/src/ipv6.ts#L1617)
249
- - `regularExpressionString(substringSearch?: boolean): string` — Generate a regular expression string that can be used to find or validate all variations of this address [src](https://github.com/beaugunderson/ip-address/blob/main/src/ipv6.ts#L1669)
250
- - `regularExpression(substringSearch?: boolean): RegExp` — Generate a regular expression that can be used to find or validate all variations of this address. [src](https://github.com/beaugunderson/ip-address/blob/main/src/ipv6.ts#L1723)
218
+ - `canonicalForm(): string` — Returns the canonical (fully expanded) form of the address: all 8 groups, each padded to 4 hex digits, with no `::` collapsing (e.g. `2001:0db8:0000:0000:0000:0000:0000:0001`). Useful for sorting and byte-exact comparison. [src](https://github.com/beaugunderson/ip-address/blob/main/src/ipv6.ts#L937)
219
+ - `decimal(): string` — Return the decimal form of the address [src](https://github.com/beaugunderson/ip-address/blob/main/src/ipv6.ts#L945)
220
+ - `bigInt(): bigint` — Return the address as a BigInt [src](https://github.com/beaugunderson/ip-address/blob/main/src/ipv6.ts#L953)
221
+ - `to4(): Address4` — Return the last two groups of this address as an IPv4 address string. If this address carries a CIDR prefix that covers the trailing 32 bits (i.e. `subnetMask >= 96`), the resulting `Address4` inherits the corresponding v4 prefix (`subnetMask - 96`); otherwise it defaults to `/32`. [src](https://github.com/beaugunderson/ip-address/blob/main/src/ipv6.ts#L968)
222
+ - `to4in6(): string` — Return the v4-in-v6 form of the address [src](https://github.com/beaugunderson/ip-address/blob/main/src/ipv6.ts#L992)
223
+ - `inspectTeredo(): TeredoProperties` — Decodes the Teredo tunneling fields embedded in this address. Returns the Teredo prefix, server IPv4, client IPv4, raw flag bits, cone-NAT flag, UDP port, and Microsoft-format flag breakdown (reserved, universal/local, group/individual, nonce). Only meaningful for addresses in `2001::/32`. [src](https://github.com/beaugunderson/ip-address/blob/main/src/ipv6.ts#L1013)
224
+ - `inspect6to4(): SixToFourProperties` — Decodes the 6to4 tunneling fields embedded in this address. Returns the 6to4 prefix and the embedded IPv4 gateway address. Only meaningful for addresses in `2002::/16`. [src](https://github.com/beaugunderson/ip-address/blob/main/src/ipv6.ts#L1076)
225
+ - `to6to4(): Address6 | null` — Return a v6 6to4 address from a v6 v4inv6 address [src](https://github.com/beaugunderson/ip-address/blob/main/src/ipv6.ts#L1096)
226
+ - `toAddress4Nat64(prefix?: string): Address4 | null` — Extract the embedded IPv4 address from a NAT64 IPv6 address using the encoding defined by [RFC 6052](https://datatracker.ietf.org/doc/html/rfc6052). The default prefix is the well-known prefix `64:ff9b::/96`. Returns `null` if this address is not contained within the given prefix. [src](https://github.com/beaugunderson/ip-address/blob/main/src/ipv6.ts#L1165)
227
+ - `toByteArray(): number[]` — Return a byte array. To get a Node.js `Buffer`, wrap the result: `Buffer.from(address.toByteArray())`. [src](https://github.com/beaugunderson/ip-address/blob/main/src/ipv6.ts#L1200)
228
+ - `toUnsignedByteArray(): number[]` — Return an unsigned byte array. To get a Node.js `Buffer`, wrap the result: `Buffer.from(address.toUnsignedByteArray())`. [src](https://github.com/beaugunderson/ip-address/blob/main/src/ipv6.ts#L1219)
229
+ - `isCanonical(): boolean` — Returns true if the address is in the canonical form, false otherwise [src](https://github.com/beaugunderson/ip-address/blob/main/src/ipv6.ts#L1301)
230
+ - `isLinkLocal(): boolean` — Returns true if the address is a link-local unicast address in `fe80::/10` ([RFC 4291 §2.4](https://datatracker.ietf.org/doc/html/rfc4291#section-2.4)) or an IPv4-mapped / NAT64 address whose embedded IPv4 address is link-local (`169.254.0.0/16`, e.g. `::ffff:169.254.169.254`), false otherwise. [src](https://github.com/beaugunderson/ip-address/blob/main/src/ipv6.ts#L1312)
231
+ - `isMulticast(): boolean` — Returns true if the address is a multicast address, false otherwise [src](https://github.com/beaugunderson/ip-address/blob/main/src/ipv6.ts#L1325)
232
+ - `is4(): boolean` — Returns true if the address was written in v4-in-v6 dotted-quad notation (e.g. `::ffff:127.0.0.1`), false otherwise. This is a notation-level flag and does not reflect whether the address bits lie in the IPv4-mapped (`::ffff:0:0/96`) subnet — for that, see isMapped4. [src](https://github.com/beaugunderson/ip-address/blob/main/src/ipv6.ts#L1342)
233
+ - `isMapped4(): boolean` — Returns true if the address is an IPv4-mapped IPv6 address in `::ffff:0:0/96` ([RFC 4291 §2.5.5.2](https://datatracker.ietf.org/doc/html/rfc4291#section-2.5.5.2)), false otherwise. Unlike is4, this checks the underlying address bits rather than the textual notation, so `::ffff:127.0.0.1` and `::ffff:7f00:1` both return true. [src](https://github.com/beaugunderson/ip-address/blob/main/src/ipv6.ts#L1354)
234
+ - `embeddedIPv4(): Address4 | null` — If this address embeds a routable IPv4 address — i.e. it is IPv4-mapped (`::ffff:0:0/96`) or sits in the NAT64 well-known prefix (`64:ff9b::/96`, [RFC 6052](https://datatracker.ietf.org/doc/html/rfc6052)) — return that embedded address as an Address4; otherwise return null. The special-property checks (`isLoopback`, `isLinkLocal`, `isMulticast`, `isUnspecified`, `isPrivate`, `isCGNAT`, `isBroadcast`) call this first and delegate to the embedded Address4 when present, so a literal such as `::ffff:127.0.0.1` is classified by what it actually reaches (loopback) rather than by its IPv6 wrapper (which `getType()` reports as IPv4-mapped). This matters wherever the checks back a trust-boundary decision (e.g. an SSRF allow/deny filter): without normalization, `::ffff:10.0.0.1`, `::ffff:169.254.169.254`, `64:ff9b::7f00:1`, etc. would all read as non-internal. [src](https://github.com/beaugunderson/ip-address/blob/main/src/ipv6.ts#L1375)
235
+ - `isTeredo(): boolean` — Returns true if the address is a Teredo address, false otherwise [src](https://github.com/beaugunderson/ip-address/blob/main/src/ipv6.ts#L1387)
236
+ - `is6to4(): boolean` — Returns true if the address is a 6to4 address, false otherwise [src](https://github.com/beaugunderson/ip-address/blob/main/src/ipv6.ts#L1395)
237
+ - `isLoopback(): boolean` — Returns true if the address is a loopback address, false otherwise [src](https://github.com/beaugunderson/ip-address/blob/main/src/ipv6.ts#L1403)
238
+ - `isULA(): boolean` — Returns true if the address is a Unique Local Address in `fc00::/7` ([RFC 4193](https://datatracker.ietf.org/doc/html/rfc4193)). ULAs are the IPv6 equivalent of IPv4 [RFC 1918](https://datatracker.ietf.org/doc/html/rfc1918) private addresses. [src](https://github.com/beaugunderson/ip-address/blob/main/src/ipv6.ts#L1416)
239
+ - `isPrivate(): boolean` — Returns true if the address is private, i.e. a Unique Local Address in `fc00::/7` ([RFC 4193](https://datatracker.ietf.org/doc/html/rfc4193)), an address in the NAT64 local-use range `64:ff9b:1::/48` ([RFC 8215](https://datatracker.ietf.org/doc/html/rfc8215)), or an IPv4-mapped / NAT64 well-known address whose embedded IPv4 address is in one of the [RFC 1918](https://datatracker.ietf.org/doc/html/rfc1918) private ranges (e.g. `::ffff:10.0.0.1`). This is the IPv6 counterpart to Address4.isPrivate; use it instead of isULA when you need to catch mapped RFC 1918 addresses as well as native ULAs. The local-use NAT64 range is reported private as a whole rather than by its embedded IPv4 address: an operator may carve a prefix of any RFC 6052 length out of `64:ff9b:1::/48`, so the same bits decode to different IPv4 addresses under different deployments and no single decoding is correct. Use toAddress4Nat64 with the deployment's prefix to decode one. [src](https://github.com/beaugunderson/ip-address/blob/main/src/ipv6.ts#L1438)
240
+ - `isCGNAT(): boolean` — Returns true if the address is an IPv4-mapped / NAT64 address whose embedded IPv4 address is in the carrier-grade NAT range `100.64.0.0/10` ([RFC 6598](https://datatracker.ietf.org/doc/html/rfc6598)), false otherwise. There is no native IPv6 CGNAT range, so this only ever returns true for an embedded IPv4 address (e.g. `::ffff:100.64.0.1`). [src](https://github.com/beaugunderson/ip-address/blob/main/src/ipv6.ts#L1455)
241
+ - `isBroadcast(): boolean` — Returns true if the address is an IPv4-mapped / NAT64 address whose embedded IPv4 address is the limited broadcast address `255.255.255.255` ([RFC 919](https://datatracker.ietf.org/doc/html/rfc919)), false otherwise. There is no IPv6 broadcast, so this only ever returns true for an embedded IPv4 address (e.g. `::ffff:255.255.255.255`). [src](https://github.com/beaugunderson/ip-address/blob/main/src/ipv6.ts#L1472)
242
+ - `isUnspecified(): boolean` — Returns true if the address is the unspecified address `::`. [src](https://github.com/beaugunderson/ip-address/blob/main/src/ipv6.ts#L1485)
243
+ - `isDocumentation(): boolean` — Returns true if the address is in the documentation prefix `2001:db8::/32` ([RFC 3849](https://datatracker.ietf.org/doc/html/rfc3849)). [src](https://github.com/beaugunderson/ip-address/blob/main/src/ipv6.ts#L1498)
244
+ - `isBenchmarking(): boolean` — Returns true if the address is in the benchmarking range `2001:2::/48` ([RFC 5180](https://datatracker.ietf.org/doc/html/rfc5180)) or is an IPv4-mapped / NAT64 address whose embedded IPv4 address is in `198.18.0.0/15`, false otherwise. [src](https://github.com/beaugunderson/ip-address/blob/main/src/ipv6.ts#L1509)
245
+ - `isGlobal(): boolean` — Returns true if the address is globally reachable: inside the global unicast allocation `2000::/3` (the only range the [IANA IPv6 Address Space Registry](https://www.iana.org/assignments/ipv6-address-space/) assigns for global unicast; everything else is reserved, ULA, link-local, or multicast) and not in any block the [IANA IPv6 Special-Purpose Address Registry](https://www.iana.org/assignments/iana-ipv6-special-registry/) marks as not globally reachable. An IPv4-mapped or NAT64 well-known address answers for its embedded IPv4 address, so `::ffff:10.0.0.1` and `64:ff9b::7f00:1` are not global. Teredo (`2001::/32`) and 6to4 (`2002::/16`) are not global either: the registry lists them as N/A and a packet to one needs a relay. This covers everything the individual classifiers name and the blocks they do not: the discard-only prefix `100::/64`, the IETF protocol assignments in `2001::/23`, the deprecated site-local `fec0::/10` and IPv4-compatible `::/96` ranges, and unallocated space such as `4000::/3`. It is the single predicate to use where a request must not reach an internal or special-purpose destination; see SECURITY.md. [src](https://github.com/beaugunderson/ip-address/blob/main/src/ipv6.ts#L1538)
246
+ - `href(optionalPort?: string | number): string` — Returns the address as an HTTP URL with the host bracketed, e.g. `http://[2001:db8::1]/`. If `optionalPort` is provided it is appended, e.g. `http://[2001:db8::1]:8080/`. [src](https://github.com/beaugunderson/ip-address/blob/main/src/ipv6.ts#L1557)
247
+ - `link(options?: { className?: string; prefix?: string; v4?: boolean }): string` — Returns an HTML `<a>` element whose `href` encodes the address in a URL hash fragment (default prefix `/#address=`). Useful for linking between pages of an address-inspector UI. [src](https://github.com/beaugunderson/ip-address/blob/main/src/ipv6.ts#L1575)
248
+ - `group(): string` — Groups an address. Returns an HTML fragment: each group is wrapped in a `<span>` carrying the group classes an address-inspector UI hovers on. The address content is HTML-escaped; anything you concatenate around it is your responsibility. [src](https://github.com/beaugunderson/ip-address/blob/main/src/ipv6.ts#L1620)
249
+ - `regularExpressionString(substringSearch?: boolean): string` — Generate a regular expression string that can be used to find or validate all variations of this address [src](https://github.com/beaugunderson/ip-address/blob/main/src/ipv6.ts#L1672)
250
+ - `regularExpression(substringSearch?: boolean): RegExp` — Generate a regular expression that can be used to find or validate all variations of this address. [src](https://github.com/beaugunderson/ip-address/blob/main/src/ipv6.ts#L1726)
251
251
 
252
252
  **Properties**
253
253
 
@@ -265,9 +265,9 @@ A few terms used throughout the API can be confusing if you haven't worked deepl
265
265
  - `subnetMask: number` — [src](https://github.com/beaugunderson/ip-address/blob/main/src/ipv6.ts#L108)
266
266
  - `v4: boolean` — [src](https://github.com/beaugunderson/ip-address/blob/main/src/ipv6.ts#L109)
267
267
  - `zone: string` — [src](https://github.com/beaugunderson/ip-address/blob/main/src/ipv6.ts#L110)
268
- - `isInSubnet: (address: Address4 | Address6) => boolean` — Returns true if the given address is in the subnet of the current address. An `Address4` is never in the subnet of an `Address6`; convert with `Address6.fromAddress4()` or `to4()` to compare across families. [src](https://github.com/beaugunderson/ip-address/blob/main/src/ipv6.ts#L1274)
269
- - `isHostInSubnet: (address: Address4 | Address6) => boolean` — Returns true if this address's host bits fall inside the given subnet, ignoring this address's own subnet mask. Prefer this over `isInSubnet` when classifying a single address, so the answer doesn't change with the CIDR suffix the caller happened to write — notably when the address came from untrusted input and the result backs a trust-boundary decision. An `Address4` is never in the subnet of an `Address6`; convert with `Address6.fromAddress4()` or `to4()` to compare across families. [src](https://github.com/beaugunderson/ip-address/blob/main/src/ipv6.ts#L1286)
270
- - `isCorrect: () => boolean` — Returns true if the address is correct, false otherwise [src](https://github.com/beaugunderson/ip-address/blob/main/src/ipv6.ts#L1292)
268
+ - `isInSubnet: (address: Address4 | Address6) => boolean` — Returns true if the given address is in the subnet of the current address. An `Address4` is never in the subnet of an `Address6`; convert with `Address6.fromAddress4()` or `to4()` to compare across families. [src](https://github.com/beaugunderson/ip-address/blob/main/src/ipv6.ts#L1277)
269
+ - `isHostInSubnet: (address: Address4 | Address6) => boolean` — Returns true if this address's host bits fall inside the given subnet, ignoring this address's own subnet mask. Prefer this over `isInSubnet` when classifying a single address, so the answer doesn't change with the CIDR suffix the caller happened to write — notably when the address came from untrusted input and the result backs a trust-boundary decision. An `Address4` is never in the subnet of an `Address6`; convert with `Address6.fromAddress4()` or `to4()` to compare across families. [src](https://github.com/beaugunderson/ip-address/blob/main/src/ipv6.ts#L1289)
270
+ - `isCorrect: () => boolean` — Returns true if the address is correct, false otherwise [src](https://github.com/beaugunderson/ip-address/blob/main/src/ipv6.ts#L1295)
271
271
 
272
272
  </details>
273
273
 
@@ -733,7 +733,7 @@ class Address6 {
733
733
  address = this.parse4in6(address);
734
734
  const badCharacters = address.match(constants6.RE_BAD_CHARACTERS);
735
735
  if (badCharacters) {
736
- throw new address_error_1.AddressError(`Bad character${badCharacters.length > 1 ? 's' : ''} detected in address: ${badCharacters.join('')}`, address.replace(constants6.RE_BAD_CHARACTERS, '<span class="parse-error">$1</span>'));
736
+ throw new address_error_1.AddressError(`Bad character${badCharacters.length > 1 ? 's' : ''} detected in address: ${badCharacters.join('')}`, address.replace(constants6.RE_BAD_CHARACTERS, (character) => `<span class="parse-error">${helpers.escapeHtml(character)}</span>`));
737
737
  }
738
738
  const badAddress = address.match(constants6.RE_BAD_ADDRESS);
739
739
  if (badAddress) {
@@ -16,7 +16,7 @@
16
16
  "bigint",
17
17
  "browser"
18
18
  ],
19
- "version": "10.7.5",
19
+ "version": "10.7.6",
20
20
  "author": "Beau Gunderson <beau@beaugunderson.com> (https://beaugunderson.com/)",
21
21
  "license": "MIT",
22
22
  "main": "dist/ip-address.js",
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "express-rate-limit",
3
- "version": "8.7.2",
3
+ "version": "8.7.3",
4
4
  "description": "Basic IP rate-limiting middleware for Express. Use to limit repeated requests to public APIs and/or endpoints such as password reset.",
5
5
  "author": {
6
6
  "name": "Nathan Friedly",
@@ -1,4 +1,4 @@
1
- import{CommandParser as p}from"./parser.js";import{initCommand as f}from"./commands/init.js";import{statusCommand as g}from"./commands/status.js";import{daemonCommand as h}from"./commands/daemon.js";import{dashboardCommand as u}from"./commands/dashboard.js";import{scanCommand as C}from"./commands/scan.js";import{chpassCommand as b}from"./commands/chpass.js";import{doctorCommand as x}from"./commands/doctor.js";import{uninstallCommand as $}from"./commands/uninstall.js";import{initCliLocale as E,t as e}from"./i18n/index.js";import{WEAVE_VERSION as S}from"@weavecode/server";const w=process.emitWarning.bind(process);process.emitWarning=(n,...r)=>{if(!(typeof n=="string"?n:String(n)).includes("SQLite is an experimental feature"))return w(n,...r)};const l=()=>S;function v(n){if(n.description){console.log(` ${n.name.padEnd(12)}${e(n.description)}`);for(const r of n.subcommands??[]){const o=[r.name,...r.aliases??[]].join(", "),s=r.description?e(r.description):"";console.log(` ${o.padEnd(12)}${s}`)}}}function a(n){const r=l();console.log(`${e("help.tagline",{version:r})}
2
- `),console.log(`${e("help.usage")}
3
- `),console.log(e("help.commands"));for(const o of n.getAllCommands())v(o);console.log(`
4
- ${e("help.globalOptions")}`);for(const o of n.getGlobalOptions()){const s=o.short?`-${o.short}, --${o.name}`:` --${o.name}`;console.log(` ${s.padEnd(20)}${e(o.description)}`)}}function L(n){console.error(e("help.subcommands"));for(const r of n.subcommands??[]){const o=[r.name,...r.aliases??[]].join(", "),s=r.description?e(r.description):"";console.error(` ${o.padEnd(12)}${s}`)}}export class CLI{parser;constructor(){this.parser=new p,this.registerCommands()}registerCommands(){this.parser.registerCommand(f),this.parser.registerCommand($),this.parser.registerCommand(g),this.parser.registerCommand(h),this.parser.registerCommand(u),this.parser.registerCommand(C),this.parser.registerCommand(b),this.parser.registerCommand(x)}async run(r=process.argv.slice(2)){delete process.env.CLAUDE_CODE_CHILD_SESSION,await E();const o=this.parser.parse(r);if(o.flags.version){console.log(l());return}if(o.flags.help||o.command.length===0){a(this.parser);return}let s;for(const t of o.command)s=(s?s.subcommands?.find(c=>c.name===t||c.aliases?.includes(t)):this.parser.getCommand(t))??s;if(!s?.action){if(s?.subcommands?.length){const t=o.positional[0];console.error(t?e("cli.unknownSubcommand",{command:s.name,subcommand:t}):e("cli.missingSubcommand",{command:s.name})),L(s),process.exit(1)}console.error(e("cli.unknownCommand",{command:o.command.join(" ")})),a(this.parser),process.exit(1)}const i=s.maxPositionals??0;if(o.positional.length>i){const t=o.command.join(" ");console.error(e("cli.unexpectedPositional",{command:t,arg:o.positional[i]})),a(this.parser),process.exit(1)}const m=this.parser.validateFlags(o.flags,s);if(m.length>0){for(const t of m)console.error(e("cli.error",{error:t}));process.exit(1)}const d={commandPath:o.command,flags:o.flags,positional:o.positional,raw:o.raw};await s.action(d)}}
1
+ import{CommandParser as p}from"./parser.js";import{initCommand as f}from"./commands/init.js";import{statusCommand as g}from"./commands/status.js";import{daemonCommand as h}from"./commands/daemon.js";import{dashboardCommand as C}from"./commands/dashboard.js";import{scanCommand as u}from"./commands/scan.js";import{chpassCommand as $}from"./commands/chpass.js";import{doctorCommand as b}from"./commands/doctor.js";import{uninstallCommand as E}from"./commands/uninstall.js";import{initCliLocale as x,t as a}from"./i18n/index.js";import{WEAVE_VERSION as S}from"@weavecode/server";const w=process.emitWarning.bind(process);process.emitWarning=(n,...r)=>{if(!(typeof n=="string"?n:String(n)).includes("SQLite is an experimental feature"))return w(n,...r)};const l=()=>S;function v(n){if(n.description){console.log(` ${n.name.padEnd(12)}${a(n.description)}`);for(const r of n.subcommands??[]){const o=[r.name,...r.aliases??[]].join(", "),s=r.description?a(r.description):"";console.log(` ${o.padEnd(12)}${s}`)}}}function i(n){const r=l();console.log(`${a("help.tagline",{version:r})}
2
+ `),console.log(`${a("help.usage")}
3
+ `),console.log(a("help.commands"));for(const o of n.getAllCommands())v(o);console.log(`
4
+ ${a("help.globalOptions")}`);for(const o of n.getGlobalOptions()){const s=o.short?`-${o.short}, --${o.name}`:` --${o.name}`;console.log(` ${s.padEnd(20)}${a(o.description)}`)}}function L(n){console.error(a("help.subcommands"));for(const r of n.subcommands??[]){const o=[r.name,...r.aliases??[]].join(", "),s=r.description?a(r.description):"";console.error(` ${o.padEnd(12)}${s}`)}}export class CLI{parser;constructor(){this.parser=new p,this.registerCommands()}registerCommands(){this.parser.registerCommand(f),this.parser.registerCommand(E),this.parser.registerCommand(g),this.parser.registerCommand(h),this.parser.registerCommand(C),this.parser.registerCommand(u),this.parser.registerCommand($),this.parser.registerCommand(b)}async run(r=process.argv.slice(2)){delete process.env.CLAUDE_CODE_CHILD_SESSION,await x();const o=this.parser.parse(r);if(o.flags.version){console.log(l());return}if(o.flags.help||o.command.length===0){i(this.parser);return}let s;for(const e of o.command)s=(s?s.subcommands?.find(c=>c.name===e||c.aliases?.includes(e)):this.parser.getCommand(e))??s;if(!s?.action){if(s?.subcommands?.length){const e=o.positional[0];console.error(e?a("cli.unknownSubcommand",{command:s.name,subcommand:e}):a("cli.missingSubcommand",{command:s.name})),L(s),process.exit(1)}console.error(a("cli.unknownCommand",{command:o.command.join(" ")})),i(this.parser),process.exit(1)}const m=s.maxPositionals??0;if(o.positional.length>m){const e=o.command.join(" ");console.error(a("cli.unexpectedPositional",{command:e,arg:o.positional[m]})),i(this.parser),process.exit(1)}const t=this.parser.validateFlags(o.flags,s);if(t.length>0){for(const e of t)console.error(a("cli.error",{error:e}));process.exit(1)}const d={commandPath:o.command,flags:o.flags,positional:o.positional,raw:o.raw};await s.action(d)}}
@@ -1 +1 @@
1
- import{DAEMON_HOST as c}from"@weavecode/server";import{logger as s}from"@weavecode/core";import{t as r}from"../i18n/index.js";import{ensureDaemonRunning as i}from"./daemon.js";import{localTokenHeader as p}from"./daemon-auth.js";const m=6;async function h(n){const t=n.positional[0];if(typeof t!="string"||t.length<m){s.warn(r("out.chpass.usage")),process.exitCode=1;return}const a=await i();try{const o=await fetch(`http://${c}:${a.port}/auth/password`,{method:"PUT",headers:{"content-type":"application/json",...p()},body:JSON.stringify({next:t})}),e=await o.json().catch(()=>({}));if(!o.ok)throw new Error(typeof e.error=="string"?e.error:`HTTP ${o.status}`);s.success(r("out.chpass.ok"))}catch(o){s.warn(r("out.chpass.fail",{error:o instanceof Error?o.message:String(o)})),process.exitCode=1}}export const chpassCommand={name:"chpass",description:"cmd.chpass.desc",action:h,maxPositionals:1};
1
+ import{DAEMON_HOST as c}from"@weavecode/server";import{logger as s}from"@weavecode/core";import{t as r}from"../i18n/index.js";import{ensureDaemonRunning as i}from"./daemon.js";import{localTokenHeader as p}from"./daemon-auth.js";const m=6;async function h(n){const t=n.positional[0];if(typeof t!="string"||t.length<m){s.warn(r("out.chpass.usage")),process.exitCode=1;return}const e=await i();try{const o=await fetch(`http://${c}:${e.port}/auth/password`,{method:"PUT",headers:{"content-type":"application/json",...p()},body:JSON.stringify({next:t})}),a=await o.json().catch(()=>({}));if(!o.ok)throw new Error(typeof a.error=="string"?a.error:`HTTP ${o.status}`);s.success(r("out.chpass.ok"))}catch(o){s.warn(r("out.chpass.fail",{error:o instanceof Error?o.message:String(o)})),process.exitCode=1}}export const chpassCommand={name:"chpass",description:"cmd.chpass.desc",action:h,maxPositionals:1};
@@ -1 +1 @@
1
- import{existsSync as e,readFileSync as o,rmSync as n}from"node:fs";import{getAuthPath as a,getInitialPasswordPath as i}from"@weavecode/server";import{logger as c}from"@weavecode/core";import{t as l}from"../i18n/index.js";export function localTokenHeader(){try{const t=JSON.parse(o(a(),"utf8"));return typeof t.localToken=="string"&&t.localToken?{"x-weave-local":t.localToken}:{}}catch{return{}}}export function announceInitialPassword(){const t=i();if(!e(t))return;let r;try{r=o(t,"utf8").trim()}catch{return}n(t,{force:!0}),r&&c.info(l("out.dash.initialPassword",{password:r}))}
1
+ import{existsSync as a,readFileSync as r,rmSync as e}from"node:fs";import{getAuthPath as n,getInitialPasswordPath as s}from"@weavecode/server";import{logger as i}from"@weavecode/core";import{t as c}from"../i18n/index.js";export function localTokenHeader(){try{const t=JSON.parse(r(n(),"utf8"));return typeof t.localToken=="string"&&t.localToken?{"x-weave-local":t.localToken}:{}}catch{return{}}}export function announceInitialPassword(){const t=s();if(!a(t))return;let o;try{o=r(t,"utf8").trim()}catch{return}e(t,{force:!0}),o&&i.info(c("out.dash.initialPassword",{password:o}))}
@@ -1,2 +1,2 @@
1
- import{spawn as f}from"node:child_process";import{DEFAULT_PORT as c,DAEMON_HOST as u,isPortFree as h,findFreePort as y,readDaemonState as p,writeDaemonState as $,clearDaemonState as g,resolveDaemonEntry as D,accessUrls as P}from"@weavecode/server";import{logger as a}from"@weavecode/core";import{t as r}from"../i18n/index.js";export async function probeDaemon(t){try{const e=await fetch(`http://${u}:${t}/health`);return e.ok?(await e.json()).service==="weave-daemon":!1}catch{return!1}}export async function waitForDaemon(t,e=1e4){const o=Date.now()+e;for(;!await probeDaemon(t);){if(Date.now()>=o)return!1;await new Promise(n=>setTimeout(n,100))}return!0}async function x(t,e){if(process.platform!=="win32")return!1;const o=i=>/\s/.test(i)?`"${i}"`:i,n=i=>`'${i.replace(/'/g,"''")}'`,s=`$ErrorActionPreference='Stop';$su=[wmiclass]'Win32_ProcessStartup';$psi=$su.CreateInstance();$psi.ShowWindow=0;$proc=[wmiclass]'Win32_Process';$r=$proc.Create(${n([t,...e].map(o).join(" "))},${n(process.cwd())},$psi);if($r.ReturnValue -ne 0){exit 1}`,d=Buffer.from(s,"utf16le").toString("base64");return new Promise(i=>{const m=f("powershell.exe",["-NoProfile","-NonInteractive","-EncodedCommand",d],{windowsHide:!0,stdio:"ignore"});m.on("error",()=>i(!1)),m.on("exit",w=>i(w===0))})}export async function ensureDaemonRunning(){const t=p();if(t&&await probeDaemon(t.port))return{port:t.port,started:!1,ready:!0};if(await probeDaemon(c))return{port:c,started:!1,ready:!0};const e=await h(c)?c:await y(c+1);$({pid:0,port:e,startedAt:new Date().toISOString()});const o=D(),n=o.isTs?["--import","tsx",o.path]:[o.path];await x(process.execPath,n)||f(process.execPath,n,{detached:!0,stdio:"ignore"}).unref();const s=await waitForDaemon(e);return{port:e,started:!0,ready:s}}async function S(){const t=await ensureDaemonRunning();if(!t.started){a.info(r("out.daemon.alreadyRunning",{port:t.port}));return}t.ready?a.success(r("out.daemon.started",{host:u,port:t.port})):a.warn(r("out.daemon.startUnconfirmed",{port:t.port}))}async function l(t){return await(await fetch(`http://${u}:${t}/health`)).json()}async function A(){const t=p(),e=t?.port??c;let o=t?.pid;if(await probeDaemon(e))o=(await l(e)).pid;else if(!t){a.info(r("out.daemon.statusNotRunning"));return}let n;if(o)try{process.kill(o),n=o}catch{}g(),n!==void 0?(await R(n,e),a.success(r("out.daemon.stopped",{pid:n}))):a.warn(r("out.daemon.statusStale",{pid:o??0,port:e}))}async function R(t,e,o=5e3){const n=Date.now()+o;for(;;){let s;try{process.kill(t,0),s=!0}catch{s=!1}if(!s&&!await probeDaemon(e)||Date.now()>=n)return;await new Promise(d=>setTimeout(d,100))}}async function T(){const t=p(),e=t?.port??c;if(await probeDaemon(e)){const o=await l(e);a.info(r("out.daemon.statusRunning",{pid:o.pid,port:o.port,uptime:Math.round(o.uptimeMs/1e3)}));const n=P(e,t?.tlsPort??0);n.length>0&&(a.dim(r("out.daemon.urlsTitle")),a.dim(n.map(s=>` ${s.url}`).join(`
2
- `)))}else t?a.warn(r("out.daemon.statusStale",{pid:t.pid,port:t.port})):a.info(r("out.daemon.statusNotRunning"))}export const daemonCommand={name:"daemon",description:"cmd.daemon.desc",subcommands:[{name:"start",description:"cmd.daemon.start.desc",action:S},{name:"stop",description:"cmd.daemon.stop.desc",action:A},{name:"status",description:"cmd.daemon.status.desc",action:T}]};
1
+ import{spawn as w}from"node:child_process";import{DEFAULT_PORT as c,DAEMON_HOST as d,isPortFree as h,findFreePort as y,readDaemonState as u,writeDaemonState as $,clearDaemonState as g,resolveDaemonEntry as D,accessUrls as P}from"@weavecode/server";import{logger as n}from"@weavecode/core";import{localTokenHeader as S}from"./daemon-auth.js";import{t as r}from"../i18n/index.js";export async function probeDaemon(t){try{const e=await fetch(`http://${d}:${t}/health`);return e.ok?(await e.json()).service==="weave-daemon":!1}catch{return!1}}export async function waitForDaemon(t,e=1e4){const o=Date.now()+e;for(;!await probeDaemon(t);){if(Date.now()>=o)return!1;await new Promise(a=>setTimeout(a,100))}return!0}async function x(t,e){if(process.platform!=="win32")return!1;const o=i=>/\s/.test(i)?`"${i}"`:i,a=i=>`'${i.replace(/'/g,"''")}'`,s=`$ErrorActionPreference='Stop';$su=[wmiclass]'Win32_ProcessStartup';$psi=$su.CreateInstance();$psi.ShowWindow=0;$proc=[wmiclass]'Win32_Process';$r=$proc.Create(${a([t,...e].map(o).join(" "))},${a(process.cwd())},$psi);if($r.ReturnValue -ne 0){exit 1}`,p=Buffer.from(s,"utf16le").toString("base64");return new Promise(i=>{const m=w("powershell.exe",["-NoProfile","-NonInteractive","-EncodedCommand",p],{windowsHide:!0,stdio:"ignore"});m.on("error",()=>i(!1)),m.on("exit",l=>i(l===0))})}export async function ensureDaemonRunning(){const t=u();if(t&&await probeDaemon(t.port))return{port:t.port,started:!1,ready:!0};if(await probeDaemon(c))return{port:c,started:!1,ready:!0};const e=await h(c)?c:await y(c+1);$({pid:0,port:e,startedAt:new Date().toISOString()});const o=D(),a=o.isTs?["--import","tsx",o.path]:[o.path];await x(process.execPath,a)||w(process.execPath,a,{detached:!0,stdio:"ignore"}).unref();const s=await waitForDaemon(e);return{port:e,started:!0,ready:s}}async function T(){const t=await ensureDaemonRunning();if(!t.started){n.info(r("out.daemon.alreadyRunning",{port:t.port}));return}t.ready?n.success(r("out.daemon.started",{host:d,port:t.port})):n.warn(r("out.daemon.startUnconfirmed",{port:t.port}))}async function f(t){return await(await fetch(`http://${d}:${t}/health`)).json()}async function R(t){const e=S();if(!e["x-weave-local"])return!1;const o=new AbortController,a=setTimeout(()=>o.abort(),2e3);try{return(await fetch(`http://${d}:${t}/daemon/shutdown`,{method:"POST",headers:e,signal:o.signal})).ok}catch{return!1}finally{clearTimeout(a)}}async function v(){const t=u(),e=t?.port??c;let o=t?.pid;if(await probeDaemon(e))o=(await f(e)).pid;else if(!t){n.info(r("out.daemon.statusNotRunning"));return}let a;if(o)if(await R(e))a=o;else try{process.kill(o),a=o}catch{}g(),a!==void 0?(await b(a,e),n.success(r("out.daemon.stopped",{pid:a}))):n.warn(r("out.daemon.statusStale",{pid:o??0,port:e}))}async function b(t,e,o=5e3){const a=Date.now()+o;for(;;){let s;try{process.kill(t,0),s=!0}catch{s=!1}if(!s&&!await probeDaemon(e)||Date.now()>=a)return;await new Promise(p=>setTimeout(p,100))}}async function A(){const t=u(),e=t?.port??c;if(await probeDaemon(e)){const o=await f(e);n.info(r("out.daemon.statusRunning",{pid:o.pid,port:o.port,uptime:Math.round(o.uptimeMs/1e3)}));const a=P(e,t?.tlsPort??0);a.length>0&&(n.dim(r("out.daemon.urlsTitle")),n.dim(a.map(s=>` ${s.url}`).join(`
2
+ `)))}else t?n.warn(r("out.daemon.statusStale",{pid:t.pid,port:t.port})):n.info(r("out.daemon.statusNotRunning"))}export const daemonCommand={name:"daemon",description:"cmd.daemon.desc",subcommands:[{name:"start",description:"cmd.daemon.start.desc",action:T},{name:"stop",description:"cmd.daemon.stop.desc",action:v},{name:"status",description:"cmd.daemon.status.desc",action:A}]};
@@ -1,2 +1,2 @@
1
- import{spawn as p}from"node:child_process";import{accessUrls as m,DAEMON_HOST as d,readDaemonState as c,resolveStaticDir as l}from"@weavecode/server";import{logger as o}from"@weavecode/core";import{t as n}from"../i18n/index.js";import{ensureDaemonRunning as u}from"./daemon.js";import{announceInitialPassword as f}from"./daemon-auth.js";export function openBrowser(r){const[e,t]=process.platform==="win32"?["cmd",["/c","start","",r]]:process.platform==="darwin"?["open",[r]]:["xdg-open",[r]],a=p(e,t,{detached:!0,stdio:"ignore"});a.on("error",()=>{o.dim(n("out.dash.browserFailed"))}),a.unref()}export function dashboardUrl(r){return`http://${d}:${r}/`}async function h(r){const e=!!r.flags.noOpen,t=await u();t.started?t.ready?(o.success(n("out.daemon.started",{host:d,port:t.port})),o.dim(n("out.dash.stopHint"))):o.warn(n("out.daemon.startUnconfirmed",{port:t.port})):o.info(n("out.daemon.alreadyRunning",{port:t.port})),l()||(o.warn(n("out.dash.noBundle")),o.dim(n("out.dash.buildHint")));const a=dashboardUrl(t.port);o.info(n("out.dash.url",{url:a}));const s=m(t.port,c()?.tlsPort??0);if(s.length>0&&(o.dim(n("out.daemon.urlsTitle")),o.dim(s.map(i=>` ${i.url}`).join(`
2
- `))),f(),e){o.dim(n("out.dash.noOpen"));return}openBrowser(a)}export const dashboardCommand={name:"dashboard",aliases:["dash"],description:"cmd.dashboard.desc",options:[{name:"no-open",description:"flag.dashboard.noOpen",type:"boolean",default:!1}],action:h};
1
+ import{spawn as p}from"node:child_process";import{accessUrls as m,DAEMON_HOST as d,readDaemonState as u,resolveStaticDir as c}from"@weavecode/server";import{logger as o}from"@weavecode/core";import{t as r}from"../i18n/index.js";import{ensureDaemonRunning as l}from"./daemon.js";import{announceInitialPassword as f}from"./daemon-auth.js";export function openBrowser(a){const[s,t]=process.platform==="win32"?["cmd",["/c","start","",a]]:process.platform==="darwin"?["open",[a]]:["xdg-open",[a]],n=p(s,t,{detached:!0,stdio:"ignore"});n.on("error",()=>{o.dim(r("out.dash.browserFailed"))}),n.unref()}export function dashboardUrl(a){return`http://${d}:${a}/`}async function h(a){const s=!!a.flags.noOpen,t=await l();t.started?t.ready?(o.success(r("out.daemon.started",{host:d,port:t.port})),o.dim(r("out.dash.stopHint"))):o.warn(r("out.daemon.startUnconfirmed",{port:t.port})):o.info(r("out.daemon.alreadyRunning",{port:t.port})),c()||(o.warn(r("out.dash.noBundle")),o.dim(r("out.dash.buildHint")));const n=dashboardUrl(t.port);o.info(r("out.dash.url",{url:n}));const e=m(t.port,u()?.tlsPort??0);if(e.length>0&&(o.dim(r("out.daemon.urlsTitle")),o.dim(e.map(i=>` ${i.url}`).join(`
2
+ `))),f(),s){o.dim(r("out.dash.noOpen"));return}openBrowser(n)}export const dashboardCommand={name:"dashboard",aliases:["dash"],description:"cmd.dashboard.desc",options:[{name:"no-open",description:"flag.dashboard.noOpen",type:"boolean",default:!1}],action:h};
@@ -1 +1 @@
1
- import{existsSync as m,readFileSync as w}from"node:fs";import l from"node:path";import{DAEMON_HOST as S,DEFAULT_PORT as x,getDbPath as y,ensureDataLayout as T,openDatabase as N,ProjectRepository as b,readDaemonState as P}from"@weavecode/server";import{formatTable as p,logger as r}from"@weavecode/core";import{checkHarness as E}from"../init/harness-checks.js";import{probeDaemon as D}from"./daemon.js";import{localTokenHeader as C}from"./daemon-auth.js";import{t as o}from"../i18n/index.js";const q={"no-mechanism":"out.doctor.reason.noMechanism","no-credentials":"out.doctor.reason.noCredentials","auth-token-required":"out.doctor.reason.authTokenRequired","no-peer-name":"out.doctor.reason.noPeerName","no-backend":"out.doctor.reason.noBackend","no-pane-env":"out.doctor.reason.noPaneEnv","pane-env-conflict":"out.doctor.reason.paneEnvConflict"},R={"no-hook-script":"out.doctor.hint.noHookScript","hook-script-not-weave":"out.doctor.hint.hookScriptNotWeave","hook-script-stale":"out.doctor.hint.hookScriptStale","no-events":"out.doctor.hint.noEvents","no-inbox-credentials":"out.doctor.hint.noInboxCredentials","inbox-token-required":"out.doctor.hint.inboxTokenRequired","no-peer-name":"out.doctor.hint.noPeerName","terminal-no-backend":"out.doctor.hint.terminalNoBackend","terminal-no-pane-env":"out.doctor.hint.terminalNoPaneEnv","terminal-pane-env-conflict":"out.doctor.hint.terminalPaneEnvConflict","not-running":"out.doctor.hint.notRunning",queued:"out.doctor.hint.queued",stalled:"out.doctor.hint.stalled"};function k(n,e){if(!e)return"";const i=n[e];return i?o(i):e}function H(n){if(!n||!n.present)return o("out.doctor.diagScriptNone");const e=n.source==="user"?o("out.doctor.diagSourceUser"):n.source==="project"?o("out.doctor.diagSourceProject"):o("out.doctor.diagSourceNone");if(!n.weaveOwned)return o("out.doctor.diagScriptNotOwned",{source:e});const i=o("out.doctor.diagYes");return o("out.doctor.diagScriptValue",{harness:n.harness,source:e,version:n.generatedVersion??o("out.doctor.diagMissing"),inbox:n.reportsInbox?i:o("out.doctor.diagNo"),pane:n.reportsPaneEnv?i:o("out.doctor.diagNo")})}function g(n){const e=k(q,n.reason);return n.status==="ready"?o("out.doctor.diagReady"):n.status==="unknown"?o("out.doctor.diagUnknown",{reason:e}):o("out.doctor.diagUnavailable",{reason:e})}async function O(n,e){let i;try{const t=await fetch(`http://${S}:${n}/messaging/diagnostics?project=${e}`,{headers:C()});if(!t.ok)throw new Error(`HTTP ${t.status}`);try{i=await t.json()}catch{throw new Error(`HTTP ${t.status}`)}}catch(t){r.warn(o("out.doctor.diagFailed",{error:t instanceof Error?t.message:String(t)}));return}const{daemon:a}=i,s=i.projects.find(t=>t.id===e)?.captures[0]??null;if(console.log(),r.info(o("out.doctor.diagHeader",{id:e})),console.log(p([[o("out.doctor.diagDaemon"),o("out.doctor.diagDaemonValue",{version:a.version,platform:a.platform,preset:a.terminalPreset,channel:o(a.terminalTextChannel?"out.doctor.diagChannelOn":"out.doctor.diagChannelOff")})],[o("out.doctor.diagScript"),H(s)]])),i.sessions.length===0){r.dim(o("out.doctor.diagNoSessions"));return}const d=t=>t===null?o("out.doctor.diagUnknownAlive"):o(t?"out.doctor.diagYes":"out.doctor.diagNo");for(const t of i.sessions)console.log(),console.log(" "+o("out.doctor.diagSession",{id:t.sessionId.slice(0,8),title:t.title??o("out.doctor.diagUntitled"),alive:d(t.alive),events:t.eventCount,last:t.lastEventType??o("out.doctor.diagMissing")})),console.log(" "+o("out.doctor.diagChannels",{inbox:g(t.channels.inbox),queue:g(t.channels.queue),relay:g(t.channels.relay),terminal:g(t.channels.terminal)})),console.log(" "+o("out.doctor.diagQueue",{pending:t.queue.pending,stalled:o(t.queue.stalled?"out.doctor.diagYes":"out.doctor.diagNo")})),t.hints.length>0&&r.dim(" "+o("out.doctor.diagHints",{hints:t.hints.map(c=>k(R,c)).join("\uFF1B")}))}const v=n=>{const e=l.resolve(n);return process.platform==="win32"?e.toLowerCase():e};function j(n){if(!m(y()))return null;const e=N();try{const i=new b(e),a=v(n),s=[...i.list(),...i.listArchived()].find(d=>v(d.path)===a);return s?{id:s.id,source:s.source,archived:s.archivedAt!==null,token:s.token}:null}finally{e.close()}}function A(n){const e=l.join(n,".weave","token");return m(e)?w(e,"utf-8").trim():null}export const doctorCommand={name:"doctor",description:"cmd.doctor.desc",options:[{name:"dir",short:"d",description:"flag.dir",type:"string",default:process.cwd()}],async action(n){T();const e=l.resolve(String(n.flags.dir??process.cwd())),i=m(l.join(e,".weave","config.yaml")),s=P()?.port??x,d=await D(s),t=j(e),c=A(e);let u;c===null?u=o("out.doctor.tokenMissing"):t?c===t.token?u=o("out.doctor.tokenOk"):u=o("out.doctor.tokenStale"):u=o("out.doctor.tokenUnregistered"),r.info(o("out.doctor.header")),console.log(p([[o("out.doctor.dir"),e],[o("out.doctor.initialized"),i?o("out.doctor.yes"):o("out.doctor.no")],[o("out.doctor.daemon"),d?o("out.doctor.daemonRunning",{port:s}):o("out.doctor.daemonStopped")],[o("out.doctor.registered"),t?o(t.archived?"out.doctor.registeredArchived":"out.doctor.registeredYes",{id:t.id,source:t.source}):o("out.doctor.registeredNo")],[o("out.doctor.token"),u]])),console.log();const f=await E(e);if(f.length>0){r.warn(o("out.status.issuesFound",{count:f.length}));for(const h of f)r.warn(o("out.status.issue",{message:h.message})),r.dim(o("out.status.fix",{fix:h.fix}));console.log()}if(d&&t&&!t.archived&&await O(s,t.id),!t){r.warn(o("out.doctor.warnNotRegistered")),r.dim(o("out.doctor.fixInit")),i||r.dim(o("out.doctor.fixScan",{dir:e}));return}if(t.archived){r.warn(o("out.doctor.warnArchived"));return}if(c===null){r.warn(o("out.doctor.warnTokenMissing")),r.dim(o("out.doctor.fixInit"));return}if(c!==t.token){r.warn(o("out.doctor.warnTokenStale")),r.dim(o("out.doctor.fixInit"));return}r.success(o("out.doctor.ok")),d||r.dim(o("out.doctor.fixDaemon"))}};
1
+ import{existsSync as m,readFileSync as k}from"node:fs";import u from"node:path";import{DAEMON_HOST as w,DEFAULT_PORT as S,getDbPath as x,ensureDataLayout as y,openDatabase as N,ProjectRepository as b,readDaemonState as T}from"@weavecode/server";import{formatTable as f,logger as r}from"@weavecode/core";import{checkHarness as P}from"../init/harness-checks.js";import{probeDaemon as E}from"./daemon.js";import{localTokenHeader as C}from"./daemon-auth.js";import{t as o}from"../i18n/index.js";const q={"no-mechanism":"out.doctor.reason.noMechanism","no-credentials":"out.doctor.reason.noCredentials","auth-token-required":"out.doctor.reason.authTokenRequired","no-peer-name":"out.doctor.reason.noPeerName","no-backend":"out.doctor.reason.noBackend","no-pane-env":"out.doctor.reason.noPaneEnv","pane-env-conflict":"out.doctor.reason.paneEnvConflict"},D={"no-hook-script":"out.doctor.hint.noHookScript","hook-script-not-weave":"out.doctor.hint.hookScriptNotWeave","hook-script-stale":"out.doctor.hint.hookScriptStale","no-events":"out.doctor.hint.noEvents","no-inbox-credentials":"out.doctor.hint.noInboxCredentials","inbox-token-required":"out.doctor.hint.inboxTokenRequired","no-peer-name":"out.doctor.hint.noPeerName","terminal-no-backend":"out.doctor.hint.terminalNoBackend","terminal-no-pane-env":"out.doctor.hint.terminalNoPaneEnv","terminal-pane-env-conflict":"out.doctor.hint.terminalPaneEnvConflict","not-running":"out.doctor.hint.notRunning",queued:"out.doctor.hint.queued",stalled:"out.doctor.hint.stalled"};function p(n,e){if(!e)return"";const i=n[e];return i?o(i):e}function j(n){if(!n||!n.present)return o("out.doctor.diagScriptNone");const e=n.source==="user"?o("out.doctor.diagSourceUser"):n.source==="project"?o("out.doctor.diagSourceProject"):o("out.doctor.diagSourceNone");if(!n.weaveOwned)return o("out.doctor.diagScriptNotOwned",{source:e});const i=o("out.doctor.diagYes");return o("out.doctor.diagScriptValue",{harness:n.harness,source:e,version:n.generatedVersion??o("out.doctor.diagMissing"),inbox:n.reportsInbox?i:o("out.doctor.diagNo"),pane:n.reportsPaneEnv?i:o("out.doctor.diagNo")})}function l(n){const e=p(q,n.reason);return n.status==="ready"?o("out.doctor.diagReady"):n.status==="unknown"?o("out.doctor.diagUnknown",{reason:e}):o("out.doctor.diagUnavailable",{reason:e})}async function H(n,e){let i;try{const t=await fetch(`http://${w}:${n}/messaging/diagnostics?project=${e}`,{headers:C()});if(!t.ok)throw new Error(`HTTP ${t.status}`);try{i=await t.json()}catch{throw new Error(`HTTP ${t.status}`)}}catch(t){r.warn(o("out.doctor.diagFailed",{error:t instanceof Error?t.message:String(t)}));return}const{daemon:d}=i,s=i.projects.find(t=>t.id===e)?.captures[0]??null;if(console.log(),r.info(o("out.doctor.diagHeader",{id:e})),console.log(f([[o("out.doctor.diagDaemon"),o("out.doctor.diagDaemonValue",{version:d.version,platform:d.platform,preset:d.terminalPreset,channel:o(d.terminalTextChannel?"out.doctor.diagChannelOn":"out.doctor.diagChannelOff")})],[o("out.doctor.diagScript"),j(s)]])),i.sessions.length===0){r.dim(o("out.doctor.diagNoSessions"));return}const a=t=>t===null?o("out.doctor.diagUnknownAlive"):o(t?"out.doctor.diagYes":"out.doctor.diagNo");for(const t of i.sessions)console.log(),console.log(" "+o("out.doctor.diagSession",{id:t.sessionId.slice(0,8),title:t.title??o("out.doctor.diagUntitled"),alive:a(t.alive),events:t.eventCount,last:t.lastEventType??o("out.doctor.diagMissing")})),console.log(" "+o("out.doctor.diagChannels",{inbox:l(t.channels.inbox),queue:l(t.channels.queue),relay:l(t.channels.relay),terminal:l(t.channels.terminal)})),console.log(" "+o("out.doctor.diagQueue",{pending:t.queue.pending,stalled:o(t.queue.stalled?"out.doctor.diagYes":"out.doctor.diagNo")})),t.hints.length>0&&r.dim(" "+o("out.doctor.diagHints",{hints:t.hints.map(c=>p(D,c)).join("\uFF1B")}))}const v=n=>{const e=u.resolve(n);return process.platform==="win32"?e.toLowerCase():e};function O(n){if(!m(x()))return null;const e=N();try{const i=new b(e),d=v(n),s=[...i.list(),...i.listArchived()].find(a=>v(a.path)===d);return s?{id:s.id,source:s.source,archived:s.archivedAt!==null,token:s.token}:null}finally{e.close()}}function R(n){const e=u.join(n,".weave","token");return m(e)?k(e,"utf-8").trim():null}export const doctorCommand={name:"doctor",description:"cmd.doctor.desc",options:[{name:"dir",short:"d",description:"flag.dir",type:"string",default:process.cwd()}],async action(n){y();const e=u.resolve(String(n.flags.dir??process.cwd())),i=m(u.join(e,".weave","config.yaml")),d=T()?.port??S,s=await E(d),a=O(e),t=R(e);let c;t===null?c=o("out.doctor.tokenMissing"):a?t===a.token?c=o("out.doctor.tokenOk"):c=o("out.doctor.tokenStale"):c=o("out.doctor.tokenUnregistered"),r.info(o("out.doctor.header")),console.log(f([[o("out.doctor.dir"),e],[o("out.doctor.initialized"),i?o("out.doctor.yes"):o("out.doctor.no")],[o("out.doctor.daemon"),s?o("out.doctor.daemonRunning",{port:d}):o("out.doctor.daemonStopped")],[o("out.doctor.registered"),a?o(a.archived?"out.doctor.registeredArchived":"out.doctor.registeredYes",{id:a.id,source:a.source}):o("out.doctor.registeredNo")],[o("out.doctor.token"),c]])),console.log();const g=await P(e);if(g.length>0){r.warn(o("out.status.issuesFound",{count:g.length}));for(const h of g)r.warn(o("out.status.issue",{message:h.message})),r.dim(o("out.status.fix",{fix:h.fix}));console.log()}if(s&&a&&!a.archived&&await H(d,a.id),!a){r.warn(o("out.doctor.warnNotRegistered")),r.dim(o("out.doctor.fixInit")),i||r.dim(o("out.doctor.fixScan",{dir:e}));return}if(a.archived){r.warn(o("out.doctor.warnArchived"));return}if(t===null){r.warn(o("out.doctor.warnTokenMissing")),r.dim(o("out.doctor.fixInit"));return}if(t!==a.token){r.warn(o("out.doctor.warnTokenStale")),r.dim(o("out.doctor.fixInit"));return}r.success(o("out.doctor.ok")),s||r.dim(o("out.doctor.fixDaemon"))}};
@@ -1 +1 @@
1
- import{PresetSchema as f,HARNESS_KEYS as m,logger as i,formatTable as p,resolveComponents as g}from"@weavecode/core";import{executeInit as u}from"../init/executor.js";import{registerProject as h,WEAVE_VERSION as S}from"@weavecode/server";import{t as e}from"../i18n/index.js";const d=["preToolUse","postToolUse","userPromptSubmit","sessionStart","stop","stopFailure","subagentStop","subagentStart","notification","postToolUseFailure","permissionRequest","permissionDenied","preCompact","sessionEnd","preModelSwitch"];function k(r){const s=r.trim();if(!s)return{};const c=Object.fromEntries(d.map(n=>[n,!1]));if(s==="none")return c;const a=new Set(s.split(",").map(n=>n.trim()).filter(Boolean)),o=[...a].filter(n=>!d.includes(n));return o.length>0&&i.warn(e("init.hooksUnknownKeys",{keys:o.join(", ")})),Object.fromEntries(d.map(n=>[n,a.has(n)]))}export function parseHarnessFlag(r){const s=r.trim();if(!s)return;const c=s.split(",").map(n=>n.trim().toLowerCase()).filter(Boolean),a=[...new Set(c.filter(n=>m.includes(n)))],o=c.filter(n=>!m.includes(n));return o.length>0&&i.warn(e("init.harnessUnknownKeys",{keys:o.join(", ")})),a.length>0?a:["claude"]}export const initCommand={name:"init",description:"cmd.init.desc",options:[{name:"preset",short:"p",description:"flag.init.preset",type:"string",default:"default",choices:["minimal","default","full"]},{name:"force",short:"f",description:"flag.init.force",type:"boolean",default:!1},{name:"no-interactive",description:"flag.init.noInteractive",type:"boolean",default:!1},{name:"dir",short:"d",description:"flag.dir",type:"string",default:process.cwd()},{name:"hooks",description:"flag.init.hooks",type:"string",default:""},{name:"harness",description:"flag.init.harness",type:"string",default:""}],async action(r){const s=f.parse(r.flags.preset??"default"),c=!!r.flags.force,a=r.flags.noInteractive!==!0&&r.flags.interactive!==!1,o=String(r.flags.dir??process.cwd());i.info(e("init.banner",{version:S})),i.dim(e("init.presetTarget",{preset:s,target:o}));const n=g(s);let t;try{t=await u({targetDir:o,force:c,interactive:a,preset:s,harnesses:parseHarnessFlag(String(r.flags.harness??"")),components:n,hooks:k(String(r.flags.hooks??"")),skills:{},commands:{},agents:{},mcp:{}})}catch(l){i.error(e("init.failed",{error:l instanceof Error?l.message:String(l)})),process.exit(1)}if(t.success){h(o,"init"),i.success(e("init.complete"));const l=[[e("init.table.directories"),String(t.created.directories.length)],[e("init.table.filesCreated"),String(t.created.files.length)],[e("init.table.filesMerged"),String(t.merged.length)],[e("init.table.weaveUpdated"),String(t.updated.length)],[e("init.table.skills"),String(t.summary.skillsCount)],[e("init.table.commands"),String(t.summary.commandsCount)],[e("init.table.agents"),String(t.summary.agentsCount)]];console.log(p(l)),console.log(),t.merged.length>0&&i.dim(e("init.merged",{count:t.merged.length})),t.updated.length>0&&i.dim(e("init.refreshed",{count:t.updated.length})),t.removed.length>0&&i.dim(e("init.removed",{count:t.removed.length})),t.skipped.length>0&&i.dim(e("init.skipped",{count:t.skipped.length}))}else{i.error(e("init.completedWithErrors"));for(const l of t.errors)i.error(e("init.errorLine",{error:l}))}}};
1
+ import{PresetSchema as p,HARNESS_KEYS as m,logger as n,formatTable as g,resolveComponents as f}from"@weavecode/core";import{executeInit as u}from"../init/executor.js";import{registerProject as h,WEAVE_VERSION as S}from"@weavecode/server";import{t as e}from"../i18n/index.js";const d=["preToolUse","postToolUse","userPromptSubmit","sessionStart","stop","stopFailure","subagentStop","subagentStart","notification","postToolUseFailure","permissionRequest","permissionDenied","preCompact","sessionEnd","preModelSwitch"];function b(r){const s=r.trim();if(!s)return{};const c=Object.fromEntries(d.map(i=>[i,!1]));if(s==="none")return c;const a=new Set(s.split(",").map(i=>i.trim()).filter(Boolean)),o=[...a].filter(i=>!d.includes(i));return o.length>0&&n.warn(e("init.hooksUnknownKeys",{keys:o.join(", ")})),Object.fromEntries(d.map(i=>[i,a.has(i)]))}export function parseHarnessFlag(r){const s=r.trim();if(!s)return;const c=s.split(",").map(i=>i.trim().toLowerCase()).filter(Boolean),a=[...new Set(c.filter(i=>m.includes(i)))],o=c.filter(i=>!m.includes(i));return o.length>0&&n.warn(e("init.harnessUnknownKeys",{keys:o.join(", ")})),a.length>0?a:["claude"]}export const initCommand={name:"init",description:"cmd.init.desc",options:[{name:"preset",short:"p",description:"flag.init.preset",type:"string",default:"default",choices:["minimal","default","full"]},{name:"force",short:"f",description:"flag.init.force",type:"boolean",default:!1},{name:"no-interactive",description:"flag.init.noInteractive",type:"boolean",default:!1},{name:"dir",short:"d",description:"flag.dir",type:"string",default:process.cwd()},{name:"hooks",description:"flag.init.hooks",type:"string",default:""},{name:"harness",description:"flag.init.harness",type:"string",default:""}],async action(r){const s=p.parse(r.flags.preset??"default"),c=!!r.flags.force,a=r.flags.noInteractive!==!0&&r.flags.interactive!==!1,o=String(r.flags.dir??process.cwd());n.info(e("init.banner",{version:S})),n.dim(e("init.presetTarget",{preset:s,target:o}));const i=f(s);let t;try{t=await u({targetDir:o,force:c,interactive:a,preset:s,harnesses:parseHarnessFlag(String(r.flags.harness??"")),components:i,hooks:b(String(r.flags.hooks??"")),skills:{},commands:{},agents:{},mcp:{}})}catch(l){n.error(e("init.failed",{error:l instanceof Error?l.message:String(l)})),process.exit(1)}if(t.success){h(o,"init"),n.success(e("init.complete"));const l=[[e("init.table.directories"),String(t.created.directories.length)],[e("init.table.filesCreated"),String(t.created.files.length)],[e("init.table.filesMerged"),String(t.merged.length)],[e("init.table.weaveUpdated"),String(t.updated.length)],[e("init.table.skills"),String(t.summary.skillsCount)],[e("init.table.commands"),String(t.summary.commandsCount)],[e("init.table.agents"),String(t.summary.agentsCount)]];console.log(g(l)),console.log(),t.merged.length>0&&n.dim(e("init.merged",{count:t.merged.length})),t.updated.length>0&&n.dim(e("init.refreshed",{count:t.updated.length})),t.removed.length>0&&n.dim(e("init.removed",{count:t.removed.length})),t.skipped.length>0&&n.dim(e("init.skipped",{count:t.skipped.length}))}else{n.error(e("init.completedWithErrors"));for(const l of t.errors)n.error(e("init.errorLine",{error:l}))}}};
@@ -1,2 +1,2 @@
1
- import{DAEMON_HOST as h}from"@weavecode/server";import{logger as a}from"@weavecode/core";import{createRuntimeRegistry as y}from"@weavecode/harness";import{ensureDaemonRunning as d}from"./daemon.js";import{t as i}from"../i18n/index.js";async function u(s,o,e){const t=await fetch(`http://${h}:${s}${o}`,e),n=await t.json().catch(()=>({}));if(!t.ok)throw new Error(String(n.error??`HTTP ${t.status}`));return n}export function resolveSessionRef(s,o){const e=o.toLowerCase(),t=s.filter(c=>c.sessionId.toLowerCase()===e);if(t.length===1)return{row:t[0]};const n=s.filter(c=>c.sessionId.toLowerCase().startsWith(e));if(n.length===1)return{row:n[0]};const r=s.filter(c=>c.title!=null&&c.title.toLowerCase().includes(e));if(r.length===1)return{row:r[0]};const g=n.length>0?n:r;return g.length>1?{error:"ambiguous",rows:g}:{error:"not-found"}}export function currentSessionId(s,o){for(const e of o){if(!e)continue;const t=s[e];if(typeof t=="string"&&t!=="")return t}return null}export function pickReplyTarget(s,o){for(let e=s.length-1;e>=0;e--){const t=s[e];if(t.toSessionId===o&&t.fromSessionId!=null)return t.fromSessionId}return null}function I(s){const o=s[0].map((e,t)=>Math.max(...s.map(n=>n[t].length)));return s.map(e=>e.map((t,n)=>t.padEnd(o[n])).join(" ").trimEnd()).join(`
2
- `)}const l=s=>s.slice(0,8);function f(s,o){return u(s,"/sessions").then(({sessions:e})=>{const t=resolveSessionRef(e,o);if("row"in t)return t.row;throw t.error==="ambiguous"?new Error(i("out.msg.ambiguous",{ref:o,candidates:t.rows.map(n=>`${l(n.sessionId)}${n.title?` (${n.title})`:""}`).join(", ")})):new Error(i("out.msg.notFound",{ref:o}))})}function p(){const s=y().byCapability("messaging").flatMap(o=>o.messaging?.sessionEnv?[o.messaging.sessionEnv]:[]);return currentSessionId(process.env,s)}async function w(s,o,e,t,n){const r=await f(s,o),g=await u(s,`/sessions/${encodeURIComponent(r.sessionId)}/messages`,{method:"POST",headers:{"content-type":"application/json"},body:JSON.stringify({text:e,mode:t,fromKind:"cli",fromSessionId:n})});a.success(i("out.msg.sendOk",{target:r.title??l(r.sessionId),id:g.messageId,status:g.status}))}async function S(s,o){const{sessions:e}=await u(s,"/sessions");if(!o){const{capabilities:r}=await u(s,"/messaging/capabilities"),g=new Set(r.filter(m=>m.discovery).map(m=>m.harness)),c=e.map(m=>[l(m.sessionId),m.title??"",m.harness??"-",m.turnOpen===void 0?"-":m.turnOpen?i("out.msg.busy"):i("out.msg.idle"),m.harness!=null&&g.has(m.harness)?"\u2713":"\u2014"]);if(c.length===0){a.info(i("out.msg.noSessions"));return}a.info(i("out.msg.sessionHeader",{n:c.length})),console.log(I([[i("out.msg.col.session"),i("out.msg.col.title"),i("out.msg.col.harness"),i("out.msg.col.state"),i("out.msg.col.msg")],...c]));return}const t=await f(s,o),{messages:n}=await u(s,`/sessions/${encodeURIComponent(t.sessionId)}/messages`);a.info(i("out.msg.threadHeader",{session:t.title??t.sessionId,n:n.length}));for(const r of n){const g=r.fromSessionId===t.sessionId?"\u25B6":"\u25C0",c=r.fromKind==="dashboard"?"dashboard":r.fromKind==="cli"?"cli":r.fromSessionId??"?";console.log(`${r.createdAt.slice(11,19)} ${g} ${c} [${r.status}] ${r.text.slice(0,80)}`)}}async function C(s,o,e){const t=await f(s,o),n=p(),r=await u(s,`/sessions/${encodeURIComponent(t.sessionId)}/watch`,{method:"POST",headers:{"content-type":"application/json"},body:JSON.stringify({watcherSessionId:n,notify:e??null})});a.success(i("out.msg.watchOk",{target:t.title??l(t.sessionId),id:r.watchId,via:n??i("out.msg.watchViaDashboard")}))}async function x(s,o){const e=p();if(!e){a.warn(i("out.msg.replyNoSession")),process.exitCode=1;return}const{messages:t}=await u(s,`/sessions/${encodeURIComponent(e)}/messages`),n=pickReplyTarget(t,e);if(!n){a.warn(i("out.msg.replyNothing")),process.exitCode=1;return}await w(s,n,o,"inject",e)}export const msgCommand={name:"msg",description:"cmd.msg.desc",subcommands:[{name:"ls",description:"cmd.msg.ls.desc",async action(s){const o=await d();try{await S(o.port,s.positional[0])}catch(e){a.warn(i("out.msg.failed",{error:e instanceof Error?e.message:String(e)})),process.exitCode=1}}},{name:"send",description:"cmd.msg.send.desc",options:[{name:"mode",short:"m",description:"flag.msg.mode",type:"string",choices:["auto","inject","headless"],default:"inject"}],async action(s){const o=s.positional[0],e=s.positional.slice(1).join(" ");if(!o||!e){a.warn(i("out.msg.sendUsage")),process.exitCode=1;return}const t=await d();try{await w(t.port,o,e,String(s.flags.mode??"inject"),p())}catch(n){a.warn(i("out.msg.sendFail",{error:n instanceof Error?n.message:String(n)})),process.exitCode=1}}},{name:"watch",description:"cmd.msg.watch.desc",options:[{name:"notify",description:"flag.msg.notify",type:"string"}],async action(s){const o=s.positional[0];if(!o){a.warn(i("out.msg.watchUsage")),process.exitCode=1;return}const e=await d();try{await C(e.port,o,s.flags.notify==null?void 0:String(s.flags.notify))}catch(t){a.warn(i("out.msg.watchFail",{error:t instanceof Error?t.message:String(t)})),process.exitCode=1}}},{name:"reply",description:"cmd.msg.reply.desc",async action(s){const o=s.positional.join(" ");if(!o){a.warn(i("out.msg.replyUsage")),process.exitCode=1;return}const e=await d();try{await x(e.port,o)}catch(t){a.warn(i("out.msg.sendFail",{error:t instanceof Error?t.message:String(t)})),process.exitCode=1}}}]};
1
+ import{DAEMON_HOST as h}from"@weavecode/server";import{logger as a}from"@weavecode/core";import{createRuntimeRegistry as y}from"@weavecode/harness";import{ensureDaemonRunning as u}from"./daemon.js";import{t as i}from"../i18n/index.js";async function g(s,o,e){const t=await fetch(`http://${h}:${s}${o}`,e),n=await t.json().catch(()=>({}));if(!t.ok)throw new Error(String(n.error??`HTTP ${t.status}`));return n}export function resolveSessionRef(s,o){const e=o.toLowerCase(),t=s.filter(c=>c.sessionId.toLowerCase()===e);if(t.length===1)return{row:t[0]};const n=s.filter(c=>c.sessionId.toLowerCase().startsWith(e));if(n.length===1)return{row:n[0]};const r=s.filter(c=>c.title!=null&&c.title.toLowerCase().includes(e));if(r.length===1)return{row:r[0]};const m=n.length>0?n:r;return m.length>1?{error:"ambiguous",rows:m}:{error:"not-found"}}export function currentSessionId(s,o){for(const e of o){if(!e)continue;const t=s[e];if(typeof t=="string"&&t!=="")return t}return null}export function pickReplyTarget(s,o){for(let e=s.length-1;e>=0;e--){const t=s[e];if(t.toSessionId===o&&t.fromSessionId!=null)return t.fromSessionId}return null}function I(s){const o=s[0].map((e,t)=>Math.max(...s.map(n=>n[t].length)));return s.map(e=>e.map((t,n)=>t.padEnd(o[n])).join(" ").trimEnd()).join(`
2
+ `)}const l=s=>s.slice(0,8);function f(s,o){return g(s,"/sessions").then(({sessions:e})=>{const t=resolveSessionRef(e,o);if("row"in t)return t.row;throw t.error==="ambiguous"?new Error(i("out.msg.ambiguous",{ref:o,candidates:t.rows.map(n=>`${l(n.sessionId)}${n.title?` (${n.title})`:""}`).join(", ")})):new Error(i("out.msg.notFound",{ref:o}))})}function p(){const s=y().byCapability("messaging").flatMap(o=>o.messaging?.sessionEnv?[o.messaging.sessionEnv]:[]);return currentSessionId(process.env,s)}async function w(s,o,e,t,n){const r=await f(s,o),m=await g(s,`/sessions/${encodeURIComponent(r.sessionId)}/messages`,{method:"POST",headers:{"content-type":"application/json"},body:JSON.stringify({text:e,mode:t,fromKind:"cli",fromSessionId:n})});a.success(i("out.msg.sendOk",{target:r.title??l(r.sessionId),id:m.messageId,status:m.status}))}async function S(s,o){const{sessions:e}=await g(s,"/sessions");if(!o){const{capabilities:r}=await g(s,"/messaging/capabilities"),m=new Set(r.filter(d=>d.discovery).map(d=>d.harness)),c=e.map(d=>[l(d.sessionId),d.title??"",d.harness??"-",d.turnOpen===void 0?"-":d.turnOpen?i("out.msg.busy"):i("out.msg.idle"),d.harness!=null&&m.has(d.harness)?"\u2713":"\u2014"]);if(c.length===0){a.info(i("out.msg.noSessions"));return}a.info(i("out.msg.sessionHeader",{n:c.length})),console.log(I([[i("out.msg.col.session"),i("out.msg.col.title"),i("out.msg.col.harness"),i("out.msg.col.state"),i("out.msg.col.msg")],...c]));return}const t=await f(s,o),{messages:n}=await g(s,`/sessions/${encodeURIComponent(t.sessionId)}/messages`);a.info(i("out.msg.threadHeader",{session:t.title??t.sessionId,n:n.length}));for(const r of n){const m=r.fromSessionId===t.sessionId?"\u25B6":"\u25C0",c=r.fromKind==="dashboard"?"dashboard":r.fromKind==="cli"?"cli":r.fromSessionId??"?";console.log(`${r.createdAt.slice(11,19)} ${m} ${c} [${r.status}] ${r.text.slice(0,80)}`)}}async function C(s,o,e){const t=await f(s,o),n=p(),r=await g(s,`/sessions/${encodeURIComponent(t.sessionId)}/watch`,{method:"POST",headers:{"content-type":"application/json"},body:JSON.stringify({watcherSessionId:n,notify:e??null})});a.success(i("out.msg.watchOk",{target:t.title??l(t.sessionId),id:r.watchId,via:n??i("out.msg.watchViaDashboard")}))}async function x(s,o){const e=p();if(!e){a.warn(i("out.msg.replyNoSession")),process.exitCode=1;return}const{messages:t}=await g(s,`/sessions/${encodeURIComponent(e)}/messages`),n=pickReplyTarget(t,e);if(!n){a.warn(i("out.msg.replyNothing")),process.exitCode=1;return}await w(s,n,o,"inject",e)}export const msgCommand={name:"msg",description:"cmd.msg.desc",subcommands:[{name:"ls",description:"cmd.msg.ls.desc",async action(s){const o=await u();try{await S(o.port,s.positional[0])}catch(e){a.warn(i("out.msg.failed",{error:e instanceof Error?e.message:String(e)})),process.exitCode=1}}},{name:"send",description:"cmd.msg.send.desc",options:[{name:"mode",short:"m",description:"flag.msg.mode",type:"string",choices:["auto","inject","headless"],default:"inject"}],async action(s){const o=s.positional[0],e=s.positional.slice(1).join(" ");if(!o||!e){a.warn(i("out.msg.sendUsage")),process.exitCode=1;return}const t=await u();try{await w(t.port,o,e,String(s.flags.mode??"inject"),p())}catch(n){a.warn(i("out.msg.sendFail",{error:n instanceof Error?n.message:String(n)})),process.exitCode=1}}},{name:"watch",description:"cmd.msg.watch.desc",options:[{name:"notify",description:"flag.msg.notify",type:"string"}],async action(s){const o=s.positional[0];if(!o){a.warn(i("out.msg.watchUsage")),process.exitCode=1;return}const e=await u();try{await C(e.port,o,s.flags.notify==null?void 0:String(s.flags.notify))}catch(t){a.warn(i("out.msg.watchFail",{error:t instanceof Error?t.message:String(t)})),process.exitCode=1}}},{name:"reply",description:"cmd.msg.reply.desc",async action(s){const o=s.positional.join(" ");if(!o){a.warn(i("out.msg.replyUsage")),process.exitCode=1;return}const e=await u();try{await x(e.port,o)}catch(t){a.warn(i("out.msg.sendFail",{error:t instanceof Error?t.message:String(t)})),process.exitCode=1}}}]};