@winspan/claude-forge 9.2.0 → 9.12.0

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 (591) hide show
  1. package/DEVELOPMENT.md +80 -19
  2. package/README.md +13 -6
  3. package/dist/catalogs/agents.json +19 -24
  4. package/dist/catalogs/skills.json +139 -27
  5. package/dist/claudemd/templates/swarm-protocol.md +1 -1
  6. package/dist/cli/commands/agent.d.ts +169 -0
  7. package/dist/cli/commands/agent.d.ts.map +1 -0
  8. package/dist/cli/commands/agent.js +690 -0
  9. package/dist/cli/commands/agent.js.map +1 -0
  10. package/dist/cli/commands/codegraph.d.ts +17 -0
  11. package/dist/cli/commands/codegraph.d.ts.map +1 -0
  12. package/dist/cli/commands/codegraph.js +263 -0
  13. package/dist/cli/commands/codegraph.js.map +1 -0
  14. package/dist/cli/commands/decisions.d.ts.map +1 -1
  15. package/dist/cli/commands/decisions.js +46 -9
  16. package/dist/cli/commands/decisions.js.map +1 -1
  17. package/dist/cli/commands/executions.d.ts.map +1 -1
  18. package/dist/cli/commands/executions.js +2 -1
  19. package/dist/cli/commands/executions.js.map +1 -1
  20. package/dist/cli/commands/insights-goal-check.d.ts +5 -1
  21. package/dist/cli/commands/insights-goal-check.d.ts.map +1 -1
  22. package/dist/cli/commands/insights-goal-check.js +15 -15
  23. package/dist/cli/commands/insights-goal-check.js.map +1 -1
  24. package/dist/cli/commands/knowledge.d.ts +51 -0
  25. package/dist/cli/commands/knowledge.d.ts.map +1 -1
  26. package/dist/cli/commands/knowledge.js +202 -29
  27. package/dist/cli/commands/knowledge.js.map +1 -1
  28. package/dist/cli/commands/loop.d.ts +95 -0
  29. package/dist/cli/commands/loop.d.ts.map +1 -0
  30. package/dist/cli/commands/loop.js +408 -0
  31. package/dist/cli/commands/loop.js.map +1 -0
  32. package/dist/cli/commands/maintenance.d.ts +33 -0
  33. package/dist/cli/commands/maintenance.d.ts.map +1 -0
  34. package/dist/cli/commands/maintenance.js +75 -0
  35. package/dist/cli/commands/maintenance.js.map +1 -0
  36. package/dist/cli/commands/mcp.d.ts +23 -0
  37. package/dist/cli/commands/mcp.d.ts.map +1 -1
  38. package/dist/cli/commands/mcp.js +82 -0
  39. package/dist/cli/commands/mcp.js.map +1 -1
  40. package/dist/cli/commands/skills.d.ts +131 -0
  41. package/dist/cli/commands/skills.d.ts.map +1 -1
  42. package/dist/cli/commands/skills.js +409 -9
  43. package/dist/cli/commands/skills.js.map +1 -1
  44. package/dist/cli/commands/stats.d.ts.map +1 -1
  45. package/dist/cli/commands/stats.js +9 -2
  46. package/dist/cli/commands/stats.js.map +1 -1
  47. package/dist/cli/index.js +8 -0
  48. package/dist/cli/index.js.map +1 -1
  49. package/dist/core/constants.d.ts +37 -0
  50. package/dist/core/constants.d.ts.map +1 -1
  51. package/dist/core/constants.js +43 -0
  52. package/dist/core/constants.js.map +1 -1
  53. package/dist/core/diagnostics/checks.d.ts.map +1 -1
  54. package/dist/core/diagnostics/checks.js +2 -1
  55. package/dist/core/diagnostics/checks.js.map +1 -1
  56. package/dist/core/diagnostics/daemon-status.d.ts +1 -1
  57. package/dist/core/diagnostics/daemon-status.d.ts.map +1 -1
  58. package/dist/core/diagnostics/daemon-status.js +1 -1
  59. package/dist/core/diagnostics/daemon-status.js.map +1 -1
  60. package/dist/core/diagnostics/entropy-checks.d.ts +3 -2
  61. package/dist/core/diagnostics/entropy-checks.d.ts.map +1 -1
  62. package/dist/core/diagnostics/entropy-checks.js +10 -5
  63. package/dist/core/diagnostics/entropy-checks.js.map +1 -1
  64. package/dist/core/diagnostics/heartbeat-reader.d.ts +28 -0
  65. package/dist/core/diagnostics/heartbeat-reader.d.ts.map +1 -0
  66. package/dist/core/diagnostics/heartbeat-reader.js +50 -0
  67. package/dist/core/diagnostics/heartbeat-reader.js.map +1 -0
  68. package/dist/core/event-fields.d.ts +27 -0
  69. package/dist/core/event-fields.d.ts.map +1 -1
  70. package/dist/core/event-fields.js +43 -0
  71. package/dist/core/event-fields.js.map +1 -1
  72. package/dist/core/governance/global-inject.d.ts +34 -4
  73. package/dist/core/governance/global-inject.d.ts.map +1 -1
  74. package/dist/core/governance/global-inject.js +80 -25
  75. package/dist/core/governance/global-inject.js.map +1 -1
  76. package/dist/core/insights/agent-anchor-guard.d.ts +77 -0
  77. package/dist/core/insights/agent-anchor-guard.d.ts.map +1 -0
  78. package/dist/core/insights/agent-anchor-guard.js +119 -0
  79. package/dist/core/insights/agent-anchor-guard.js.map +1 -0
  80. package/dist/core/insights/agent-distill-context.d.ts +55 -0
  81. package/dist/core/insights/agent-distill-context.d.ts.map +1 -0
  82. package/dist/core/insights/agent-distill-context.js +146 -0
  83. package/dist/core/insights/agent-distill-context.js.map +1 -0
  84. package/dist/core/insights/agent-distill-spawn.d.ts +56 -0
  85. package/dist/core/insights/agent-distill-spawn.d.ts.map +1 -0
  86. package/dist/core/insights/agent-distill-spawn.js +179 -0
  87. package/dist/core/insights/agent-distill-spawn.js.map +1 -0
  88. package/dist/core/insights/agent-drift.d.ts +66 -0
  89. package/dist/core/insights/agent-drift.d.ts.map +1 -0
  90. package/dist/core/insights/agent-drift.js +109 -0
  91. package/dist/core/insights/agent-drift.js.map +1 -0
  92. package/dist/core/insights/agent-evolution-sources.d.ts +21 -0
  93. package/dist/core/insights/agent-evolution-sources.d.ts.map +1 -0
  94. package/dist/core/insights/agent-evolution-sources.js +36 -0
  95. package/dist/core/insights/agent-evolution-sources.js.map +1 -0
  96. package/dist/core/insights/agent-health.d.ts +142 -0
  97. package/dist/core/insights/agent-health.d.ts.map +1 -0
  98. package/dist/core/insights/agent-health.js +296 -0
  99. package/dist/core/insights/agent-health.js.map +1 -0
  100. package/dist/core/insights/agent-patch-apply.d.ts +45 -0
  101. package/dist/core/insights/agent-patch-apply.d.ts.map +1 -0
  102. package/dist/core/insights/agent-patch-apply.js +165 -0
  103. package/dist/core/insights/agent-patch-apply.js.map +1 -0
  104. package/dist/core/insights/agent-suggest.d.ts +128 -0
  105. package/dist/core/insights/agent-suggest.d.ts.map +1 -0
  106. package/dist/core/insights/agent-suggest.js +284 -0
  107. package/dist/core/insights/agent-suggest.js.map +1 -0
  108. package/dist/core/insights/coverage-tiers.d.ts +46 -0
  109. package/dist/core/insights/coverage-tiers.d.ts.map +1 -0
  110. package/dist/core/insights/coverage-tiers.js +95 -0
  111. package/dist/core/insights/coverage-tiers.js.map +1 -0
  112. package/dist/{daemon/services → core/insights}/experience-extractor.d.ts +0 -7
  113. package/dist/core/insights/experience-extractor.d.ts.map +1 -0
  114. package/dist/{daemon/services → core/insights}/experience-extractor.js +5 -9
  115. package/dist/core/insights/experience-extractor.js.map +1 -0
  116. package/dist/{daemon/services → core/insights}/violation-reporter.d.ts +20 -1
  117. package/dist/core/insights/violation-reporter.d.ts.map +1 -0
  118. package/dist/{daemon/services → core/insights}/violation-reporter.js +56 -4
  119. package/dist/core/insights/violation-reporter.js.map +1 -0
  120. package/dist/core/loop/loop-engine.d.ts +140 -0
  121. package/dist/core/loop/loop-engine.d.ts.map +1 -0
  122. package/dist/core/loop/loop-engine.js +266 -0
  123. package/dist/core/loop/loop-engine.js.map +1 -0
  124. package/dist/core/queue/index.d.ts.map +1 -1
  125. package/dist/core/queue/index.js +2 -1
  126. package/dist/core/queue/index.js.map +1 -1
  127. package/dist/core/storage/base.d.ts +159 -0
  128. package/dist/core/storage/base.d.ts.map +1 -1
  129. package/dist/core/storage/base.js +523 -0
  130. package/dist/core/storage/base.js.map +1 -1
  131. package/dist/core/storage/codegraph-types.d.ts +79 -0
  132. package/dist/core/storage/codegraph-types.d.ts.map +1 -0
  133. package/dist/core/storage/codegraph-types.js +14 -0
  134. package/dist/core/storage/codegraph-types.js.map +1 -0
  135. package/dist/core/storage/codegraph.d.ts +186 -0
  136. package/dist/core/storage/codegraph.d.ts.map +1 -0
  137. package/dist/core/storage/codegraph.js +452 -0
  138. package/dist/core/storage/codegraph.js.map +1 -0
  139. package/dist/core/storage/decisions.d.ts +30 -5
  140. package/dist/core/storage/decisions.d.ts.map +1 -1
  141. package/dist/core/storage/decisions.js +45 -13
  142. package/dist/core/storage/decisions.js.map +1 -1
  143. package/dist/core/storage/events.d.ts +127 -0
  144. package/dist/core/storage/events.d.ts.map +1 -1
  145. package/dist/core/storage/events.js +318 -3
  146. package/dist/core/storage/events.js.map +1 -1
  147. package/dist/core/storage/feedback.d.ts +3 -23
  148. package/dist/core/storage/feedback.d.ts.map +1 -1
  149. package/dist/core/storage/feedback.js +37 -38
  150. package/dist/core/storage/feedback.js.map +1 -1
  151. package/dist/core/storage/injections.d.ts +40 -0
  152. package/dist/core/storage/injections.d.ts.map +1 -1
  153. package/dist/core/storage/injections.js +69 -0
  154. package/dist/core/storage/injections.js.map +1 -1
  155. package/dist/core/storage/knowledge.d.ts +226 -0
  156. package/dist/core/storage/knowledge.d.ts.map +1 -1
  157. package/dist/core/storage/knowledge.js +391 -4
  158. package/dist/core/storage/knowledge.js.map +1 -1
  159. package/dist/core/storage/pipeline-rollup.d.ts +1 -7
  160. package/dist/core/storage/pipeline-rollup.d.ts.map +1 -1
  161. package/dist/core/storage/pipeline-rollup.js +18 -57
  162. package/dist/core/storage/pipeline-rollup.js.map +1 -1
  163. package/dist/core/storage/routing.d.ts +34 -0
  164. package/dist/core/storage/routing.d.ts.map +1 -1
  165. package/dist/core/storage/routing.js +92 -2
  166. package/dist/core/storage/routing.js.map +1 -1
  167. package/dist/core/storage/rows.d.ts +5 -25
  168. package/dist/core/storage/rows.d.ts.map +1 -1
  169. package/dist/core/storage/schema.sql +92 -27
  170. package/dist/core/storage/sessions.d.ts.map +1 -1
  171. package/dist/core/storage/sessions.js +2 -1
  172. package/dist/core/storage/sessions.js.map +1 -1
  173. package/dist/core/storage/skills.d.ts +159 -0
  174. package/dist/core/storage/skills.d.ts.map +1 -1
  175. package/dist/core/storage/skills.js +350 -4
  176. package/dist/core/storage/skills.js.map +1 -1
  177. package/dist/core/storage/sqlite.d.ts +81 -25
  178. package/dist/core/storage/sqlite.d.ts.map +1 -1
  179. package/dist/core/storage/sqlite.js +143 -45
  180. package/dist/core/storage/sqlite.js.map +1 -1
  181. package/dist/core/storage/tasks.d.ts +270 -0
  182. package/dist/core/storage/tasks.d.ts.map +1 -1
  183. package/dist/core/storage/tasks.js +495 -16
  184. package/dist/core/storage/tasks.js.map +1 -1
  185. package/dist/core/storage/tool-intercepts.d.ts +1 -1
  186. package/dist/core/storage/tool-intercepts.js +1 -1
  187. package/dist/core/types.d.ts +26 -3
  188. package/dist/core/types.d.ts.map +1 -1
  189. package/dist/core/types.js +1 -3
  190. package/dist/core/types.js.map +1 -1
  191. package/dist/core/utils/binary-paths.d.ts +32 -0
  192. package/dist/core/utils/binary-paths.d.ts.map +1 -1
  193. package/dist/core/utils/binary-paths.js +52 -0
  194. package/dist/core/utils/binary-paths.js.map +1 -1
  195. package/dist/core/utils/claude-cli-resolver.d.ts.map +1 -0
  196. package/dist/{skills/distill → core/utils}/claude-cli-resolver.js +1 -1
  197. package/dist/core/utils/claude-cli-resolver.js.map +1 -0
  198. package/dist/core/utils/claude-cli-spawn.d.ts +1 -1
  199. package/dist/core/utils/claude-cli-spawn.js +2 -2
  200. package/dist/core/utils/claude-cli-spawn.js.map +1 -1
  201. package/dist/core/utils/noise-prompt.d.ts +1 -1
  202. package/dist/core/utils/noise-prompt.js +1 -1
  203. package/dist/core/utils/time.d.ts +26 -0
  204. package/dist/core/utils/time.d.ts.map +1 -1
  205. package/dist/core/utils/time.js +33 -0
  206. package/dist/core/utils/time.js.map +1 -1
  207. package/dist/daemon/config-store.d.ts.map +1 -1
  208. package/dist/daemon/config-store.js +14 -5
  209. package/dist/daemon/config-store.js.map +1 -1
  210. package/dist/daemon/event-parser.d.ts.map +1 -1
  211. package/dist/daemon/event-parser.js +5 -0
  212. package/dist/daemon/event-parser.js.map +1 -1
  213. package/dist/daemon/handlers/post-tool-use.d.ts +24 -16
  214. package/dist/daemon/handlers/post-tool-use.d.ts.map +1 -1
  215. package/dist/daemon/handlers/post-tool-use.js +76 -116
  216. package/dist/daemon/handlers/post-tool-use.js.map +1 -1
  217. package/dist/daemon/handlers/pre-tool-use.d.ts +35 -10
  218. package/dist/daemon/handlers/pre-tool-use.d.ts.map +1 -1
  219. package/dist/daemon/handlers/pre-tool-use.js +71 -38
  220. package/dist/daemon/handlers/pre-tool-use.js.map +1 -1
  221. package/dist/daemon/handlers/stop.d.ts +20 -0
  222. package/dist/daemon/handlers/stop.d.ts.map +1 -1
  223. package/dist/daemon/handlers/stop.js +96 -8
  224. package/dist/daemon/handlers/stop.js.map +1 -1
  225. package/dist/daemon/handlers/user-prompt.d.ts +16 -1
  226. package/dist/daemon/handlers/user-prompt.d.ts.map +1 -1
  227. package/dist/daemon/handlers/user-prompt.js +97 -56
  228. package/dist/daemon/handlers/user-prompt.js.map +1 -1
  229. package/dist/daemon/handlers/violation-content-backfill.d.ts +76 -0
  230. package/dist/daemon/handlers/violation-content-backfill.d.ts.map +1 -0
  231. package/dist/daemon/handlers/violation-content-backfill.js +167 -0
  232. package/dist/daemon/handlers/violation-content-backfill.js.map +1 -0
  233. package/dist/daemon/index.d.ts +19 -0
  234. package/dist/daemon/index.d.ts.map +1 -1
  235. package/dist/daemon/index.js +125 -200
  236. package/dist/daemon/index.js.map +1 -1
  237. package/dist/daemon/rules/defaults.d.ts.map +1 -1
  238. package/dist/daemon/rules/defaults.js +151 -64
  239. package/dist/daemon/rules/defaults.js.map +1 -1
  240. package/dist/daemon/rules/types.d.ts +28 -22
  241. package/dist/daemon/rules/types.d.ts.map +1 -1
  242. package/dist/daemon/rules/workflow-defaults.js +9 -9
  243. package/dist/daemon/rules/workflow-defaults.js.map +1 -1
  244. package/dist/daemon/services/codegraph-sync.d.ts +94 -0
  245. package/dist/daemon/services/codegraph-sync.d.ts.map +1 -0
  246. package/dist/daemon/services/codegraph-sync.js +159 -0
  247. package/dist/daemon/services/codegraph-sync.js.map +1 -0
  248. package/dist/daemon/services/decision-hint.d.ts +47 -10
  249. package/dist/daemon/services/decision-hint.d.ts.map +1 -1
  250. package/dist/daemon/services/decision-hint.js +99 -24
  251. package/dist/daemon/services/decision-hint.js.map +1 -1
  252. package/dist/daemon/services/event-ttl-sweep.d.ts.map +1 -1
  253. package/dist/daemon/services/event-ttl-sweep.js +3 -2
  254. package/dist/daemon/services/event-ttl-sweep.js.map +1 -1
  255. package/dist/daemon/services/feedback-aggregator.d.ts +14 -26
  256. package/dist/daemon/services/feedback-aggregator.d.ts.map +1 -1
  257. package/dist/daemon/services/feedback-aggregator.js +23 -63
  258. package/dist/daemon/services/feedback-aggregator.js.map +1 -1
  259. package/dist/daemon/services/heartbeat-writer.d.ts +6 -15
  260. package/dist/daemon/services/heartbeat-writer.d.ts.map +1 -1
  261. package/dist/daemon/services/heartbeat-writer.js +7 -36
  262. package/dist/daemon/services/heartbeat-writer.js.map +1 -1
  263. package/dist/daemon/services/kb-injector.d.ts +1 -1
  264. package/dist/daemon/services/kb-injector.d.ts.map +1 -1
  265. package/dist/daemon/services/kb-injector.js +10 -2
  266. package/dist/daemon/services/kb-injector.js.map +1 -1
  267. package/dist/daemon/services/kb-rebuild-scheduler.d.ts +95 -0
  268. package/dist/daemon/services/kb-rebuild-scheduler.d.ts.map +1 -0
  269. package/dist/daemon/services/kb-rebuild-scheduler.js +149 -0
  270. package/dist/daemon/services/kb-rebuild-scheduler.js.map +1 -0
  271. package/dist/daemon/services/loop-hint.d.ts +139 -0
  272. package/dist/daemon/services/loop-hint.d.ts.map +1 -0
  273. package/dist/daemon/services/loop-hint.js +272 -0
  274. package/dist/daemon/services/loop-hint.js.map +1 -0
  275. package/dist/daemon/services/outcome-classification-service.js +1 -1
  276. package/dist/daemon/services/outcome-classification-service.js.map +1 -1
  277. package/dist/daemon/services/task-segmenter.d.ts +11 -0
  278. package/dist/daemon/services/task-segmenter.d.ts.map +1 -1
  279. package/dist/daemon/services/task-segmenter.js +48 -2
  280. package/dist/daemon/services/task-segmenter.js.map +1 -1
  281. package/dist/daemon/startup/maintenance-schedulers.d.ts +68 -0
  282. package/dist/daemon/startup/maintenance-schedulers.d.ts.map +1 -0
  283. package/dist/daemon/startup/maintenance-schedulers.js +294 -0
  284. package/dist/daemon/startup/maintenance-schedulers.js.map +1 -0
  285. package/dist/daemon/templates/agents/agent-retro-distiller.md +106 -0
  286. package/dist/daemon/templates/agents/claudemd-writer.md +1 -0
  287. package/dist/daemon/templates/agents/coder.md +165 -8
  288. package/dist/daemon/templates/agents/decision-maker.md +107 -21
  289. package/dist/daemon/templates/agents/doc-reviewer.md +4 -1
  290. package/dist/daemon/templates/agents/harness-debug-full.md +85 -3
  291. package/dist/daemon/templates/agents/knowledge-builder.md +1 -0
  292. package/dist/daemon/templates/agents/patch-applier.md +1 -0
  293. package/dist/daemon/templates/agents/planner.md +55 -3
  294. package/dist/daemon/templates/agents/safety-net-implementer.md +278 -0
  295. package/dist/daemon/templates/agents/skill-distiller.md +1 -0
  296. package/dist/daemon/templates/agents/task-boundary-classifier.md +1 -0
  297. package/dist/daemon/templates/agents/verify-agent.md +128 -5
  298. package/dist/hooks/stop.sh +7 -1
  299. package/dist/knowledge/builder.js +36 -7
  300. package/dist/knowledge/builder.js.map +1 -1
  301. package/dist/knowledge/constants.d.ts +10 -5
  302. package/dist/knowledge/constants.d.ts.map +1 -1
  303. package/dist/knowledge/constants.js +10 -5
  304. package/dist/knowledge/constants.js.map +1 -1
  305. package/dist/knowledge/graph/edge-extractor.d.ts +45 -0
  306. package/dist/knowledge/graph/edge-extractor.d.ts.map +1 -0
  307. package/dist/knowledge/graph/edge-extractor.js +242 -0
  308. package/dist/knowledge/graph/edge-extractor.js.map +1 -0
  309. package/dist/knowledge/graph/impact.d.ts +73 -0
  310. package/dist/knowledge/graph/impact.d.ts.map +1 -0
  311. package/dist/knowledge/graph/impact.js +94 -0
  312. package/dist/knowledge/graph/impact.js.map +1 -0
  313. package/dist/knowledge/graph/types.d.ts +22 -0
  314. package/dist/knowledge/graph/types.d.ts.map +1 -0
  315. package/dist/knowledge/graph/types.js +13 -0
  316. package/dist/knowledge/graph/types.js.map +1 -0
  317. package/dist/knowledge/prompt.d.ts +9 -0
  318. package/dist/knowledge/prompt.d.ts.map +1 -1
  319. package/dist/knowledge/prompt.js +17 -5
  320. package/dist/knowledge/prompt.js.map +1 -1
  321. package/dist/knowledge/query.d.ts +13 -0
  322. package/dist/knowledge/query.d.ts.map +1 -1
  323. package/dist/knowledge/query.js +107 -10
  324. package/dist/knowledge/query.js.map +1 -1
  325. package/dist/knowledge/repo-map.d.ts +11 -5
  326. package/dist/knowledge/repo-map.d.ts.map +1 -1
  327. package/dist/knowledge/repo-map.js +42 -3
  328. package/dist/knowledge/repo-map.js.map +1 -1
  329. package/dist/knowledge/validator.d.ts.map +1 -1
  330. package/dist/knowledge/validator.js +69 -2
  331. package/dist/knowledge/validator.js.map +1 -1
  332. package/dist/mcp/server.d.ts +64 -8
  333. package/dist/mcp/server.d.ts.map +1 -1
  334. package/dist/mcp/server.js +233 -18
  335. package/dist/mcp/server.js.map +1 -1
  336. package/dist/skills/distill/distiller.js +1 -1
  337. package/dist/skills/distill/distiller.js.map +1 -1
  338. package/dist/skills/distilled/distilled-api-design.md +4 -0
  339. package/dist/skills/distilled/distilled-brainstorming.md +79 -0
  340. package/dist/skills/distilled/distilled-brand-guidelines.md +86 -0
  341. package/dist/skills/distilled/distilled-canvas-design.md +128 -0
  342. package/dist/skills/distilled/distilled-claude-api.md +185 -0
  343. package/dist/skills/distilled/distilled-creator.md +5 -2
  344. package/dist/skills/distilled/distilled-dispatching-parallel-agents.md +136 -0
  345. package/dist/skills/distilled/distilled-doc-coauthoring.md +144 -0
  346. package/dist/skills/distilled/distilled-docx.md +231 -0
  347. package/dist/skills/distilled/distilled-executing-plans.md +85 -50
  348. package/dist/skills/distilled/distilled-finishing-a-development-branch.md +213 -0
  349. package/dist/skills/distilled/distilled-frontend-design.md +118 -0
  350. package/dist/skills/distilled/distilled-harness-engineering.md +1 -1
  351. package/dist/skills/distilled/distilled-receiving-code-review.md +185 -0
  352. package/dist/skills/distilled/distilled-subagent-driven-development.md +124 -0
  353. package/dist/skills/distilled/distilled-systematic-debugging.md +108 -260
  354. package/dist/skills/distilled/distilled-test-driven-development.md +432 -0
  355. package/dist/skills/distilled/distilled-using-superpowers.md +134 -0
  356. package/dist/skills/distilled/distilled-verification-before-completion.md +88 -78
  357. package/dist/skills/distilled/distilled-writing-skills.md +175 -0
  358. package/dist/skills/registry.d.ts +10 -50
  359. package/dist/skills/registry.d.ts.map +1 -1
  360. package/dist/skills/registry.js +7 -118
  361. package/dist/skills/registry.js.map +1 -1
  362. package/dist/skills/tools/pipeline-suggest.js +2 -2
  363. package/dist/skills/tools/pipeline-suggest.js.map +1 -1
  364. package/dist/skills/tools/skill-invoke.d.ts +2 -1
  365. package/dist/skills/tools/skill-invoke.d.ts.map +1 -1
  366. package/dist/skills/tools/skill-invoke.js +3 -1
  367. package/dist/skills/tools/skill-invoke.js.map +1 -1
  368. package/dist/web/analytics/anti-pattern-detector.d.ts.map +1 -1
  369. package/dist/web/analytics/anti-pattern-detector.js +6 -1
  370. package/dist/web/analytics/anti-pattern-detector.js.map +1 -1
  371. package/dist/web/analytics/drift-detector.d.ts +6 -0
  372. package/dist/web/analytics/drift-detector.d.ts.map +1 -1
  373. package/dist/web/analytics/drift-detector.js +15 -8
  374. package/dist/web/analytics/drift-detector.js.map +1 -1
  375. package/dist/web/analytics/weekly-report.d.ts +13 -0
  376. package/dist/web/analytics/weekly-report.d.ts.map +1 -1
  377. package/dist/web/analytics/weekly-report.js +17 -3
  378. package/dist/web/analytics/weekly-report.js.map +1 -1
  379. package/dist/web/routes/_helpers.d.ts +31 -0
  380. package/dist/web/routes/_helpers.d.ts.map +1 -1
  381. package/dist/web/routes/_helpers.js +33 -0
  382. package/dist/web/routes/_helpers.js.map +1 -1
  383. package/dist/web/routes/agent-distill.d.ts +49 -0
  384. package/dist/web/routes/agent-distill.d.ts.map +1 -0
  385. package/dist/web/routes/agent-distill.js +526 -0
  386. package/dist/web/routes/agent-distill.js.map +1 -0
  387. package/dist/web/routes/config.d.ts +56 -0
  388. package/dist/web/routes/config.d.ts.map +1 -0
  389. package/dist/web/routes/config.js +243 -0
  390. package/dist/web/routes/config.js.map +1 -0
  391. package/dist/web/routes/decisions.js +1 -1
  392. package/dist/web/routes/decisions.js.map +1 -1
  393. package/dist/web/routes/error-handler.d.ts +0 -4
  394. package/dist/web/routes/error-handler.d.ts.map +1 -1
  395. package/dist/web/routes/error-handler.js +0 -8
  396. package/dist/web/routes/error-handler.js.map +1 -1
  397. package/dist/web/routes/events.d.ts.map +1 -1
  398. package/dist/web/routes/events.js +2 -1
  399. package/dist/web/routes/events.js.map +1 -1
  400. package/dist/web/routes/insights.d.ts.map +1 -1
  401. package/dist/web/routes/insights.js +0 -0
  402. package/dist/web/routes/insights.js.map +1 -1
  403. package/dist/web/routes/knowledge.d.ts +43 -2
  404. package/dist/web/routes/knowledge.d.ts.map +1 -1
  405. package/dist/web/routes/knowledge.js +117 -6
  406. package/dist/web/routes/knowledge.js.map +1 -1
  407. package/dist/web/routes/pipeline.d.ts +0 -9
  408. package/dist/web/routes/pipeline.d.ts.map +1 -1
  409. package/dist/web/routes/pipeline.js +0 -4
  410. package/dist/web/routes/pipeline.js.map +1 -1
  411. package/dist/web/routes/rules.d.ts.map +1 -1
  412. package/dist/web/routes/rules.js +20 -6
  413. package/dist/web/routes/rules.js.map +1 -1
  414. package/dist/web/routes/sessions.d.ts.map +1 -1
  415. package/dist/web/routes/sessions.js +8 -7
  416. package/dist/web/routes/sessions.js.map +1 -1
  417. package/dist/web/routes/skill-stats.d.ts.map +1 -1
  418. package/dist/web/routes/skill-stats.js +153 -16
  419. package/dist/web/routes/skill-stats.js.map +1 -1
  420. package/dist/web/routes/skills-distill.js +1 -1
  421. package/dist/web/routes/skills-distill.js.map +1 -1
  422. package/dist/web/routes/stats.d.ts.map +1 -1
  423. package/dist/web/routes/stats.js +2 -1
  424. package/dist/web/routes/stats.js.map +1 -1
  425. package/dist/web/routes/task-timeline.d.ts +95 -19
  426. package/dist/web/routes/task-timeline.d.ts.map +1 -1
  427. package/dist/web/routes/task-timeline.js +344 -88
  428. package/dist/web/routes/task-timeline.js.map +1 -1
  429. package/dist/web/routes/tasks.d.ts.map +1 -1
  430. package/dist/web/routes/tasks.js +52 -30
  431. package/dist/web/routes/tasks.js.map +1 -1
  432. package/dist/web/routes/violations.d.ts +1 -1
  433. package/dist/web/routes/violations.d.ts.map +1 -1
  434. package/dist/web/routes/violations.js +3 -2
  435. package/dist/web/routes/violations.js.map +1 -1
  436. package/dist/web/server.d.ts.map +1 -1
  437. package/dist/web/server.js +20 -0
  438. package/dist/web/server.js.map +1 -1
  439. package/dist/web/services/agent-distill-manager.d.ts +122 -0
  440. package/dist/web/services/agent-distill-manager.d.ts.map +1 -0
  441. package/dist/web/services/agent-distill-manager.js +397 -0
  442. package/dist/web/services/agent-distill-manager.js.map +1 -0
  443. package/dist/web/services/distill-manager.d.ts +47 -0
  444. package/dist/web/services/distill-manager.d.ts.map +1 -1
  445. package/dist/web/services/distill-manager.js +103 -0
  446. package/dist/web/services/distill-manager.js.map +1 -1
  447. package/dist/web/static/assets/AgentDetailPage-DlUeA1sX.js +2 -0
  448. package/dist/web/static/assets/AgentDetailPage-DlUeA1sX.js.map +1 -0
  449. package/dist/web/static/assets/AgentDistillRunPage-Cybo4bii.js +3 -0
  450. package/dist/web/static/assets/AgentDistillRunPage-Cybo4bii.js.map +1 -0
  451. package/dist/web/static/assets/AgentsPage-Qd9FExLG.js +2 -0
  452. package/dist/web/static/assets/AgentsPage-Qd9FExLG.js.map +1 -0
  453. package/dist/web/static/assets/DaemonHealthPage-DTSVqtrI.js +2 -0
  454. package/dist/web/static/assets/DaemonHealthPage-DTSVqtrI.js.map +1 -0
  455. package/dist/web/static/assets/DecisionDetailPage-b4BA8dhc.js +2 -0
  456. package/dist/web/static/assets/DecisionDetailPage-b4BA8dhc.js.map +1 -0
  457. package/dist/web/static/assets/DecisionsPage-a3NRo_T7.js +2 -0
  458. package/dist/web/static/assets/DecisionsPage-a3NRo_T7.js.map +1 -0
  459. package/dist/web/static/assets/DiagnosticsPage-DIVdiIQG.js +2 -0
  460. package/dist/web/static/assets/DiagnosticsPage-DIVdiIQG.js.map +1 -0
  461. package/dist/web/static/assets/DistillDetailPage-U6a3l2iP.js +4 -0
  462. package/dist/web/static/assets/DistillDetailPage-U6a3l2iP.js.map +1 -0
  463. package/dist/web/static/assets/DistillPage-O7BHtRN8.js +2 -0
  464. package/dist/web/static/assets/DistillPage-O7BHtRN8.js.map +1 -0
  465. package/dist/web/static/assets/DistillRunPage-D1JuRWWr.js +2 -0
  466. package/dist/web/static/assets/DistillRunPage-D1JuRWWr.js.map +1 -0
  467. package/dist/web/static/assets/GlobalScopeHint-Q3wTJx3F.js +2 -0
  468. package/dist/web/static/assets/GlobalScopeHint-Q3wTJx3F.js.map +1 -0
  469. package/dist/web/static/assets/IssueDetailPage-BDfrtk2C.js +2 -0
  470. package/dist/web/static/assets/IssueDetailPage-BDfrtk2C.js.map +1 -0
  471. package/dist/web/static/assets/IssuesPage-SKmhlCrw.js +2 -0
  472. package/dist/web/static/assets/IssuesPage-SKmhlCrw.js.map +1 -0
  473. package/dist/web/static/assets/KbDetailPage-Yna86Na8.js +2 -0
  474. package/dist/web/static/assets/KbDetailPage-Yna86Na8.js.map +1 -0
  475. package/dist/web/static/assets/KbHitsPage-Cljl7H9p.js +2 -0
  476. package/dist/web/static/assets/KbHitsPage-Cljl7H9p.js.map +1 -0
  477. package/dist/web/static/assets/{MarkdownRenderer-DZmTl-8J.js → MarkdownRenderer-DlDQNihj.js} +2 -2
  478. package/dist/web/static/assets/{MarkdownRenderer-DZmTl-8J.js.map → MarkdownRenderer-DlDQNihj.js.map} +1 -1
  479. package/dist/web/static/assets/NotFound-LMzbP51V.js +2 -0
  480. package/dist/web/static/assets/{NotFound-BQPh0vaF.js.map → NotFound-LMzbP51V.js.map} +1 -1
  481. package/dist/web/static/assets/SettingsPage-DzoK4PKg.js +2 -0
  482. package/dist/web/static/assets/SettingsPage-DzoK4PKg.js.map +1 -0
  483. package/dist/web/static/assets/SkillDetailPage-BuBJJ_NX.js +2 -0
  484. package/dist/web/static/assets/SkillDetailPage-BuBJJ_NX.js.map +1 -0
  485. package/dist/web/static/assets/SkillsPage-aojkJpBc.js +2 -0
  486. package/dist/web/static/assets/SkillsPage-aojkJpBc.js.map +1 -0
  487. package/dist/web/static/assets/TaskDetailPage-1ckxnGhw.js +4 -0
  488. package/dist/web/static/assets/TaskDetailPage-1ckxnGhw.js.map +1 -0
  489. package/dist/web/static/assets/TasksHubPage-C2PLh3eg.js +6 -0
  490. package/dist/web/static/assets/TasksHubPage-C2PLh3eg.js.map +1 -0
  491. package/dist/web/static/assets/WorkplacePage-DHrp5VxS.js +2 -0
  492. package/dist/web/static/assets/WorkplacePage-DHrp5VxS.js.map +1 -0
  493. package/dist/web/static/assets/arco-DV6xCLhr.js +14 -0
  494. package/dist/web/static/assets/arco-DV6xCLhr.js.map +1 -0
  495. package/dist/web/static/assets/charts-BSV4cyC4.js +37 -0
  496. package/dist/web/static/assets/charts-BSV4cyC4.js.map +1 -0
  497. package/dist/web/static/assets/{index-7bl3kbcx.css → index-B_v_MKlb.css} +1 -1
  498. package/dist/web/static/assets/index-DileOOE4.js +4 -0
  499. package/dist/web/static/assets/index-DileOOE4.js.map +1 -0
  500. package/dist/web/static/assets/markdown-CA7ePUts.js +30 -0
  501. package/dist/web/static/assets/markdown-CA7ePUts.js.map +1 -0
  502. package/dist/web/static/assets/{outcome-DUn1NjlC.js → outcome-BKGy9azt.js} +2 -2
  503. package/dist/web/static/assets/{outcome-DUn1NjlC.js.map → outcome-BKGy9azt.js.map} +1 -1
  504. package/dist/web/static/assets/{query-S6X1S7K9.js → query-CgCOpYWf.js} +2 -2
  505. package/dist/web/static/assets/{query-S6X1S7K9.js.map → query-CgCOpYWf.js.map} +1 -1
  506. package/dist/web/static/assets/{react-router-JVUrkhdd.js → react-router-Cxmg8RuL.js} +3 -3
  507. package/dist/web/static/assets/{react-router-JVUrkhdd.js.map → react-router-Cxmg8RuL.js.map} +1 -1
  508. package/dist/web/static/assets/{syntax-highlighter-BkZfCDsz.js → syntax-highlighter-BDYycNja.js} +3 -3
  509. package/dist/web/static/assets/{syntax-highlighter-BkZfCDsz.js.map → syntax-highlighter-BDYycNja.js.map} +1 -1
  510. package/dist/web/static/assets/task-title-BhOcemuR.js +2 -0
  511. package/dist/web/static/assets/task-title-BhOcemuR.js.map +1 -0
  512. package/dist/web/static/assets/useAgentStats-B-uTgqBd.js +2 -0
  513. package/dist/web/static/assets/useAgentStats-B-uTgqBd.js.map +1 -0
  514. package/dist/web/static/assets/useDecisions-D-G2Ft5T.js +2 -0
  515. package/dist/web/static/assets/useDecisions-D-G2Ft5T.js.map +1 -0
  516. package/dist/web/static/assets/useDistill-21dZkXlT.js +3 -0
  517. package/dist/web/static/assets/useDistill-21dZkXlT.js.map +1 -0
  518. package/dist/web/static/assets/useEffectiveProject-DQiyX54y.js +2 -0
  519. package/dist/web/static/assets/useEffectiveProject-DQiyX54y.js.map +1 -0
  520. package/dist/web/static/assets/useIssuesFeed-CFiyQkAL.js +2 -0
  521. package/dist/web/static/assets/useIssuesFeed-CFiyQkAL.js.map +1 -0
  522. package/dist/web/static/assets/useKbHits-xKXWgqh9.js +2 -0
  523. package/dist/web/static/assets/useKbHits-xKXWgqh9.js.map +1 -0
  524. package/dist/web/static/assets/useSkillStats-B5hbIwdf.js +2 -0
  525. package/dist/web/static/assets/useSkillStats-B5hbIwdf.js.map +1 -0
  526. package/dist/web/static/assets/vendor-DS-q4Eyc.js +36 -0
  527. package/dist/web/static/assets/vendor-DS-q4Eyc.js.map +1 -0
  528. package/dist/web/static/index.html +6 -6
  529. package/package.json +5 -3
  530. package/dist/core/storage/workflow-recommendations.d.ts +0 -124
  531. package/dist/core/storage/workflow-recommendations.d.ts.map +0 -1
  532. package/dist/core/storage/workflow-recommendations.js +0 -274
  533. package/dist/core/storage/workflow-recommendations.js.map +0 -1
  534. package/dist/daemon/services/experience-extractor.d.ts.map +0 -1
  535. package/dist/daemon/services/experience-extractor.js.map +0 -1
  536. package/dist/daemon/services/violation-reporter.d.ts.map +0 -1
  537. package/dist/daemon/services/violation-reporter.js.map +0 -1
  538. package/dist/daemon/templates/agents/harness-hotfix.md +0 -99
  539. package/dist/daemon/templates/agents/hybrid-feature-with-safety.md +0 -104
  540. package/dist/daemon/templates/agents/refactor-specialist.md +0 -98
  541. package/dist/skills/distill/claude-cli-resolver.d.ts.map +0 -1
  542. package/dist/skills/distill/claude-cli-resolver.js.map +0 -1
  543. package/dist/skills/distilled/distilled-defi-amm-security.md +0 -293
  544. package/dist/skills/keyword-score.d.ts +0 -29
  545. package/dist/skills/keyword-score.d.ts.map +0 -1
  546. package/dist/skills/keyword-score.js +0 -54
  547. package/dist/skills/keyword-score.js.map +0 -1
  548. package/dist/web/static/assets/AgentContentPage-DkeRNxok.js +0 -2
  549. package/dist/web/static/assets/AgentContentPage-DkeRNxok.js.map +0 -1
  550. package/dist/web/static/assets/AgentDelegationTable-ByBa0x1l.js +0 -2
  551. package/dist/web/static/assets/AgentDelegationTable-ByBa0x1l.js.map +0 -1
  552. package/dist/web/static/assets/ContextInsightsPage-oUk7_I8u.js +0 -3
  553. package/dist/web/static/assets/ContextInsightsPage-oUk7_I8u.js.map +0 -1
  554. package/dist/web/static/assets/DaemonHealthPage-DG2fyOP7.js +0 -2
  555. package/dist/web/static/assets/DaemonHealthPage-DG2fyOP7.js.map +0 -1
  556. package/dist/web/static/assets/DecisionsPage-CMAPEnKb.js +0 -2
  557. package/dist/web/static/assets/DecisionsPage-CMAPEnKb.js.map +0 -1
  558. package/dist/web/static/assets/DiagnosticsPage-DQd-Zm4r.js +0 -2
  559. package/dist/web/static/assets/DiagnosticsPage-DQd-Zm4r.js.map +0 -1
  560. package/dist/web/static/assets/DriftTab-DqpepOhI.js +0 -2
  561. package/dist/web/static/assets/DriftTab-DqpepOhI.js.map +0 -1
  562. package/dist/web/static/assets/HealthHomePage-CN6zNIie.js +0 -3
  563. package/dist/web/static/assets/HealthHomePage-CN6zNIie.js.map +0 -1
  564. package/dist/web/static/assets/KbHitRateTable-ByEIWujF.js +0 -2
  565. package/dist/web/static/assets/KbHitRateTable-ByEIWujF.js.map +0 -1
  566. package/dist/web/static/assets/NotFound-BQPh0vaF.js +0 -2
  567. package/dist/web/static/assets/ProjectSwitcher-D3lZMFd3.js +0 -2
  568. package/dist/web/static/assets/ProjectSwitcher-D3lZMFd3.js.map +0 -1
  569. package/dist/web/static/assets/SettingsPage-oLJBNzQj.js +0 -2
  570. package/dist/web/static/assets/SettingsPage-oLJBNzQj.js.map +0 -1
  571. package/dist/web/static/assets/SkillContentPage-DK5rgfgw.js +0 -2
  572. package/dist/web/static/assets/SkillContentPage-DK5rgfgw.js.map +0 -1
  573. package/dist/web/static/assets/SkillStatsTable-DYMzjEUV.js +0 -2
  574. package/dist/web/static/assets/SkillStatsTable-DYMzjEUV.js.map +0 -1
  575. package/dist/web/static/assets/SkillsDistillTab-C7qaG8q3.js +0 -2
  576. package/dist/web/static/assets/SkillsDistillTab-C7qaG8q3.js.map +0 -1
  577. package/dist/web/static/assets/TasksHubPage-03wsRRsJ.js +0 -6
  578. package/dist/web/static/assets/TasksHubPage-03wsRRsJ.js.map +0 -1
  579. package/dist/web/static/assets/ViolationsPage-DSiLr-9O.js +0 -3
  580. package/dist/web/static/assets/ViolationsPage-DSiLr-9O.js.map +0 -1
  581. package/dist/web/static/assets/arco-Bhi3a6Qp.js +0 -14
  582. package/dist/web/static/assets/arco-Bhi3a6Qp.js.map +0 -1
  583. package/dist/web/static/assets/charts-BuHQWDbQ.js +0 -37
  584. package/dist/web/static/assets/charts-BuHQWDbQ.js.map +0 -1
  585. package/dist/web/static/assets/index-BIYnq1Dx.js +0 -4
  586. package/dist/web/static/assets/index-BIYnq1Dx.js.map +0 -1
  587. package/dist/web/static/assets/useTabsParam-k8qte_0C.js +0 -2
  588. package/dist/web/static/assets/useTabsParam-k8qte_0C.js.map +0 -1
  589. package/dist/web/static/assets/vendor-DWgdB1eY.js +0 -65
  590. package/dist/web/static/assets/vendor-DWgdB1eY.js.map +0 -1
  591. /package/dist/{skills/distill → core/utils}/claude-cli-resolver.d.ts +0 -0
