@weavecode/weave 0.1.4 → 0.1.6

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (362) hide show
  1. package/node_modules/@modelcontextprotocol/sdk/node_modules/express/node_modules/encodeurl/README.md +14 -0
  2. package/node_modules/@modelcontextprotocol/sdk/node_modules/express/node_modules/encodeurl/index.js +5 -10
  3. package/node_modules/@modelcontextprotocol/sdk/node_modules/express/node_modules/encodeurl/package.json +10 -6
  4. package/node_modules/@modelcontextprotocol/sdk/node_modules/express/node_modules/qs/CHANGELOG.md +42 -0
  5. package/node_modules/@modelcontextprotocol/sdk/node_modules/express/node_modules/qs/README.md +38 -10
  6. package/node_modules/@modelcontextprotocol/sdk/node_modules/express/node_modules/qs/dist/qs.js +18 -18
  7. package/node_modules/@modelcontextprotocol/sdk/node_modules/express/node_modules/qs/lib/parse.js +16 -4
  8. package/node_modules/@modelcontextprotocol/sdk/node_modules/express/node_modules/qs/lib/utils.js +13 -2
  9. package/node_modules/@modelcontextprotocol/sdk/node_modules/express/node_modules/qs/package.json +1 -1
  10. package/node_modules/@modelcontextprotocol/sdk/node_modules/express-rate-limit/dist/index.cjs +6 -2
  11. package/node_modules/@modelcontextprotocol/sdk/node_modules/express-rate-limit/dist/index.mjs +6 -2
  12. package/node_modules/@modelcontextprotocol/sdk/node_modules/express-rate-limit/package.json +10 -10
  13. package/node_modules/@modelcontextprotocol/sdk/node_modules/jose/dist/types/jwt/decrypt.d.ts +3 -0
  14. package/node_modules/@modelcontextprotocol/sdk/node_modules/jose/dist/types/jwt/unsecured.d.ts +2 -0
  15. package/node_modules/@modelcontextprotocol/sdk/node_modules/jose/dist/types/jwt/verify.d.ts +3 -0
  16. package/node_modules/@modelcontextprotocol/sdk/node_modules/jose/dist/types/types.d.ts +8 -0
  17. package/node_modules/@modelcontextprotocol/sdk/node_modules/jose/dist/types/util/decode_jwt.d.ts +1 -0
  18. package/node_modules/@modelcontextprotocol/sdk/node_modules/jose/dist/webapi/jwks/remote.js +1 -1
  19. package/node_modules/@modelcontextprotocol/sdk/node_modules/jose/package.json +1 -1
  20. package/node_modules/@weavecode/cli/dist/cli.js +4 -4
  21. package/node_modules/@weavecode/cli/dist/commands/chpass.js +1 -1
  22. package/node_modules/@weavecode/cli/dist/commands/daemon-auth.js +1 -1
  23. package/node_modules/@weavecode/cli/dist/commands/daemon.d.ts +2 -0
  24. package/node_modules/@weavecode/cli/dist/commands/daemon.js +2 -2
  25. package/node_modules/@weavecode/cli/dist/commands/dashboard.js +2 -2
  26. package/node_modules/@weavecode/cli/dist/commands/doctor.js +1 -1
  27. package/node_modules/@weavecode/cli/dist/commands/init.js +1 -1
  28. package/node_modules/@weavecode/cli/dist/commands/msg.js +2 -2
  29. package/node_modules/@weavecode/cli/dist/commands/scan.js +1 -1
  30. package/node_modules/@weavecode/cli/dist/commands/status.js +2 -2
  31. package/node_modules/@weavecode/cli/dist/commands/uninstall.js +1 -1
  32. package/node_modules/@weavecode/cli/dist/i18n/dict/en.js +4 -4
  33. package/node_modules/@weavecode/cli/dist/i18n/dict/zh.d.ts +5 -1
  34. package/node_modules/@weavecode/cli/dist/i18n/dict/zh.js +5 -5
  35. package/node_modules/@weavecode/cli/dist/i18n/index.js +1 -1
  36. package/node_modules/@weavecode/cli/dist/i18n/t.js +1 -1
  37. package/node_modules/@weavecode/cli/dist/init/claudemd-gen.js +3 -3
  38. package/node_modules/@weavecode/cli/dist/init/executor.js +3 -3
  39. package/node_modules/@weavecode/cli/dist/init/git-commit.js +2 -2
  40. package/node_modules/@weavecode/cli/dist/init/harnesses/claude.js +7 -7
  41. package/node_modules/@weavecode/cli/dist/init/harnesses/codex.js +1 -1
  42. package/node_modules/@weavecode/cli/dist/init/instruction-link.js +1 -1
  43. package/node_modules/@weavecode/cli/dist/init/plugin-templates.js +1 -1
  44. package/node_modules/@weavecode/cli/dist/init/prompt.js +4 -4
  45. package/node_modules/@weavecode/cli/dist/init/provision.js +1 -1
  46. package/node_modules/@weavecode/cli/dist/init/uninstall.js +6 -6
  47. package/node_modules/@weavecode/cli/dist/init/wiring.js +1 -1
  48. package/node_modules/@weavecode/cli/dist/parser.js +1 -1
  49. package/node_modules/@weavecode/cli/dist/statusline/ansi.js +1 -1
  50. package/node_modules/@weavecode/cli/dist/statusline/mock-input.js +1 -1
  51. package/node_modules/@weavecode/cli/dist/statusline/preview.js +2 -2
  52. package/node_modules/@weavecode/cli/package.json +5 -5
  53. package/node_modules/@weavecode/core/dist/harness-checks.js +1 -1
  54. package/node_modules/@weavecode/core/dist/harness.d.ts +14 -0
  55. package/node_modules/@weavecode/core/dist/harness.js +1 -1
  56. package/node_modules/@weavecode/core/dist/index.d.ts +1 -1
  57. package/node_modules/@weavecode/core/dist/index.js +1 -1
  58. package/node_modules/@weavecode/core/dist/platform.js +1 -1
  59. package/node_modules/@weavecode/core/dist/types.js +1 -1
  60. package/node_modules/@weavecode/core/dist/utils/fs.js +1 -1
  61. package/node_modules/@weavecode/core/dist/utils/logger.js +1 -1
  62. package/node_modules/@weavecode/core/package.json +1 -1
  63. package/node_modules/@weavecode/harness/dist/claude/assets.js +4 -4
  64. package/node_modules/@weavecode/harness/dist/claude/capture.js +9 -9
  65. package/node_modules/@weavecode/harness/dist/claude/commands.d.ts +3 -0
  66. package/node_modules/@weavecode/harness/dist/claude/commands.js +2 -3
  67. package/node_modules/@weavecode/harness/dist/claude/config.js +2 -2
  68. package/node_modules/@weavecode/harness/dist/claude/detect.js +1 -1
  69. package/node_modules/@weavecode/harness/dist/claude/edits.js +1 -1
  70. package/node_modules/@weavecode/harness/dist/claude/event-source.js +1 -1
  71. package/node_modules/@weavecode/harness/dist/claude/images.js +2 -2
  72. package/node_modules/@weavecode/harness/dist/claude/index.d.ts +1 -0
  73. package/node_modules/@weavecode/harness/dist/claude/index.js +1 -1
  74. package/node_modules/@weavecode/harness/dist/claude/liveness.js +1 -1
  75. package/node_modules/@weavecode/harness/dist/claude/mcp-gen.js +1 -1
  76. package/node_modules/@weavecode/harness/dist/claude/messaging.js +2 -2
  77. package/node_modules/@weavecode/harness/dist/claude/model-aliases.js +1 -1
  78. package/node_modules/@weavecode/harness/dist/claude/narration.d.ts +0 -11
  79. package/node_modules/@weavecode/harness/dist/claude/narration.js +1 -1
  80. package/node_modules/@weavecode/harness/dist/claude/peers.js +1 -1
  81. package/node_modules/@weavecode/harness/dist/claude/plan.js +1 -1
  82. package/node_modules/@weavecode/harness/dist/claude/plugins.js +4 -4
  83. package/node_modules/@weavecode/harness/dist/claude/prompt-inbox.js +1 -1
  84. package/node_modules/@weavecode/harness/dist/claude/prompt.js +3 -3
  85. package/node_modules/@weavecode/harness/dist/claude/questions.js +2 -2
  86. package/node_modules/@weavecode/harness/dist/claude/resume.js +1 -1
  87. package/node_modules/@weavecode/harness/dist/claude/rewind.d.ts +8 -0
  88. package/node_modules/@weavecode/harness/dist/claude/rewind.js +1 -0
  89. package/node_modules/@weavecode/harness/dist/claude/settings-gen.js +1 -1
  90. package/node_modules/@weavecode/harness/dist/claude/side-question.js +2 -2
  91. package/node_modules/@weavecode/harness/dist/claude/statusline/generator.js +39 -18
  92. package/node_modules/@weavecode/harness/dist/claude/statusline/git-cache.js +1 -1
  93. package/node_modules/@weavecode/harness/dist/claude/statusline/surface.js +2 -2
  94. package/node_modules/@weavecode/harness/dist/claude/transcript-cursor.d.ts +26 -0
  95. package/node_modules/@weavecode/harness/dist/claude/transcript-cursor.js +2 -0
  96. package/node_modules/@weavecode/harness/dist/claude/transcript.js +7 -7
  97. package/node_modules/@weavecode/harness/dist/codex/assets.js +1 -1
  98. package/node_modules/@weavecode/harness/dist/codex/capture.js +2 -2
  99. package/node_modules/@weavecode/harness/dist/codex/commands.js +4 -4
  100. package/node_modules/@weavecode/harness/dist/codex/config.js +2 -2
  101. package/node_modules/@weavecode/harness/dist/codex/detect.js +1 -1
  102. package/node_modules/@weavecode/harness/dist/codex/event-source.js +2 -2
  103. package/node_modules/@weavecode/harness/dist/codex/images.js +1 -1
  104. package/node_modules/@weavecode/harness/dist/codex/index.js +1 -1
  105. package/node_modules/@weavecode/harness/dist/codex/liveness.js +1 -1
  106. package/node_modules/@weavecode/harness/dist/codex/mcp.js +1 -1
  107. package/node_modules/@weavecode/harness/dist/codex/messaging.js +2 -2
  108. package/node_modules/@weavecode/harness/dist/codex/narration.js +1 -1
  109. package/node_modules/@weavecode/harness/dist/codex/plugin-state.js +1 -1
  110. package/node_modules/@weavecode/harness/dist/codex/plugins.js +3 -3
  111. package/node_modules/@weavecode/harness/dist/codex/provision.js +1 -1
  112. package/node_modules/@weavecode/harness/dist/codex/questions.js +2 -2
  113. package/node_modules/@weavecode/harness/dist/codex/rollout.js +5 -5
  114. package/node_modules/@weavecode/harness/dist/codex/side-question.js +4 -4
  115. package/node_modules/@weavecode/harness/dist/codex/titles.js +4 -4
  116. package/node_modules/@weavecode/harness/dist/codex/toml.js +13 -13
  117. package/node_modules/@weavecode/harness/dist/codex/transcript.js +2 -2
  118. package/node_modules/@weavecode/harness/dist/driver.d.ts +49 -1
  119. package/node_modules/@weavecode/harness/dist/driver.js +1 -1
  120. package/node_modules/@weavecode/harness/dist/init/generated.js +2 -2
  121. package/node_modules/@weavecode/harness/dist/init/pipeline.js +1 -1
  122. package/node_modules/@weavecode/harness/dist/registry-wiring.js +1 -1
  123. package/node_modules/@weavecode/harness/dist/shared/install-link.js +1 -1
  124. package/node_modules/@weavecode/harness/dist/shared/json-cap.js +1 -1
  125. package/node_modules/@weavecode/harness/package.json +2 -2
  126. package/node_modules/@weavecode/server/dist/config/dotted.js +1 -1
  127. package/node_modules/@weavecode/server/dist/config/profiles.d.ts +19 -13
  128. package/node_modules/@weavecode/server/dist/config/profiles.js +2 -2
  129. package/node_modules/@weavecode/server/dist/daemon/ai-config.js +2 -2
  130. package/node_modules/@weavecode/server/dist/daemon/ai-context.js +6 -6
  131. package/node_modules/@weavecode/server/dist/daemon/ai-routes.js +4 -4
  132. package/node_modules/@weavecode/server/dist/daemon/api-log.js +3 -3
  133. package/node_modules/@weavecode/server/dist/daemon/auth-routes.js +1 -1
  134. package/node_modules/@weavecode/server/dist/daemon/auto-start.js +6 -6
  135. package/node_modules/@weavecode/server/dist/daemon/capture-routes.js +1 -1
  136. package/node_modules/@weavecode/server/dist/daemon/config-routes.js +1 -1
  137. package/node_modules/@weavecode/server/dist/daemon/cron.js +1 -1
  138. package/node_modules/@weavecode/server/dist/daemon/dashboard-auth.js +2 -2
  139. package/node_modules/@weavecode/server/dist/daemon/dashboard-pusher.js +1 -1
  140. package/node_modules/@weavecode/server/dist/daemon/data-bus.js +1 -1
  141. package/node_modules/@weavecode/server/dist/daemon/decision-config.js +2 -2
  142. package/node_modules/@weavecode/server/dist/daemon/dev-entry.js +1 -1
  143. package/node_modules/@weavecode/server/dist/daemon/entry.js +7 -1
  144. package/node_modules/@weavecode/server/dist/daemon/fs-browser.js +1 -1
  145. package/node_modules/@weavecode/server/dist/daemon/hook-pipeline.js +1 -1
  146. package/node_modules/@weavecode/server/dist/daemon/hooks-routes.js +1 -1
  147. package/node_modules/@weavecode/server/dist/daemon/http.js +1 -1
  148. package/node_modules/@weavecode/server/dist/daemon/liveness.js +1 -1
  149. package/node_modules/@weavecode/server/dist/daemon/mcp-orchestration.js +1 -1
  150. package/node_modules/@weavecode/server/dist/daemon/narration-watcher.js +2 -2
  151. package/node_modules/@weavecode/server/dist/daemon/opener/backend-ghostty.js +1 -1
  152. package/node_modules/@weavecode/server/dist/daemon/opener/backend-iterm.js +1 -1
  153. package/node_modules/@weavecode/server/dist/daemon/opener/backend-konsole.js +2 -2
  154. package/node_modules/@weavecode/server/dist/daemon/opener/backend-terminal-app.js +1 -1
  155. package/node_modules/@weavecode/server/dist/daemon/opener/backend-wezterm.js +1 -1
  156. package/node_modules/@weavecode/server/dist/daemon/opener/backend-wt.js +1 -1
  157. package/node_modules/@weavecode/server/dist/daemon/opener/backend.js +1 -1
  158. package/node_modules/@weavecode/server/dist/daemon/opener/launch.js +1 -1
  159. package/node_modules/@weavecode/server/dist/daemon/opener/pty-terminals.js +4 -4
  160. package/node_modules/@weavecode/server/dist/daemon/opener/shared.js +1 -1
  161. package/node_modules/@weavecode/server/dist/daemon/opener/wezterm-mux.js +1 -1
  162. package/node_modules/@weavecode/server/dist/daemon/opener/wt.js +3 -3
  163. package/node_modules/@weavecode/server/dist/daemon/opener.d.ts +2 -0
  164. package/node_modules/@weavecode/server/dist/daemon/opener.js +1 -1
  165. package/node_modules/@weavecode/server/dist/daemon/port.js +1 -1
  166. package/node_modules/@weavecode/server/dist/daemon/project-files.d.ts +12 -6
  167. package/node_modules/@weavecode/server/dist/daemon/project-files.js +2 -2
  168. package/node_modules/@weavecode/server/dist/daemon/project-harnesses.js +2 -2
  169. package/node_modules/@weavecode/server/dist/daemon/project-updates-refresher.js +1 -1
  170. package/node_modules/@weavecode/server/dist/daemon/prompt-images.js +1 -1
  171. package/node_modules/@weavecode/server/dist/daemon/routes/hooks-admin.js +1 -1
  172. package/node_modules/@weavecode/server/dist/daemon/routes/market.js +1 -1
  173. package/node_modules/@weavecode/server/dist/daemon/routes/orchestration.js +1 -1
  174. package/node_modules/@weavecode/server/dist/daemon/routes/path-refs.js +1 -1
  175. package/node_modules/@weavecode/server/dist/daemon/routes/project-files.js +1 -1
  176. package/node_modules/@weavecode/server/dist/daemon/routes/projects.js +1 -1
  177. package/node_modules/@weavecode/server/dist/daemon/routes/search.js +1 -1
  178. package/node_modules/@weavecode/server/dist/daemon/routes/session-control.js +1 -1
  179. package/node_modules/@weavecode/server/dist/daemon/routes/session-insights.js +1 -1
  180. package/node_modules/@weavecode/server/dist/daemon/routes/settings-statusline.js +1 -1
  181. package/node_modules/@weavecode/server/dist/daemon/routes/uploads.js +1 -1
  182. package/node_modules/@weavecode/server/dist/daemon/routes/visualizations.d.ts +3 -0
  183. package/node_modules/@weavecode/server/dist/daemon/routes/visualizations.js +1 -0
  184. package/node_modules/@weavecode/server/dist/daemon/routes/watches.js +1 -1
  185. package/node_modules/@weavecode/server/dist/daemon/server.js +8 -8
  186. package/node_modules/@weavecode/server/dist/daemon/session-open.js +1 -1
  187. package/node_modules/@weavecode/server/dist/daemon/session-probe.d.ts +5 -4
  188. package/node_modules/@weavecode/server/dist/daemon/session-probe.js +1 -1
  189. package/node_modules/@weavecode/server/dist/daemon/settings.js +2 -2
  190. package/node_modules/@weavecode/server/dist/daemon/snapshot-refresher.js +1 -1
  191. package/node_modules/@weavecode/server/dist/daemon/sse-hub.js +1 -1
  192. package/node_modules/@weavecode/server/dist/daemon/start.js +1 -1
  193. package/node_modules/@weavecode/server/dist/daemon/state.js +2 -2
  194. package/node_modules/@weavecode/server/dist/daemon/static.js +1 -1
  195. package/node_modules/@weavecode/server/dist/daemon/terminal-topology-refresher.js +1 -1
  196. package/node_modules/@weavecode/server/dist/daemon/tls.js +1 -1
  197. package/node_modules/@weavecode/server/dist/daemon/toolkit-routes.js +1 -1
  198. package/node_modules/@weavecode/server/dist/daemon/upload-sessions.js +1 -1
  199. package/node_modules/@weavecode/server/dist/db/db.js +6 -2
  200. package/node_modules/@weavecode/server/dist/db/layout.js +1 -1
  201. package/node_modules/@weavecode/server/dist/hooks/answer-keys.js +1 -1
  202. package/node_modules/@weavecode/server/dist/hooks/bus.d.ts +3 -1
  203. package/node_modules/@weavecode/server/dist/hooks/bus.js +1 -1
  204. package/node_modules/@weavecode/server/dist/hooks/dashboard-rate.js +1 -1
  205. package/node_modules/@weavecode/server/dist/hooks/decision-judge.js +1 -1
  206. package/node_modules/@weavecode/server/dist/hooks/delivery/ack-gate.d.ts +12 -6
  207. package/node_modules/@weavecode/server/dist/hooks/delivery/ack-gate.js +1 -1
  208. package/node_modules/@weavecode/server/dist/hooks/delivery/channels.d.ts +3 -3
  209. package/node_modules/@weavecode/server/dist/hooks/delivery/channels.js +1 -1
  210. package/node_modules/@weavecode/server/dist/hooks/delivery/keys.d.ts +19 -9
  211. package/node_modules/@weavecode/server/dist/hooks/delivery/keys.js +1 -1
  212. package/node_modules/@weavecode/server/dist/hooks/delivery/queue.js +1 -1
  213. package/node_modules/@weavecode/server/dist/hooks/delivery/relay.d.ts +2 -2
  214. package/node_modules/@weavecode/server/dist/hooks/delivery/relay.js +1 -1
  215. package/node_modules/@weavecode/server/dist/hooks/delivery/send.js +2 -2
  216. package/node_modules/@weavecode/server/dist/hooks/delivery/views.d.ts +3 -1
  217. package/node_modules/@weavecode/server/dist/hooks/delivery/views.js +1 -1
  218. package/node_modules/@weavecode/server/dist/hooks/dispatcher.js +6 -6
  219. package/node_modules/@weavecode/server/dist/hooks/edge-extract.js +1 -1
  220. package/node_modules/@weavecode/server/dist/hooks/handlers/webhook.js +1 -1
  221. package/node_modules/@weavecode/server/dist/hooks/headless-runner.js +2 -2
  222. package/node_modules/@weavecode/server/dist/hooks/inbox-socket.js +2 -2
  223. package/node_modules/@weavecode/server/dist/hooks/inbox-worker.js +3 -3
  224. package/node_modules/@weavecode/server/dist/hooks/match.js +1 -1
  225. package/node_modules/@weavecode/server/dist/hooks/message-deliverer.d.ts +45 -38
  226. package/node_modules/@weavecode/server/dist/hooks/message-deliverer.js +5 -3
  227. package/node_modules/@weavecode/server/dist/hooks/mirror.js +4 -4
  228. package/node_modules/@weavecode/server/dist/hooks/orchestration-engine.js +7 -7
  229. package/node_modules/@weavecode/server/dist/hooks/orchestration-graph.js +1 -1
  230. package/node_modules/@weavecode/server/dist/hooks/plugin-installer.js +3 -3
  231. package/node_modules/@weavecode/server/dist/hooks/plugin-loader.js +1 -1
  232. package/node_modules/@weavecode/server/dist/hooks/plugin-project-state.js +1 -1
  233. package/node_modules/@weavecode/server/dist/hooks/prompt-flusher.js +1 -1
  234. package/node_modules/@weavecode/server/dist/hooks/promptbox.js +8 -8
  235. package/node_modules/@weavecode/server/dist/hooks/push-notify.js +2 -2
  236. package/node_modules/@weavecode/server/dist/hooks/question-tracker.js +1 -1
  237. package/node_modules/@weavecode/server/dist/hooks/registry.js +1 -1
  238. package/node_modules/@weavecode/server/dist/hooks/resume-runner.js +1 -1
  239. package/node_modules/@weavecode/server/dist/hooks/session-purge.js +1 -1
  240. package/node_modules/@weavecode/server/dist/hooks/side-questions.js +1 -1
  241. package/node_modules/@weavecode/server/dist/hooks/synthetic-sessions.js +1 -1
  242. package/node_modules/@weavecode/server/dist/hooks/toolkit-scan.js +1 -1
  243. package/node_modules/@weavecode/server/dist/hooks/toolkit.js +5 -5
  244. package/node_modules/@weavecode/server/dist/hooks/watch-engine.js +1 -1
  245. package/node_modules/@weavecode/server/dist/install/apply-update.js +1 -1
  246. package/node_modules/@weavecode/server/dist/install/capabilities.js +1 -1
  247. package/node_modules/@weavecode/server/dist/install/codex-toml.js +1 -1
  248. package/node_modules/@weavecode/server/dist/install/file-assets.js +1 -1
  249. package/node_modules/@weavecode/server/dist/install/fingerprint.js +1 -1
  250. package/node_modules/@weavecode/server/dist/install/global-config.js +1 -1
  251. package/node_modules/@weavecode/server/dist/install/global-file-assets.js +1 -1
  252. package/node_modules/@weavecode/server/dist/install/init-files.js +2 -2
  253. package/node_modules/@weavecode/server/dist/install/install-ledger.js +1 -1
  254. package/node_modules/@weavecode/server/dist/install/installer.js +1 -1
  255. package/node_modules/@weavecode/server/dist/install/library-index.js +1 -1
  256. package/node_modules/@weavecode/server/dist/install/mcp-rows.js +1 -1
  257. package/node_modules/@weavecode/server/dist/install/plugin-install.js +1 -1
  258. package/node_modules/@weavecode/server/dist/install/plugin-rows.js +1 -1
  259. package/node_modules/@weavecode/server/dist/install/plugin-templates.js +1 -1
  260. package/node_modules/@weavecode/server/dist/install/project-config.js +1 -1
  261. package/node_modules/@weavecode/server/dist/install/reader.js +1 -1
  262. package/node_modules/@weavecode/server/dist/install/scan-cache.js +1 -1
  263. package/node_modules/@weavecode/server/dist/install/scanner.js +1 -1
  264. package/node_modules/@weavecode/server/dist/install/settings-mcp.js +2 -2
  265. package/node_modules/@weavecode/server/dist/install/updates.js +1 -1
  266. package/node_modules/@weavecode/server/dist/market/builtin.js +1 -1
  267. package/node_modules/@weavecode/server/dist/market/identity.js +1 -1
  268. package/node_modules/@weavecode/server/dist/market/import.js +2 -2
  269. package/node_modules/@weavecode/server/dist/market/refresh.js +1 -1
  270. package/node_modules/@weavecode/server/dist/market/resolve.js +1 -1
  271. package/node_modules/@weavecode/server/dist/market/updates.js +1 -1
  272. package/node_modules/@weavecode/server/dist/registry.js +2 -2
  273. package/node_modules/@weavecode/server/dist/repositories/hook-dispatches.js +5 -5
  274. package/node_modules/@weavecode/server/dist/repositories/hook-events.d.ts +1 -1
  275. package/node_modules/@weavecode/server/dist/repositories/hook-events.js +5 -5
  276. package/node_modules/@weavecode/server/dist/repositories/hook-rules.js +4 -4
  277. package/node_modules/@weavecode/server/dist/repositories/libraries.js +1 -1
  278. package/node_modules/@weavecode/server/dist/repositories/orchestrations.js +7 -7
  279. package/node_modules/@weavecode/server/dist/repositories/plugin-states.js +1 -1
  280. package/node_modules/@weavecode/server/dist/repositories/projects.js +2 -2
  281. package/node_modules/@weavecode/server/dist/repositories/push-subscriptions.js +2 -2
  282. package/node_modules/@weavecode/server/dist/repositories/session-watches.js +4 -4
  283. package/node_modules/@weavecode/server/dist/repositories/sessions.d.ts +11 -1
  284. package/node_modules/@weavecode/server/dist/repositories/sessions.js +4 -2
  285. package/node_modules/@weavecode/server/dist/repositories/uploads.d.ts +14 -4
  286. package/node_modules/@weavecode/server/dist/repositories/uploads.js +11 -11
  287. package/node_modules/@weavecode/server/dist/statusline/cache-sweeper.js +1 -1
  288. package/node_modules/@weavecode/server/dist/statusline/generator.js +1 -1
  289. package/node_modules/@weavecode/server/dist/statusline/manager.js +3 -3
  290. package/node_modules/@weavecode/server/dist/surfaces.d.ts +3 -1
  291. package/node_modules/@weavecode/server/dist/surfaces.js +1 -1
  292. package/node_modules/@weavecode/server/dist/watch/cache.js +1 -1
  293. package/node_modules/@weavecode/server/dist/watch/classifier.js +1 -1
  294. package/node_modules/@weavecode/server/dist/watch/plugin-mods.js +1 -1
  295. package/node_modules/@weavecode/server/dist/watch/sync-scheduler.js +1 -1
  296. package/node_modules/@weavecode/server/dist/watch/watch-service.js +1 -1
  297. package/node_modules/@weavecode/server/package.json +4 -4
  298. package/node_modules/@weavecode/server/web/dist/assets/{abnfDiagram-WEYOIA3C-DA-K085F.js → abnfDiagram-WEYOIA3C-CbIFQh0R.js} +1 -1
  299. package/node_modules/@weavecode/server/web/dist/assets/{arc-BI1jnmdZ.js → arc-DH8-rYAa.js} +1 -1
  300. package/node_modules/@weavecode/server/web/dist/assets/{architectureDiagram-ZHVYKT53-DbdBgric.js → architectureDiagram-ZHVYKT53-qnv6S0sc.js} +1 -1
  301. package/node_modules/@weavecode/server/web/dist/assets/{blockDiagram-RJAE7QA3-BPRBmzb-.js → blockDiagram-RJAE7QA3-pT5eO-cB.js} +1 -1
  302. package/node_modules/@weavecode/server/web/dist/assets/{c4Diagram-XDPPPE54-C4D5sRs1.js → c4Diagram-XDPPPE54-DHDBDMb1.js} +1 -1
  303. package/node_modules/@weavecode/server/web/dist/assets/channel-BHPeeuzN.js +1 -0
  304. package/node_modules/@weavecode/server/web/dist/assets/{chunk-2E7WHVMD-9ZSKiNU3.js → chunk-2E7WHVMD-CT951PH5.js} +1 -1
  305. package/node_modules/@weavecode/server/web/dist/assets/{chunk-2Q5K7J3B-i0AOjw_8.js → chunk-2Q5K7J3B-E5AD7_ZY.js} +1 -1
  306. package/node_modules/@weavecode/server/web/dist/assets/{chunk-4EMNKR2T-DTpLfX1H.js → chunk-4EMNKR2T-DWz9qkcy.js} +1 -1
  307. package/node_modules/@weavecode/server/web/dist/assets/{chunk-55XCU76K-COQYRD4q.js → chunk-55XCU76K-D-SgWD8w.js} +1 -1
  308. package/node_modules/@weavecode/server/web/dist/assets/{chunk-5VM5RSS4-VsftEbvo.js → chunk-5VM5RSS4-ci6YzbO5.js} +1 -1
  309. package/node_modules/@weavecode/server/web/dist/assets/{chunk-JWPE2WC7-DonektJN.js → chunk-JWPE2WC7-CY4mr2f4.js} +1 -1
  310. package/node_modules/@weavecode/server/web/dist/assets/{chunk-VQ5W62QI-CaKUwuul.js → chunk-VQ5W62QI-CON8zyg8.js} +1 -1
  311. package/node_modules/@weavecode/server/web/dist/assets/{chunk-XXDRQBXY-DXH3D_MT.js → chunk-XXDRQBXY-DXXXZ4pW.js} +1 -1
  312. package/node_modules/@weavecode/server/web/dist/assets/{chunk-ZCHMQSOR-COwyAuGn.js → chunk-ZCHMQSOR-CukvPvkM.js} +2 -2
  313. package/node_modules/@weavecode/server/web/dist/assets/{classDiagram-v2-4MYWR3UA-DEvMZ6mX.js → classDiagram-v2-4MYWR3UA-GiWZ9xtF.js} +1 -1
  314. package/node_modules/@weavecode/server/web/dist/assets/{cose-bilkent-JH36ORCC-6JBJHfH6.js → cose-bilkent-JH36ORCC-D7aJ-akq.js} +1 -1
  315. package/node_modules/@weavecode/server/web/dist/assets/{cynefin-EF2NZ3EQ-C4GM4sjT.js → cynefin-EF2NZ3EQ-9B__MaRM.js} +1 -1
  316. package/node_modules/@weavecode/server/web/dist/assets/{cynefinDiagram-WF24UDRP-Cqgi0MBP.js → cynefinDiagram-WF24UDRP-B2ujZh2k.js} +1 -1
  317. package/node_modules/@weavecode/server/web/dist/assets/{dagre-NK4GIZVX-CljrnkCY.js → dagre-NK4GIZVX-nHaB6IWf.js} +1 -1
  318. package/node_modules/@weavecode/server/web/dist/assets/{diagram-CBK3MWTC-C3PyOj5J.js → diagram-CBK3MWTC-xKfjDvgr.js} +1 -1
  319. package/node_modules/@weavecode/server/web/dist/assets/{diagram-I5XIIV2D-I5brQlaZ.js → diagram-I5XIIV2D-BHT2-5mY.js} +1 -1
  320. package/node_modules/@weavecode/server/web/dist/assets/{diagram-ODIL2UCW-BX9uFNbU.js → diagram-ODIL2UCW-CckywF4W.js} +1 -1
  321. package/node_modules/@weavecode/server/web/dist/assets/{diagram-PFBEJUXE-y7D-VmqJ.js → diagram-PFBEJUXE-Dpjlc7Wh.js} +1 -1
  322. package/node_modules/@weavecode/server/web/dist/assets/{diagram-RJA3I4VV-DLUL8W42.js → diagram-RJA3I4VV-M6WznOaW.js} +1 -1
  323. package/node_modules/@weavecode/server/web/dist/assets/{diagram-TYUNFSNR-DLCC3ILi.js → diagram-TYUNFSNR-DgRJ3zL1.js} +1 -1
  324. package/node_modules/@weavecode/server/web/dist/assets/{ebnfDiagram-V4P3TTPT-D7vALia7.js → ebnfDiagram-V4P3TTPT-BzzVN__a.js} +1 -1
  325. package/node_modules/@weavecode/server/web/dist/assets/{elk-QONTBCTQ-Ct2_hatz.js → elk-QONTBCTQ-Ch6Gs9G9.js} +1 -1
  326. package/node_modules/@weavecode/server/web/dist/assets/{erDiagram-KYQIGQAA-DxLai58T.js → erDiagram-KYQIGQAA-COxT-Pxb.js} +1 -1
  327. package/node_modules/@weavecode/server/web/dist/assets/{flowDiagram-IUGLLWBU-AWn2IHrF.js → flowDiagram-IUGLLWBU-CJVWnTBa.js} +1 -1
  328. package/node_modules/@weavecode/server/web/dist/assets/{ganttDiagram-R7GPNTJY-DmRHd4Wz.js → ganttDiagram-R7GPNTJY-BkRpWPUl.js} +1 -1
  329. package/node_modules/@weavecode/server/web/dist/assets/{gitGraphDiagram-PDYL7XHY-Ccj-t3zg.js → gitGraphDiagram-PDYL7XHY-Ba8BJcvZ.js} +1 -1
  330. package/node_modules/@weavecode/server/web/dist/assets/index-CtifxEiF.css +11 -0
  331. package/node_modules/@weavecode/server/web/dist/assets/index-FwH9INgS.js +1090 -0
  332. package/node_modules/@weavecode/server/web/dist/assets/{infoDiagram-MVDRKAX5-BHquFlQa.js → infoDiagram-MVDRKAX5-HTQ5FUNK.js} +1 -1
  333. package/node_modules/@weavecode/server/web/dist/assets/{ishikawaDiagram-HPEHV2GE-CVogEbdm.js → ishikawaDiagram-HPEHV2GE-BNjEDIZy.js} +1 -1
  334. package/node_modules/@weavecode/server/web/dist/assets/{journeyDiagram-BOSHW7O7-DC9XG9oh.js → journeyDiagram-BOSHW7O7-Cao6h91a.js} +1 -1
  335. package/node_modules/@weavecode/server/web/dist/assets/{kanban-definition-FNSA4HC5-C_eu7DC_.js → kanban-definition-FNSA4HC5-CXIx2CHQ.js} +1 -1
  336. package/node_modules/@weavecode/server/web/dist/assets/{linear-keTbWHJ-.js → linear-65WmlvQb.js} +1 -1
  337. package/node_modules/@weavecode/server/web/dist/assets/{mermaid.core-4sbg0MnY.js → mermaid.core-D39fi_iR.js} +4 -4
  338. package/node_modules/@weavecode/server/web/dist/assets/{mindmap-definition-6OY57UG3-kMQS0S2l.js → mindmap-definition-6OY57UG3-DHqpz_AK.js} +1 -1
  339. package/node_modules/@weavecode/server/web/dist/assets/{pegDiagram-ECIUJNBX-DcUFoEwP.js → pegDiagram-ECIUJNBX-Cpy1nsER.js} +1 -1
  340. package/node_modules/@weavecode/server/web/dist/assets/{pieDiagram-GNMPY74T-BQJ7WDCx.js → pieDiagram-GNMPY74T-B1IyNqzr.js} +1 -1
  341. package/node_modules/@weavecode/server/web/dist/assets/{quadrantDiagram-D57K4MC3-C7Oi1-sq.js → quadrantDiagram-D57K4MC3-zSM6o7mB.js} +1 -1
  342. package/node_modules/@weavecode/server/web/dist/assets/{railroadDiagram-Y72NRBL7-CEF2QbOF.js → railroadDiagram-Y72NRBL7-oM4XJIwA.js} +1 -1
  343. package/node_modules/@weavecode/server/web/dist/assets/{requirementDiagram-EQYSW5RA-CTjjFS7X.js → requirementDiagram-EQYSW5RA-CbCLBjHf.js} +1 -1
  344. package/node_modules/@weavecode/server/web/dist/assets/{sankeyDiagram-SY24JHO5-j0S5kubS.js → sankeyDiagram-SY24JHO5-BucVk6EP.js} +1 -1
  345. package/node_modules/@weavecode/server/web/dist/assets/{sequenceDiagram-BLEHNHQU-B76EsZp4.js → sequenceDiagram-BLEHNHQU-Dg8CYEnT.js} +1 -1
  346. package/node_modules/@weavecode/server/web/dist/assets/{sizeCapture-INFHLROL-r0DZuqAy.js → sizeCapture-INFHLROL-C51zb7Oc.js} +1 -1
  347. package/node_modules/@weavecode/server/web/dist/assets/{stateDiagram-v2-A6IESKWZ-B4DR9LHz.js → stateDiagram-v2-A6IESKWZ-BvK2l3is.js} +1 -1
  348. package/node_modules/@weavecode/server/web/dist/assets/{swimlanes-B3ENRKFQ-Dbcl85ro.js → swimlanes-B3ENRKFQ-Ds7QOfXW.js} +1 -1
  349. package/node_modules/@weavecode/server/web/dist/assets/swimlanesDiagram-AYQRV4AK-ByBF02UJ.js +8 -0
  350. package/node_modules/@weavecode/server/web/dist/assets/{timeline-definition-JXYKGLGB-BlBXXRNf.js → timeline-definition-JXYKGLGB-CadU4Qq4.js} +1 -1
  351. package/node_modules/@weavecode/server/web/dist/assets/{usecaseDiagram-WPOLBNNX-Ck1M0dpc.js → usecaseDiagram-WPOLBNNX-BYuZwTDZ.js} +1 -1
  352. package/node_modules/@weavecode/server/web/dist/assets/{vennDiagram-Q3Y3IDCW-N8B-ohWk.js → vennDiagram-Q3Y3IDCW-C7zgxe07.js} +1 -1
  353. package/node_modules/@weavecode/server/web/dist/assets/{wardleyDiagram-IVAIDKWA-DX-AMXq_.js → wardleyDiagram-IVAIDKWA-DA4Otf4s.js} +1 -1
  354. package/node_modules/@weavecode/server/web/dist/assets/{xychartDiagram-4URNHDU4-4fgL48Yl.js → xychartDiagram-4URNHDU4-Bs5YGwMU.js} +1 -1
  355. package/node_modules/@weavecode/server/web/dist/index.html +2 -2
  356. package/node_modules/@weavecode/server/web/dist/sw.js +14 -12
  357. package/node_modules/@weavecode/templates/package.json +2 -2
  358. package/package.json +6 -6
  359. package/node_modules/@weavecode/server/web/dist/assets/channel-DcCJrvon.js +0 -1
  360. package/node_modules/@weavecode/server/web/dist/assets/index-BSxzia7U.js +0 -1031
  361. package/node_modules/@weavecode/server/web/dist/assets/index-CEpJpR7P.css +0 -11
  362. package/node_modules/@weavecode/server/web/dist/assets/swimlanesDiagram-AYQRV4AK-CZ_6SSBd.js +0 -8