@@ -0,0 +1,397 @@
1
+ /**
2
+ * AgentDistillManager — per-agent retro-distill job manager for the web
3
+ * `POST /api/agent/distill/run` path (decision 568a8c53).
4
+ *
5
+ * Structurally MIRRORS `distill-manager.ts` (session map / SSE event broadcast /
6
+ * TTL GC / AbortController cancel) but is a SEPARATE class so the proven skill
7
+ * distill path is never touched (Option B — blast-radius isolation). The two
8
+ * differ in lock semantics:
9
+ * - skill distill: ONE global job at a time.
10
+ * - agent distill: per-agent mutex (different agents may run in parallel; the
11
+ * SAME agent's second run → AgentDistillConflictError / 409), plus a global
12
+ * concurrency cap (MAX_CONCURRENT_AGENT_DISTILL) to avoid an LLM storm.
13
+ *
14
+ * 红线 (decision 568a8c53 / core-belief #2): the ONLY caller of `start()` is the
15
+ * human-triggered `POST /api/agent/distill/run` route. This module must NEVER be
16
+ * imported by daemon startup / loop / scheduler code (import-graph guard test).
17
+ *
18
+ * Cost safety: real spawns burn LLM. Tests inject a fake `spawn` returning a
19
+ * pre-baked envelope string — the real `spawnAgentRetroDistiller` is NEVER
20
+ * exercised by automated tests.
21
+ */
22
+ import { randomBytes } from 'node:crypto';
23
+ import { promises as fsp } from 'node:fs';
24
+ import path from 'node:path';
25
+ import { logger } from '../../core/utils/logger.js';
26
+ import { SQLiteStorage } from '../../core/storage/sqlite.js';
27
+ import { FORGE_PATHS } from '../../core/constants.js';
28
+ import { spawnAgentRetroDistiller, parseAgentPatchEnvelope, } from '../../core/insights/agent-distill-spawn.js';
29
+ import { scanAgentPatch } from '../../core/insights/agent-anchor-guard.js';
30
+ import { buildAgentDistillContextFor, renderDraft, } from '../../cli/commands/agent.js';
31
+ /** Finished sessions live this long before GC. */
32
+ const SESSION_TTL_MS = 5 * 60 * 1000;
33
+ /**
34
+ * Global cap on concurrently-running agent distills (independent of the per-agent
35
+ * mutex). Guards against an LLM-spawn storm (vitest IO-storm教训 / decision
36
+ * 8a51b15d analogue): even with N distinct agents, never spawn more than this at
37
+ * once.
38
+ */
39
+ export const MAX_CONCURRENT_AGENT_DISTILL = 2;
40
+ export class AgentDistillConflictError extends Error {
41
+ agent;
42
+ status = 409;
43
+ constructor(agent) {
44
+ super(`Agent distill already running for "${agent}"`);
45
+ this.agent = agent;
46
+ this.name = 'AgentDistillConflictError';
47
+ }
48
+ }
49
+ export class AgentDistillCapacityError extends Error {
50
+ status = 409;
51
+ constructor() {
52
+ super(`Too many agent distills running (cap ${MAX_CONCURRENT_AGENT_DISTILL})`);
53
+ this.name = 'AgentDistillCapacityError';
54
+ }
55
+ }
56
+ export class AgentDistillManager {
57
+ /** Per-agent mutex: agent → its in-flight session. */
58
+ running = new Map();
59
+ sessions = new Map();
60
+ listeners = new Map();
61
+ lastFinished = null;
62
+ /** True iff the given agent has an in-flight distill. */
63
+ isBusy(agent) {
64
+ const s = this.running.get(agent);
65
+ return s != null && s.doneAt === null;
66
+ }
67
+ /** Count of in-flight distills across all agents. */
68
+ runningCount() {
69
+ let n = 0;
70
+ for (const s of this.running.values())
71
+ if (s.doneAt === null)
72
+ n++;
73
+ return n;
74
+ }
75
+ /** Agent name of any single in-flight distill (UI convenience). */
76
+ getBusyAgent() {
77
+ for (const s of this.running.values())
78
+ if (s.doneAt === null)
79
+ return s.agent;
80
+ return null;
81
+ }
82
+ getSession(id) {
83
+ return this.sessions.get(id) ?? null;
84
+ }
85
+ getLastFinished() {
86
+ return this.lastFinished;
87
+ }
88
+ /**
89
+ * Kick off a per-agent distill run. Throws AgentDistillConflictError (same
90
+ * agent already running) or AgentDistillCapacityError (global cap reached).
91
+ * Returns immediately; the spawn runs in the background. Subscribers get
92
+ * events via subscribe().
93
+ */
94
+ start(options) {
95
+ const agent = (options.agent ?? '').trim();
96
+ if (this.isBusy(agent)) {
97
+ throw new AgentDistillConflictError(agent);
98
+ }
99
+ if (this.runningCount() >= MAX_CONCURRENT_AGENT_DISTILL) {
100
+ throw new AgentDistillCapacityError();
101
+ }
102
+ const runId = `agent-distill-${randomBytes(6).toString('hex')}`;
103
+ const session = {
104
+ runId,
105
+ agent,
106
+ startedAt: Date.now(),
107
+ doneAt: null,
108
+ events: [],
109
+ cancelRequested: false,
110
+ draftPath: null,
111
+ lastError: null,
112
+ };
113
+ this.running.set(agent, session);
114
+ this.sessions.set(runId, session);
115
+ this.pushEvent(runId, {
116
+ type: 'start',
117
+ at: new Date().toISOString(),
118
+ agent,
119
+ message: `Agent distill started: ${agent}`,
120
+ runId,
121
+ });
122
+ void this.runWithChildProcess(session, options).finally(() => {
123
+ session.doneAt = Date.now();
124
+ this.lastFinished = session;
125
+ if (this.running.get(agent) === session)
126
+ this.running.delete(agent);
127
+ setTimeout(() => {
128
+ this.sessions.delete(runId);
129
+ this.listeners.delete(runId);
130
+ }, SESSION_TTL_MS).unref?.();
131
+ });
132
+ return { runId };
133
+ }
134
+ subscribe(runId, listener) {
135
+ let set = this.listeners.get(runId);
136
+ if (!set) {
137
+ set = new Set();
138
+ this.listeners.set(runId, set);
139
+ }
140
+ set.add(listener);
141
+ return () => {
142
+ const s = this.listeners.get(runId);
143
+ if (s)
144
+ s.delete(listener);
145
+ };
146
+ }
147
+ cancel(runId) {
148
+ const session = this.sessions.get(runId);
149
+ if (!session || session.doneAt !== null)
150
+ return false;
151
+ session.cancelRequested = true;
152
+ return true;
153
+ }
154
+ pushEvent(runId, ev) {
155
+ const session = this.sessions.get(runId);
156
+ if (!session)
157
+ return;
158
+ session.events.push(ev);
159
+ const subs = this.listeners.get(runId);
160
+ if (subs) {
161
+ for (const fn of subs) {
162
+ try {
163
+ fn(ev);
164
+ }
165
+ catch (err) {
166
+ logger.warn(`[AgentDistillManager] listener error: ${err}`);
167
+ }
168
+ }
169
+ }
170
+ }
171
+ /**
172
+ * Assemble read-only context → gate → spawn distiller → parse envelope →
173
+ * anchor-guard → write draft. Terminates with one of: done | cancelled |
174
+ * error. NEVER writes the template itself (that is the adopt path).
175
+ */
176
+ async runWithChildProcess(session, opts) {
177
+ const { runId, agent } = session;
178
+ const abort = new AbortController();
179
+ const cancelPoll = setInterval(() => {
180
+ if (session.cancelRequested && !abort.signal.aborted)
181
+ abort.abort();
182
+ }, 100).unref?.();
183
+ const clearPoll = () => {
184
+ if (cancelPoll)
185
+ clearInterval(cancelPoll);
186
+ };
187
+ this.pushEvent(runId, {
188
+ type: 'phase-changed',
189
+ at: new Date().toISOString(),
190
+ agent,
191
+ message: '组装信号 + 评估门槛…',
192
+ runId,
193
+ });
194
+ const ownStorage = !opts.storage;
195
+ let storage;
196
+ try {
197
+ storage = opts.storage ?? new SQLiteStorage(FORGE_PATHS.database());
198
+ }
199
+ catch (err) {
200
+ clearPoll();
201
+ this.pushEvent(runId, {
202
+ type: 'error',
203
+ at: new Date().toISOString(),
204
+ agent,
205
+ errorMessage: `cannot open storage: ${err instanceof Error ? err.message : String(err)}`,
206
+ runId,
207
+ });
208
+ return;
209
+ }
210
+ try {
211
+ if (session.cancelRequested) {
212
+ this.pushEvent(runId, {
213
+ type: 'cancelled',
214
+ at: new Date().toISOString(),
215
+ agent,
216
+ message: 'Cancelled before start',
217
+ runId,
218
+ });
219
+ return;
220
+ }
221
+ // ── read-only signal context (shared with CLI). ────────────────────────
222
+ let built;
223
+ try {
224
+ built = buildAgentDistillContextFor(agent, {
225
+ storage,
226
+ templatesDir: opts.templatesDir,
227
+ days: opts.days,
228
+ maxFailures: opts.maxFailures,
229
+ });
230
+ }
231
+ catch (err) {
232
+ this.pushEvent(runId, {
233
+ type: 'error',
234
+ at: new Date().toISOString(),
235
+ agent,
236
+ errorMessage: err instanceof Error ? err.message : String(err),
237
+ runId,
238
+ });
239
+ return;
240
+ }
241
+ const { ctx, currentVersion } = built;
242
+ // ── gate (门槛 1): honest degradation, NOT an error. ───────────────────
243
+ if (!ctx.enoughSignal) {
244
+ this.pushEvent(runId, {
245
+ type: 'done',
246
+ at: new Date().toISOString(),
247
+ agent,
248
+ message: ctx.insufficientReason ?? '数据不足,未产改进草案。',
249
+ currentVersion,
250
+ maturity: ctx.maturity,
251
+ runId,
252
+ });
253
+ return;
254
+ }
255
+ // ── spawn the distiller (real LLM, or injected fake in tests). ─────────
256
+ this.pushEvent(runId, {
257
+ type: 'distiller-spawned',
258
+ at: new Date().toISOString(),
259
+ agent,
260
+ message: 'spawn agent-retro-distiller…',
261
+ maturity: ctx.maturity,
262
+ runId,
263
+ });
264
+ const spawnFn = opts.spawn ?? ((p, sig) => spawnAgentRetroDistiller(p, { cancelSignal: sig }));
265
+ let raw;
266
+ try {
267
+ raw = await spawnFn(ctx.prompt, abort.signal);
268
+ }
269
+ catch (err) {
270
+ if (session.cancelRequested) {
271
+ this.pushEvent(runId, {
272
+ type: 'cancelled',
273
+ at: new Date().toISOString(),
274
+ agent,
275
+ message: 'Cancelled by user',
276
+ runId,
277
+ });
278
+ return;
279
+ }
280
+ this.pushEvent(runId, {
281
+ type: 'error',
282
+ at: new Date().toISOString(),
283
+ agent,
284
+ errorMessage: `distiller spawn failed: ${err instanceof Error ? err.message : String(err)}`,
285
+ runId,
286
+ });
287
+ return;
288
+ }
289
+ // ── parse the envelope. ────────────────────────────────────────────────
290
+ const envelope = parseAgentPatchEnvelope(raw);
291
+ if (envelope === null) {
292
+ this.pushEvent(runId, {
293
+ type: 'error',
294
+ at: new Date().toISOString(),
295
+ agent,
296
+ errorMessage: 'distiller output has no recognizable ---AGENT-PATCH--- or ---NOOP--- envelope; no draft written.',
297
+ runId,
298
+ });
299
+ return;
300
+ }
301
+ if (envelope.kind === 'noop') {
302
+ this.pushEvent(runId, {
303
+ type: 'done',
304
+ at: new Date().toISOString(),
305
+ agent,
306
+ message: `distiller 判定无值得改的改动(NOOP):${envelope.rationale}`,
307
+ currentVersion,
308
+ maturity: ctx.maturity,
309
+ runId,
310
+ });
311
+ return;
312
+ }
313
+ // ── anchor-guard (校验 1 of 2; adopt re-checks). ───────────────────────
314
+ const violations = scanAgentPatch(envelope.patch);
315
+ if (violations.length > 0) {
316
+ this.pushEvent(runId, {
317
+ type: 'anchor-rejected',
318
+ at: new Date().toISOString(),
319
+ agent,
320
+ message: `patch 触碰 ${violations.length} 处保护区——草案 REJECTED,未写文件`,
321
+ violations: violations.map((v) => ({ region: v.region, line: v.line, patchLine: v.patchLine })),
322
+ runId,
323
+ });
324
+ this.pushEvent(runId, {
325
+ type: 'error',
326
+ at: new Date().toISOString(),
327
+ agent,
328
+ errorMessage: `anchor-guard rejected ${violations.length} protected-region edit(s)`,
329
+ runId,
330
+ });
331
+ return;
332
+ }
333
+ // ── write the human-reviewed DRAFT (NEVER the template). ───────────────
334
+ const today = new Date().toISOString().slice(0, 10);
335
+ const outBase = opts.outBaseDir ?? path.join(process.cwd(), 'docs', 'design');
336
+ const outDir = path.join(outBase, today, 'agent-distill');
337
+ const targetVersion = envelope.targetVersion ?? currentVersion + 1;
338
+ const draftPath = path.join(outDir, `${agent}-v${targetVersion}-draft.md`);
339
+ await fsp.mkdir(outDir, { recursive: true });
340
+ await fsp.writeFile(draftPath, renderDraft(agent, currentVersion, targetVersion, ctx.maturity, envelope.rationale, envelope.patch), 'utf-8');
341
+ session.draftPath = draftPath;
342
+ this.pushEvent(runId, {
343
+ type: 'draft-written',
344
+ at: new Date().toISOString(),
345
+ agent,
346
+ message: `草案已写入(人审,未落模板):${draftPath}`,
347
+ draftPath,
348
+ targetVersion,
349
+ currentVersion,
350
+ maturity: ctx.maturity,
351
+ runId,
352
+ });
353
+ this.pushEvent(runId, {
354
+ type: 'done',
355
+ at: new Date().toISOString(),
356
+ agent,
357
+ message: '草案生成完成',
358
+ draftPath,
359
+ targetVersion,
360
+ currentVersion,
361
+ maturity: ctx.maturity,
362
+ runId,
363
+ });
364
+ }
365
+ catch (err) {
366
+ const msg = err instanceof Error ? err.message : String(err);
367
+ session.lastError = msg;
368
+ this.pushEvent(runId, {
369
+ type: 'error',
370
+ at: new Date().toISOString(),
371
+ agent,
372
+ errorMessage: msg,
373
+ runId,
374
+ });
375
+ logger.warn(`[AgentDistillManager] run failed: ${msg}`);
376
+ }
377
+ finally {
378
+ clearPoll();
379
+ if (ownStorage) {
380
+ try {
381
+ storage.close();
382
+ }
383
+ catch { /* ignore */ }
384
+ }
385
+ }
386
+ }
387
+ /** Test-only: reset internal state. @internal */
388
+ _reset() {
389
+ this.running.clear();
390
+ this.sessions.clear();
391
+ this.listeners.clear();
392
+ this.lastFinished = null;
393
+ }
394
+ }
395
+ /** Module-level singleton (one manager per daemon; per-agent locks inside). */
396
+ export const agentDistillManager = new AgentDistillManager();
397
+ //# sourceMappingURL=agent-distill-manager.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"agent-distill-manager.js","sourceRoot":"","sources":["../../../src/web/services/agent-distill-manager.ts"],"names":[],"mappings":"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"}
@@ -27,6 +27,16 @@
27
27
  * JSON file (writeFile is atomic on POSIX — acceptable, documented in spec).
28
28
  */
29
29
  import { DEFAULT_STATE_PATH, type DistillState, type RunOptions, type RunResult } from '../../skills/distill/index.js';
30
+ /**
31
+ * Minimal contract DistillManager needs from the daemon's SkillRegistry —
32
+ * just `reload()`. Typed structurally (not importing the class) so the web
33
+ * service stays decoupled from the daemon and no circular import is created
34
+ * (decision 4e592120). The daemon injects its real singleton via
35
+ * `setRegistry()` at startup.
36
+ */
37
+ export interface ReloadableRegistry {
38
+ reload(): void;
39
+ }
30
40
  /**
31
41
  * Event types emitted to SSE subscribers.
32
42
  * R-D: `gate-paused` removed (no sample-approve gate in R-B; never emitted).
@@ -75,6 +85,20 @@ export declare class DistillManager {
75
85
  private sessions;
76
86
  private listeners;
77
87
  private lastFinished;
88
+ /**
89
+ * The daemon's live SkillRegistry singleton. Injected at startup via
90
+ * `setRegistry()`. When set, a successful distill run that produced new
91
+ * skill files triggers `reload()` so the dashboard / MCP skill list reflect
92
+ * the new skill WITHOUT a daemon restart (decision 4e592120 invariant b).
93
+ * null in tests / pre-injection — sync + reload are then skipped fail-soft.
94
+ */
95
+ private registry;
96
+ /**
97
+ * Inject the daemon's SkillRegistry so post-distill `reload()` can refresh
98
+ * the in-memory skill list (used by /api/skills + MCP skill-list, all on the
99
+ * same singleton). Idempotent; safe to call once at daemon startup.
100
+ */
101
+ setRegistry(registry: ReloadableRegistry | null): void;
78
102
  /** True when a distill job is currently running. */