@@ -1 +1 @@
1
- import{readFile as x,readdir as h,stat as w}from"node:fs/promises";import e from"node:path";import{WEAVE_PLUGIN_MANIFEST as y,WeavePluginManifestSchema as L,HARNESS_KEYS as I}from"@weavecode/core";import{builtinPacksDir as W}from"../market/builtin.js";import{getDataRoot as J}from"../db/paths.js";import{hasNonEmptyModules as E}from"../watch/plugin-mods.js";const S=".claude-plugin",v="plugin.json",K="weave.json",_=2,O=10,D=["claude"];export function builtinToolkitRoot(){return e.resolve(W(J()))}async function d(t){try{return(await w(t)).isDirectory()}catch{return!1}}async function p(t){try{const n=JSON.parse(await x(t,"utf8"));return n&&typeof n=="object"&&!Array.isArray(n)?n:null}catch{return null}}export async function isToolkitPackDir(t){return await N(t)?!0:await d(e.join(t,"skills"))||await d(e.join(t,"commands"))||await d(e.join(t,"agents"))}async function N(t){if(await p(e.join(t,S,v)))return!0;try{return await w(e.join(t,y)),!0}catch{}return E(await p(e.join(t,"hooks","hooks.json")))}async function V(t){try{return(await h(t,{withFileTypes:!0})).filter(o=>o.isDirectory()).map(o=>o.name).sort()}catch{return[]}}async function P(t){try{return(await h(t,{withFileTypes:!0})).filter(o=>o.isFile()&&o.name.endsWith(".md")).map(o=>o.name.replace(/\.md$/,"")).sort()}catch{return[]}}function G(t){if(!Array.isArray(t)||t.length===0)return D;const n=t.filter(o=>I.includes(o));return n.length>0?n:D}export async function parseToolkitPack(t,n,o){const i=e.basename(t),a=await p(e.join(t,S,v)),s=await p(e.join(t,y)),r=await p(e.join(t,K)),m=await V(e.join(t,"skills")),g=await P(e.join(t,"commands")),c=await P(e.join(t,"agents")),f=await p(e.join(t,"hooks","hooks.json")),j=E(f),T=!!f&&typeof f.hooks=="object"&&f.hooks!==null,u=[];if(m.length>0&&u.push("skill"),g.length>0&&u.push("command"),c.length>0&&u.push("agent"),j?u.push("mod"):T&&u.push("hook"),s&&u.push("rule"),u.length===0)return null;const k=typeof r?.kind=="string"?r.kind:null,F=k&&["skill","hook","mod","rule","surface"].includes(k)?k:j?"mod":T?"hook":s&&!a?"rule":m.length>0?"skill":"surface",l=s?L.safeParse(s):null,C=l?.success?l.data.id:i,R=(typeof a?.name=="string"?a.name:void 0)??(l?.success?l.data.name:void 0)??i,b=(l?.success?l.data.version:void 0)??(typeof a?.version=="string"?a.version:void 0)??"0.0.0",A=(typeof a?.description=="string"?a.description:void 0)??(l?.success?l.data.description:void 0);return{id:C,name:R,version:b,...A?{description:A}:{},scope:o,dir:t,provenance:n.provenance,sourceRoot:n.root,targets:G(r?.targets),kind:F,components:u,ccPack:!!a,weavePack:!!s,skills:m}}function M(t){return t==="node_modules"||t.startsWith(".")}export async function discoverToolkitPacks(t){const n=t.provenance==="market",o=n?O:_,i=async(a,s,r)=>{if(await isToolkitPackDir(a)&&!(s===0&&n&&!await N(a))){const f=await parseToolkitPack(a,t,r);return f?[f]:[]}if(s>=o)return[];let m;try{m=await h(a,{withFileTypes:!0})}catch{return[]}return(await Promise.all(m.filter(c=>c.isDirectory()&&!M(c.name)).map(c=>i(e.join(a,c.name),s+1,s===0?c.name:r)))).flat()};return i(t.root,0,"")}export function discoverToolkitSources(){return[{root:builtinToolkitRoot(),provenance:"builtin"}]}export async function discoverWeavePackDirs(t){const n=[],o=async(i,a)=>{try{await w(e.join(i,y)),n.push(i);return}catch{}if(a>=_)return;let s;try{s=await h(i,{withFileTypes:!0})}catch{return}for(const r of s)!r.isDirectory()||M(r.name)||await o(e.join(i,r.name),a+1)};return await o(t,0),n}
1
+ import{readFile as M,readdir as d,stat as y}from"node:fs/promises";import o from"node:path";import{WEAVE_PLUGIN_MANIFEST as w,WeavePluginManifestSchema as I,HARNESS_KEYS as G}from"@weavecode/core";import{builtinPacksDir as J}from"../market/builtin.js";import{getDataRoot as K}from"../db/paths.js";import{hasNonEmptyModules as P}from"../watch/plugin-mods.js";const T=".claude-plugin",D="plugin.json",L="weave.json",A=2,O=10,F=["claude"];export function builtinToolkitRoot(){return o.resolve(J(K()))}async function k(n){try{return(await y(n)).isDirectory()}catch{return!1}}async function m(n){try{const t=JSON.parse(await M(n,"utf8"));return t&&typeof t=="object"&&!Array.isArray(t)?t:null}catch{return null}}export async function isToolkitPackDir(n){return await S(n)?!0:await k(o.join(n,"skills"))||await k(o.join(n,"commands"))||await k(o.join(n,"agents"))}async function S(n){if(await m(o.join(n,T,D)))return!0;try{return await y(o.join(n,w)),!0}catch{}return P(await m(o.join(n,"hooks","hooks.json")))}async function V(n){try{return(await d(n,{withFileTypes:!0})).filter(t=>t.isDirectory()).map(t=>t.name).sort()}catch{return[]}}async function b(n){try{return(await d(n,{withFileTypes:!0})).filter(t=>t.isFile()&&t.name.endsWith(".md")).map(t=>t.name.replace(/\.md$/,"")).sort()}catch{return[]}}function C(n){if(!Array.isArray(n)||n.length===0)return F;const t=n.filter(c=>G.includes(c));return t.length>0?t:F}export async function parseToolkitPack(n,t,c){const r=o.basename(n),i=await m(o.join(n,T,D)),e=await m(o.join(n,w)),a=await m(o.join(n,L)),p=await V(o.join(n,"skills")),s=await b(o.join(n,"commands")),E=await b(o.join(n,"agents")),f=await m(o.join(n,"hooks","hooks.json")),j=P(f),v=!!f&&typeof f.hooks=="object"&&f.hooks!==null,u=[];if(p.length>0&&u.push("skill"),s.length>0&&u.push("command"),E.length>0&&u.push("agent"),j?u.push("mod"):v&&u.push("hook"),e&&u.push("rule"),u.length===0)return null;const h=typeof a?.kind=="string"?a.kind:null,N=h&&["skill","hook","mod","rule","surface"].includes(h)?h:j?"mod":v?"hook":e&&!i?"rule":p.length>0?"skill":"surface",l=e?I.safeParse(e):null,W=l?.success?l.data.id:r,R=(typeof i?.name=="string"?i.name:void 0)??(l?.success?l.data.name:void 0)??r,_=(l?.success?l.data.version:void 0)??(typeof i?.version=="string"?i.version:void 0)??"0.0.0",g=(typeof i?.description=="string"?i.description:void 0)??(l?.success?l.data.description:void 0);return{id:W,name:R,version:_,...g?{description:g}:{},scope:c,dir:n,provenance:t.provenance,sourceRoot:t.root,targets:C(a?.targets),kind:N,components:u,ccPack:!!i,weavePack:!!e,skills:p}}function x(n){return n==="node_modules"||n.startsWith(".")}export async function discoverToolkitPacks(n){const t=n.provenance==="market",c=t?O:A,r=async(i,e,a)=>{if(await isToolkitPackDir(i)&&!(e===0&&t&&!await S(i))){const s=await parseToolkitPack(i,n,a);return s?[s]:[]}if(e>=c)return[];let p;try{p=await d(i,{withFileTypes:!0})}catch{return[]}return(await Promise.all(p.filter(s=>s.isDirectory()&&!x(s.name)).map(s=>r(o.join(i,s.name),e+1,e===0?s.name:a)))).flat()};return r(n.root,0,"")}export function discoverToolkitSources(){return[{root:builtinToolkitRoot(),provenance:"builtin"}]}export async function discoverWeavePackDirs(n){const t=[],c=async(r,i)=>{try{await y(o.join(r,w)),t.push(r);return}catch{}if(i>=A)return;let e;try{e=await d(r,{withFileTypes:!0})}catch{return}for(const a of e)!a.isDirectory()||x(a.name)||await c(o.join(r,a.name),i+1)};return await c(n,0),t}
@@ -1,5 +1,5 @@
1
- import{cp as I,mkdir as P,readFile as T,readdir as h,rm as w,writeFile as F}from"node:fs/promises";import{spawn as S}from"node:child_process";import{homedir as H}from"node:os";import c from"node:path";import{hashFile as y}from"../install/fingerprint.js";import{fileAssetTargetDir as L}from"../install/file-assets.js";import{assetSurfaceFor as N,pluginSurfaceFor as $}from"../surfaces.js";import{marketLibraryRoots as q}from"../market/resolve.js";import{marketIdOf as m}from"../market/identity.js";import{installPluginPack as A}from"../install/plugin-install.js";import{effective as V,setProjectEnabled as O}from"./plugin-project-state.js";import{builtinToolkitRoot as K,discoverToolkitPacks as B}from"./toolkit-scan.js";export class ToolkitError extends Error{code;constructor(t,e){super(t),this.code=e,this.name="ToolkitError"}}export const MIN_MOD_HOST_VERSION=[2,1,287];const W=1e4;export function isVersionAtLeast(a,t){const e=a.split(".").map(s=>Number.parseInt(s,10));for(let s=0;s<t.length;s++){const n=Number.isFinite(e[s])?e[s]:0;if(n>t[s])return!0;if(n<t[s])return!1}return!0}let b;function J(a){if(!(a.exitCode!==null||a.signalCode!==null)){if(process.platform==="win32"&&a.pid!==void 0){S("taskkill",["/pid",String(a.pid),"/t","/f"],{windowsHide:!0,stdio:"ignore"}).unref();return}a.kill("SIGKILL")}}export async function detectClaudeVersion(){if(b&&Date.now()-b.at<6e5)return b.value;const a=await new Promise(t=>{let e="";const s=process.platform==="win32"?S("claude --version",{windowsHide:!0,shell:!0,stdio:["ignore","pipe","pipe"]}):S("claude",["--version"],{windowsHide:!0,stdio:["ignore","pipe","pipe"]}),n=setTimeout(()=>{J(s),t(null)},5e3);s.stdout?.on("data",i=>e+=i.toString()),s.on("error",()=>{clearTimeout(n),t(null)}),s.on("close",()=>{clearTimeout(n);const i=/(\d+\.\d+\.\d+)/.exec(e);t(i?i[1]:null)})});return a!==null&&(b={value:a,at:Date.now()}),a}async function C(a,t,e){let s;try{s=await h(c.join(a,...t.split("/").filter(Boolean)),{withFileTypes:!0})}catch{return}for(const n of s){if(n.name==="node_modules"||n.name===".git")continue;const i=t?`${t}/${n.name}`:n.name;n.isDirectory()?await C(a,i,e):e.push({rel:i,abs:c.join(a,...i.split("/"))})}}const p=a=>a.ccPack||a.kind==="mod";async function R(a,t){const e=[];if(t.skills.length>0)for(const s of t.targets){if(s==="claude"&&p(t))continue;const n=N(s).projectSkillsRoots()[0];for(const i of t.skills){const o=[];await C(c.join(t.dir,"skills",i),"",o);for(const r of o)e.push({src:r.abs,rel:`${n}/${i}/${r.rel}`})}}if(!p(t))for(const s of t.targets)for(const[n,i]of[["commands","command"],["agents","agent"]]){const o=c.join(t.dir,n),r=[];if(await C(o,"",r),r.length===0)continue;const l=G(i,s,a);if(l)for(const u of r){const g=u.rel.split("/").pop();e.push({src:u.abs,rel:v(c.relative(a,c.join(l,g)))})}}return e}function G(a,t,e){try{return L(a,t,"project",e,H())}catch{return null}}function v(a){return a.split(c.sep).join("/")}function x(a,t){return c.join(a,".weave","toolkit",`${t}.json`)}async function k(a){try{const t=JSON.parse(await T(a,"utf8"));return t&&typeof t=="object"&&typeof t.packId=="string"?t:null}catch{return null}}export async function projectFileNamespaces(a){const t=new Map,e=c.join(a,".weave","toolkit");let s;try{s=await h(e)}catch{return t}for(const n of s){if(!n.endsWith(".json"))continue;const i=await k(c.join(e,n)),o=i?m(i.sourceDir):void 0;if(!(!i||!o))for(const r of Object.keys(i.files))t.set(r,o)}return t}export async function projectPackFiles(a){const t=new Map,e=c.join(a,".weave","toolkit");let s;try{s=await h(e)}catch{return t}for(const n of s){if(!n.endsWith(".json"))continue;const i=await k(c.join(e,n));if(i)for(const[o,r]of Object.entries(i.files))typeof r=="string"&&t.set(o,r)}return t}async function M(a){try{return await T(a),!0}catch{return!1}}async function _(a,t){const e=new Set;for(const n of t){let i=c.posix.dirname(n);for(;i&&i!=="."&&i!=="/";)e.add(i),i=c.posix.dirname(i)}const s=[...e].sort((n,i)=>i.split("/").length-n.split("/").length);for(const n of s){const i=c.join(a,...n.split("/"));try{(await h(i)).length===0&&await w(i,{recursive:!0,force:!0})}catch{}}}export function evaluateModHostGate(a){return process.env.WEAVE_SKIP_MOD_VERSION_CHECK==="1"?{ok:!0}:a?isVersionAtLeast(a,MIN_MOD_HOST_VERSION)?{ok:!0}:{ok:!1,message:`\u5BBF\u4E3B Claude Code ${a} \u4F4E\u4E8E 2.1.287\uFF0Cmod \u5DE5\u5177\u5305\u4E0D\u843D\u76D8\uFF08\u8BF7\u5148\u5347\u7EA7 Claude Code\uFF09`}:{ok:!0,warning:"\u65E0\u6CD5\u68C0\u6D4B\u5BBF\u4E3B Claude Code \u7248\u672C\uFF0Cmod \u5DE5\u5177\u5305\u9700\u8981 \u2265 2.1.287 \u624D\u80FD\u88AB\u52A0\u8F7D"}}export class ToolkitService{deps;packsCache;constructor(t){this.deps=t}sources(){const e=[{root:this.deps.builtinRoot??K(),provenance:"builtin"}];if(this.deps.libraries)for(const n of q(this.deps.libraries))e.push({root:n,provenance:"market"});const s=new Set;return e.filter(n=>{const i=c.resolve(n.root);return s.has(i)?!1:(s.add(i),!0)})}async allPacks(){const t=this.sources(),e=t.map(r=>c.resolve(r.root)).join("|"),s=Date.now(),n=this.packsCache;if(n&&n.key===e&&s-n.at<W)return n.packs;const i=Promise.all(t.map(r=>B(r))).then(r=>r.flat()),o={at:s,key:e,packs:i};return this.packsCache=o,i.catch(()=>{this.packsCache===o&&(this.packsCache=void 0)}),i}async list(t){const e=this.requireProject(t),s=await this.allPacks(),n=await Promise.all(s.map(i=>this.packInfo(e,i)));return await this.healMeta(e,n),{packs:n,legacyCopies:await this.scanLegacyCopies(e)}}async enable(t,e,s){const n=this.requireProject(t),i=await this.resolvePack(e,s),o=[];if(i.kind==="mod"&&i.targets.includes("claude")){const d=this.deps.claudeVersion??detectClaudeVersion,f=evaluateModHostGate(await d());if(!f.ok)throw new ToolkitError(f.message??"mod host gate","host-version");f.warning&&o.push(f.warning)}const r=n.path;if(p(i)&&i.targets.includes("claude")){const d=this.pluginSurface();await A(d,i),await d.setProjectEnabled(r,i.name,!0,m(i.dir))}const u=x(r,i.id),g=await this.readRecordHealed(r,i.id),j=g??{packId:i.id,provenance:i.provenance,sourceRoot:i.sourceRoot,sourceDir:i.dir,enabledAt:new Date().toISOString(),files:{}};let E=g===null;const D=await R(r,i);for(const d of D){const f=c.join(r,...d.rel.split("/"));if(j.files[d.rel]!==void 0){await M(f)||(await P(c.dirname(f),{recursive:!0}),await I(d.src,f));continue}await y(f)==="missing"&&(await P(c.dirname(f),{recursive:!0}),await I(d.src,f),j.files[d.rel]=await y(d.src),E=!0)}return D.length>0?E&&(await P(c.dirname(u),{recursive:!0}),await F(u,JSON.stringify(j,null,2)+`
2
- `,"utf8")):g&&await w(u,{force:!0}),i.weavePack&&O(n,i.id,!0,{projects:this.deps.projects}),this.rememberEnabled(n,i.id,!0),{pack:await this.packInfo(this.requireProject(t),i),warnings:o}}async disable(t,e,s){const n=this.requireProject(t),i=await this.resolvePack(e,s);return await this.applyDisabled(n,i),{pack:await this.packInfo(this.requireProject(t),i),warnings:[]}}async applyDisabled(t,e){await this.removePackFiles(t,e,e.sourceRoot),p(e)&&e.targets.includes("claude")&&await this.pluginSurface().setProjectEnabled(t.path,e.name,!1,m(e.dir)),e.weavePack&&O(t,e.id,!1,{projects:this.deps.projects}),this.rememberEnabled(t,e.id,!1)}async uninstall(t,e,s){const n=this.requireProject(t),i=await this.resolvePack(e,s);return await this.applyDisabled(n,i),p(i)&&i.targets.includes("claude")&&await this.pluginSurface().uninstall(i.name,m(i.dir)),{pack:await this.packInfo(this.requireProject(t),i),warnings:[]}}async removePackFiles(t,e,s){const n=x(t.path,e.id),i=await k(n);if(!i||s&&c.resolve(i.sourceRoot)!==c.resolve(s))return;const o=[];for(const[r,l]of Object.entries(i.files)){const u=c.join(t.path,...r.split("/"));await y(u)===l&&(await w(u,{force:!0}),o.push(r))}await w(n,{force:!0}),await _(t.path,o)}requireProject(t){const e=this.deps.projects.getById(t);if(!e)throw new ToolkitError(`Project not found: ${t}`,"not-found");return e}async resolvePack(t,e){this.packsCache=void 0;const s=(await this.allPacks()).filter(o=>o.id===t);if(e){const o=s.find(r=>c.resolve(r.sourceRoot)===c.resolve(e));if(o)return o}const i=s.find(o=>o.provenance==="builtin")??s[0];if(!i)throw new ToolkitError(`Toolkit pack not found: ${t}`,"not-found");return i}async computeEnabled(t,e){const s=[],n=await this.readRecordHealed(t.path,e.id);if((await R(t.path,e)).length>0){let o=!!n;if(n){for(const r of Object.keys(n.files))if(!await M(c.join(t.path,...r.split("/")))){o=!1;break}}s.push(o)}if(p(e)&&e.targets.includes("claude")){const o=this.pluginSurface(),r=m(e.dir);s.push(await o.isInstalled(e.name,r)&&await o.readProjectEnabled(t.path,e.name,r))}return e.weavePack&&s.push(V(t,e.id,{states:this.deps.states,defaultEnabled:!1})),s.length>0?s.every(Boolean):!1}async installedScopes(t){const e=(await this.pluginSurface().readInstalled())[t];return!e||e.length===0?void 0:[...new Set(e.map(n=>n.scope??"user"))]}async packInfo(t,e){const s=await this.computeEnabled(t,e),n=m(e.dir),i=p(e)&&e.targets.includes("claude")?this.pluginSurface().pluginKey(e.name,n):void 0,o=i?await this.installedScopes(i):void 0,r={...e,...n?{namespace:n}:{},enabled:s,installed:await this.computeInstalled(t,e,s),...i?{key:i}:{},...o&&o.length>0?{scopes:o}:{}};if(e.weavePack){const l=this.deps.plugins.list().find(u=>u.id===e.id);l&&(r.weave={status:l.status,ruleCount:l.ruleCount,...l.error?{error:l.error}:{}})}return r}async computeInstalled(t,e,s){return e.weavePack&&!p(e)?!0:p(e)&&e.targets.includes("claude")?this.pluginSurface().isInstalled(e.name,m(e.dir)):s||!!await this.readRecordHealed(t.path,e.id)}enabledIndex(t){const s=this.deps.projects.getMeta(t.id)?.toolkit,n=s&&typeof s=="object"?s.enabled:void 0;return Array.isArray(n)?n.filter(i=>typeof i=="string"):[]}rememberEnabled(t,e,s){const n=new Set(this.enabledIndex(t));s?n.add(e):n.delete(e),this.deps.projects.setMeta(t.id,{toolkit:{enabled:[...n].sort()}})}async healMeta(t,e){const s=[...new Set(e.filter(r=>r.enabled).map(r=>r.id))].sort(),n=[...new Set(this.enabledIndex(t))].sort(),i=new Set(e.map(r=>r.id)),o=[...new Set([...n.filter(r=>!i.has(r)),...s])].sort();o.join(`
3
- `)!==n.join(`
4
- `)&&this.deps.projects.setMeta(t.id,{toolkit:{enabled:o}})}pluginSurface(){return this.deps.pluginSurface??$("claude")}async readRecordHealed(t,e){const s=x(t,e),n=await k(s);if(!n)return null;const i=v(c.relative(t,this.pluginSurface().projectPluginDir(t))),o=Object.keys(n.files).filter(l=>l.startsWith(`${i}/`));if(o.length===0)return n;const r=[];for(const l of o){const u=c.join(t,...l.split("/"));await y(u)===n.files[l]&&(await w(u,{force:!0}),r.push(l)),delete n.files[l]}return await _(t,r),await F(s,JSON.stringify(n,null,2)+`
5
- `,"utf8"),n}async scanLegacyCopies(t){const e=this.pluginSurface().projectPluginDir(t.path);let s;try{s=await h(e,{withFileTypes:!0})}catch{return[]}return s.map(n=>v(c.relative(t.path,c.join(e,n.name)))).sort()}async cleanupLegacyCopies(t){const e=this.requireProject(t),s=this.pluginSurface().projectPluginDir(e.path);let n;try{n=await h(s,{withFileTypes:!0})}catch{return{removed:[]}}const i=[];for(const o of n){const r=c.join(s,o.name);await w(r,{recursive:!0,force:!0}),i.push(v(c.relative(e.path,r)))}try{(await h(s)).length===0&&await w(s,{recursive:!0,force:!0})}catch{}return{removed:i.sort()}}}
1
+ import{cp as D,mkdir as b,readFile as I,readdir as h,rm as w,writeFile as x}from"node:fs/promises";import{spawn as P}from"node:child_process";import{homedir as M}from"node:os";import c from"node:path";import{hashFile as g}from"../install/fingerprint.js";import{fileAssetTargetDir as H}from"../install/file-assets.js";import{assetSurfaceFor as $,pluginSurfaceFor as q}from"../surfaces.js";import{marketLibraryRoots as A}from"../market/resolve.js";import{marketIdOf as m}from"../market/identity.js";import{installPluginPack as N}from"../install/plugin-install.js";import{effective as _,setProjectEnabled as O}from"./plugin-project-state.js";import{builtinToolkitRoot as L,discoverToolkitPacks as V}from"./toolkit-scan.js";export class ToolkitError extends Error{code;constructor(t,e){super(t),this.code=e,this.name="ToolkitError"}}export const MIN_MOD_HOST_VERSION=[2,1,287];const K=1e4;export function isVersionAtLeast(o,t){const e=o.split(".").map(s=>Number.parseInt(s,10));for(let s=0;s<t.length;s++){const a=Number.isFinite(e[s])?e[s]:0;if(a>t[s])return!0;if(a<t[s])return!1}return!0}let y;function W(o){if(!(o.exitCode!==null||o.signalCode!==null)){if(process.platform==="win32"&&o.pid!==void 0){P("taskkill",["/pid",String(o.pid),"/t","/f"],{windowsHide:!0,stdio:"ignore"}).unref();return}o.kill("SIGKILL")}}export async function detectClaudeVersion(){if(y&&Date.now()-y.at<6e5)return y.value;const o=await new Promise(t=>{let e="";const s=process.platform==="win32"?P("claude --version",{windowsHide:!0,shell:!0,stdio:["ignore","pipe","pipe"]}):P("claude",["--version"],{windowsHide:!0,stdio:["ignore","pipe","pipe"]}),a=setTimeout(()=>{W(s),t(null)},5e3);s.stdout?.on("data",i=>e+=i.toString()),s.on("error",()=>{clearTimeout(a),t(null)}),s.on("close",()=>{clearTimeout(a);const i=/(\d+\.\d+\.\d+)/.exec(e);t(i?i[1]:null)})});return o!==null&&(y={value:o,at:Date.now()}),o}async function S(o,t,e){let s;try{s=await h(c.join(o,...t.split("/").filter(Boolean)),{withFileTypes:!0})}catch{return}for(const a of s){if(a.name==="node_modules"||a.name===".git")continue;const i=t?`${t}/${a.name}`:a.name;a.isDirectory()?await S(o,i,e):e.push({rel:i,abs:c.join(o,...i.split("/"))})}}const f=o=>o.ccPack||o.kind==="mod";async function R(o,t){const e=[];if(t.skills.length>0)for(const s of t.targets){if(s==="claude"&&f(t))continue;const a=$(s).projectSkillsRoots()[0];for(const i of t.skills){const r=[];await S(c.join(t.dir,"skills",i),"",r);for(const n of r)e.push({src:n.abs,rel:`${a}/${i}/${n.rel}`})}}if(!f(t))for(const s of t.targets)for(const[a,i]of[["commands","command"],["agents","agent"]]){const r=c.join(t.dir,a),n=[];if(await S(r,"",n),n.length===0)continue;const l=J(i,s,o);if(l)for(const u of n){const k=u.rel.split("/").pop();e.push({src:u.abs,rel:j(c.relative(o,c.join(l,k)))})}}return e}function J(o,t,e){try{return H(o,t,"project",e,M())}catch{return null}}function j(o){return o.split(c.sep).join("/")}function C(o,t){return c.join(o,".weave","toolkit",`${t}.json`)}async function v(o){try{const t=JSON.parse(await I(o,"utf8"));return t&&typeof t=="object"&&typeof t.packId=="string"?t:null}catch{return null}}export async function projectFileNamespaces(o){const t=new Map,e=c.join(o,".weave","toolkit");let s;try{s=await h(e)}catch{return t}for(const a of s){if(!a.endsWith(".json"))continue;const i=await v(c.join(e,a)),r=i?m(i.sourceDir):void 0;if(!(!i||!r))for(const n of Object.keys(i.files))t.set(n,r)}return t}export async function projectPackFiles(o){const t=new Map,e=c.join(o,".weave","toolkit");let s;try{s=await h(e)}catch{return t}for(const a of s){if(!a.endsWith(".json"))continue;const i=await v(c.join(e,a));if(i)for(const[r,n]of Object.entries(i.files))typeof n=="string"&&t.set(r,n)}return t}async function T(o){try{return await I(o),!0}catch{return!1}}async function B(o,t){const e=new Set;for(const a of t){let i=c.posix.dirname(a);for(;i&&i!=="."&&i!=="/";)e.add(i),i=c.posix.dirname(i)}const s=[...e].sort((a,i)=>i.split("/").length-a.split("/").length);for(const a of s){const i=c.join(o,...a.split("/"));try{(await h(i)).length===0&&await w(i,{recursive:!0,force:!0})}catch{}}}export function evaluateModHostGate(o){return process.env.WEAVE_SKIP_MOD_VERSION_CHECK==="1"?{ok:!0}:o?isVersionAtLeast(o,MIN_MOD_HOST_VERSION)?{ok:!0}:{ok:!1,message:`\u5BBF\u4E3B Claude Code ${o} \u4F4E\u4E8E 2.1.287\uFF0Cmod \u5DE5\u5177\u5305\u4E0D\u843D\u76D8\uFF08\u8BF7\u5148\u5347\u7EA7 Claude Code\uFF09`}:{ok:!0,warning:"\u65E0\u6CD5\u68C0\u6D4B\u5BBF\u4E3B Claude Code \u7248\u672C\uFF0Cmod \u5DE5\u5177\u5305\u9700\u8981 \u2265 2.1.287 \u624D\u80FD\u88AB\u52A0\u8F7D"}}export class ToolkitService{deps;packsCache;constructor(t){this.deps=t}sources(){const t=[{root:this.deps.builtinRoot??L(),provenance:"builtin"}];if(this.deps.libraries)for(const s of A(this.deps.libraries))t.push({root:s,provenance:"market"});const e=new Set;return t.filter(s=>{const a=c.resolve(s.root);return e.has(a)?!1:(e.add(a),!0)})}async allPacks(){const t=this.sources(),e=t.map(n=>c.resolve(n.root)).join("|"),s=Date.now(),a=this.packsCache;if(a&&a.key===e&&s-a.at<K)return a.packs;const i=Promise.all(t.map(n=>V(n))).then(n=>n.flat()),r={at:s,key:e,packs:i};return this.packsCache=r,i.catch(()=>{this.packsCache===r&&(this.packsCache=void 0)}),i}async list(t){const e=this.requireProject(t),s=await this.allPacks(),a=await Promise.all(s.map(i=>this.packInfo(e,i)));return await this.healMeta(e,a),{packs:a,legacyCopies:await this.scanLegacyCopies(e)}}async enable(t,e,s){const a=this.requireProject(t),i=await this.resolvePack(e,s),r=[];if(i.kind==="mod"&&i.targets.includes("claude")){const d=this.deps.claudeVersion??detectClaudeVersion,p=evaluateModHostGate(await d());if(!p.ok)throw new ToolkitError(p.message??"mod host gate","host-version");p.warning&&r.push(p.warning)}const n=a.path;if(f(i)&&i.targets.includes("claude")){const d=this.pluginSurface();await N(d,i),await d.setProjectEnabled(n,i.name,!0,m(i.dir))}const l=C(n,i.id),u=await this.readRecordHealed(n,i.id),k=u??{packId:i.id,provenance:i.provenance,sourceRoot:i.sourceRoot,sourceDir:i.dir,enabledAt:new Date().toISOString(),files:{}};let E=u===null;const F=await R(n,i);for(const d of F){const p=c.join(n,...d.rel.split("/"));if(k.files[d.rel]!==void 0){await T(p)||(await b(c.dirname(p),{recursive:!0}),await D(d.src,p));continue}await g(p)==="missing"&&(await b(c.dirname(p),{recursive:!0}),await D(d.src,p),k.files[d.rel]=await g(d.src),E=!0)}return F.length>0?E&&(await b(c.dirname(l),{recursive:!0}),await x(l,JSON.stringify(k,null,2)+`
2
+ `,"utf8")):u&&await w(l,{force:!0}),i.weavePack&&O(a,i.id,!0,{projects:this.deps.projects}),this.rememberEnabled(a,i.id,!0),{pack:await this.packInfo(this.requireProject(t),i),warnings:r}}async disable(t,e,s){const a=this.requireProject(t),i=await this.resolvePack(e,s);return await this.applyDisabled(a,i),{pack:await this.packInfo(this.requireProject(t),i),warnings:[]}}async applyDisabled(t,e){await this.removePackFiles(t,e,e.sourceRoot),f(e)&&e.targets.includes("claude")&&await this.pluginSurface().setProjectEnabled(t.path,e.name,!1,m(e.dir)),e.weavePack&&O(t,e.id,!1,{projects:this.deps.projects}),this.rememberEnabled(t,e.id,!1)}async uninstall(t,e,s){const a=this.requireProject(t),i=await this.resolvePack(e,s);return await this.applyDisabled(a,i),f(i)&&i.targets.includes("claude")&&await this.pluginSurface().uninstall(i.name,m(i.dir)),{pack:await this.packInfo(this.requireProject(t),i),warnings:[]}}async removePackFiles(t,e,s){const a=C(t.path,e.id),i=await v(a);if(!i||s&&c.resolve(i.sourceRoot)!==c.resolve(s))return;const r=[];for(const[n,l]of Object.entries(i.files)){const u=c.join(t.path,...n.split("/"));await g(u)===l&&(await w(u,{force:!0}),r.push(n))}await w(a,{force:!0}),await B(t.path,r)}requireProject(t){const e=this.deps.projects.getById(t);if(!e)throw new ToolkitError(`Project not found: ${t}`,"not-found");return e}async resolvePack(t,e){this.packsCache=void 0;const s=(await this.allPacks()).filter(i=>i.id===t);if(e){const i=s.find(r=>c.resolve(r.sourceRoot)===c.resolve(e));if(i)return i}const a=s.find(i=>i.provenance==="builtin")??s[0];if(!a)throw new ToolkitError(`Toolkit pack not found: ${t}`,"not-found");return a}async computeEnabled(t,e){const s=[],a=await this.readRecordHealed(t.path,e.id);if((await R(t.path,e)).length>0){let i=!!a;if(a){for(const r of Object.keys(a.files))if(!await T(c.join(t.path,...r.split("/")))){i=!1;break}}s.push(i)}if(f(e)&&e.targets.includes("claude")){const i=this.pluginSurface(),r=m(e.dir);s.push(await i.isInstalled(e.name,r)&&await i.readProjectEnabled(t.path,e.name,r))}return e.weavePack&&s.push(_(t,e.id,{states:this.deps.states,defaultEnabled:!1})),s.length>0?s.every(Boolean):!1}async installedScopes(t){const e=(await this.pluginSurface().readInstalled())[t];return!e||e.length===0?void 0:[...new Set(e.map(s=>s.scope??"user"))]}async packInfo(t,e){const s=await this.computeEnabled(t,e),a=m(e.dir),i=f(e)&&e.targets.includes("claude")?this.pluginSurface().pluginKey(e.name,a):void 0,r=i?await this.installedScopes(i):void 0,n={...e,...a?{namespace:a}:{},enabled:s,installed:await this.computeInstalled(t,e,s),...i?{key:i}:{},...r&&r.length>0?{scopes:r}:{}};if(e.weavePack){const l=this.deps.plugins.list().find(u=>u.id===e.id);l&&(n.weave={status:l.status,ruleCount:l.ruleCount,...l.error?{error:l.error}:{}})}return n}async computeInstalled(t,e,s){return e.weavePack&&!f(e)?!0:f(e)&&e.targets.includes("claude")?this.pluginSurface().isInstalled(e.name,m(e.dir)):s||!!await this.readRecordHealed(t.path,e.id)}enabledIndex(t){const e=this.deps.projects.getMeta(t.id)?.toolkit,s=e&&typeof e=="object"?e.enabled:void 0;return Array.isArray(s)?s.filter(a=>typeof a=="string"):[]}rememberEnabled(t,e,s){const a=new Set(this.enabledIndex(t));s?a.add(e):a.delete(e),this.deps.projects.setMeta(t.id,{toolkit:{enabled:[...a].sort()}})}async healMeta(t,e){const s=[...new Set(e.filter(n=>n.enabled).map(n=>n.id))].sort(),a=[...new Set(this.enabledIndex(t))].sort(),i=new Set(e.map(n=>n.id)),r=[...new Set([...a.filter(n=>!i.has(n)),...s])].sort();r.join(`
3
+ `)!==a.join(`
4
+ `)&&this.deps.projects.setMeta(t.id,{toolkit:{enabled:r}})}pluginSurface(){return this.deps.pluginSurface??q("claude")}async readRecordHealed(t,e){const s=C(t,e),a=await v(s);if(!a)return null;const i=j(c.relative(t,this.pluginSurface().projectPluginDir(t))),r=Object.keys(a.files).filter(l=>l.startsWith(`${i}/`));if(r.length===0)return a;const n=[];for(const l of r){const u=c.join(t,...l.split("/"));await g(u)===a.files[l]&&(await w(u,{force:!0}),n.push(l)),delete a.files[l]}return await B(t,n),await x(s,JSON.stringify(a,null,2)+`
5
+ `,"utf8"),a}async scanLegacyCopies(t){const e=this.pluginSurface().projectPluginDir(t.path);let s;try{s=await h(e,{withFileTypes:!0})}catch{return[]}return s.map(a=>j(c.relative(t.path,c.join(e,a.name)))).sort()}async cleanupLegacyCopies(t){const e=this.requireProject(t),s=this.pluginSurface().projectPluginDir(e.path);let a;try{a=await h(s,{withFileTypes:!0})}catch{return{removed:[]}}const i=[];for(const r of a){const n=c.join(s,r.name);await w(n,{recursive:!0,force:!0}),i.push(j(c.relative(e.path,n)))}try{(await h(s)).length===0&&await w(s,{recursive:!0,force:!0})}catch{}return{removed:i.sort()}}}
@@ -1 +1 @@
1
- import{HARNESS_LIFECYCLE as o}from"@weavecode/core";import{messagingSurfaceFor as c}from"../surfaces.js";import{pidAliveOf as a}from"../daemon/claude-liveness.js";import{combinedLivenessOf as l}from"../daemon/liveness.js";const f=1e3;export class WatchEngine{deps;lastHitAt=new Map;constructor(e){this.deps=e,e.bus.subscribe(t=>this.onBus(t))}onEvent(e){try{const i=(this.deps.surfaceFor?.(e.source)??c(e.source)).idleSignals.includes(e.eventType),n=o[e.source].close.includes(e.eventType);if(!i&&!n)return;for(const d of this.deps.watches.listPendingByTarget(e.sessionId))n&&d.onEvents.includes("turnEnd")?this.fire(d,"turnEnd"):i&&d.onEvents.includes("idle")&&this.fire(d,"idle")}catch{}}onBus(e){if(e.kind==="message.finished"&&!(e.status!=="failed"&&e.status!=="timeout"))try{for(const t of this.deps.watches.listPendingByTarget(e.sessionId))t.onEvents.includes("messageFailed")&&this.fire(t,"messageFailed")}catch{}}created(e){try{if(!e.onEvents.includes("idle")&&!e.onEvents.includes("turnEnd"))return;this.deps.sessions.turnOpenOf(e.targetSessionId)===!1&&this.fire(e,e.onEvents.includes("idle")?"idle":"turnEnd")}catch{}}sweepTerminated(){try{const e=this.deps.livenessOf?.()??l(),t=new Map(this.deps.sessions.listWithCounts().map(s=>[s.sessionId,s]));let i=0;for(const s of this.deps.watches.listPending()){if(s.remaining===null||!s.onEvents.includes("idle")&&!s.onEvents.includes("turnEnd"))continue;const n=t.get(s.targetSessionId);n&&a(n,e)!==!1||this.fire(s,"idle")&&i++}return i}catch{return 0}}fire(e,t){const i=Date.now(),s=this.lastHitAt.get(e.id);if(s!==void 0&&i-s<f)return!1;const n=this.deps.watches.consumeHit(e.id);if(!n)return!1;this.lastHitAt.set(e.id,i),n.firedAt!==null&&this.lastHitAt.delete(e.id);const d=new Date(i).toISOString();return this.deps.bus.emit({kind:"watch.fired",watchId:e.id,targetSessionId:e.targetSessionId,watcherSessionId:e.watcherSessionId,reason:t,at:d}),e.watcherSessionId==null||this.deps.deliverer.send({toSessionId:e.watcherSessionId,text:e.notify??this.defaultNotify(e.targetSessionId,t),fromKind:"session",fromSessionId:e.targetSessionId,mode:"inject"}).catch(()=>{}),!0}defaultNotify(e,t){return`Session ${this.deps.sessions.getBySessionId(e)?.title??e.slice(0,8)} ${watchReasonPhrase(t)} (trigger=watch:${e})`}}export function watchReasonPhrase(r){return r==="messageFailed"?"had a failed message delivery":r==="turnEnd"?"finished its turn":"is now idle"}
1
+ import{HARNESS_LIFECYCLE as r}from"@weavecode/core";import{messagingSurfaceFor as a}from"../surfaces.js";import{pidAliveOf as c}from"../daemon/claude-liveness.js";import{combinedLivenessOf as l}from"../daemon/liveness.js";const u=1e3;export class WatchEngine{deps;lastHitAt=new Map;constructor(s){this.deps=s,s.bus.subscribe(e=>this.onBus(e))}onEvent(s){try{const e=(this.deps.surfaceFor?.(s.source)??a(s.source)).idleSignals.includes(s.eventType),i=r[s.source].close.includes(s.eventType);if(!e&&!i)return;for(const t of this.deps.watches.listPendingByTarget(s.sessionId))i&&t.onEvents.includes("turnEnd")?this.fire(t,"turnEnd"):e&&t.onEvents.includes("idle")&&this.fire(t,"idle")}catch{}}onBus(s){if(s.kind==="message.finished"&&!(s.status!=="failed"&&s.status!=="timeout"))try{for(const e of this.deps.watches.listPendingByTarget(s.sessionId))e.onEvents.includes("messageFailed")&&this.fire(e,"messageFailed")}catch{}}created(s){try{if(!s.onEvents.includes("idle")&&!s.onEvents.includes("turnEnd"))return;this.deps.sessions.turnOpenOf(s.targetSessionId)===!1&&this.fire(s,s.onEvents.includes("idle")?"idle":"turnEnd")}catch{}}sweepTerminated(){try{const s=this.deps.livenessOf?.()??l(),e=new Map(this.deps.sessions.listWithCounts().map(t=>[t.sessionId,t]));let i=0;for(const t of this.deps.watches.listPending()){if(t.remaining===null||!t.onEvents.includes("idle")&&!t.onEvents.includes("turnEnd"))continue;const n=e.get(t.targetSessionId);n&&c(n,s)!==!1||this.fire(t,"idle")&&i++}return i}catch{return 0}}fire(s,e){const i=Date.now(),t=this.lastHitAt.get(s.id);if(t!==void 0&&i-t<u)return!1;const n=this.deps.watches.consumeHit(s.id);if(!n)return!1;this.lastHitAt.set(s.id,i),n.firedAt!==null&&this.lastHitAt.delete(s.id);const o=new Date(i).toISOString();return this.deps.bus.emit({kind:"watch.fired",watchId:s.id,targetSessionId:s.targetSessionId,watcherSessionId:s.watcherSessionId,reason:e,at:o}),s.watcherSessionId==null||this.deps.deliverer.send({toSessionId:s.watcherSessionId,text:s.notify??this.defaultNotify(s.targetSessionId,e),fromKind:"session",fromSessionId:s.targetSessionId,mode:"inject"}).catch(()=>{}),!0}defaultNotify(s,e){return`Session ${this.deps.sessions.getBySessionId(s)?.title??s.slice(0,8)} ${watchReasonPhrase(e)} (trigger=watch:${s})`}}export function watchReasonPhrase(d){return d==="messageFailed"?"had a failed message delivery":d==="turnEnd"?"finished its turn":"is now idle"}
@@ -1 +1 @@
1
- import{rm as u,cp as y,mkdir as d}from"node:fs/promises";import{homedir as f}from"node:os";import l from"node:path";import{applyStatuslineConfig as w}from"../statusline/manager.js";import{readStatuslineConfig as S}from"../statusline/manager.js";import{buildLibraryIndex as g,findSkillSource as k,findMcpSource as h,findFileAssetSource as x}from"./library-index.js";import{detectUpdates as E}from"./updates.js";import{materializePluginTemplate as F}from"./plugin-templates.js";import{applyInitFile as $}from"./init-files.js";import{FILE_ASSET_SPECS as A,fileAssetTargetDir as C,isFileAssetCategory as b}from"./file-assets.js";import{assetSurfaceFor as p}from"../surfaces.js";export async function applyUpdate(t,o,m,i){const c=m??(i?await g(i):await g([])),a=o.agent??"claude";if(o.category==="skill"){const e=k(c,o.name);if(!e)throw new Error(`No library source for skill "${o.name}"`);const n=o.scope==="user"?p(a).globalSkillsRoots(f())[0]:l.join(t,...p(a).projectSkillsRoots()[0].split("/")),s=l.join(n,o.name);await u(s,{recursive:!0,force:!0}),await y(e.dirPath,s,{recursive:!0});return}if(b(o.category)){const e=x(c,o.category,o.name);if(!e)throw new Error(`No library source for ${o.category} "${o.name}"`);const n=C(o.category,a,o.scope,t,f());await d(n,{recursive:!0});const s=l.join(n,`${o.name}${A[o.category].ext}`);await u(s,{force:!0}),await y(e.filePath,s);return}const r=h(c,o.name);if(!r)throw new Error(`No library source for MCP "${o.name}"`);await p(a).mcpWrite(o.scope,t,f(),o.name,r.config)}export async function syncAll(t,o,m,i){const c=i??await g(o),a=await E(t,o,m,c),r=[];for(const e of a.skills)e.custom||!e.outdated||(await applyUpdate(t,{category:"skill",name:e.name,scope:e.scope,agent:e.agent},c),r.push({category:"skill",name:e.name,scope:e.scope,agent:e.agent}));for(const e of a.mcp)e.custom||!e.outdated||(await applyUpdate(t,{category:"mcp",name:e.name,scope:e.scope,agent:e.agent},c),r.push({category:"mcp",name:e.name,scope:e.scope,agent:e.agent}));for(const e of a.files)e.custom||!e.outdated||(await applyUpdate(t,{category:e.category,name:e.name,scope:e.scope},c),r.push({category:e.category,name:e.name,scope:e.scope}));for(const e of a.pluginTemplates)e.outdated&&(await F(e),r.push({category:e.category,name:e.name,scope:"project"}));for(const e of a.initFiles)await $(e)&&r.push({category:"init",name:e.relPath,scope:"project"});return{updated:r,skipped:0}}export async function refreshStatusline(t){const o=await S(t);await w(t,o)}
1
+ import{rm as g,cp as y,mkdir as d}from"node:fs/promises";import{homedir as m}from"node:os";import f from"node:path";import{applyStatuslineConfig as w}from"../statusline/manager.js";import{readStatuslineConfig as S}from"../statusline/manager.js";import{buildLibraryIndex as l,findSkillSource as h,findMcpSource as k,findFileAssetSource as b}from"./library-index.js";import{detectUpdates as E}from"./updates.js";import{materializePluginTemplate as F}from"./plugin-templates.js";import{applyInitFile as $}from"./init-files.js";import{FILE_ASSET_SPECS as j,fileAssetTargetDir as x,isFileAssetCategory as A}from"./file-assets.js";import{assetSurfaceFor as u}from"../surfaces.js";export async function applyUpdate(t,a,p,c){const s=p??(c?await l(c):await l([])),o=a.agent??"claude";if(a.category==="skill"){const e=h(s,a.name);if(!e)throw new Error(`No library source for skill "${a.name}"`);const n=a.scope==="user"?u(o).globalSkillsRoots(m())[0]:f.join(t,...u(o).projectSkillsRoots()[0].split("/")),i=f.join(n,a.name);await g(i,{recursive:!0,force:!0}),await y(e.dirPath,i,{recursive:!0});return}if(A(a.category)){const e=b(s,a.category,a.name);if(!e)throw new Error(`No library source for ${a.category} "${a.name}"`);const n=x(a.category,o,a.scope,t,m());await d(n,{recursive:!0});const i=f.join(n,`${a.name}${j[a.category].ext}`);await g(i,{force:!0}),await y(e.filePath,i);return}const r=k(s,a.name);if(!r)throw new Error(`No library source for MCP "${a.name}"`);await u(o).mcpWrite(a.scope,t,m(),a.name,r.config)}export async function syncAll(t,a,p,c){const s=c??await l(a),o=await E(t,a,p,s),r=[];for(const e of o.skills)e.custom||!e.outdated||(await applyUpdate(t,{category:"skill",name:e.name,scope:e.scope,agent:e.agent},s),r.push({category:"skill",name:e.name,scope:e.scope,agent:e.agent}));for(const e of o.mcp)e.custom||!e.outdated||(await applyUpdate(t,{category:"mcp",name:e.name,scope:e.scope,agent:e.agent},s),r.push({category:"mcp",name:e.name,scope:e.scope,agent:e.agent}));for(const e of o.files)e.custom||!e.outdated||(await applyUpdate(t,{category:e.category,name:e.name,scope:e.scope},s),r.push({category:e.category,name:e.name,scope:e.scope}));for(const e of o.pluginTemplates)e.outdated&&(await F(e),r.push({category:e.category,name:e.name,scope:"project"}));for(const e of o.initFiles)await $(e)&&r.push({category:"init",name:e.relPath,scope:"project"});return{updated:r,skipped:0}}export async function refreshStatusline(t){const a=await S(t);await w(t,a)}
@@ -1 +1 @@
1
- import p from"node:path";import{homedir as m}from"node:os";import{HARNESS_KEYS as l}from"@weavecode/core";import{FILE_ASSET_SPECS as h,FILE_ASSET_CATEGORIES as S}from"./file-assets.js";import{assetSurfaces as u,configSurfaces as j,statuslineSurfaces as E}from"../surfaces.js";function f(r,c){return p.join("~",p.relative(c,r)).split(p.sep).join("/")}export function installCapabilities(){const r=m(),c={};for(const s of S){const t=h[s].dirs,o=[];for(const e of l){const n=t[e];if(!n)continue;const i=[];n.project&&i.push("project"),n.user&&i.push("user"),i.length>0&&o.push({harness:e,scopes:i})}c[s]={surfaces:o}}c.skill={surfaces:u().map(s=>{const t=[],o={},e=s.projectSkillsRoots()[0];e&&(t.push("project"),o.project=e);const n=s.globalSkillsRoots(r)[0];return n&&(t.push("user"),o.user=f(n,r)),{harness:s.harness,scopes:t,dest:o}})},c.mcp={surfaces:u().map(s=>{const t={},o=s.mcpDest("project",r),e=s.mcpDest("user",r);return o&&(t.project=o),e&&(t.user=f(e,r)),{harness:s.harness,scopes:s.mcpScopes(),dest:t}}).filter(s=>s.scopes.length>0)};const a=E().map(({harness:s,surface:t})=>({harness:s,tui:t.tui,segments:[...t.segments]}));return{categories:c,statusline:a,config:j().map(s=>s.harness)}}
1
+ import p from"node:path";import{homedir as m}from"node:os";import{HARNESS_KEYS as l}from"@weavecode/core";import{FILE_ASSET_SPECS as h,FILE_ASSET_CATEGORIES as S}from"./file-assets.js";import{assetSurfaces as i,configSurfaces as j,statuslineSurfaces as E}from"../surfaces.js";function u(o,n){return p.join("~",p.relative(n,o)).split(p.sep).join("/")}export function installCapabilities(){const o=m(),n={};for(const s of S){const e=h[s].dirs,r=[];for(const t of l){const c=e[t];if(!c)continue;const a=[];c.project&&a.push("project"),c.user&&a.push("user"),a.length>0&&r.push({harness:t,scopes:a})}n[s]={surfaces:r}}n.skill={surfaces:i().map(s=>{const e=[],r={},t=s.projectSkillsRoots()[0];t&&(e.push("project"),r.project=t);const c=s.globalSkillsRoots(o)[0];return c&&(e.push("user"),r.user=u(c,o)),{harness:s.harness,scopes:e,dest:r}})},n.mcp={surfaces:i().map(s=>{const e={},r=s.mcpDest("project",o),t=s.mcpDest("user",o);return r&&(e.project=r),t&&(e.user=u(t,o)),{harness:s.harness,scopes:s.mcpScopes(),dest:e}}).filter(s=>s.scopes.length>0)};const f=E().map(({harness:s,surface:e})=>({harness:s,tui:e.tui,segments:[...e.segments]}));return{categories:n,statusline:f,config:j().map(s=>s.harness)}}
@@ -1 +1 @@
1
- import{homedir as t}from"node:os";import{assetSurfaceFor as x}from"../surfaces.js";import{codexMcpExists as c,readCodexMcpServers as d,removeCodexMcpServer as n,writeCodexMcpServer as p}from"@weavecode/harness";export{CodexTomlCorruptError,parseDottedKey,sectionHeaderKey,renderTomlKey,renderTomlHeader,renderTomlString,splitTomlSections,upsertTomlSection,removeTomlSection,parseSectionEntries,upsertCodexPluginEnabledInText,readCodexMcpFromText,upsertCodexMcpInText,removeCodexMcpFromText}from"@weavecode/harness";export function codexConfigFile(e=t()){return x("codex").userConfigFile(e)}export function readCodexMcpServers(e=codexConfigFile()){return d(e)}export function codexMcpExists(e,r=codexConfigFile()){return c(e,r)}export function writeCodexMcpServer(e,r,o=codexConfigFile()){return p(e,r,o)}export function removeCodexMcpServer(e,r=codexConfigFile()){return n(e,r)}
1
+ import{homedir as t}from"node:os";import{assetSurfaceFor as n}from"../surfaces.js";import{codexMcpExists as p,readCodexMcpServers as x,removeCodexMcpServer as c,writeCodexMcpServer as d}from"@weavecode/harness";export{CodexTomlCorruptError,parseDottedKey,sectionHeaderKey,renderTomlKey,renderTomlHeader,renderTomlString,splitTomlSections,upsertTomlSection,removeTomlSection,parseSectionEntries,upsertCodexPluginEnabledInText,readCodexMcpFromText,upsertCodexMcpInText,removeCodexMcpFromText}from"@weavecode/harness";export function codexConfigFile(e=t()){return n("codex").userConfigFile(e)}export function readCodexMcpServers(e=codexConfigFile()){return x(e)}export function codexMcpExists(e,r=codexConfigFile()){return p(e,r)}export function writeCodexMcpServer(e,r,o=codexConfigFile()){return d(e,r,o)}export function removeCodexMcpServer(e,r=codexConfigFile()){return c(e,r)}
@@ -1 +1 @@
1
- import{assetSurfaceFor as i}from"../surfaces.js";export{FILE_ASSET_SPECS,FILE_ASSET_CATEGORIES,isFileAssetCategory}from"@weavecode/harness";export function fileAssetTargetDir(r,e,t,o,S){return i(e).targetDir(r,t,o,S)}
1
+ import{assetSurfaceFor as s}from"../surfaces.js";export{FILE_ASSET_SPECS,FILE_ASSET_CATEGORIES,isFileAssetCategory}from"@weavecode/harness";export function fileAssetTargetDir(r,e,t,i,o){return s(e).targetDir(r,t,i,o)}
@@ -1 +1 @@
1
- import{readdir as m,readFile as u,stat as l}from"node:fs/promises";import{createHash as h}from"node:crypto";import c from"node:path";const f=new Set([".weave",".git","node_modules"]);export async function hashSkillDir(e,t=f){const a=h("sha256"),r=[];await p(e,e,r,t),r.sort((n,i)=>n.rel.localeCompare(i.rel));for(const n of r){a.update(n.rel),a.update("\0");let i;try{i=await u(n.abs)}catch{continue}a.update(i),a.update("\0")}return a.digest("hex")}async function p(e,t,a,r){let n;try{n=await m(t,{withFileTypes:!0})}catch{return}const i=[];for(const s of n)s.name.startsWith(".")&&r.has(s.name)||(!r.has(s.name)&&s.isDirectory()?i.push(p(e,c.join(t,s.name),a,r)):s.isFile()&&a.push({rel:c.relative(e,t).replace(/\\/g,"/")+"/"+s.name,abs:c.join(t,s.name)}));await Promise.all(i)}export async function maxMtimeDir(e,t=f){let a;try{a=await m(e,{withFileTypes:!0})}catch{return 0}return(await Promise.all(a.map(async n=>{if(n.name.startsWith(".")&&t.has(n.name))return 0;const i=c.join(e,n.name);if(n.isDirectory())return maxMtimeDir(i,t);if(!n.isFile())return 0;try{return(await l(i)).mtimeMs}catch{return 0}}))).reduce((n,i)=>Math.max(n,i),0)}export function hashMcpConfig(e){return h("sha256").update(JSON.stringify(o(e))).digest("hex")}export async function hashFile(e){try{const t=await u(e);return h("sha256").update(t).digest("hex")}catch{return"missing"}}function o(e){if(Array.isArray(e))return e.map(o);if(e&&typeof e=="object"){const t={};for(const a of Object.keys(e).sort())t[a]=o(e[a]);return t}return e}export class FingerprintCache{cache=new Map;fileCache=new Map;async get(t){const a=await maxMtimeDir(t),r=this.cache.get(t);if(r&&r.maxMtime===a)return r.hash;const n=await hashSkillDir(t);return this.cache.set(t,{maxMtime:a,hash:n}),n}async getFile(t){let a;try{a=(await l(t)).mtimeMs}catch{return"missing"}const r=this.fileCache.get(t);if(r&&r.maxMtime===a)return r.hash;const n=await hashFile(t);return this.fileCache.set(t,{maxMtime:a,hash:n}),n}invalidate(t){this.cache.delete(t)}clear(){this.cache.clear(),this.fileCache.clear()}}
1
+ import{readdir as m,readFile as u,stat as l}from"node:fs/promises";import{createHash as h}from"node:crypto";import c from"node:path";const f=new Set([".weave",".git","node_modules"]);export async function hashSkillDir(e,t=f){const r=h("sha256"),a=[];await p(e,e,a,t),a.sort((i,n)=>i.rel.localeCompare(n.rel));for(const i of a){r.update(i.rel),r.update("\0");let n;try{n=await u(i.abs)}catch{continue}r.update(n),r.update("\0")}return r.digest("hex")}async function p(e,t,r,a){let i;try{i=await m(t,{withFileTypes:!0})}catch{return}const n=[];for(const s of i)s.name.startsWith(".")&&a.has(s.name)||(!a.has(s.name)&&s.isDirectory()?n.push(p(e,c.join(t,s.name),r,a)):s.isFile()&&r.push({rel:c.relative(e,t).replace(/\\/g,"/")+"/"+s.name,abs:c.join(t,s.name)}));await Promise.all(n)}export async function maxMtimeDir(e,t=f){let r;try{r=await m(e,{withFileTypes:!0})}catch{return 0}return(await Promise.all(r.map(async a=>{if(a.name.startsWith(".")&&t.has(a.name))return 0;const i=c.join(e,a.name);if(a.isDirectory())return maxMtimeDir(i,t);if(!a.isFile())return 0;try{return(await l(i)).mtimeMs}catch{return 0}}))).reduce((a,i)=>Math.max(a,i),0)}export function hashMcpConfig(e){return h("sha256").update(JSON.stringify(o(e))).digest("hex")}export async function hashFile(e){try{const t=await u(e);return h("sha256").update(t).digest("hex")}catch{return"missing"}}function o(e){if(Array.isArray(e))return e.map(o);if(e&&typeof e=="object"){const t={};for(const r of Object.keys(e).sort())t[r]=o(e[r]);return t}return e}export class FingerprintCache{cache=new Map;fileCache=new Map;async get(t){const r=await maxMtimeDir(t),a=this.cache.get(t);if(a&&a.maxMtime===r)return a.hash;const i=await hashSkillDir(t);return this.cache.set(t,{maxMtime:r,hash:i}),i}async getFile(t){let r;try{r=(await l(t)).mtimeMs}catch{return"missing"}const a=this.fileCache.get(t);if(a&&a.maxMtime===r)return a.hash;const i=await hashFile(t);return this.fileCache.set(t,{maxMtime:r,hash:i}),i}invalidate(t){this.cache.delete(t)}clear(){this.cache.clear(),this.fileCache.clear()}}
@@ -1 +1 @@
1
- import{readFile as E,readdir as h,access as J,stat as x,realpath as G}from"node:fs/promises";import{homedir as c}from"node:os";import l from"node:path";import{AssetNotFoundError as g}from"./installer.js";import{readClaudeJson as N}from"@weavecode/harness";import{FileTooLargeError as W,MAX_BYTES as v}from"./reader.js";import{assetSurfaceFor as y,assetSurfaces as R,pluginStateFor as k,pluginSurfaceFor as $}from"../surfaces.js";import{installForm as L,linkOrCopy as _,removeInstalled as z}from"../market/install-link.js";export{ClaudeJsonCorruptError}from"@weavecode/harness";const I=".claude.json",U=".claude/plugins/installed_plugins.json";function B(){return l.join(c(),I)}function S(){return y("claude").globalSkillsRoots(c())[0]}function M(t=c()){return l.join(t,U)}function K(){return y("claude").userConfigFile(c())}function O(){return y("codex").globalSkillsRoots(c())[0]}function X(){return y("codex").globalSkillsRoots(c())}function P(){const t=y("codex").pluginCacheDir?.(c());if(!t)throw new Error("codex has no plugin cache surface");return t}export function globalPersonalSkillRootsOwned(){return R().flatMap(t=>t.globalSkillsRoots(c()).map(n=>({harness:t.harness,root:n})))}export function globalPersonalSkillRoots(){return globalPersonalSkillRootsOwned().map(t=>t.root)}async function T(t){try{return await J(t),!0}catch{return!1}}async function m(t){try{return(await x(t)).isDirectory()}catch{return!1}}export function readGlobalClaudeJson(){return N(c())}export async function readGlobalMcpServers(){const t=(await readGlobalClaudeJson()).mcpServers;return!t||typeof t!="object"||Array.isArray(t)?{}:t}export async function writeGlobalMcpServer(t,n){await y("claude").mcpWrite("user","",c(),t,n)}export async function removeGlobalMcpServer(t){await y("claude").mcpRemove("user","",c(),t)}export async function readGlobalSkills(){const t=S();try{const n=await h(t,{withFileTypes:!0}),o=[];for(const e of n)!e.isDirectory()&&!e.isSymbolicLink()||await m(l.join(t,e.name))&&o.push(e.name);return o.sort((e,r)=>e.localeCompare(r))}catch{return[]}}export async function installGlobalSkill(t,n,o="claude"){const e=y(o).globalSkillsRoots(c())[0],r=l.join(e,n);if(await T(r))throw new Error(`Global ${o} skill "${n}" already exists`);return await _(t,r),r}export async function uninstallGlobalSkill(t,n="claude"){const o=y(n).globalSkillsRoots(c())[0];await z(l.join(o,t))}async function C(t=c()){const n=M(t);if(!await T(n))return{};try{const o=JSON.parse(await E(n,"utf-8"));return o&&typeof o=="object"&&!Array.isArray(o)?o:{}}catch{return{}}}async function j(t){if(!await m(t))return[];let n;try{n=await h(t,{withFileTypes:!0})}catch{return[]}const o=[];for(const e of n){if(e.name.startsWith(".")||!e.isDirectory()&&!e.isSymbolicLink())continue;const r=l.join(t,e.name);if(!await m(r))continue;const i=await L(r);i!=="absent"&&o.push({name:e.name,dir:r,form:i})}return o.sort((e,r)=>e.name.localeCompare(r.name))}export async function installedPluginNamespaces(t=c()){const o=(await C(t)).plugins;if(!o||typeof o!="object"||Array.isArray(o))return[];const e=[];for(const[r,i]of Object.entries(o)){const{market:s}=$("claude").parsePluginKey(r);for(const a of Array.isArray(i)?i:[])a&&typeof a.installPath=="string"&&e.push({dir:a.installPath,namespace:s})}return e}async function Y(){const n=(await C()).plugins;if(!n||typeof n!="object"||Array.isArray(n))return[];const o=[];for(const[e,r]of Object.entries(n)){const i=Array.isArray(r)?r:[];if(i.length===0)continue;const s=[...i].filter(d=>d&&typeof d.installPath=="string").pop();if(!s?.installPath)continue;const a=await j(l.join(s.installPath,"skills")),{name:u,market:p}=$("claude").parsePluginKey(e);o.push({source:"claude-plugin",label:u,namespace:p,skills:a,pluginKey:e})}return o.sort((e,r)=>e.label.localeCompare(r.label))}async function q(){const t=new Map;for(const o of X())for(const e of await j(o))t.has(e.name)||t.set(e.name,e);return{source:"codex-personal",label:"Codex \xB7 \u4E2A\u4EBA",skills:[...t.values()].sort((o,e)=>o.name.localeCompare(e.name))}}async function H(){const t=P();if(!await m(t))return[];const n=[];let o;try{o=await h(t,{withFileTypes:!0})}catch{return[]}for(const e of o){if(!e.isDirectory()&&!e.isSymbolicLink())continue;const r=l.join(t,e.name);let i;try{i=await h(r,{withFileTypes:!0})}catch{continue}for(const s of i){if(!s.isDirectory()&&!s.isSymbolicLink())continue;const a=l.join(r,s.name);let u;try{u=await h(a,{withFileTypes:!0})}catch{continue}const p=u.filter(w=>w.isDirectory()||w.isSymbolicLink());if(p.length===0)continue;const d=p.map(w=>w.name).sort().pop(),f=await j(l.join(a,d,"skills")),b=`${s.name}@${e.name}`;n.push({source:"codex-plugin",label:s.name,namespace:e.name,skills:f,pluginKey:b})}}return n.sort((e,r)=>e.label.localeCompare(r.label))}async function Q(){const t=S(),n=await readGlobalSkills(),o=[];for(const e of n){const r=l.join(t,e),i=await L(r);i!=="absent"&&o.push({name:e,dir:r,form:i})}return{source:"claude-personal",label:"Claude Code \xB7 \u4E2A\u4EBA",skills:o}}export async function readGlobalSkillGroups(){const[t,n,o,e,r,i]=await Promise.all([Q(),Y(),q(),H(),readClaudePluginEnabled(),readCodexPluginEnabled()]),s=(a,u)=>({...a,enabled:a.pluginKey?u[a.pluginKey]??!1:void 0});return[t,...n.map(a=>s(a,r)),o,...e.map(a=>s(a,i))]}export async function resolveGlobalSkillDir(t,n,o){if(t==="claude-personal"){const f=l.join(S(),n);return await m(f)?f:null}if(t==="codex-personal"){const f=l.join(O(),n);return await m(f)?f:null}if(t==="claude-plugin"){if(!o)return null;const b=(await C()).plugins;if(!b||typeof b!="object"||Array.isArray(b))return null;const w=b[o],F=[...Array.isArray(w)?w:[]].filter(D=>D&&typeof D.installPath=="string").pop();if(!F?.installPath)return null;const A=l.join(F.installPath,"skills",n);return await m(A)?A:null}if(!o)return null;const e=o.lastIndexOf("@");if(e<=0)return null;const r=o.slice(0,e),i=o.slice(e+1),s=l.join(P(),i,r);if(!await m(s))return null;let a;try{a=await h(s,{withFileTypes:!0})}catch{return null}const u=a.filter(f=>f.isDirectory()||f.isSymbolicLink());if(u.length===0)return null;const p=u.map(f=>f.name).sort().pop(),d=l.join(s,p,"skills",n);return await m(d)?d:null}function V(t){const n=l.resolve(t),o=c();return R().find(r=>{const i=[...r.globalSkillsRoots(o)],s=r.pluginCacheDir?.(o);return s&&i.push(s),i.some(a=>n===l.resolve(a)||n.startsWith(l.resolve(a)+l.sep))})?.harness??"claude"}export async function listGlobalSkillFiles(t){const n=V(t),o=[],e=async(r,i)=>{let s;try{s=await h(r,{withFileTypes:!0})}catch{return}for(const a of s){if(a.name.startsWith("."))continue;const u=l.join(r,a.name),p=i?`${i}/${a.name}`:a.name;if((a.isDirectory()||a.isSymbolicLink())&&await m(u))await e(u,p);else if(a.isFile()||a.isSymbolicLink())try{const d=await x(u);d.isFile()&&o.push({absPath:u,relPath:p,category:"skill",agent:n,mtimeMs:d.mtimeMs})}catch{}}};return await e(t,""),o.sort((r,i)=>r.relPath.localeCompare(i.relPath))}export async function readGlobalSkillFile(t,n){const o=l.normalize(n).replace(/\\/g,"/");if(l.isAbsolute(n))throw new g(`Absolute paths are not allowed: "${n}"`);if(o.split("/").some(p=>p===".."))throw new g(`Path traversal is not allowed: "${n}"`);const e=l.join(t,o);let r;try{r=await x(e)}catch{throw new g(`File not found: "${n}"`)}if(!r.isFile())throw new g(`Not a file: "${n}"`);if(r.size>v)throw new W(`File exceeds ${v} bytes: "${n}"`);let i=t,s=e;try{[i,s]=await Promise.all([G(t),G(e)])}catch{throw new g(`File not found: "${n}"`)}const a=i.endsWith(l.sep)?i:i+l.sep;if(s!==i&&!s.startsWith(a))throw new g(`Resolved path escapes the skill directory: "${n}"`);return{content:await E(e,"utf-8"),size:r.size}}export async function readClaudePluginEnabled(){return k("claude").readGlobalEnabled()}export async function writeClaudePluginEnabled(t,n){return k("claude").writeGlobalEnabled(t,n)}export async function readCodexPluginEnabled(){return k("codex").readGlobalEnabled()}export async function writeCodexPluginEnabled(t,n){return k("codex").writeGlobalEnabled(t,n)}export{S as globalSkillsPath,B as claudeJsonPath,M as claudePluginsJsonPath,K as claudeSettingsPath,O as codexSkillsPath,P as codexPluginsCachePath};
1
+ import{readFile as E,readdir as w,access as J,stat as S,realpath as G}from"node:fs/promises";import{homedir as f}from"node:os";import s from"node:path";import{AssetNotFoundError as b}from"./installer.js";import{readClaudeJson as K}from"@weavecode/harness";import{FileTooLargeError as O,MAX_BYTES as v}from"./reader.js";import{assetSurfaceFor as m,assetSurfaces as $,pluginStateFor as k,pluginSurfaceFor as R}from"../surfaces.js";import{installForm as D,linkOrCopy as W,removeInstalled as B}from"../market/install-link.js";export{ClaudeJsonCorruptError}from"@weavecode/harness";const z=".claude.json",N=".claude/plugins/installed_plugins.json";function I(){return s.join(f(),z)}function x(){return m("claude").globalSkillsRoots(f())[0]}function L(t=f()){return s.join(t,N)}function _(){return m("claude").userConfigFile(f())}function T(){return m("codex").globalSkillsRoots(f())[0]}function X(){return m("codex").globalSkillsRoots(f())}function P(){const t=m("codex").pluginCacheDir?.(f());if(!t)throw new Error("codex has no plugin cache surface");return t}export function globalPersonalSkillRootsOwned(){return $().flatMap(t=>t.globalSkillsRoots(f()).map(e=>({harness:t.harness,root:e})))}export function globalPersonalSkillRoots(){return globalPersonalSkillRootsOwned().map(t=>t.root)}async function M(t){try{return await J(t),!0}catch{return!1}}async function y(t){try{return(await S(t)).isDirectory()}catch{return!1}}export function readGlobalClaudeJson(){return K(f())}export async function readGlobalMcpServers(){const t=(await readGlobalClaudeJson()).mcpServers;return!t||typeof t!="object"||Array.isArray(t)?{}:t}export async function writeGlobalMcpServer(t,e){await m("claude").mcpWrite("user","",f(),t,e)}export async function removeGlobalMcpServer(t){await m("claude").mcpRemove("user","",f(),t)}export async function readGlobalSkills(){const t=x();try{const e=await w(t,{withFileTypes:!0}),n=[];for(const a of e)!a.isDirectory()&&!a.isSymbolicLink()||await y(s.join(t,a.name))&&n.push(a.name);return n.sort((a,o)=>a.localeCompare(o))}catch{return[]}}export async function installGlobalSkill(t,e,n="claude"){const a=m(n).globalSkillsRoots(f())[0],o=s.join(a,e);if(await M(o))throw new Error(`Global ${n} skill "${e}" already exists`);return await W(t,o),o}export async function uninstallGlobalSkill(t,e="claude"){const n=m(e).globalSkillsRoots(f())[0];await B(s.join(n,t))}async function j(t=f()){const e=L(t);if(!await M(e))return{};try{const n=JSON.parse(await E(e,"utf-8"));return n&&typeof n=="object"&&!Array.isArray(n)?n:{}}catch{return{}}}async function A(t){if(!await y(t))return[];let e;try{e=await w(t,{withFileTypes:!0})}catch{return[]}const n=[];for(const a of e){if(a.name.startsWith(".")||!a.isDirectory()&&!a.isSymbolicLink())continue;const o=s.join(t,a.name);if(!await y(o))continue;const r=await D(o);r!=="absent"&&n.push({name:a.name,dir:o,form:r})}return n.sort((a,o)=>a.name.localeCompare(o.name))}export async function installedPluginNamespaces(t=f()){const e=(await j(t)).plugins;if(!e||typeof e!="object"||Array.isArray(e))return[];const n=[];for(const[a,o]of Object.entries(e)){const{market:r}=R("claude").parsePluginKey(a);for(const i of Array.isArray(o)?o:[])i&&typeof i.installPath=="string"&&n.push({dir:i.installPath,namespace:r})}return n}async function Y(){const t=(await j()).plugins;if(!t||typeof t!="object"||Array.isArray(t))return[];const e=[];for(const[n,a]of Object.entries(t)){const o=Array.isArray(a)?a:[];if(o.length===0)continue;const r=[...o].filter(p=>p&&typeof p.installPath=="string").pop();if(!r?.installPath)continue;const i=await A(s.join(r.installPath,"skills")),{name:l,market:u}=R("claude").parsePluginKey(n);e.push({source:"claude-plugin",label:l,namespace:u,skills:i,pluginKey:n})}return e.sort((n,a)=>n.label.localeCompare(a.label))}async function q(){const t=new Map;for(const e of X())for(const n of await A(e))t.has(n.name)||t.set(n.name,n);return{source:"codex-personal",label:"Codex \xB7 \u4E2A\u4EBA",skills:[...t.values()].sort((e,n)=>e.name.localeCompare(n.name))}}async function H(){const t=P();if(!await y(t))return[];const e=[];let n;try{n=await w(t,{withFileTypes:!0})}catch{return[]}for(const a of n){if(!a.isDirectory()&&!a.isSymbolicLink())continue;const o=s.join(t,a.name);let r;try{r=await w(o,{withFileTypes:!0})}catch{continue}for(const i of r){if(!i.isDirectory()&&!i.isSymbolicLink())continue;const l=s.join(o,i.name);let u;try{u=await w(l,{withFileTypes:!0})}catch{continue}const p=u.filter(h=>h.isDirectory()||h.isSymbolicLink());if(p.length===0)continue;const d=p.map(h=>h.name).sort().pop(),c=await A(s.join(l,d,"skills")),g=`${i.name}@${a.name}`;e.push({source:"codex-plugin",label:i.name,namespace:a.name,skills:c,pluginKey:g})}}return e.sort((a,o)=>a.label.localeCompare(o.label))}async function Q(){const t=x(),e=await readGlobalSkills(),n=[];for(const a of e){const o=s.join(t,a),r=await D(o);r!=="absent"&&n.push({name:a,dir:o,form:r})}return{source:"claude-personal",label:"Claude Code \xB7 \u4E2A\u4EBA",skills:n}}export async function readGlobalSkillGroups(){const[t,e,n,a,o,r]=await Promise.all([Q(),Y(),q(),H(),readClaudePluginEnabled(),readCodexPluginEnabled()]),i=(l,u)=>({...l,enabled:l.pluginKey?u[l.pluginKey]??!1:void 0});return[t,...e.map(l=>i(l,o)),n,...a.map(l=>i(l,r))]}export async function resolveGlobalSkillDir(t,e,n){if(t==="claude-personal"){const c=s.join(x(),e);return await y(c)?c:null}if(t==="codex-personal"){const c=s.join(T(),e);return await y(c)?c:null}if(t==="claude-plugin"){if(!n)return null;const c=(await j()).plugins;if(!c||typeof c!="object"||Array.isArray(c))return null;const g=c[n],h=[...Array.isArray(g)?g:[]].filter(C=>C&&typeof C.installPath=="string").pop();if(!h?.installPath)return null;const F=s.join(h.installPath,"skills",e);return await y(F)?F:null}if(!n)return null;const a=n.lastIndexOf("@");if(a<=0)return null;const o=n.slice(0,a),r=n.slice(a+1),i=s.join(P(),r,o);if(!await y(i))return null;let l;try{l=await w(i,{withFileTypes:!0})}catch{return null}const u=l.filter(c=>c.isDirectory()||c.isSymbolicLink());if(u.length===0)return null;const p=u.map(c=>c.name).sort().pop(),d=s.join(i,p,"skills",e);return await y(d)?d:null}function U(t){const e=s.resolve(t),n=f();return $().find(a=>{const o=[...a.globalSkillsRoots(n)],r=a.pluginCacheDir?.(n);return r&&o.push(r),o.some(i=>e===s.resolve(i)||e.startsWith(s.resolve(i)+s.sep))})?.harness??"claude"}export async function listGlobalSkillFiles(t){const e=U(t),n=[],a=async(o,r)=>{let i;try{i=await w(o,{withFileTypes:!0})}catch{return}for(const l of i){if(l.name.startsWith("."))continue;const u=s.join(o,l.name),p=r?`${r}/${l.name}`:l.name;if((l.isDirectory()||l.isSymbolicLink())&&await y(u))await a(u,p);else if(l.isFile()||l.isSymbolicLink())try{const d=await S(u);d.isFile()&&n.push({absPath:u,relPath:p,category:"skill",agent:e,mtimeMs:d.mtimeMs})}catch{}}};return await a(t,""),n.sort((o,r)=>o.relPath.localeCompare(r.relPath))}export async function readGlobalSkillFile(t,e){const n=s.normalize(e).replace(/\\/g,"/");if(s.isAbsolute(e))throw new b(`Absolute paths are not allowed: "${e}"`);if(n.split("/").some(u=>u===".."))throw new b(`Path traversal is not allowed: "${e}"`);const a=s.join(t,n);let o;try{o=await S(a)}catch{throw new b(`File not found: "${e}"`)}if(!o.isFile())throw new b(`Not a file: "${e}"`);if(o.size>v)throw new O(`File exceeds ${v} bytes: "${e}"`);let r=t,i=a;try{[r,i]=await Promise.all([G(t),G(a)])}catch{throw new b(`File not found: "${e}"`)}const l=r.endsWith(s.sep)?r:r+s.sep;if(i!==r&&!i.startsWith(l))throw new b(`Resolved path escapes the skill directory: "${e}"`);return{content:await E(a,"utf-8"),size:o.size}}export async function readClaudePluginEnabled(){return k("claude").readGlobalEnabled()}export async function writeClaudePluginEnabled(t,e){return k("claude").writeGlobalEnabled(t,e)}export async function readCodexPluginEnabled(){return k("codex").readGlobalEnabled()}export async function writeCodexPluginEnabled(t,e){return k("codex").writeGlobalEnabled(t,e)}export{x as globalSkillsPath,I as claudeJsonPath,L as claudePluginsJsonPath,_ as claudeSettingsPath,T as codexSkillsPath,P as codexPluginsCachePath};
@@ -1 +1 @@
1
- import{lstat as S,readdir as _,stat as P}from"node:fs/promises";import{homedir as g}from"node:os";import c from"node:path";import{classifyAgent as w,classifyAsset as h}from"../watch/classifier.js";import{PluginModsSniffer as I}from"../watch/plugin-mods.js";import{installedPluginNamespaces as D}from"./global-config.js";const L=["commands","agents","workflows","rules","output-styles","hooks","themes","routines","plugins"],A=["CLAUDE.md","settings.json","settings.local.json"],k=["prompts"],R=["config.toml","AGENTS.md"],T=new Set(["skills","node_modules",".git"]),U=new Set(["marketplaces","data",".in_use"]),y=".claude/plugins",F=`${y}/`,N=6,O=10,$=5e3,j=[{prefix:".claude",dirs:L,files:A},{prefix:".codex",dirs:k,files:R}];async function d(s,n,o){try{const e=await S(s),a=e.isSymbolicLink(),t=a?await P(s):e;if(!t.isFile())return null;let i=h(n);return i==="plugin"&&(i=o.refine(i,n,s)),{absPath:s,relPath:n,category:i,agent:w(n),mtimeMs:t.mtimeMs,...a?{isSymlink:!0}:{}}}catch{return null}}async function f(s,n,o,e,a){if(o>e)return[];let t;try{t=await _(s,{withFileTypes:!0})}catch{return[]}return(await Promise.all(t.map(async l=>{const u=c.join(s,l.name),r=`${n}/${l.name}`;if(l.isDirectory())return E(r,l.name)?[]:f(u,r,o+1,e,a);if(l.isSymbolicLink())try{if((await P(u)).isDirectory())return E(r,l.name)?[]:f(u,r,o+1,e,a)}catch{return[]}const m=await d(u,r,a);return m?[m]:[]}))).flat()}function E(s,n){return T.has(n)?!0:s.startsWith(F)&&U.has(n)}export async function listGlobalFileAssets(s=g()){const n=new I({revalidate:!1}),e=(await Promise.all(j.map(async t=>{const i=c.join(s,...t.prefix.split("/")),[l,u]=await Promise.all([Promise.all(t.files.map(r=>d(c.join(i,r),`${t.prefix}/${r}`,n))),Promise.all(t.dirs.map(r=>{const m=`${t.prefix}/${r}`,p=m===y?O:N;return f(c.join(i,r),m,1,p,n)}))]);return[...l.filter(r=>r!==null),...u.flat()]}))).flat(),a=await D(s);return e.sort((t,i)=>t.relPath.localeCompare(i.relPath)),e.slice(0,$).map(t=>{const i=x(t.absPath,a);return i?{...t,namespace:i}:t})}function x(s,n){let o;for(const e of n){const a=c.relative(c.resolve(e.dir),c.resolve(s));a===""||a.startsWith("..")||c.isAbsolute(a)||(!o||e.dir.length>o.dir.length)&&(o=e)}return o?.namespace}
1
+ import{lstat as g,readdir as w,stat as f}from"node:fs/promises";import{homedir as P}from"node:os";import l from"node:path";import{classifyAgent as k,classifyAsset as x}from"../watch/classifier.js";import{PluginModsSniffer as S}from"../watch/plugin-mods.js";import{installedPluginNamespaces as $}from"./global-config.js";const j=["commands","agents","workflows","rules","output-styles","hooks","themes","routines","plugins"],A=["CLAUDE.md","settings.json","settings.local.json"],b=["prompts"],v=["config.toml","AGENTS.md"],D=new Set(["skills","node_modules",".git"]),F=new Set(["marketplaces","data",".in_use"]),p=".claude/plugins",L=`${p}/`,E=6,M=10,N=5e3,T=[{prefix:".claude",dirs:j,files:A},{prefix:".codex",dirs:b,files:v}];async function d(e,i,s){try{const o=await g(e),t=o.isSymbolicLink(),a=t?await f(e):o;if(!a.isFile())return null;let r=x(i);return r==="plugin"&&(r=s.refine(r,i,e)),{absPath:e,relPath:i,category:r,agent:k(i),mtimeMs:a.mtimeMs,...t?{isSymlink:!0}:{}}}catch{return null}}async function u(e,i,s,o,t){if(s>o)return[];let a;try{a=await w(e,{withFileTypes:!0})}catch{return[]}return(await Promise.all(a.map(async r=>{const m=l.join(e,r.name),n=`${i}/${r.name}`;if(r.isDirectory())return h(n,r.name)?[]:u(m,n,s+1,o,t);if(r.isSymbolicLink())try{if((await f(m)).isDirectory())return h(n,r.name)?[]:u(m,n,s+1,o,t)}catch{return[]}const c=await d(m,n,t);return c?[c]:[]}))).flat()}function h(e,i){return D.has(i)?!0:e.startsWith(L)&&F.has(i)}export async function listGlobalFileAssets(e=P()){const i=new S({revalidate:!1}),s=(await Promise.all(T.map(async t=>{const a=l.join(e,...t.prefix.split("/")),[r,m]=await Promise.all([Promise.all(t.files.map(n=>d(l.join(a,n),`${t.prefix}/${n}`,i))),Promise.all(t.dirs.map(n=>{const c=`${t.prefix}/${n}`,y=c===p?M:E;return u(l.join(a,n),c,1,y,i)}))]);return[...r.filter(n=>n!==null),...m.flat()]}))).flat(),o=await $(e);return s.sort((t,a)=>t.relPath.localeCompare(a.relPath)),s.slice(0,N).map(t=>{const a=_(t.absPath,o);return a?{...t,namespace:a}:t})}function _(e,i){let s;for(const o of i){const t=l.relative(l.resolve(o.dir),l.resolve(e));t===""||t.startsWith("..")||l.isAbsolute(t)||(!s||o.dir.length>s.dir.length)&&(s=o)}return s?.namespace}
@@ -1,2 +1,2 @@
1
- import{mkdir as y,readFile as m,writeFile as g}from"node:fs/promises";import l from"node:path";import{DEFAULT_HOOKS as f,DEFAULT_MCP as w,HARNESS_KEYS as C,detectPlatform as E,isHarness as x,resolveComponents as O}from"@weavecode/core";import{WEAVE_CONTENT_MARKER as h,generateInitFiles as S}from"@weavecode/harness";import{gitClassify as k}from"./git-classify.js";import{generateStatuslineScript as F}from"../statusline/generator.js";import{readStatuslineConfig as v,statuslineScriptRelPath as A}from"../statusline/manager.js";import{WEAVE_VERSION as P}from"../version.js";function b(t){const e={};for(const o of t.split(`
2
- `)){const n=o.indexOf(":");if(n<=0)continue;const s=o.slice(0,n).trim(),i=o.slice(n+1).trim();if(s)try{e[s]=JSON.parse(i)}catch{e[s]=i}}return e}function I(t){if(typeof t!="object"||t===null)return f;const e=t,o=Object.fromEntries(Object.keys(f).filter(n=>typeof f[n]=="boolean"&&!(n in e)).map(n=>[n,!1]));return{...f,...o,...e}}export async function readInitRuntime(t){let e;try{e=await m(l.join(t,".weave","config.yaml"),"utf-8")}catch{e=""}const o=b(e),n=o.preset,s=o.components,i=o.hooks,a=o.mcp,c=o.harnesses;return{initVersion:typeof o.initVersion=="string"?o.initVersion:null,preset:n==="minimal"||n==="full"||n==="default"?n:"default",harnesses:Array.isArray(c)?c.filter(x):[],components:O(n==="minimal"||n==="full"||n==="default"?n:"default",typeof s=="object"&&s!==null?s:void 0),hooks:I(i),mcp:{...w,...typeof a=="object"&&a!==null?a:{}}}}function R(){return E()}function V(t,e){return{projectPath:t,version:P,platform:R(),components:e.components,hooks:e.hooks,mcp:e.mcp}}async function _(t,e){if(!e.components.helpers)return[];const o=await v(t);return[{relPath:A(),weaveMarker:h,content:F(o)}]}async function N(t){try{return await m(t,"utf-8")}catch{return null}}function H(t,e){return t.merge?e===null?t.content:t.merge(e,t.content):e!==null&&!e.includes(t.weaveMarker??h)?null:t.content}async function M(t){try{return await m(l.join(t,".weave","config.yaml"),"utf-8"),!0}catch{return!1}}export async function detectInitFileUpdates(t){if(!await M(t))return[];const e=await readInitRuntime(t),o=V(t,e),n=e.harnesses.length>0?e.harnesses:[C[0]],s=[...await _(t,e)];for(const r of n)s.push(...await S(r,o));const i=[];for(const r of s){const p=l.join(t,...r.relPath.split("/")),d=await N(p),u=H(r,d);i.push({relPath:r.relPath,targetPath:p,outdated:u!==null&&u!==d,syncClass:null,expectedContent:u})}const a=i.filter(r=>r.outdated),c=await k(t,a.map(r=>r.relPath));for(const r of a)r.syncClass=c.classOf(r.relPath);return i}export async function applyInitFile(t){return t.syncClass!=="auto"||!t.outdated||t.expectedContent===null?!1:(await y(l.dirname(t.targetPath),{recursive:!0}),await g(t.targetPath,t.expectedContent,"utf-8"),!0)}export function needsInit(t){return t.some(e=>e.syncClass==="manual"&&e.outdated)}
1
+ import{mkdir as y,readFile as p,writeFile as w}from"node:fs/promises";import l from"node:path";import{DEFAULT_HOOKS as u,DEFAULT_MCP as g,HARNESS_KEYS as P,detectPlatform as C,isHarness as E,resolveComponents as S}from"@weavecode/core";import{WEAVE_CONTENT_MARKER as h,generateInitFiles as O}from"@weavecode/harness";import{gitClassify as j}from"./git-classify.js";import{generateStatuslineScript as k}from"../statusline/generator.js";import{readStatuslineConfig as v,statuslineScriptRelPath as x}from"../statusline/manager.js";import{WEAVE_VERSION as A}from"../version.js";function F(t){const e={};for(const r of t.split(`
2
+ `)){const n=r.indexOf(":");if(n<=0)continue;const a=r.slice(0,n).trim(),s=r.slice(n+1).trim();if(a)try{e[a]=JSON.parse(s)}catch{e[a]=s}}return e}function b(t){if(typeof t!="object"||t===null)return u;const e=t,r=Object.fromEntries(Object.keys(u).filter(n=>typeof u[n]=="boolean"&&!(n in e)).map(n=>[n,!1]));return{...u,...r,...e}}export async function readInitRuntime(t){let e;try{e=await p(l.join(t,".weave","config.yaml"),"utf-8")}catch{e=""}const r=F(e),n=r.preset,a=r.components,s=r.hooks,i=r.mcp,c=r.harnesses;return{initVersion:typeof r.initVersion=="string"?r.initVersion:null,preset:n==="minimal"||n==="full"||n==="default"?n:"default",harnesses:Array.isArray(c)?c.filter(E):[],components:S(n==="minimal"||n==="full"||n==="default"?n:"default",typeof a=="object"&&a!==null?a:void 0),hooks:b(s),mcp:{...g,...typeof i=="object"&&i!==null?i:{}}}}function I(){return C()}function R(t,e){return{projectPath:t,version:A,platform:I(),components:e.components,hooks:e.hooks,mcp:e.mcp}}async function V(t,e){if(!e.components.helpers)return[];const r=await v(t);return[{relPath:x(),weaveMarker:h,content:k(r)}]}async function _(t){try{return await p(t,"utf-8")}catch{return null}}function N(t,e){return t.merge?e===null?t.content:t.merge(e,t.content):e!==null&&!e.includes(t.weaveMarker??h)?null:t.content}async function M(t){try{return await p(l.join(t,".weave","config.yaml"),"utf-8"),!0}catch{return!1}}export async function detectInitFileUpdates(t){if(!await M(t))return[];const e=await readInitRuntime(t),r=R(t,e),n=e.harnesses.length>0?e.harnesses:[P[0]],a=[...await V(t,e)];for(const o of n)a.push(...await O(o,r));const s=[];for(const o of a){const m=l.join(t,...o.relPath.split("/")),d=await _(m),f=N(o,d);s.push({relPath:o.relPath,targetPath:m,outdated:f!==null&&f!==d,syncClass:null,expectedContent:f})}const i=s.filter(o=>o.outdated),c=await j(t,i.map(o=>o.relPath));for(const o of i)o.syncClass=c.classOf(o.relPath);return s}export async function applyInitFile(t){return t.syncClass!=="auto"||!t.outdated||t.expectedContent===null?!1:(await y(l.dirname(t.targetPath),{recursive:!0}),await w(t.targetPath,t.expectedContent,"utf-8"),!0)}export function needsInit(t){return t.some(e=>e.syncClass==="manual"&&e.outdated)}
@@ -1,2 +1,2 @@
1
- import{mkdir as c,readFile as l,writeFile as y}from"node:fs/promises";import r from"node:path";const i=r.join(".weave","installed.json"),s=t=>[t.category,t.name,t.agent,t.assetCategory??""].join("\0");function g(t){if(!t||typeof t!="object")return!1;const e=t;return(e.category==="skill"||e.category==="mcp"||e.category==="file")&&typeof e.name=="string"&&e.name!==""&&typeof e.agent=="string"}export async function readInstalledLedger(t){try{const e=JSON.parse(await l(r.join(t,i),"utf-8"));return Array.isArray(e.assets)?e.assets.filter(g):[]}catch{return[]}}export async function recordInstalled(t,e){const n=await readInstalledLedger(t);n.some(a=>s(a)===s(e))||await o(t,[...n,e])}export async function forgetInstalled(t,e){const n=await readInstalledLedger(t),a=n.filter(f=>s(f)!==s(e));a.length!==n.length&&await o(t,a)}async function o(t,e){const n=r.join(t,i);await c(r.dirname(n),{recursive:!0}),await y(n,`${JSON.stringify({version:1,assets:e},null,2)}
1
+ import{mkdir as l,readFile as f,writeFile as y}from"node:fs/promises";import r from"node:path";const i=r.join(".weave","installed.json"),s=e=>[e.category,e.name,e.agent,e.assetCategory??""].join("\0");function g(e){if(!e||typeof e!="object")return!1;const t=e;return(t.category==="skill"||t.category==="mcp"||t.category==="file")&&typeof t.name=="string"&&t.name!==""&&typeof t.agent=="string"}export async function readInstalledLedger(e){try{const t=JSON.parse(await f(r.join(e,i),"utf-8"));return Array.isArray(t.assets)?t.assets.filter(g):[]}catch{return[]}}export async function recordInstalled(e,t){const n=await readInstalledLedger(e);n.some(a=>s(a)===s(t))||await o(e,[...n,t])}export async function forgetInstalled(e,t){const n=await readInstalledLedger(e),a=n.filter(c=>s(c)!==s(t));a.length!==n.length&&await o(e,a)}async function o(e,t){const n=r.join(e,i);await l(r.dirname(n),{recursive:!0}),await y(n,`${JSON.stringify({version:1,assets:t},null,2)}
2
2
  `,"utf-8")}
@@ -1 +1 @@
1
- import{cp as p,rm as k,readFile as C,access as F,mkdir as g}from"node:fs/promises";import{homedir as c}from"node:os";import n from"node:path";import{FILE_ASSET_SPECS as x,fileAssetTargetDir as y}from"./file-assets.js";import{assetSurfaceFor as l}from"../surfaces.js";import{forgetInstalled as d,recordInstalled as w}from"./install-ledger.js";import{installForm as $,removeInstalled as v}from"../market/install-link.js";export class InstallConflictError extends Error{constructor(r){super(r),this.name="InstallConflictError"}}export class AssetNotFoundError extends Error{constructor(r){super(r),this.name="AssetNotFoundError"}}function u(t){if(!t||t.includes("/")||t.includes("\\")||t.includes("..")||t.includes(n.sep))throw new Error(`Invalid asset name: "${t}"`)}async function S(t){try{return await F(t),!0}catch{return!1}}function E(t){return l(t).projectSkillsRoots()}export async function installSkill(t,r,o,i="claude"){u(o);const e=E(i);for(const a of e)if(await $(n.join(t,a,o))!=="absent")throw new InstallConflictError(`Skill "${o}" is already installed${i==="codex"?" (Codex)":""}`);const s=n.join(t,e[0],o);return await p(r,s,{recursive:!0}),await w(t,{category:"skill",name:o,agent:i}),s}export async function uninstallSkill(t,r,o="claude"){u(r);let i;for(const e of E(o)){const s=n.join(t,e,r);if(await $(s)!=="absent"){i=s;break}}if(!i)throw new AssetNotFoundError(`Skill "${r}" is not installed${o==="codex"?" (Codex)":""}`);await v(i),await d(t,{category:"skill",name:r,agent:o})}export async function installFileAsset(t,r,o,i,e="claude",s="project"){u(o);const a=y(r,e,s,t,c()),f=n.join(a,`${o}${x[r].ext}`);if(await S(f))throw new InstallConflictError(`${r} "${o}" is already installed`);return await g(a,{recursive:!0}),await p(i,f),s==="project"&&await w(t,{category:"file",name:o,agent:e,assetCategory:r}),f}export async function uninstallFileAsset(t,r,o,i="claude",e="project"){u(o);const s=y(r,i,e,t,c()),a=n.join(s,`${o}${x[r].ext}`);if(!await S(a))throw new AssetNotFoundError(`${r} "${o}" is not installed`);await k(a,{force:!0}),e==="project"&&await d(t,{category:"file",name:o,agent:i,assetCategory:r})}export async function installMcp(t,r,o){if(r in await readMcpServers(t))throw new InstallConflictError(`MCP server "${r}" is already configured`);await l("claude").mcpWrite("project",t,c(),r,o),await w(t,{category:"mcp",name:r,agent:"claude"})}export async function uninstallMcp(t,r){if(!await l("claude").mcpRemove("project",t,c(),r))throw new AssetNotFoundError(`MCP server "${r}" is not configured`);await d(t,{category:"mcp",name:r,agent:"claude"})}export async function readMcpJson(t){try{const r=await C(t,"utf-8"),o=JSON.parse(r);return o&&typeof o=="object"?o:{}}catch{return{}}}export async function readMcpServers(t){return l("claude").mcpRead("project",t,c())}
1
+ import{cp as w,rm as j,readFile as S,access as h,mkdir as E}from"node:fs/promises";import{homedir as c}from"node:os";import i from"node:path";import{FILE_ASSET_SPECS as m,fileAssetTargetDir as y}from"./file-assets.js";import{assetSurfaceFor as l}from"../surfaces.js";import{forgetInstalled as d,recordInstalled as p}from"./install-ledger.js";import{installForm as g,removeInstalled as k}from"../market/install-link.js";export class InstallConflictError extends Error{constructor(a){super(a),this.name="InstallConflictError"}}export class AssetNotFoundError extends Error{constructor(a){super(a),this.name="AssetNotFoundError"}}function u(e){if(!e||e.includes("/")||e.includes("\\")||e.includes("..")||e.includes(i.sep))throw new Error(`Invalid asset name: "${e}"`)}async function x(e){try{return await h(e),!0}catch{return!1}}function $(e){return l(e).projectSkillsRoots()}export async function installSkill(e,a,t,n="claude"){u(t);const r=$(n);for(const o of r)if(await g(i.join(e,o,t))!=="absent")throw new InstallConflictError(`Skill "${t}" is already installed${n==="codex"?" (Codex)":""}`);const s=i.join(e,r[0],t);return await w(a,s,{recursive:!0}),await p(e,{category:"skill",name:t,agent:n}),s}export async function uninstallSkill(e,a,t="claude"){u(a);let n;for(const r of $(t)){const s=i.join(e,r,a);if(await g(s)!=="absent"){n=s;break}}if(!n)throw new AssetNotFoundError(`Skill "${a}" is not installed${t==="codex"?" (Codex)":""}`);await k(n),await d(e,{category:"skill",name:a,agent:t})}export async function installFileAsset(e,a,t,n,r="claude",s="project"){u(t);const o=y(a,r,s,e,c()),f=i.join(o,`${t}${m[a].ext}`);if(await x(f))throw new InstallConflictError(`${a} "${t}" is already installed`);return await E(o,{recursive:!0}),await w(n,f),s==="project"&&await p(e,{category:"file",name:t,agent:r,assetCategory:a}),f}export async function uninstallFileAsset(e,a,t,n="claude",r="project"){u(t);const s=y(a,n,r,e,c()),o=i.join(s,`${t}${m[a].ext}`);if(!await x(o))throw new AssetNotFoundError(`${a} "${t}" is not installed`);await j(o,{force:!0}),r==="project"&&await d(e,{category:"file",name:t,agent:n,assetCategory:a})}export async function installMcp(e,a,t){if(a in await readMcpServers(e))throw new InstallConflictError(`MCP server "${a}" is already configured`);await l("claude").mcpWrite("project",e,c(),a,t),await p(e,{category:"mcp",name:a,agent:"claude"})}export async function uninstallMcp(e,a){if(!await l("claude").mcpRemove("project",e,c(),a))throw new AssetNotFoundError(`MCP server "${a}" is not configured`);await d(e,{category:"mcp",name:a,agent:"claude"})}export async function readMcpJson(e){try{const a=await S(e,"utf-8"),t=JSON.parse(a);return t&&typeof t=="object"?t:{}}catch{return{}}}export async function readMcpServers(e){return l("claude").mcpRead("project",e,c())}
@@ -1 +1 @@
1
- import{getLibraryScan as u}from"./scan-cache.js";export async function buildLibraryIndex(e){const a=new Map,r=new Map,s=new Map;for(const t of e){const m=t.kind==="skill"||t.kind==="both",p=t.kind==="mcp"||t.kind==="both";let o;try{o=await u(t.path)}catch{continue}if(m){for(const n of o.skills)a.has(n.name)||a.set(n.name,{name:n.name,libraryId:t.id,libraryPath:t.path,dirPath:n.dirPath});for(const n of Object.values(o.files))for(const i of n){const c=`${i.category}/${i.name}`;s.has(c)||s.set(c,{name:i.name,category:i.category,libraryId:t.id,libraryPath:t.path,filePath:i.filePath})}}if(p){for(const n of o.mcp)if(!r.has(n.name)){const{name:i,command:c,args:f,env:l,sourcePath:d}=n,h={command:c,...f&&{args:f},...l&&{env:l}};r.set(n.name,{name:i,libraryId:t.id,libraryPath:t.path,config:h,sourcePath:d})}}}return{skills:a,mcp:r,files:s}}export function findSkillSource(e,a){return e.skills.get(a)}export function findMcpSource(e,a){return e.mcp.get(a)}export function findFileAssetSource(e,a,r){return e.files.get(`${a}/${r}`)}
1
+ import{getLibraryScan as u}from"./scan-cache.js";export async function buildLibraryIndex(e){const a=new Map,i=new Map,s=new Map;for(const n of e){const m=n.kind==="skill"||n.kind==="both",d=n.kind==="mcp"||n.kind==="both";let o;try{o=await u(n.path)}catch{continue}if(m){for(const t of o.skills)a.has(t.name)||a.set(t.name,{name:t.name,libraryId:n.id,libraryPath:n.path,dirPath:t.dirPath});for(const t of Object.values(o.files))for(const r of t){const c=`${r.category}/${r.name}`;s.has(c)||s.set(c,{name:r.name,category:r.category,libraryId:n.id,libraryPath:n.path,filePath:r.filePath})}}if(d){for(const t of o.mcp)if(!i.has(t.name)){const{name:r,command:c,args:f,env:l,sourcePath:h}=t,p={command:c,...f&&{args:f},...l&&{env:l}};i.set(t.name,{name:r,libraryId:n.id,libraryPath:n.path,config:p,sourcePath:h})}}}return{skills:a,mcp:i,files:s}}export function findSkillSource(e,a){return e.skills.get(a)}export function findMcpSource(e,a){return e.mcp.get(a)}export function findFileAssetSource(e,a,i){return e.files.get(`${a}/${i}`)}
@@ -1 +1 @@
1
- import{homedir as u}from"node:os";import{readMcpEnableMap as m,mcpOverrideOf as d,resolveMcpEffective as h}from"./settings-mcp.js";import{assetSurfaces as n}from"../surfaces.js";import{BUILTIN_MCP_SERVERS as b}from"./builtin-mcp.js";import{readDaemonState as S}from"../daemon/state.js";export async function readMcpRows(c){const f=await m(c),t=[];for(const e of n()){const o=e.mcpScopes();for(const s of o){const r=e.harness==="claude"&&s==="project"?f:null,l=await e.mcpRead(s,c,u()).catch(()=>({}));for(const[a,p]of Object.entries(l))t.push({key:a,category:"mcp",harness:e.harness,scope:s,installScopes:o,enable:r?d(r,a):null,effective:r?h(r,a):!0,detail:p})}}const i=S()?.port;for(const e of n())for(const o of b)e.harness==="claude"&&(t.some(s=>s.harness==="claude"&&s.key===o.name)||t.push({key:o.name,category:"mcp",harness:"claude",scope:"user",installScopes:["user"],install:"absent",enable:null,effective:!1,detail:{url:`http://127.0.0.1:${i??6420}${o.path}`},builtin:!0}));return t}
1
+ import{homedir as m}from"node:os";import{readMcpEnableMap as u,mcpOverrideOf as d,resolveMcpEffective as h}from"./settings-mcp.js";import{assetSurfaces as n}from"../surfaces.js";import{BUILTIN_MCP_SERVERS as S}from"./builtin-mcp.js";import{readDaemonState as b}from"../daemon/state.js";export async function readMcpRows(c){const p=await u(c),o=[];for(const e of n()){const s=e.mcpScopes();for(const a of s){const t=e.harness==="claude"&&a==="project"?p:null,l=await e.mcpRead(a,c,m()).catch(()=>({}));for(const[r,i]of Object.entries(l))o.push({key:r,category:"mcp",harness:e.harness,scope:a,installScopes:s,enable:t?d(t,r):null,effective:t?h(t,r):!0,detail:i})}}const f=b()?.port;for(const e of n())for(const s of S)e.harness==="claude"&&(o.some(a=>a.harness==="claude"&&a.key===s.name)||o.push({key:s.name,category:"mcp",harness:"claude",scope:"user",installScopes:["user"],install:"absent",enable:null,effective:!1,detail:{url:`http://127.0.0.1:${f??6420}${s.path}`},builtin:!0}));return o}
@@ -1 +1 @@
1
- import t from"node:path";import{marketIdOf as o}from"../market/identity.js";import{marketDir as e}from"../market/manifest.js";export async function installPluginPack(n,r){const i=o(r.dir);return n.globalInstall(r.dir,{name:r.name,version:r.version,description:r.description,...i?{marketplace:{name:i,dir:t.join(e(),i)}}:{}})}
1
+ import r from"node:path";import{marketIdOf as t}from"../market/identity.js";import{marketDir as a}from"../market/manifest.js";export async function installPluginPack(o,i){const n=t(i.dir);return o.globalInstall(i.dir,{name:i.name,version:i.version,description:i.description,...n?{marketplace:{name:n,dir:r.join(a(),n)}}:{}})}
@@ -1 +1 @@
1
- import{pluginSurfaces as b,pluginStateSurfaces as g}from"../surfaces.js";const u=["user","project","local"],v=(s,e)=>e in s?s[e]?"on":"off":"inherit";function y(s,e){for(let n=u.length-1;n>=0;n--){const o=s[u[n]][e];if(o!==void 0)return o}return!1}export async function readPluginRows(s){const e=[],n=b();for(const{harness:o,surface:a}of n){const l=a.pluginScopes(),[t,c]=await Promise.all([a.readInstalled().catch(()=>({})),a.readEnabledOverrides(s).catch(()=>({user:{},project:{},local:{}}))]),p=new Set(Object.keys(t));for(const r of u)for(const f of Object.keys(c[r]))p.add(f);for(const r of p){const f=t[r],d=y(c,r);for(const i of l)e.push({key:r,category:"plugin",harness:o,scope:i,installScopes:l,install:f?.some(h=>(h.scope??"user")===i)?"installed":"absent",enable:v(c[i],r),effective:d})}}for(const{harness:o,state:a}of g()){if(n.some(t=>t.harness===o))continue;const l=await a.readGlobalEnabled().catch(()=>({}));for(const[t,c]of Object.entries(l))e.push({key:t,category:"plugin",harness:o,scope:"user",installScopes:[],enable:c?"on":"off",effective:c})}return e}
1
+ import{pluginSurfaces as b,pluginStateSurfaces as g}from"../surfaces.js";const u=["user","project","local"],y=(s,e)=>e in s?s[e]?"on":"off":"inherit";function S(s,e){for(let n=u.length-1;n>=0;n--){const o=s[u[n]][e];if(o!==void 0)return o}return!1}export async function readPluginRows(s){const e=[],n=b();for(const{harness:o,surface:a}of n){const f=a.pluginScopes(),[t,c]=await Promise.all([a.readInstalled().catch(()=>({})),a.readEnabledOverrides(s).catch(()=>({user:{},project:{},local:{}}))]),p=new Set(Object.keys(t));for(const r of u)for(const l of Object.keys(c[r]))p.add(l);for(const r of p){const l=t[r],d=S(c,r);for(const i of f)e.push({key:r,category:"plugin",harness:o,scope:i,installScopes:f,install:l?.some(h=>(h.scope??"user")===i)?"installed":"absent",enable:y(c[i],r),effective:d})}}for(const{harness:o,state:a}of g()){if(n.some(t=>t.harness===o))continue;const f=await a.readGlobalEnabled().catch(()=>({}));for(const[t,c]of Object.entries(f))e.push({key:t,category:"plugin",harness:o,scope:"user",installScopes:[],enable:c?"on":"off",effective:c})}return e}
@@ -1 +1 @@
1
- import{cp as f,mkdir as d,readdir as P,readFile as h,rm as w}from"node:fs/promises";import{homedir as y}from"node:os";import a from"node:path";import{WEAVE_PLUGIN_MANIFEST as k,WeavePluginManifestSchema as v}from"@weavecode/core";import{assetSurfaceFor as E}from"../surfaces.js";const T={skills:"skill",commands:"command",agents:"agent"};async function j(t){const e=[];let s;try{s=await P(t)}catch{return e}for(const o of s){const i=a.join(t,o);try{const c=JSON.parse(await h(a.join(i,k),"utf8")),r=v.safeParse(c);r.success&&e.push({dir:i,manifest:r.data})}catch{}}return e}function S(t,e,s){const o=[];if(!s.templates)return o;const i=E("claude"),c=a.join(t,...i.projectSkillsRoots()[0].split("/"));for(const[r,l]of Object.entries(s.templates)){const n=T[r];if(n)for(const p of l??[]){const u=a.resolve(e,p);if(!u.startsWith(a.resolve(e)+a.sep))continue;const m=a.basename(u),g=n==="skill"?c:i.targetDir(n,"project",t,y());o.push({pluginId:s.id,category:n,name:m.replace(/\.md$/,""),sourcePath:u,targetPath:a.join(g,m)})}}return o}export async function detectPluginTemplateUpdates(t,e){const s=[],o=a.join(t,".weave","plugins");for(const{dir:i,manifest:c}of await j(o))for(const r of S(t,i,c)){const[l,n]=r.category==="skill"?await Promise.all([e.get(r.sourcePath),e.get(r.targetPath)]):await Promise.all([e.getFile(r.sourcePath),e.getFile(r.targetPath)]);s.push({...r,outdated:l!==n})}return s}export async function materializePluginTemplate(t){if(t.category==="skill"){await w(t.targetPath,{recursive:!0,force:!0}),await f(t.sourcePath,t.targetPath,{recursive:!0});return}await d(a.dirname(t.targetPath),{recursive:!0}),await f(t.sourcePath,t.targetPath)}
1
+ import{cp as f,mkdir as h,readdir as d,readFile as P,rm as w}from"node:fs/promises";import{homedir as j}from"node:os";import r from"node:path";import{WEAVE_PLUGIN_MANIFEST as y,WeavePluginManifestSchema as k}from"@weavecode/core";import{assetSurfaceFor as v}from"../surfaces.js";const S={skills:"skill",commands:"command",agents:"agent"};async function F(t){const a=[];let s;try{s=await d(t)}catch{return a}for(const o of s){const i=r.join(t,o);try{const c=JSON.parse(await P(r.join(i,y),"utf8")),e=k.safeParse(c);e.success&&a.push({dir:i,manifest:e.data})}catch{}}return a}function E(t,a,s){const o=[];if(!s.templates)return o;const i=v("claude"),c=r.join(t,...i.projectSkillsRoots()[0].split("/"));for(const[e,l]of Object.entries(s.templates)){const n=S[e];if(n)for(const p of l??[]){const u=r.resolve(a,p);if(!u.startsWith(r.resolve(a)+r.sep))continue;const m=r.basename(u),g=n==="skill"?c:i.targetDir(n,"project",t,j());o.push({pluginId:s.id,category:n,name:m.replace(/\.md$/,""),sourcePath:u,targetPath:r.join(g,m)})}}return o}export async function detectPluginTemplateUpdates(t,a){const s=[],o=r.join(t,".weave","plugins");for(const{dir:i,manifest:c}of await F(o))for(const e of E(t,i,c)){const[l,n]=e.category==="skill"?await Promise.all([a.get(e.sourcePath),a.get(e.targetPath)]):await Promise.all([a.getFile(e.sourcePath),a.getFile(e.targetPath)]);s.push({...e,outdated:l!==n})}return s}export async function materializePluginTemplate(t){if(t.category==="skill"){await w(t.targetPath,{recursive:!0,force:!0}),await f(t.sourcePath,t.targetPath,{recursive:!0});return}await h(r.dirname(t.targetPath),{recursive:!0}),await f(t.sourcePath,t.targetPath)}
@@ -1,2 +1,2 @@
1
- import{readFile as a,writeFile as e,mkdir as s}from"node:fs/promises";import i from"node:path";const c=".weave",f="config.json";export const DEFAULT_PROJECT_CONFIG={lastSyncAt:null};function o(t){return i.join(t,c,f)}function u(t){return{lastSyncAt:t.lastSyncAt??DEFAULT_PROJECT_CONFIG.lastSyncAt}}export async function readProjectConfig(t){try{const n=await a(o(t),"utf-8");return u(JSON.parse(n))}catch{return DEFAULT_PROJECT_CONFIG}}export async function writeProjectConfig(t,n){const r=i.join(t,c);await s(r,{recursive:!0}),await e(o(t),`${JSON.stringify(n,null,2)}
1
+ import{readFile as i,writeFile as e,mkdir as s}from"node:fs/promises";import a from"node:path";const o=".weave",u="config.json";export const DEFAULT_PROJECT_CONFIG={lastSyncAt:null};function c(t){return a.join(t,o,u)}function f(t){return{lastSyncAt:t.lastSyncAt??DEFAULT_PROJECT_CONFIG.lastSyncAt}}export async function readProjectConfig(t){try{const n=await i(c(t),"utf-8");return f(JSON.parse(n))}catch{return DEFAULT_PROJECT_CONFIG}}export async function writeProjectConfig(t,n){const r=a.join(t,o);await s(r,{recursive:!0}),await e(c(t),`${JSON.stringify(n,null,2)}
2
2
  `,"utf-8")}export async function markSynced(t,n){const r=await readProjectConfig(t);await writeProjectConfig(t,{...r,lastSyncAt:n})}
@@ -1 +1 @@
1
- import{readFile as p,stat as w}from"node:fs/promises";import{homedir as d}from"node:os";import r from"node:path";import{AssetNotFoundError as a}from"./installer.js";import{assetSurfaces as f}from"../surfaces.js";export class PathEscapeError extends Error{constructor(o){super(o),this.name="PathEscapeError"}}export class FileTooLargeError extends Error{constructor(o){super(o),this.name="FileTooLargeError"}}export const MAX_BYTES=512*1024;export function resolveWithinProject(e,o){const t=r.normalize(o).replace(/\\/g,"/");if(r.isAbsolute(o))throw new PathEscapeError(`Absolute paths are not allowed: "${o}"`);if(t.split("/").some(i=>i===".."))throw new PathEscapeError(`Path traversal is not allowed: "${o}"`);const s=r.join(e,t),n=e.endsWith(r.sep)?e:e+r.sep;if(s!==e&&!s.startsWith(n))throw new PathEscapeError(`Resolved path escapes the project: "${o}"`);return s}export function resolveProjectFile(e,o){const t=r.normalize(o).replace(/\\/g,"/"),s=f().flatMap(c=>c.projectSkillsRoots().map(l=>l.split("/")[0])),n=t.split("/")[0]??"";if(!(t===".mcp.json"||t==="CLAUDE.md"||t==="AGENTS.md"||s.includes(n)||t===".weave"||t.startsWith(".weave/")))throw new PathEscapeError(`Path is outside the allowed roots: "${o}"`);return resolveWithinProject(e,t)}export async function readProjectFile(e,o){const t=resolveProjectFile(e,o);let s;try{s=await w(t)}catch{throw new a(`File not found: "${o}"`)}if(!s.isFile())throw new a(`Not a file: "${o}"`);if(s.size>MAX_BYTES)throw new FileTooLargeError(`File exceeds ${MAX_BYTES} bytes: "${o}"`);return{content:await p(t,"utf-8"),size:s.size}}export async function readGlobalFile(e){return readProjectFile(d(),e)}
1
+ import{readFile as c,stat as p}from"node:fs/promises";import{homedir as h}from"node:os";import s from"node:path";import{AssetNotFoundError as n}from"./installer.js";import{assetSurfaces as w}from"../surfaces.js";export class PathEscapeError extends Error{constructor(t){super(t),this.name="PathEscapeError"}}export class FileTooLargeError extends Error{constructor(t){super(t),this.name="FileTooLargeError"}}export const MAX_BYTES=512*1024;export function resolveWithinProject(e,t){const r=s.normalize(t).replace(/\\/g,"/");if(s.isAbsolute(t))throw new PathEscapeError(`Absolute paths are not allowed: "${t}"`);if(r.split("/").some(i=>i===".."))throw new PathEscapeError(`Path traversal is not allowed: "${t}"`);const o=s.join(e,r),a=e.endsWith(s.sep)?e:e+s.sep;if(o!==e&&!o.startsWith(a))throw new PathEscapeError(`Resolved path escapes the project: "${t}"`);return o}export function resolveProjectFile(e,t){const r=s.normalize(t).replace(/\\/g,"/"),o=w().flatMap(i=>i.projectSkillsRoots().map(l=>l.split("/")[0])),a=r.split("/")[0]??"";if(!(r===".mcp.json"||r==="CLAUDE.md"||r==="AGENTS.md"||o.includes(a)||r===".weave"||r.startsWith(".weave/")))throw new PathEscapeError(`Path is outside the allowed roots: "${t}"`);return resolveWithinProject(e,r)}export async function readProjectFile(e,t){const r=resolveProjectFile(e,t);let o;try{o=await p(r)}catch{throw new n(`File not found: "${t}"`)}if(!o.isFile())throw new n(`Not a file: "${t}"`);if(o.size>MAX_BYTES)throw new FileTooLargeError(`File exceeds ${MAX_BYTES} bytes: "${t}"`);return{content:await c(r,"utf-8"),size:o.size}}export async function readGlobalFile(e){return readProjectFile(h(),e)}
@@ -1 +1 @@
1
- import{mkdir as l,readFile as w,rm as u,writeFile as m}from"node:fs/promises";import{existsSync as d}from"node:fs";import t from"node:path";import{scanLibraryFileAssets as g,scanLibraryMcp as A,scanLibraryPlugins as v,scanLibrarySkills as S}from"./scanner.js";const y="scans.json",f=1;function c(e){const r=t.resolve(e);return t.join(t.dirname(r),".weave-scans",t.basename(r))}const a=new Map,o=new Map;export async function scanLibrary(e){const{plugins:r,packRoots:n}=await v(e),[s,i,p]=await Promise.all([S(e,n),A(e,n),g(e,n)]);return{plugins:r,packRoots:n,skills:s,mcp:i,files:p}}export async function getLibraryScan(e){const r=t.resolve(e),n=a.get(r);if(n)return n;const s=o.get(r);if(s)return s;const i=k(r);o.set(r,i);try{return await i}finally{o.delete(r)}}async function k(e){if(!d(e)){try{await u(c(e),{recursive:!0,force:!0})}catch{}const s=await scanLibrary(e);return a.set(e,s),s}const r=await L(e);if(r)return a.set(e,r),r;const n=await scanLibrary(e);return await F(e,n),a.set(e,n),n}async function L(e){try{const r=JSON.parse(await w(t.join(c(e),y),"utf8"));return!r||r.version!==f||r.root!==e||!Array.isArray(r.plugins)||!Array.isArray(r.packRoots)||!Array.isArray(r.skills)||!Array.isArray(r.mcp)||!r.files||typeof r.files!="object"?null:r}catch{return null}}async function F(e,r){try{await l(c(e),{recursive:!0}),await m(t.join(c(e),y),JSON.stringify({version:f,root:e,...r}),"utf8")}catch{}}export async function invalidateScan(e){const r=t.resolve(e);a.delete(r);const n=o.get(r);n&&await n.catch(()=>{}),await u(c(r),{recursive:!0,force:!0}),a.delete(r)}export function clearScanCache(){a.clear()}
1
+ import{mkdir as p,readFile as w,rm as l,writeFile as m}from"node:fs/promises";import{existsSync as v}from"node:fs";import s from"node:path";import{scanLibraryFileAssets as g,scanLibraryMcp as A,scanLibraryPlugins as b,scanLibrarySkills as d}from"./scanner.js";const u="scans.json",y=1;function c(a){const r=s.resolve(a);return s.join(s.dirname(r),".weave-scans",s.basename(r))}const i=new Map,o=new Map;export async function scanLibrary(a){const{plugins:r,packRoots:t}=await b(a),[n,e,f]=await Promise.all([d(a,t),A(a,t),g(a,t)]);return{plugins:r,packRoots:t,skills:n,mcp:e,files:f}}export async function getLibraryScan(a){const r=s.resolve(a),t=i.get(r);if(t)return t;const n=o.get(r);if(n)return n;const e=k(r);o.set(r,e);try{return await e}finally{o.delete(r)}}async function k(a){if(!v(a)){try{await l(c(a),{recursive:!0,force:!0})}catch{}const n=await scanLibrary(a);return i.set(a,n),n}const r=await S(a);if(r)return i.set(a,r),r;const t=await scanLibrary(a);return await L(a,t),i.set(a,t),t}async function S(a){try{const r=JSON.parse(await w(s.join(c(a),u),"utf8"));return!r||r.version!==y||r.root!==a||!Array.isArray(r.plugins)||!Array.isArray(r.packRoots)||!Array.isArray(r.skills)||!Array.isArray(r.mcp)||!r.files||typeof r.files!="object"?null:r}catch{return null}}async function L(a,r){try{await p(c(a),{recursive:!0}),await m(s.join(c(a),u),JSON.stringify({version:y,root:a,...r}),"utf8")}catch{}}export async function invalidateScan(a){const r=s.resolve(a);i.delete(r);const t=o.get(r);t&&await t.catch(()=>{}),await l(c(r),{recursive:!0,force:!0}),i.delete(r)}export function clearScanCache(){i.clear()}
@@ -1 +1 @@
1
- import{readdir as l,readFile as j,stat as E}from"node:fs/promises";import{join as o,basename as p,relative as f,dirname as S}from"node:path";import{FILE_ASSET_SPECS as A,FILE_ASSET_CATEGORIES as h}from"./file-assets.js";import{hasNonEmptyModules as L}from"../watch/plugin-mods.js";import{parseToolkitPack as I}from"../hooks/toolkit-scan.js";import{marketIdOf as T}from"../market/identity.js";import{pluginSurfaceFor as d}from"../surfaces.js";function _(t){if(!(!(t.ccPack||t.kind==="mod")||!t.targets.includes("claude")))return d("claude").pluginKey(t.name,T(t.dir))}const y=new Set(["node_modules",".git","dist","build",".next","coverage",".cache"]);async function g(t){try{return(await E(t)).isFile()}catch{return!1}}async function D(t){if(await g(o(t,".claude-plugin","plugin.json"))||await g(o(t,"weave-plugin.json")))return!0;try{const e=JSON.parse(await j(o(t,"hooks","hooks.json"),"utf8"));return L(e)}catch{return!1}}const M=10;export async function scanLibraryPlugins(t){const e=[],r=[],c=async(a,n)=>{if(await D(a)){r.push(f(t,a).replace(/\\/g,"/"));const s=await I(a,{root:t,provenance:"market"},"");if(s){const u=[];for(const k of s.skills)await g(o(a,"skills",k,"SKILL.md"))&&u.push(k);const m=_(s);e.push({name:s.name,version:s.version,...s.description?{description:s.description}:{},...m?{key:m}:{},dirPath:s.dir,relPath:f(t,a).replace(/\\/g,"/"),ccPack:s.ccPack,weavePack:s.weavePack,kind:s.kind,components:s.components,targets:s.targets,skills:u})}return}if(n>=M)return;let i;try{i=await l(a,{withFileTypes:!0})}catch{return}for(const s of i)s.isDirectory()&&(s.name.startsWith(".")||y.has(s.name)||await c(o(a,s.name),n+1))};return await c(t,0),{plugins:e.sort((a,n)=>a.relPath.localeCompare(n.relPath)),packRoots:r.sort((a,n)=>a.localeCompare(n))}}function w(t,e){return!e||e.length===0?!1:e.some(r=>r===""||t===r||t.startsWith(`${r}/`))}export async function scanLibrarySkills(t,e){const r=[];return await P(t,t,r,e),r.sort((c,a)=>c.name.localeCompare(a.name))}async function P(t,e,r,c){if(w(f(t,e).replace(/\\/g,"/"),c))return;let a;try{a=await l(e,{withFileTypes:!0})}catch{return}if(a.some(n=>n.isFile()&&n.name==="SKILL.md")){r.push({name:p(e),dirPath:e,relPath:f(t,e).replace(/\\/g,"/"),group:f(t,S(e)).replace(/\\/g,"/")});return}for(const n of a)n.isDirectory()&&(n.name.startsWith(".")||y.has(n.name)||await P(t,o(e,n.name),r,c))}export async function scanLibraryMcp(t,e){const r=[];await v(t,t,r,e);const c=[];for(const a of r)try{const n=JSON.parse(await j(a.abs,"utf-8"));O(n,a,c)}catch{}return c.sort((a,n)=>a.name.localeCompare(n.name))}async function v(t,e,r,c){if(w(f(t,e).replace(/\\/g,"/"),c))return;let a;try{a=await l(e,{withFileTypes:!0})}catch{return}for(const n of a)if(n.isDirectory()){if(n.name.startsWith(".")||y.has(n.name))continue;await v(t,o(e,n.name),r,c)}else if(n.isFile()){const i=n.name.replace(/\.mcp\.json$/i,"").replace(/\.json$/i,""),s=/\.mcp\.json$/i.test(n.name),u=p(e)==="mcp"&&/\.json$/i.test(n.name);(s||u)&&i&&r.push({abs:o(e,n.name),rel:f(t,o(e,n.name)).replace(/\\/g,"/")})}}function O(t,e,r){const c=e.rel.replace(/\.mcp\.json$/i,"").replace(/\.json$/i,"").replace(/^.*\//,"");if(t&&typeof t=="object"&&!Array.isArray(t)){const a=t,n=a.mcpServers;if(n&&typeof n=="object"&&!Array.isArray(n)){for(const[s,u]of Object.entries(n)){const m=F(s,u);m&&r.push({...m,sourcePath:e.abs,relPath:e.rel})}return}const i=F(c,a);i&&r.push({...i,sourcePath:e.abs,relPath:e.rel})}}function F(t,e){if(!e||typeof e!="object"||Array.isArray(e))return null;const r=e;if(typeof r.command!="string"||!r.command)return null;const c={name:t,command:r.command};if(Array.isArray(r.args)&&(c.args=r.args.filter(a=>typeof a=="string")),r.env&&typeof r.env=="object"&&!Array.isArray(r.env)){const a={};for(const[n,i]of Object.entries(r.env))typeof i=="string"&&(a[n]=i);Object.keys(a).length&&(c.env=a)}return c}const C=Object.fromEntries(h.flatMap(t=>Object.values(A[t].dirs).map(e=>e?.project).filter(e=>e!==void 0).map(e=>[p(e),t])));export async function scanLibraryFileAssets(t,e){const r={};for(const c of h)r[c]=[];await b(t,t,r,e);for(const c of h)r[c].sort((a,n)=>a.name.localeCompare(n.name));return r}async function b(t,e,r,c){if(w(f(t,e).replace(/\\/g,"/"),c))return;let a;try{a=await l(e,{withFileTypes:!0})}catch{return}if(a.some(i=>i.isFile()&&i.name==="SKILL.md"))return;const n=C[p(e)];if(n){const i=A[n];for(const s of a){if(!s.isFile()||!s.name.endsWith(i.ext))continue;const u=s.name.slice(0,-i.ext.length);if(!u)continue;const m=o(e,s.name);r[n].push({name:u,filePath:m,relPath:f(t,m).replace(/\\/g,"/"),group:f(t,S(e)).replace(/\\/g,"/"),category:n})}return}for(const i of a)i.isDirectory()&&(i.name.startsWith(".")||y.has(i.name)||await b(t,o(e,i.name),r,c))}
1
+ import{readdir as p,readFile as k,stat as F}from"node:fs/promises";import{join as c,basename as u,relative as l,dirname as j}from"node:path";import{FILE_ASSET_SPECS as P,FILE_ASSET_CATEGORIES as h}from"./file-assets.js";import{hasNonEmptyModules as L}from"../watch/plugin-mods.js";import{parseToolkitPack as E}from"../hooks/toolkit-scan.js";import{marketIdOf as O}from"../market/identity.js";import{pluginSurfaceFor as T}from"../surfaces.js";function C(e){if(!(!(e.ccPack||e.kind==="mod")||!e.targets.includes("claude")))return T("claude").pluginKey(e.name,O(e.dir))}const y=new Set(["node_modules",".git","dist","build",".next","coverage",".cache"]);async function d(e){try{return(await F(e)).isFile()}catch{return!1}}async function I(e){if(await d(c(e,".claude-plugin","plugin.json"))||await d(c(e,"weave-plugin.json")))return!0;try{const a=JSON.parse(await k(c(e,"hooks","hooks.json"),"utf8"));return L(a)}catch{return!1}}const x=10;export async function scanLibraryPlugins(e){const a=[],n=[],o=async(t,r)=>{if(await I(t)){n.push(l(e,t).replace(/\\/g,"/"));const s=await E(t,{root:e,provenance:"market"},"");if(s){const m=[];for(const w of s.skills)await d(c(t,"skills",w,"SKILL.md"))&&m.push(w);const f=C(s);a.push({name:s.name,version:s.version,...s.description?{description:s.description}:{},...f?{key:f}:{},dirPath:s.dir,relPath:l(e,t).replace(/\\/g,"/"),ccPack:s.ccPack,weavePack:s.weavePack,kind:s.kind,components:s.components,targets:s.targets,skills:m})}return}if(r>=x)return;let i;try{i=await p(t,{withFileTypes:!0})}catch{return}for(const s of i)s.isDirectory()&&(s.name.startsWith(".")||y.has(s.name)||await o(c(t,s.name),r+1))};return await o(e,0),{plugins:a.sort((t,r)=>t.relPath.localeCompare(r.relPath)),packRoots:n.sort((t,r)=>t.localeCompare(r))}}function g(e,a){return!a||a.length===0?!1:a.some(n=>n===""||e===n||e.startsWith(`${n}/`))}export async function scanLibrarySkills(e,a){const n=[];return await b(e,e,n,a),n.sort((o,t)=>o.name.localeCompare(t.name))}async function b(e,a,n,o){if(g(l(e,a).replace(/\\/g,"/"),o))return;let t;try{t=await p(a,{withFileTypes:!0})}catch{return}if(t.some(r=>r.isFile()&&r.name==="SKILL.md")){n.push({name:u(a),dirPath:a,relPath:l(e,a).replace(/\\/g,"/"),group:l(e,j(a)).replace(/\\/g,"/")});return}for(const r of t)r.isDirectory()&&(r.name.startsWith(".")||y.has(r.name)||await b(e,c(a,r.name),n,o))}export async function scanLibraryMcp(e,a){const n=[];await v(e,e,n,a);const o=[];for(const t of n)try{const r=JSON.parse(await k(t.abs,"utf-8"));$(r,t,o)}catch{}return o.sort((t,r)=>t.name.localeCompare(r.name))}async function v(e,a,n,o){if(g(l(e,a).replace(/\\/g,"/"),o))return;let t;try{t=await p(a,{withFileTypes:!0})}catch{return}for(const r of t)if(r.isDirectory()){if(r.name.startsWith(".")||y.has(r.name))continue;await v(e,c(a,r.name),n,o)}else if(r.isFile()){const i=r.name.replace(/\.mcp\.json$/i,"").replace(/\.json$/i,""),s=/\.mcp\.json$/i.test(r.name),m=u(a)==="mcp"&&/\.json$/i.test(r.name);(s||m)&&i&&n.push({abs:c(a,r.name),rel:l(e,c(a,r.name)).replace(/\\/g,"/")})}}function $(e,a,n){const o=a.rel.replace(/\.mcp\.json$/i,"").replace(/\.json$/i,"").replace(/^.*\//,"");if(e&&typeof e=="object"&&!Array.isArray(e)){const t=e,r=t.mcpServers;if(r&&typeof r=="object"&&!Array.isArray(r)){for(const[s,m]of Object.entries(r)){const f=S(s,m);f&&n.push({...f,sourcePath:a.abs,relPath:a.rel})}return}const i=S(o,t);i&&n.push({...i,sourcePath:a.abs,relPath:a.rel})}}function S(e,a){if(!a||typeof a!="object"||Array.isArray(a))return null;const n=a;if(typeof n.command!="string"||!n.command)return null;const o={name:e,command:n.command};if(Array.isArray(n.args)&&(o.args=n.args.filter(t=>typeof t=="string")),n.env&&typeof n.env=="object"&&!Array.isArray(n.env)){const t={};for(const[r,i]of Object.entries(n.env))typeof i=="string"&&(t[r]=i);Object.keys(t).length&&(o.env=t)}return o}const W=Object.fromEntries(h.flatMap(e=>Object.values(P[e].dirs).map(a=>a?.project).filter(a=>a!==void 0).map(a=>[u(a),e])));export async function scanLibraryFileAssets(e,a){const n={};for(const o of h)n[o]=[];await A(e,e,n,a);for(const o of h)n[o].sort((t,r)=>t.name.localeCompare(r.name));return n}async function A(e,a,n,o){if(g(l(e,a).replace(/\\/g,"/"),o))return;let t;try{t=await p(a,{withFileTypes:!0})}catch{return}if(t.some(i=>i.isFile()&&i.name==="SKILL.md"))return;const r=W[u(a)];if(r){const i=P[r];for(const s of t){if(!s.isFile()||!s.name.endsWith(i.ext))continue;const m=s.name.slice(0,-i.ext.length);if(!m)continue;const f=c(a,s.name);n[r].push({name:m,filePath:f,relPath:l(e,f).replace(/\\/g,"/"),group:l(e,j(a)).replace(/\\/g,"/"),category:r})}return}for(const i of t)i.isDirectory()&&(i.name.startsWith(".")||y.has(i.name)||await A(e,c(a,i.name),n,o))}
@@ -1,2 +1,2 @@
1
- import{readFile as f,writeFile as u,mkdir as b,access as p}from"node:fs/promises";import o from"node:path";const c=".claude/settings.json";async function S(t){try{return await p(t),!0}catch{return!1}}async function d(t){const e=o.join(t,c);if(!await S(e))return{};try{const r=JSON.parse(await f(e,"utf-8"));return r&&typeof r=="object"&&!Array.isArray(r)?r:{}}catch{return{}}}async function v(t,e){const r=o.join(t,c);await b(o.dirname(r),{recursive:!0}),await u(r,`${JSON.stringify(e,null,2)}
2
- `,"utf-8")}export async function readMcpEnableMap(t){const e=await d(t),r=i(e.enabledMcpjsonServers),n=i(e.disabledMcpjsonServers),s={};for(const a of r)s[a]="enabled";for(const a of n)s[a]="disabled";return{overrides:s,enableAll:e.enableAllProjectMcpServers===!0}}const y={enabled:"on",disabled:"off",default:"inherit"},M={on:"enabled",off:"disabled",inherit:"default"};export function mcpOverrideOf(t,e){return y[t.overrides[e]??"default"]}export function resolveMcpEffective(t,e){const r=t.overrides[e];return r==="enabled"?!0:r==="disabled"?!1:t.enableAll}export async function setMcpEnableState(t,e,r){const n=await d(t),s=new Set(i(n.enabledMcpjsonServers)),a=new Set(i(n.disabledMcpjsonServers));s.delete(e),a.delete(e),r==="enabled"?s.add(e):r==="disabled"&&a.add(e),l(n,"enabledMcpjsonServers",s),l(n,"disabledMcpjsonServers",a),await v(t,n)}export function setMcpEnableOverride(t,e,r){return setMcpEnableState(t,e,M[r])}function i(t){return Array.isArray(t)?t.filter(e=>typeof e=="string"):[]}function l(t,e,r){r.size===0?delete t[e]:t[e]=[...r].sort()}
1
+ import{readFile as f,writeFile as u,mkdir as b,access as p}from"node:fs/promises";import o from"node:path";const c=".claude/settings.json";async function v(r){try{return await p(r),!0}catch{return!1}}async function d(r){const e=o.join(r,c);if(!await v(e))return{};try{const n=JSON.parse(await f(e,"utf-8"));return n&&typeof n=="object"&&!Array.isArray(n)?n:{}}catch{return{}}}async function y(r,e){const n=o.join(r,c);await b(o.dirname(n),{recursive:!0}),await u(n,`${JSON.stringify(e,null,2)}
2
+ `,"utf-8")}export async function readMcpEnableMap(r){const e=await d(r),n=i(e.enabledMcpjsonServers),t=i(e.disabledMcpjsonServers),a={};for(const s of n)a[s]="enabled";for(const s of t)a[s]="disabled";return{overrides:a,enableAll:e.enableAllProjectMcpServers===!0}}const M={enabled:"on",disabled:"off",default:"inherit"},S={on:"enabled",off:"disabled",inherit:"default"};export function mcpOverrideOf(r,e){return M[r.overrides[e]??"default"]}export function resolveMcpEffective(r,e){const n=r.overrides[e];return n==="enabled"?!0:n==="disabled"?!1:r.enableAll}export async function setMcpEnableState(r,e,n){const t=await d(r),a=new Set(i(t.enabledMcpjsonServers)),s=new Set(i(t.disabledMcpjsonServers));a.delete(e),s.delete(e),n==="enabled"?a.add(e):n==="disabled"&&s.add(e),l(t,"enabledMcpjsonServers",a),l(t,"disabledMcpjsonServers",s),await y(r,t)}export function setMcpEnableOverride(r,e,n){return setMcpEnableState(r,e,S[n])}function i(r){return Array.isArray(r)?r.filter(e=>typeof e=="string"):[]}function l(r,e,n){n.size===0?delete r[e]:r[e]=[...n].sort()}
@@ -1 +1 @@
1
- import{readdir as g,stat as w}from"node:fs/promises";import{homedir as F}from"node:os";import f from"node:path";import{hashMcpConfig as p}from"./fingerprint.js";import{buildLibraryIndex as h,findSkillSource as y,findMcpSource as m,findFileAssetSource as S}from"./library-index.js";import{readMcpServers as k}from"./installer.js";import{readGlobalMcpServers as x,readGlobalSkills as v}from"./global-config.js";import{readCodexMcpServers as C}from"./codex-toml.js";import{FILE_ASSET_CATEGORIES as E,FILE_ASSET_SPECS as M}from"./file-assets.js";import{assetSurfaces as b}from"../surfaces.js";import{readInstalledLedger as T}from"./install-ledger.js";import{detectPluginTemplateUpdates as U}from"./plugin-templates.js";import{detectInitFileUpdates as L,needsInit as A}from"./init-files.js";export async function detectUpdates(a,o,l,t){const n=t??await h(o),[s,e,r,c,u]=await Promise.all([detectSkillUpdates(a,l,n),H(a,n),detectFileAssetUpdates(a,l,n),U(a,l),L(a)]);await D(a,{skills:s,mcp:e,files:r},n);const d=s.filter(i=>!i.custom&&i.outdated).length+e.filter(i=>!i.custom&&i.outdated).length+r.filter(i=>!i.custom&&i.outdated).length+c.filter(i=>i.outdated).length+u.filter(i=>i.outdated&&i.syncClass==="auto").length;return{skills:s,mcp:e,files:r,pluginTemplates:c,initFiles:u,available:d,needsInit:A(u)}}export async function detectProjectUpdateCounts(a,o,l){const t=await h(o),n={};for(const s of a){const e=await detectUpdates(s.path,o,l,t);n[s.id]={available:e.available,needsInit:e.needsInit}}return n}async function D(a,o,l){for(const t of await T(a)){if(t.category==="skill"){if(!y(l,t.name)||o.skills.some(r=>r.scope==="project"&&r.name===t.name&&r.agent===t.agent))continue;o.skills.push({name:t.name,scope:"project",agent:t.agent,outdated:!0,custom:!1,missing:!0});continue}if(t.category==="mcp"){if(!m(l,t.name)||o.mcp.some(e=>e.scope==="project"&&e.name===t.name))continue;o.mcp.push({name:t.name,scope:"project",outdated:!0,custom:!1,missing:!0});continue}const n=t.assetCategory;n===void 0||!S(l,n,t.name)||o.files.some(e=>e.scope==="project"&&e.category===n&&e.name===t.name)||o.files.push({category:n,name:t.name,scope:"project",outdated:!0,custom:!1,missing:!0})}}async function P(a){let o;try{o=await g(a,{withFileTypes:!0})}catch{return[]}const l=[];for(const t of o)if(!(!t.isDirectory()&&!t.isSymbolicLink()))try{(await w(f.join(a,t.name))).isDirectory()&&l.push(t.name)}catch{}return l}export async function detectSkillUpdates(a,o,l){const t=F(),n=[...b().map(e=>({dir:f.join(a,...e.projectSkillsRoots()[0].split("/")),scope:"project",agent:e.harness})),...b().map(e=>({dir:e.globalSkillsRoots(t)[0],scope:"user",agent:e.harness}))],s=[];for(const e of n)for(const r of await P(e.dir)){const c=f.join(e.dir,r),u=y(l,r);if(!u){s.push({name:r,scope:e.scope,agent:e.agent,outdated:!1,custom:!0});continue}const[d,i]=await Promise.all([o.get(c),o.get(u.dirPath)]);s.push({name:r,scope:e.scope,agent:e.agent,outdated:d!==i,custom:!1,sourceDir:u.dirPath,libraryId:u.libraryId})}return s}export async function detectFileAssetUpdates(a,o,l){const t=[];for(const n of E){const s=M[n],e=s.dirs.claude?.project;if(!e)continue;const r=f.join(a,...e.split("/"));let c;try{c=(await g(r,{withFileTypes:!0})).filter(u=>u.isFile()&&u.name.endsWith(s.ext)).map(u=>u.name)}catch{continue}for(const u of c){const d=u.slice(0,-s.ext.length),i=S(l,n,d);if(!i){t.push({category:n,name:d,scope:"project",outdated:!1,custom:!0});continue}const[j,I]=await Promise.all([o.getFile(f.join(r,u)),o.getFile(i.filePath)]);t.push({category:n,name:d,scope:"project",outdated:j!==I,custom:!1,libraryId:i.libraryId})}}return t}async function H(a,o){const[l,t,n]=await Promise.all([k(a).catch(()=>({})),x().catch(()=>({})),C().catch(()=>({}))]),s=[];for(const[e,r]of Object.entries(l)){const c=m(o,e);c?s.push({name:e,scope:"project",outdated:p(r)!==p(c.config),custom:!1,libraryId:c.libraryId}):s.push({name:e,scope:"project",outdated:!1,custom:!0})}for(const[e,r]of Object.entries(t)){const c=m(o,e);c?s.push({name:e,scope:"user",outdated:p(r)!==p(c.config),custom:!1,libraryId:c.libraryId}):s.push({name:e,scope:"user",outdated:!1,custom:!0})}for(const[e,r]of Object.entries(n)){const c=m(o,e);c?s.push({name:e,scope:"user",agent:"codex",outdated:p(r)!==p(c.config),custom:!1,libraryId:c.libraryId}):s.push({name:e,scope:"user",agent:"codex",outdated:!1,custom:!0})}return s}export{v as readGlobalSkills};
1
+ import{readdir as g,stat as w}from"node:fs/promises";import{homedir as k}from"node:os";import u from"node:path";import{hashMcpConfig as p}from"./fingerprint.js";import{buildLibraryIndex as h,findSkillSource as y,findMcpSource as f,findFileAssetSource as b}from"./library-index.js";import{readMcpServers as x}from"./installer.js";import{readGlobalMcpServers as F,readGlobalSkills as P}from"./global-config.js";import{readCodexMcpServers as v}from"./codex-toml.js";import{FILE_ASSET_CATEGORIES as C,FILE_ASSET_SPECS as E}from"./file-assets.js";import{assetSurfaces as j}from"../surfaces.js";import{readInstalledLedger as T}from"./install-ledger.js";import{detectPluginTemplateUpdates as U}from"./plugin-templates.js";import{detectInitFileUpdates as A,needsInit as L}from"./init-files.js";export async function detectUpdates(n,s,i,o){const a=o??await h(s),[e,t,d,c,m]=await Promise.all([detectSkillUpdates(n,i,a),G(n,a),detectFileAssetUpdates(n,i,a),U(n,i),A(n)]);await M(n,{skills:e,mcp:t,files:d},a);const l=e.filter(r=>!r.custom&&r.outdated).length+t.filter(r=>!r.custom&&r.outdated).length+d.filter(r=>!r.custom&&r.outdated).length+c.filter(r=>r.outdated).length+m.filter(r=>r.outdated&&r.syncClass==="auto").length;return{skills:e,mcp:t,files:d,pluginTemplates:c,initFiles:m,available:l,needsInit:L(m)}}export async function detectProjectUpdateCounts(n,s,i){const o=await h(s),a={};for(const e of n){const t=await detectUpdates(e.path,s,i,o);a[e.id]={available:t.available,needsInit:t.needsInit}}return a}async function M(n,s,i){for(const o of await T(n)){if(o.category==="skill"){if(!y(i,o.name)||s.skills.some(e=>e.scope==="project"&&e.name===o.name&&e.agent===o.agent))continue;s.skills.push({name:o.name,scope:"project",agent:o.agent,outdated:!0,custom:!1,missing:!0});continue}if(o.category==="mcp"){if(!f(i,o.name)||s.mcp.some(e=>e.scope==="project"&&e.name===o.name))continue;s.mcp.push({name:o.name,scope:"project",outdated:!0,custom:!1,missing:!0});continue}const a=o.assetCategory;a===void 0||!b(i,a,o.name)||s.files.some(e=>e.scope==="project"&&e.category===a&&e.name===o.name)||s.files.push({category:a,name:o.name,scope:"project",outdated:!0,custom:!1,missing:!0})}}async function D(n){let s;try{s=await g(n,{withFileTypes:!0})}catch{return[]}const i=[];for(const o of s)if(!(!o.isDirectory()&&!o.isSymbolicLink()))try{(await w(u.join(n,o.name))).isDirectory()&&i.push(o.name)}catch{}return i}export async function detectSkillUpdates(n,s,i){const o=k(),a=[...j().map(t=>({dir:u.join(n,...t.projectSkillsRoots()[0].split("/")),scope:"project",agent:t.harness})),...j().map(t=>({dir:t.globalSkillsRoots(o)[0],scope:"user",agent:t.harness}))],e=[];for(const t of a)for(const d of await D(t.dir)){const c=u.join(t.dir,d),m=y(i,d);if(!m){e.push({name:d,scope:t.scope,agent:t.agent,outdated:!1,custom:!0});continue}const[l,r]=await Promise.all([s.get(c),s.get(m.dirPath)]);e.push({name:d,scope:t.scope,agent:t.agent,outdated:l!==r,custom:!1,sourceDir:m.dirPath,libraryId:m.libraryId})}return e}export async function detectFileAssetUpdates(n,s,i){const o=[];for(const a of C){const e=E[a],t=e.dirs.claude?.project;if(!t)continue;const d=u.join(n,...t.split("/"));let c;try{c=(await g(d,{withFileTypes:!0})).filter(m=>m.isFile()&&m.name.endsWith(e.ext)).map(m=>m.name)}catch{continue}for(const m of c){const l=m.slice(0,-e.ext.length),r=b(i,a,l);if(!r){o.push({category:a,name:l,scope:"project",outdated:!1,custom:!0});continue}const[S,I]=await Promise.all([s.getFile(u.join(d,m)),s.getFile(r.filePath)]);o.push({category:a,name:l,scope:"project",outdated:S!==I,custom:!1,libraryId:r.libraryId})}}return o}async function G(n,s){const[i,o,a]=await Promise.all([x(n).catch(()=>({})),F().catch(()=>({})),v().catch(()=>({}))]),e=[];for(const[t,d]of Object.entries(i)){const c=f(s,t);c?e.push({name:t,scope:"project",outdated:p(d)!==p(c.config),custom:!1,libraryId:c.libraryId}):e.push({name:t,scope:"project",outdated:!1,custom:!0})}for(const[t,d]of Object.entries(o)){const c=f(s,t);c?e.push({name:t,scope:"user",outdated:p(d)!==p(c.config),custom:!1,libraryId:c.libraryId}):e.push({name:t,scope:"user",outdated:!1,custom:!0})}for(const[t,d]of Object.entries(a)){const c=f(s,t);c?e.push({name:t,scope:"user",agent:"codex",outdated:p(d)!==p(c.config),custom:!1,libraryId:c.libraryId}):e.push({name:t,scope:"user",agent:"codex",outdated:!1,custom:!0})}return e}export{P as readGlobalSkills};
@@ -1 +1 @@
1
- import o from"node:path";import{lstat as l,realpath as s}from"node:fs/promises";import{builtinMarketRoot as u}from"@weavecode/templates";import{WEAVE_MARKETPLACE as f}from"@weavecode/harness";import{marketDir as m}from"./manifest.js";import{linkOrCopy as p,removeInstalled as h}from"./install-link.js";export const BUILTIN_MARKET_ID=f;export function builtinMarketDir(t){return o.join(m(t),BUILTIN_MARKET_ID)}export function builtinPacksDir(t){return o.join(builtinMarketDir(t),"plugins")}export function builtinRulesDir(t){return o.join(builtinMarketDir(t),"rules")}export function isBuiltinMarketDir(t,n){return o.resolve(t)===o.resolve(builtinMarketDir(n))}export async function ensureBuiltinMarket(t){const n=t.libraries.dataRoot,e=u(),r=builtinMarketDir(n);t.libraries.add({path:r,kind:"both"});const c=await s(e),a=await l(r).catch(()=>null);if(a){if(a.isSymbolicLink()&&await s(r).catch(()=>null)===c)return{changed:!1,form:"link"};await h(r)}try{return{changed:!0,form:await p(e,r)}}catch(i){return{changed:!1,error:i instanceof Error?i.message:String(i)}}}
1
+ import i from"node:path";import{lstat as u,realpath as s}from"node:fs/promises";import{builtinMarketRoot as c}from"@weavecode/templates";import{WEAVE_MARKETPLACE as m}from"@weavecode/harness";import{marketDir as f}from"./manifest.js";import{linkOrCopy as p,removeInstalled as h}from"./install-link.js";export const BUILTIN_MARKET_ID=m;export function builtinMarketDir(r){return i.join(f(r),BUILTIN_MARKET_ID)}export function builtinPacksDir(r){return i.join(builtinMarketDir(r),"plugins")}export function builtinRulesDir(r){return i.join(builtinMarketDir(r),"rules")}export function isBuiltinMarketDir(r,n){return i.resolve(r)===i.resolve(builtinMarketDir(n))}export async function ensureBuiltinMarket(r){const n=r.libraries.dataRoot,a=c(),t=builtinMarketDir(n);r.libraries.add({path:t,kind:"both"});const l=await s(a),e=await u(t).catch(()=>null);if(e){if(e.isSymbolicLink()&&await s(t).catch(()=>null)===l)return{changed:!1,form:"link"};await h(t)}try{return{changed:!0,form:await p(a,t)}}catch(o){return{changed:!1,error:o instanceof Error?o.message:String(o)}}}
@@ -1 +1 @@
1
- import e from"node:path";import{marketDir as n}from"./manifest.js";export function marketIdOf(i,o=n()){const r=e.relative(e.resolve(o),e.resolve(i));if(r===""||r.startsWith("..")||e.isAbsolute(r))return;const t=r.split(e.sep)[0];return t||void 0}
1
+ import t from"node:path";import{marketDir as s}from"./manifest.js";export function marketIdOf(e,o=s()){const r=t.relative(t.resolve(o),t.resolve(e));return r===""||r.startsWith("..")||t.isAbsolute(r)?void 0:r.split(t.sep)[0]||void 0}