79
103
  isBusy(): boolean;
80
104
  getCurrent(): DistillSession | null;
@@ -108,6 +132,29 @@ export declare class DistillManager {
108
132
  * one of: `done`, `cancelled`, `error`.
109
133
  */
110
134
  private runWithChildProcess;
135
+ /**
136
+ * Decision 4e592120 (invariants c/d): copy each freshly-distilled .md from
137
+ * the runtime write dir into the git source-of-truth `src/skills/distilled`
138
+ * so a later `npm run build` (rm -rf dist + cp src→dist) does not delete the
139
+ * new skill. The companion NOTICE attribution stays where the distiller
140
+ * already wrote it (not touched here).
141
+ *
142
+ * Graceful degradation:
143
+ * - Packaged/npm-global install → `srcDir` is null (no src/ checkout) → skip
144
+ * silently; runtime-only write already satisfies invariant (a).
145
+ * - When the runtime write dir IS the src dir (dev/vitest), there is nothing
146
+ * to copy → skip.
147
+ * - Any individual copy failure is logged at warn and swallowed — a persist
148
+ * miss must never fail the distill run (the runtime copy still works).
149
+ */
150
+ private persistToSource;
151
+ /**
152
+ * Decision 4e592120 (invariant b): reload the injected live SkillRegistry so
153
+ * the dashboard `/api/skills` list + MCP `skill-list` (same singleton) show
154
+ * the new skill without a daemon restart. Fail-soft: no registry injected
155
+ * (tests / pre-wire) or a reload throw is logged and swallowed.
156
+ */
157
+ private reloadRegistry;
111
158
  /**
112
159
  * Test-only: reset internal state.
113
160
  * @internal
@@ -1 +1 @@
1
- {"version":3,"file":"distill-manager.d.ts","sourceRoot":"","sources":["../../../src/web/services/distill-manager.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2BG;AAMH,OAAO,EAGL,kBAAkB,EAClB,KAAK,YAAY,EACjB,KAAK,UAAU,EACf,KAAK,SAAS,EACf,MAAM,+BAA+B,CAAC;AAmBvC;;;GAGG;AACH,MAAM,MAAM,gBAAgB,GACxB,WAAW,GACX,OAAO,GACP,UAAU,GACV,eAAe,GACf,iBAAiB,GACjB,MAAM,GACN,WAAW,GACX,OAAO,CAAC;AAEZ,MAAM,WAAW,YAAY;IAC3B,IAAI,EAAE,gBAAgB,CAAC;IACvB,2CAA2C;IAC3C,EAAE,EAAE,MAAM,CAAC;IACX,kDAAkD;IAClD,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,iDAAiD;IACjD,KAAK,CAAC,EAAE,YAAY,CAAC,OAAO,CAAC,CAAC;IAC9B,4DAA4D;IAC5D,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,yCAAyC;IACzC,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,qDAAqD;IACrD,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,YAAY,CAAC,EAAE,OAAO,CAAC;IACvB,oBAAoB;IACpB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,6CAA6C;IAC7C,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED,MAAM,WAAW,cAAc;IAC7B,KAAK,EAAE,MAAM,CAAC;IACd,SAAS,EAAE,MAAM,CAAC;IAClB,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC;IACtB,MAAM,EAAE,YAAY,EAAE,CAAC;IACvB,oFAAoF;IACpF,OAAO,EAAE,UAAU,CAAC;IACpB,oDAAoD;IACpD,UAAU,EAAE,SAAS,GAAG,IAAI,CAAC;IAC7B,+DAA+D;IAC/D,eAAe,EAAE,OAAO,CAAC;CAC1B;AAED,qBAAa,oBAAqB,SAAQ,KAAK;IAC7C,MAAM,SAAO;gBACD,GAAG,EAAE,MAAM;CAIxB;AAED,qBAAa,cAAc;IACzB,OAAO,CAAC,OAAO,CAA+B;IAC9C,OAAO,CAAC,QAAQ,CAAqC;IACrD,OAAO,CAAC,SAAS,CAAqD;IACtE,OAAO,CAAC,YAAY,CAA+B;IACnD,oDAAoD;IACpD,MAAM,IAAI,OAAO;IAIjB,UAAU,IAAI,cAAc,GAAG,IAAI;IAInC,UAAU,CAAC,EAAE,EAAE,MAAM,GAAG,cAAc,GAAG,IAAI;IAI7C,eAAe,IAAI,cAAc,GAAG,IAAI;IAIxC;;;;OAIG;IACH,KAAK,CAAC,OAAO,EAAE,UAAU,GAAG;QAAE,KAAK,EAAE,MAAM,CAAA;KAAE;IAyD7C;;;;OAIG;IACH,SAAS,CACP,KAAK,EAAE,MAAM,EACb,QAAQ,EAAE,CAAC,CAAC,EAAE,YAAY,KAAK,IAAI,GAClC,MAAM,IAAI;IAab;;;;OAIG;IACH,MAAM,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO;IAO9B,OAAO,CAAC,SAAS;IAgBjB;;;;;OAKG;YACW,mBAAmB;IA8GjC;;;OAGG;IACH,MAAM,IAAI,IAAI;CAMf;AAED,2DAA2D;AAC3D,eAAO,MAAM,cAAc,gBAAuB,CAAC;AAEnD,6DAA6D;AAC7D,OAAO,EAAE,kBAAkB,EAAE,CAAC;AAE9B,uCAAuC;AACvC,wBAAsB,gBAAgB,CACpC,SAAS,CAAC,EAAE,MAAM,GACjB,OAAO,CAAC,YAAY,GAAG,IAAI,CAAC,CAE9B;AAED,8CAA8C;AAC9C,wBAAsB,kBAAkB,CACtC,SAAS,CAAC,EAAE,MAAM,GACjB,OAAO,CAAC,OAAO,CAAC,CAOlB"}
1
+ {"version":3,"file":"distill-manager.d.ts","sourceRoot":"","sources":["../../../src/web/services/distill-manager.ts"],"names":[],"mappings":"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"}
@@ -28,7 +28,9 @@
28
28
  */
29
29
  import { randomBytes } from 'node:crypto';
30
30
  import { promises as fsp } from 'node:fs';
31
+ import path from 'node:path';
31
32
  import { logger } from '../../core/utils/logger.js';
33
+ import { resolveDistilledWriteTargets } from '../../core/utils/binary-paths.js';
32
34
  import { distillRun, readState, DEFAULT_STATE_PATH, } from '../../skills/distill/index.js';
33
35
  // R-A (spec 1851): ClaudeProvider import dropped — distill no longer takes
34
36
  // a provider. R-B will replace `runWithPolling` with a child_process spawn.
@@ -57,6 +59,22 @@ export class DistillManager {
57
59
  sessions = new Map();
58
60
  listeners = new Map();
59
61
  lastFinished = null;
62
+ /**
63
+ * The daemon's live SkillRegistry singleton. Injected at startup via
64
+ * `setRegistry()`. When set, a successful distill run that produced new
65
+ * skill files triggers `reload()` so the dashboard / MCP skill list reflect
66
+ * the new skill WITHOUT a daemon restart (decision 4e592120 invariant b).
67
+ * null in tests / pre-injection — sync + reload are then skipped fail-soft.
68
+ */
69
+ registry = null;
70
+ /**
71
+ * Inject the daemon's SkillRegistry so post-distill `reload()` can refresh
72
+ * the in-memory skill list (used by /api/skills + MCP skill-list, all on the
73
+ * same singleton). Idempotent; safe to call once at daemon startup.
74
+ */
75
+ setRegistry(registry) {
76
+ this.registry = registry;
77
+ }
60
78
  /** True when a distill job is currently running. */
61
79
  isBusy() {
62
80
  return this.current !== null && this.current.doneAt === null;
@@ -175,6 +193,14 @@ export class DistillManager {
175
193
  */
176
194
  async runWithChildProcess(session, opts) {
177
195
  const statePath = opts.statePath ?? DEFAULT_STATE_PATH;
196
+ // Decision 4e592120 (invariant a): pin the write target to the RUNTIME
197
+ // read dir (dist in prod, src in dev) resolved binDir-relative — NOT
198
+ // process.cwd(). Without this, a launchd daemon (cwd=/) falls through to
199
+ // distillRun's `process.cwd()/src/skills/distilled` default which resolves
200
+ // to /src/skills/distilled and silently writes nowhere useful. Caller may
201
+ // still override via opts.outputDir (tests / explicit paths).
202
+ const writeTargets = resolveDistilledWriteTargets();
203
+ const outputDir = opts.outputDir ?? writeTargets.runtimeDir;
178
204
  // AbortController bridges DistillSession.cancelRequested → child.kill in
179
205
  // the distiller. We poll the flag every 100ms (cheaper than rewriting
180
206
  // cancel() to be Promise-based).
@@ -208,6 +234,7 @@ export class DistillManager {
208
234
  }
209
235
  const result = await distillRun({
210
236
  ...opts,
237
+ outputDir,
211
238
  cancelSignal: abort.signal,
212
239
  onProgress: (ev) => {
213
240
  // Forward partial-message char counts as `progress` events; emit
@@ -250,6 +277,18 @@ export class DistillManager {
250
277
  });
251
278
  }
252
279
  else {
280
+ // Decision 4e592120 (invariants b/c/d): only when the run actually
281
+ // produced new skill files (skip / rejected outcomes yield no .md and
282
+ // must NOT trigger persist/reload). Persist each produced file into the
283
+ // git source-of-truth (src/) so a later `npm run build` rebuild does
284
+ // NOT delete it, then reload the live registry so the dashboard / MCP
285
+ // skill list reflect the new skill with no daemon restart. Both steps
286
+ // are fail-soft: a failure here must never turn a successful distill
287
+ // into a reported error.
288
+ if (result.distilled.length > 0) {
289
+ await this.persistToSource(result, writeTargets);
290
+ this.reloadRegistry();
291
+ }
253
292
  this.pushEvent(session.runId, {
254
293
  type: 'done',
255
294
  at: new Date().toISOString(),
@@ -276,6 +315,69 @@ export class DistillManager {
276
315
  logger.warn(`[DistillManager] run failed: ${msg}`);
277
316
  }
278
317
  }
318
+ /**
319
+ * Decision 4e592120 (invariants c/d): copy each freshly-distilled .md from
320
+ * the runtime write dir into the git source-of-truth `src/skills/distilled`
321
+ * so a later `npm run build` (rm -rf dist + cp src→dist) does not delete the
322
+ * new skill. The companion NOTICE attribution stays where the distiller
323
+ * already wrote it (not touched here).
324
+ *
325
+ * Graceful degradation:
326
+ * - Packaged/npm-global install → `srcDir` is null (no src/ checkout) → skip
327
+ * silently; runtime-only write already satisfies invariant (a).
328
+ * - When the runtime write dir IS the src dir (dev/vitest), there is nothing
329
+ * to copy → skip.
330
+ * - Any individual copy failure is logged at warn and swallowed — a persist
331
+ * miss must never fail the distill run (the runtime copy still works).
332
+ */
333
+ async persistToSource(result, targets) {
334
+ const { runtimeDir, srcDir } = targets;
335
+ // No src checkout (packaged) or runtime IS the source (dev) → nothing to do.
336
+ if (!srcDir)
337
+ return;
338
+ if (path.resolve(srcDir) === path.resolve(runtimeDir))
339
+ return;
340
+ try {
341
+ await fsp.mkdir(srcDir, { recursive: true });
342
+ }
343
+ catch (err) {
344
+ logger.warn(`[DistillManager] persist: failed to ensure src dir ${srcDir}: ${err}`);
345
+ return;
346
+ }
347
+ for (const r of result.distilled) {
348
+ try {
349
+ const fileName = path.basename(r.outputPath);
350
+ // The distiller wrote to runtimeDir (we pinned outputDir). Copy that
351
+ // exact produced file into src so the two stay byte-identical.
352
+ const from = r.outputPath;
353
+ const to = path.join(srcDir, fileName);
354
+ await fsp.copyFile(from, to);
355
+ logger.info(`[DistillManager] persisted ${fileName} → ${to}`);
356
+ }
357
+ catch (err) {
358
+ logger.warn(`[DistillManager] persist: failed to copy ${r.outputPath} to src: ${err}`);
359
+ }
360
+ }
361
+ }
362
+ /**
363
+ * Decision 4e592120 (invariant b): reload the injected live SkillRegistry so
364
+ * the dashboard `/api/skills` list + MCP `skill-list` (same singleton) show
365
+ * the new skill without a daemon restart. Fail-soft: no registry injected
366
+ * (tests / pre-wire) or a reload throw is logged and swallowed.
367
+ */
368
+ reloadRegistry() {
369
+ if (!this.registry) {
370
+ logger.debug('[DistillManager] reload skipped: no registry injected');
371
+ return;
372
+ }
373
+ try {
374
+ this.registry.reload();
375
+ logger.info('[DistillManager] SkillRegistry reloaded after distill');
376
+ }
377
+ catch (err) {
378
+ logger.warn(`[DistillManager] registry reload failed (non-fatal): ${err}`);
379
+ }
380
+ }
279
381
  /**
280
382
  * Test-only: reset internal state.
281
383
  * @internal
@@ -285,6 +387,7 @@ export class DistillManager {
285
387
  this.sessions.clear();
286
388
  this.listeners.clear();
287
389
  this.lastFinished = null;
390
+ this.registry = null;
288
391
  }
289
392
  }
290
393
  /** Module-level singleton (one distill job per daemon). */