@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.
- package/DEVELOPMENT.md +80 -19
- package/README.md +13 -6
- package/dist/catalogs/agents.json +19 -24
- package/dist/catalogs/skills.json +139 -27
- package/dist/claudemd/templates/swarm-protocol.md +1 -1
- package/dist/cli/commands/agent.d.ts +169 -0
- package/dist/cli/commands/agent.d.ts.map +1 -0
- package/dist/cli/commands/agent.js +690 -0
- package/dist/cli/commands/agent.js.map +1 -0
- package/dist/cli/commands/codegraph.d.ts +17 -0
- package/dist/cli/commands/codegraph.d.ts.map +1 -0
- package/dist/cli/commands/codegraph.js +263 -0
- package/dist/cli/commands/codegraph.js.map +1 -0
- package/dist/cli/commands/decisions.d.ts.map +1 -1
- package/dist/cli/commands/decisions.js +46 -9
- package/dist/cli/commands/decisions.js.map +1 -1
- package/dist/cli/commands/executions.d.ts.map +1 -1
- package/dist/cli/commands/executions.js +2 -1
- package/dist/cli/commands/executions.js.map +1 -1
- package/dist/cli/commands/insights-goal-check.d.ts +5 -1
- package/dist/cli/commands/insights-goal-check.d.ts.map +1 -1
- package/dist/cli/commands/insights-goal-check.js +15 -15
- package/dist/cli/commands/insights-goal-check.js.map +1 -1
- package/dist/cli/commands/knowledge.d.ts +51 -0
- package/dist/cli/commands/knowledge.d.ts.map +1 -1
- package/dist/cli/commands/knowledge.js +202 -29
- package/dist/cli/commands/knowledge.js.map +1 -1
- package/dist/cli/commands/loop.d.ts +95 -0
- package/dist/cli/commands/loop.d.ts.map +1 -0
- package/dist/cli/commands/loop.js +408 -0
- package/dist/cli/commands/loop.js.map +1 -0
- package/dist/cli/commands/maintenance.d.ts +33 -0
- package/dist/cli/commands/maintenance.d.ts.map +1 -0
- package/dist/cli/commands/maintenance.js +75 -0
- package/dist/cli/commands/maintenance.js.map +1 -0
- package/dist/cli/commands/mcp.d.ts +23 -0
- package/dist/cli/commands/mcp.d.ts.map +1 -1
- package/dist/cli/commands/mcp.js +82 -0
- package/dist/cli/commands/mcp.js.map +1 -1
- package/dist/cli/commands/skills.d.ts +131 -0
- package/dist/cli/commands/skills.d.ts.map +1 -1
- package/dist/cli/commands/skills.js +409 -9
- package/dist/cli/commands/skills.js.map +1 -1
- package/dist/cli/commands/stats.d.ts.map +1 -1
- package/dist/cli/commands/stats.js +9 -2
- package/dist/cli/commands/stats.js.map +1 -1
- package/dist/cli/index.js +8 -0
- package/dist/cli/index.js.map +1 -1
- package/dist/core/constants.d.ts +37 -0
- package/dist/core/constants.d.ts.map +1 -1
- package/dist/core/constants.js +43 -0
- package/dist/core/constants.js.map +1 -1
- package/dist/core/diagnostics/checks.d.ts.map +1 -1
- package/dist/core/diagnostics/checks.js +2 -1
- package/dist/core/diagnostics/checks.js.map +1 -1
- package/dist/core/diagnostics/daemon-status.d.ts +1 -1
- package/dist/core/diagnostics/daemon-status.d.ts.map +1 -1
- package/dist/core/diagnostics/daemon-status.js +1 -1
- package/dist/core/diagnostics/daemon-status.js.map +1 -1
- package/dist/core/diagnostics/entropy-checks.d.ts +3 -2
- package/dist/core/diagnostics/entropy-checks.d.ts.map +1 -1
- package/dist/core/diagnostics/entropy-checks.js +10 -5
- package/dist/core/diagnostics/entropy-checks.js.map +1 -1
- package/dist/core/diagnostics/heartbeat-reader.d.ts +28 -0
- package/dist/core/diagnostics/heartbeat-reader.d.ts.map +1 -0
- package/dist/core/diagnostics/heartbeat-reader.js +50 -0
- package/dist/core/diagnostics/heartbeat-reader.js.map +1 -0
- package/dist/core/event-fields.d.ts +27 -0
- package/dist/core/event-fields.d.ts.map +1 -1
- package/dist/core/event-fields.js +43 -0
- package/dist/core/event-fields.js.map +1 -1
- package/dist/core/governance/global-inject.d.ts +34 -4
- package/dist/core/governance/global-inject.d.ts.map +1 -1
- package/dist/core/governance/global-inject.js +80 -25
- package/dist/core/governance/global-inject.js.map +1 -1
- package/dist/core/insights/agent-anchor-guard.d.ts +77 -0
- package/dist/core/insights/agent-anchor-guard.d.ts.map +1 -0
- package/dist/core/insights/agent-anchor-guard.js +119 -0
- package/dist/core/insights/agent-anchor-guard.js.map +1 -0
- package/dist/core/insights/agent-distill-context.d.ts +55 -0
- package/dist/core/insights/agent-distill-context.d.ts.map +1 -0
- package/dist/core/insights/agent-distill-context.js +146 -0
- package/dist/core/insights/agent-distill-context.js.map +1 -0
- package/dist/core/insights/agent-distill-spawn.d.ts +56 -0
- package/dist/core/insights/agent-distill-spawn.d.ts.map +1 -0
- package/dist/core/insights/agent-distill-spawn.js +179 -0
- package/dist/core/insights/agent-distill-spawn.js.map +1 -0
- package/dist/core/insights/agent-drift.d.ts +66 -0
- package/dist/core/insights/agent-drift.d.ts.map +1 -0
- package/dist/core/insights/agent-drift.js +109 -0
- package/dist/core/insights/agent-drift.js.map +1 -0
- package/dist/core/insights/agent-evolution-sources.d.ts +21 -0
- package/dist/core/insights/agent-evolution-sources.d.ts.map +1 -0
- package/dist/core/insights/agent-evolution-sources.js +36 -0
- package/dist/core/insights/agent-evolution-sources.js.map +1 -0
- package/dist/core/insights/agent-health.d.ts +142 -0
- package/dist/core/insights/agent-health.d.ts.map +1 -0
- package/dist/core/insights/agent-health.js +296 -0
- package/dist/core/insights/agent-health.js.map +1 -0
- package/dist/core/insights/agent-patch-apply.d.ts +45 -0
- package/dist/core/insights/agent-patch-apply.d.ts.map +1 -0
- package/dist/core/insights/agent-patch-apply.js +165 -0
- package/dist/core/insights/agent-patch-apply.js.map +1 -0
- package/dist/core/insights/agent-suggest.d.ts +128 -0
- package/dist/core/insights/agent-suggest.d.ts.map +1 -0
- package/dist/core/insights/agent-suggest.js +284 -0
- package/dist/core/insights/agent-suggest.js.map +1 -0
- package/dist/core/insights/coverage-tiers.d.ts +46 -0
- package/dist/core/insights/coverage-tiers.d.ts.map +1 -0
- package/dist/core/insights/coverage-tiers.js +95 -0
- package/dist/core/insights/coverage-tiers.js.map +1 -0
- package/dist/{daemon/services → core/insights}/experience-extractor.d.ts +0 -7
- package/dist/core/insights/experience-extractor.d.ts.map +1 -0
- package/dist/{daemon/services → core/insights}/experience-extractor.js +5 -9
- package/dist/core/insights/experience-extractor.js.map +1 -0
- package/dist/{daemon/services → core/insights}/violation-reporter.d.ts +20 -1
- package/dist/core/insights/violation-reporter.d.ts.map +1 -0
- package/dist/{daemon/services → core/insights}/violation-reporter.js +56 -4
- package/dist/core/insights/violation-reporter.js.map +1 -0
- package/dist/core/loop/loop-engine.d.ts +140 -0
- package/dist/core/loop/loop-engine.d.ts.map +1 -0
- package/dist/core/loop/loop-engine.js +266 -0
- package/dist/core/loop/loop-engine.js.map +1 -0
- package/dist/core/queue/index.d.ts.map +1 -1
- package/dist/core/queue/index.js +2 -1
- package/dist/core/queue/index.js.map +1 -1
- package/dist/core/storage/base.d.ts +159 -0
- package/dist/core/storage/base.d.ts.map +1 -1
- package/dist/core/storage/base.js +523 -0
- package/dist/core/storage/base.js.map +1 -1
- package/dist/core/storage/codegraph-types.d.ts +79 -0
- package/dist/core/storage/codegraph-types.d.ts.map +1 -0
- package/dist/core/storage/codegraph-types.js +14 -0
- package/dist/core/storage/codegraph-types.js.map +1 -0
- package/dist/core/storage/codegraph.d.ts +186 -0
- package/dist/core/storage/codegraph.d.ts.map +1 -0
- package/dist/core/storage/codegraph.js +452 -0
- package/dist/core/storage/codegraph.js.map +1 -0
- package/dist/core/storage/decisions.d.ts +30 -5
- package/dist/core/storage/decisions.d.ts.map +1 -1
- package/dist/core/storage/decisions.js +45 -13
- package/dist/core/storage/decisions.js.map +1 -1
- package/dist/core/storage/events.d.ts +127 -0
- package/dist/core/storage/events.d.ts.map +1 -1
- package/dist/core/storage/events.js +318 -3
- package/dist/core/storage/events.js.map +1 -1
- package/dist/core/storage/feedback.d.ts +3 -23
- package/dist/core/storage/feedback.d.ts.map +1 -1
- package/dist/core/storage/feedback.js +37 -38
- package/dist/core/storage/feedback.js.map +1 -1
- package/dist/core/storage/injections.d.ts +40 -0
- package/dist/core/storage/injections.d.ts.map +1 -1
- package/dist/core/storage/injections.js +69 -0
- package/dist/core/storage/injections.js.map +1 -1
- package/dist/core/storage/knowledge.d.ts +226 -0
- package/dist/core/storage/knowledge.d.ts.map +1 -1
- package/dist/core/storage/knowledge.js +391 -4
- package/dist/core/storage/knowledge.js.map +1 -1
- package/dist/core/storage/pipeline-rollup.d.ts +1 -7
- package/dist/core/storage/pipeline-rollup.d.ts.map +1 -1
- package/dist/core/storage/pipeline-rollup.js +18 -57
- package/dist/core/storage/pipeline-rollup.js.map +1 -1
- package/dist/core/storage/routing.d.ts +34 -0
- package/dist/core/storage/routing.d.ts.map +1 -1
- package/dist/core/storage/routing.js +92 -2
- package/dist/core/storage/routing.js.map +1 -1
- package/dist/core/storage/rows.d.ts +5 -25
- package/dist/core/storage/rows.d.ts.map +1 -1
- package/dist/core/storage/schema.sql +92 -27
- package/dist/core/storage/sessions.d.ts.map +1 -1
- package/dist/core/storage/sessions.js +2 -1
- package/dist/core/storage/sessions.js.map +1 -1
- package/dist/core/storage/skills.d.ts +159 -0
- package/dist/core/storage/skills.d.ts.map +1 -1
- package/dist/core/storage/skills.js +350 -4
- package/dist/core/storage/skills.js.map +1 -1
- package/dist/core/storage/sqlite.d.ts +81 -25
- package/dist/core/storage/sqlite.d.ts.map +1 -1
- package/dist/core/storage/sqlite.js +143 -45
- package/dist/core/storage/sqlite.js.map +1 -1
- package/dist/core/storage/tasks.d.ts +270 -0
- package/dist/core/storage/tasks.d.ts.map +1 -1
- package/dist/core/storage/tasks.js +495 -16
- package/dist/core/storage/tasks.js.map +1 -1
- package/dist/core/storage/tool-intercepts.d.ts +1 -1
- package/dist/core/storage/tool-intercepts.js +1 -1
- package/dist/core/types.d.ts +26 -3
- package/dist/core/types.d.ts.map +1 -1
- package/dist/core/types.js +1 -3
- package/dist/core/types.js.map +1 -1
- package/dist/core/utils/binary-paths.d.ts +32 -0
- package/dist/core/utils/binary-paths.d.ts.map +1 -1
- package/dist/core/utils/binary-paths.js +52 -0
- package/dist/core/utils/binary-paths.js.map +1 -1
- package/dist/core/utils/claude-cli-resolver.d.ts.map +1 -0
- package/dist/{skills/distill → core/utils}/claude-cli-resolver.js +1 -1
- package/dist/core/utils/claude-cli-resolver.js.map +1 -0
- package/dist/core/utils/claude-cli-spawn.d.ts +1 -1
- package/dist/core/utils/claude-cli-spawn.js +2 -2
- package/dist/core/utils/claude-cli-spawn.js.map +1 -1
- package/dist/core/utils/noise-prompt.d.ts +1 -1
- package/dist/core/utils/noise-prompt.js +1 -1
- package/dist/core/utils/time.d.ts +26 -0
- package/dist/core/utils/time.d.ts.map +1 -1
- package/dist/core/utils/time.js +33 -0
- package/dist/core/utils/time.js.map +1 -1
- package/dist/daemon/config-store.d.ts.map +1 -1
- package/dist/daemon/config-store.js +14 -5
- package/dist/daemon/config-store.js.map +1 -1
- package/dist/daemon/event-parser.d.ts.map +1 -1
- package/dist/daemon/event-parser.js +5 -0
- package/dist/daemon/event-parser.js.map +1 -1
- package/dist/daemon/handlers/post-tool-use.d.ts +24 -16
- package/dist/daemon/handlers/post-tool-use.d.ts.map +1 -1
- package/dist/daemon/handlers/post-tool-use.js +76 -116
- package/dist/daemon/handlers/post-tool-use.js.map +1 -1
- package/dist/daemon/handlers/pre-tool-use.d.ts +35 -10
- package/dist/daemon/handlers/pre-tool-use.d.ts.map +1 -1
- package/dist/daemon/handlers/pre-tool-use.js +71 -38
- package/dist/daemon/handlers/pre-tool-use.js.map +1 -1
- package/dist/daemon/handlers/stop.d.ts +20 -0
- package/dist/daemon/handlers/stop.d.ts.map +1 -1
- package/dist/daemon/handlers/stop.js +96 -8
- package/dist/daemon/handlers/stop.js.map +1 -1
- package/dist/daemon/handlers/user-prompt.d.ts +16 -1
- package/dist/daemon/handlers/user-prompt.d.ts.map +1 -1
- package/dist/daemon/handlers/user-prompt.js +97 -56
- package/dist/daemon/handlers/user-prompt.js.map +1 -1
- package/dist/daemon/handlers/violation-content-backfill.d.ts +76 -0
- package/dist/daemon/handlers/violation-content-backfill.d.ts.map +1 -0
- package/dist/daemon/handlers/violation-content-backfill.js +167 -0
- package/dist/daemon/handlers/violation-content-backfill.js.map +1 -0
- package/dist/daemon/index.d.ts +19 -0
- package/dist/daemon/index.d.ts.map +1 -1
- package/dist/daemon/index.js +125 -200
- package/dist/daemon/index.js.map +1 -1
- package/dist/daemon/rules/defaults.d.ts.map +1 -1
- package/dist/daemon/rules/defaults.js +151 -64
- package/dist/daemon/rules/defaults.js.map +1 -1
- package/dist/daemon/rules/types.d.ts +28 -22
- package/dist/daemon/rules/types.d.ts.map +1 -1
- package/dist/daemon/rules/workflow-defaults.js +9 -9
- package/dist/daemon/rules/workflow-defaults.js.map +1 -1
- package/dist/daemon/services/codegraph-sync.d.ts +94 -0
- package/dist/daemon/services/codegraph-sync.d.ts.map +1 -0
- package/dist/daemon/services/codegraph-sync.js +159 -0
- package/dist/daemon/services/codegraph-sync.js.map +1 -0
- package/dist/daemon/services/decision-hint.d.ts +47 -10
- package/dist/daemon/services/decision-hint.d.ts.map +1 -1
- package/dist/daemon/services/decision-hint.js +99 -24
- package/dist/daemon/services/decision-hint.js.map +1 -1
- package/dist/daemon/services/event-ttl-sweep.d.ts.map +1 -1
- package/dist/daemon/services/event-ttl-sweep.js +3 -2
- package/dist/daemon/services/event-ttl-sweep.js.map +1 -1
- package/dist/daemon/services/feedback-aggregator.d.ts +14 -26
- package/dist/daemon/services/feedback-aggregator.d.ts.map +1 -1
- package/dist/daemon/services/feedback-aggregator.js +23 -63
- package/dist/daemon/services/feedback-aggregator.js.map +1 -1
- package/dist/daemon/services/heartbeat-writer.d.ts +6 -15
- package/dist/daemon/services/heartbeat-writer.d.ts.map +1 -1
- package/dist/daemon/services/heartbeat-writer.js +7 -36
- package/dist/daemon/services/heartbeat-writer.js.map +1 -1
- package/dist/daemon/services/kb-injector.d.ts +1 -1
- package/dist/daemon/services/kb-injector.d.ts.map +1 -1
- package/dist/daemon/services/kb-injector.js +10 -2
- package/dist/daemon/services/kb-injector.js.map +1 -1
- package/dist/daemon/services/kb-rebuild-scheduler.d.ts +95 -0
- package/dist/daemon/services/kb-rebuild-scheduler.d.ts.map +1 -0
- package/dist/daemon/services/kb-rebuild-scheduler.js +149 -0
- package/dist/daemon/services/kb-rebuild-scheduler.js.map +1 -0
- package/dist/daemon/services/loop-hint.d.ts +139 -0
- package/dist/daemon/services/loop-hint.d.ts.map +1 -0
- package/dist/daemon/services/loop-hint.js +272 -0
- package/dist/daemon/services/loop-hint.js.map +1 -0
- package/dist/daemon/services/outcome-classification-service.js +1 -1
- package/dist/daemon/services/outcome-classification-service.js.map +1 -1
- package/dist/daemon/services/task-segmenter.d.ts +11 -0
- package/dist/daemon/services/task-segmenter.d.ts.map +1 -1
- package/dist/daemon/services/task-segmenter.js +48 -2
- package/dist/daemon/services/task-segmenter.js.map +1 -1
- package/dist/daemon/startup/maintenance-schedulers.d.ts +68 -0
- package/dist/daemon/startup/maintenance-schedulers.d.ts.map +1 -0
- package/dist/daemon/startup/maintenance-schedulers.js +294 -0
- package/dist/daemon/startup/maintenance-schedulers.js.map +1 -0
- package/dist/daemon/templates/agents/agent-retro-distiller.md +106 -0
- package/dist/daemon/templates/agents/claudemd-writer.md +1 -0
- package/dist/daemon/templates/agents/coder.md +165 -8
- package/dist/daemon/templates/agents/decision-maker.md +107 -21
- package/dist/daemon/templates/agents/doc-reviewer.md +4 -1
- package/dist/daemon/templates/agents/harness-debug-full.md +85 -3
- package/dist/daemon/templates/agents/knowledge-builder.md +1 -0
- package/dist/daemon/templates/agents/patch-applier.md +1 -0
- package/dist/daemon/templates/agents/planner.md +55 -3
- package/dist/daemon/templates/agents/safety-net-implementer.md +278 -0
- package/dist/daemon/templates/agents/skill-distiller.md +1 -0
- package/dist/daemon/templates/agents/task-boundary-classifier.md +1 -0
- package/dist/daemon/templates/agents/verify-agent.md +128 -5
- package/dist/hooks/stop.sh +7 -1
- package/dist/knowledge/builder.js +36 -7
- package/dist/knowledge/builder.js.map +1 -1
- package/dist/knowledge/constants.d.ts +10 -5
- package/dist/knowledge/constants.d.ts.map +1 -1
- package/dist/knowledge/constants.js +10 -5
- package/dist/knowledge/constants.js.map +1 -1
- package/dist/knowledge/graph/edge-extractor.d.ts +45 -0
- package/dist/knowledge/graph/edge-extractor.d.ts.map +1 -0
- package/dist/knowledge/graph/edge-extractor.js +242 -0
- package/dist/knowledge/graph/edge-extractor.js.map +1 -0
- package/dist/knowledge/graph/impact.d.ts +73 -0
- package/dist/knowledge/graph/impact.d.ts.map +1 -0
- package/dist/knowledge/graph/impact.js +94 -0
- package/dist/knowledge/graph/impact.js.map +1 -0
- package/dist/knowledge/graph/types.d.ts +22 -0
- package/dist/knowledge/graph/types.d.ts.map +1 -0
- package/dist/knowledge/graph/types.js +13 -0
- package/dist/knowledge/graph/types.js.map +1 -0
- package/dist/knowledge/prompt.d.ts +9 -0
- package/dist/knowledge/prompt.d.ts.map +1 -1
- package/dist/knowledge/prompt.js +17 -5
- package/dist/knowledge/prompt.js.map +1 -1
- package/dist/knowledge/query.d.ts +13 -0
- package/dist/knowledge/query.d.ts.map +1 -1
- package/dist/knowledge/query.js +107 -10
- package/dist/knowledge/query.js.map +1 -1
- package/dist/knowledge/repo-map.d.ts +11 -5
- package/dist/knowledge/repo-map.d.ts.map +1 -1
- package/dist/knowledge/repo-map.js +42 -3
- package/dist/knowledge/repo-map.js.map +1 -1
- package/dist/knowledge/validator.d.ts.map +1 -1
- package/dist/knowledge/validator.js +69 -2
- package/dist/knowledge/validator.js.map +1 -1
- package/dist/mcp/server.d.ts +64 -8
- package/dist/mcp/server.d.ts.map +1 -1
- package/dist/mcp/server.js +233 -18
- package/dist/mcp/server.js.map +1 -1
- package/dist/skills/distill/distiller.js +1 -1
- package/dist/skills/distill/distiller.js.map +1 -1
- package/dist/skills/distilled/distilled-api-design.md +4 -0
- package/dist/skills/distilled/distilled-brainstorming.md +79 -0
- package/dist/skills/distilled/distilled-brand-guidelines.md +86 -0
- package/dist/skills/distilled/distilled-canvas-design.md +128 -0
- package/dist/skills/distilled/distilled-claude-api.md +185 -0
- package/dist/skills/distilled/distilled-creator.md +5 -2
- package/dist/skills/distilled/distilled-dispatching-parallel-agents.md +136 -0
- package/dist/skills/distilled/distilled-doc-coauthoring.md +144 -0
- package/dist/skills/distilled/distilled-docx.md +231 -0
- package/dist/skills/distilled/distilled-executing-plans.md +85 -50
- package/dist/skills/distilled/distilled-finishing-a-development-branch.md +213 -0
- package/dist/skills/distilled/distilled-frontend-design.md +118 -0
- package/dist/skills/distilled/distilled-harness-engineering.md +1 -1
- package/dist/skills/distilled/distilled-receiving-code-review.md +185 -0
- package/dist/skills/distilled/distilled-subagent-driven-development.md +124 -0
- package/dist/skills/distilled/distilled-systematic-debugging.md +108 -260
- package/dist/skills/distilled/distilled-test-driven-development.md +432 -0
- package/dist/skills/distilled/distilled-using-superpowers.md +134 -0
- package/dist/skills/distilled/distilled-verification-before-completion.md +88 -78
- package/dist/skills/distilled/distilled-writing-skills.md +175 -0
- package/dist/skills/registry.d.ts +10 -50
- package/dist/skills/registry.d.ts.map +1 -1
- package/dist/skills/registry.js +7 -118
- package/dist/skills/registry.js.map +1 -1
- package/dist/skills/tools/pipeline-suggest.js +2 -2
- package/dist/skills/tools/pipeline-suggest.js.map +1 -1
- package/dist/skills/tools/skill-invoke.d.ts +2 -1
- package/dist/skills/tools/skill-invoke.d.ts.map +1 -1
- package/dist/skills/tools/skill-invoke.js +3 -1
- package/dist/skills/tools/skill-invoke.js.map +1 -1
- package/dist/web/analytics/anti-pattern-detector.d.ts.map +1 -1
- package/dist/web/analytics/anti-pattern-detector.js +6 -1
- package/dist/web/analytics/anti-pattern-detector.js.map +1 -1
- package/dist/web/analytics/drift-detector.d.ts +6 -0
- package/dist/web/analytics/drift-detector.d.ts.map +1 -1
- package/dist/web/analytics/drift-detector.js +15 -8
- package/dist/web/analytics/drift-detector.js.map +1 -1
- package/dist/web/analytics/weekly-report.d.ts +13 -0
- package/dist/web/analytics/weekly-report.d.ts.map +1 -1
- package/dist/web/analytics/weekly-report.js +17 -3
- package/dist/web/analytics/weekly-report.js.map +1 -1
- package/dist/web/routes/_helpers.d.ts +31 -0
- package/dist/web/routes/_helpers.d.ts.map +1 -1
- package/dist/web/routes/_helpers.js +33 -0
- package/dist/web/routes/_helpers.js.map +1 -1
- package/dist/web/routes/agent-distill.d.ts +49 -0
- package/dist/web/routes/agent-distill.d.ts.map +1 -0
- package/dist/web/routes/agent-distill.js +526 -0
- package/dist/web/routes/agent-distill.js.map +1 -0
- package/dist/web/routes/config.d.ts +56 -0
- package/dist/web/routes/config.d.ts.map +1 -0
- package/dist/web/routes/config.js +243 -0
- package/dist/web/routes/config.js.map +1 -0
- package/dist/web/routes/decisions.js +1 -1
- package/dist/web/routes/decisions.js.map +1 -1
- package/dist/web/routes/error-handler.d.ts +0 -4
- package/dist/web/routes/error-handler.d.ts.map +1 -1
- package/dist/web/routes/error-handler.js +0 -8
- package/dist/web/routes/error-handler.js.map +1 -1
- package/dist/web/routes/events.d.ts.map +1 -1
- package/dist/web/routes/events.js +2 -1
- package/dist/web/routes/events.js.map +1 -1
- package/dist/web/routes/insights.d.ts.map +1 -1
- package/dist/web/routes/insights.js +0 -0
- package/dist/web/routes/insights.js.map +1 -1
- package/dist/web/routes/knowledge.d.ts +43 -2
- package/dist/web/routes/knowledge.d.ts.map +1 -1
- package/dist/web/routes/knowledge.js +117 -6
- package/dist/web/routes/knowledge.js.map +1 -1
- package/dist/web/routes/pipeline.d.ts +0 -9
- package/dist/web/routes/pipeline.d.ts.map +1 -1
- package/dist/web/routes/pipeline.js +0 -4
- package/dist/web/routes/pipeline.js.map +1 -1
- package/dist/web/routes/rules.d.ts.map +1 -1
- package/dist/web/routes/rules.js +20 -6
- package/dist/web/routes/rules.js.map +1 -1
- package/dist/web/routes/sessions.d.ts.map +1 -1
- package/dist/web/routes/sessions.js +8 -7
- package/dist/web/routes/sessions.js.map +1 -1
- package/dist/web/routes/skill-stats.d.ts.map +1 -1
- package/dist/web/routes/skill-stats.js +153 -16
- package/dist/web/routes/skill-stats.js.map +1 -1
- package/dist/web/routes/skills-distill.js +1 -1
- package/dist/web/routes/skills-distill.js.map +1 -1
- package/dist/web/routes/stats.d.ts.map +1 -1
- package/dist/web/routes/stats.js +2 -1
- package/dist/web/routes/stats.js.map +1 -1
- package/dist/web/routes/task-timeline.d.ts +95 -19
- package/dist/web/routes/task-timeline.d.ts.map +1 -1
- package/dist/web/routes/task-timeline.js +344 -88
- package/dist/web/routes/task-timeline.js.map +1 -1
- package/dist/web/routes/tasks.d.ts.map +1 -1
- package/dist/web/routes/tasks.js +52 -30
- package/dist/web/routes/tasks.js.map +1 -1
- package/dist/web/routes/violations.d.ts +1 -1
- package/dist/web/routes/violations.d.ts.map +1 -1
- package/dist/web/routes/violations.js +3 -2
- package/dist/web/routes/violations.js.map +1 -1
- package/dist/web/server.d.ts.map +1 -1
- package/dist/web/server.js +20 -0
- package/dist/web/server.js.map +1 -1
- package/dist/web/services/agent-distill-manager.d.ts +122 -0
- package/dist/web/services/agent-distill-manager.d.ts.map +1 -0
- package/dist/web/services/agent-distill-manager.js +397 -0
- package/dist/web/services/agent-distill-manager.js.map +1 -0
- package/dist/web/services/distill-manager.d.ts +47 -0
- package/dist/web/services/distill-manager.d.ts.map +1 -1
- package/dist/web/services/distill-manager.js +103 -0
- package/dist/web/services/distill-manager.js.map +1 -1
- package/dist/web/static/assets/AgentDetailPage-DlUeA1sX.js +2 -0
- package/dist/web/static/assets/AgentDetailPage-DlUeA1sX.js.map +1 -0
- package/dist/web/static/assets/AgentDistillRunPage-Cybo4bii.js +3 -0
- package/dist/web/static/assets/AgentDistillRunPage-Cybo4bii.js.map +1 -0
- package/dist/web/static/assets/AgentsPage-Qd9FExLG.js +2 -0
- package/dist/web/static/assets/AgentsPage-Qd9FExLG.js.map +1 -0
- package/dist/web/static/assets/DaemonHealthPage-DTSVqtrI.js +2 -0
- package/dist/web/static/assets/DaemonHealthPage-DTSVqtrI.js.map +1 -0
- package/dist/web/static/assets/DecisionDetailPage-b4BA8dhc.js +2 -0
- package/dist/web/static/assets/DecisionDetailPage-b4BA8dhc.js.map +1 -0
- package/dist/web/static/assets/DecisionsPage-a3NRo_T7.js +2 -0
- package/dist/web/static/assets/DecisionsPage-a3NRo_T7.js.map +1 -0
- package/dist/web/static/assets/DiagnosticsPage-DIVdiIQG.js +2 -0
- package/dist/web/static/assets/DiagnosticsPage-DIVdiIQG.js.map +1 -0
- package/dist/web/static/assets/DistillDetailPage-U6a3l2iP.js +4 -0
- package/dist/web/static/assets/DistillDetailPage-U6a3l2iP.js.map +1 -0
- package/dist/web/static/assets/DistillPage-O7BHtRN8.js +2 -0
- package/dist/web/static/assets/DistillPage-O7BHtRN8.js.map +1 -0
- package/dist/web/static/assets/DistillRunPage-D1JuRWWr.js +2 -0
- package/dist/web/static/assets/DistillRunPage-D1JuRWWr.js.map +1 -0
- package/dist/web/static/assets/GlobalScopeHint-Q3wTJx3F.js +2 -0
- package/dist/web/static/assets/GlobalScopeHint-Q3wTJx3F.js.map +1 -0
- package/dist/web/static/assets/IssueDetailPage-BDfrtk2C.js +2 -0
- package/dist/web/static/assets/IssueDetailPage-BDfrtk2C.js.map +1 -0
- package/dist/web/static/assets/IssuesPage-SKmhlCrw.js +2 -0
- package/dist/web/static/assets/IssuesPage-SKmhlCrw.js.map +1 -0
- package/dist/web/static/assets/KbDetailPage-Yna86Na8.js +2 -0
- package/dist/web/static/assets/KbDetailPage-Yna86Na8.js.map +1 -0
- package/dist/web/static/assets/KbHitsPage-Cljl7H9p.js +2 -0
- package/dist/web/static/assets/KbHitsPage-Cljl7H9p.js.map +1 -0
- package/dist/web/static/assets/{MarkdownRenderer-DZmTl-8J.js → MarkdownRenderer-DlDQNihj.js} +2 -2
- package/dist/web/static/assets/{MarkdownRenderer-DZmTl-8J.js.map → MarkdownRenderer-DlDQNihj.js.map} +1 -1
- package/dist/web/static/assets/NotFound-LMzbP51V.js +2 -0
- package/dist/web/static/assets/{NotFound-BQPh0vaF.js.map → NotFound-LMzbP51V.js.map} +1 -1
- package/dist/web/static/assets/SettingsPage-DzoK4PKg.js +2 -0
- package/dist/web/static/assets/SettingsPage-DzoK4PKg.js.map +1 -0
- package/dist/web/static/assets/SkillDetailPage-BuBJJ_NX.js +2 -0
- package/dist/web/static/assets/SkillDetailPage-BuBJJ_NX.js.map +1 -0
- package/dist/web/static/assets/SkillsPage-aojkJpBc.js +2 -0
- package/dist/web/static/assets/SkillsPage-aojkJpBc.js.map +1 -0
- package/dist/web/static/assets/TaskDetailPage-1ckxnGhw.js +4 -0
- package/dist/web/static/assets/TaskDetailPage-1ckxnGhw.js.map +1 -0
- package/dist/web/static/assets/TasksHubPage-C2PLh3eg.js +6 -0
- package/dist/web/static/assets/TasksHubPage-C2PLh3eg.js.map +1 -0
- package/dist/web/static/assets/WorkplacePage-DHrp5VxS.js +2 -0
- package/dist/web/static/assets/WorkplacePage-DHrp5VxS.js.map +1 -0
- package/dist/web/static/assets/arco-DV6xCLhr.js +14 -0
- package/dist/web/static/assets/arco-DV6xCLhr.js.map +1 -0
- package/dist/web/static/assets/charts-BSV4cyC4.js +37 -0
- package/dist/web/static/assets/charts-BSV4cyC4.js.map +1 -0
- package/dist/web/static/assets/{index-7bl3kbcx.css → index-B_v_MKlb.css} +1 -1
- package/dist/web/static/assets/index-DileOOE4.js +4 -0
- package/dist/web/static/assets/index-DileOOE4.js.map +1 -0
- package/dist/web/static/assets/markdown-CA7ePUts.js +30 -0
- package/dist/web/static/assets/markdown-CA7ePUts.js.map +1 -0
- package/dist/web/static/assets/{outcome-DUn1NjlC.js → outcome-BKGy9azt.js} +2 -2
- package/dist/web/static/assets/{outcome-DUn1NjlC.js.map → outcome-BKGy9azt.js.map} +1 -1
- package/dist/web/static/assets/{query-S6X1S7K9.js → query-CgCOpYWf.js} +2 -2
- package/dist/web/static/assets/{query-S6X1S7K9.js.map → query-CgCOpYWf.js.map} +1 -1
- package/dist/web/static/assets/{react-router-JVUrkhdd.js → react-router-Cxmg8RuL.js} +3 -3
- package/dist/web/static/assets/{react-router-JVUrkhdd.js.map → react-router-Cxmg8RuL.js.map} +1 -1
- package/dist/web/static/assets/{syntax-highlighter-BkZfCDsz.js → syntax-highlighter-BDYycNja.js} +3 -3
- package/dist/web/static/assets/{syntax-highlighter-BkZfCDsz.js.map → syntax-highlighter-BDYycNja.js.map} +1 -1
- package/dist/web/static/assets/task-title-BhOcemuR.js +2 -0
- package/dist/web/static/assets/task-title-BhOcemuR.js.map +1 -0
- package/dist/web/static/assets/useAgentStats-B-uTgqBd.js +2 -0
- package/dist/web/static/assets/useAgentStats-B-uTgqBd.js.map +1 -0
- package/dist/web/static/assets/useDecisions-D-G2Ft5T.js +2 -0
- package/dist/web/static/assets/useDecisions-D-G2Ft5T.js.map +1 -0
- package/dist/web/static/assets/useDistill-21dZkXlT.js +3 -0
- package/dist/web/static/assets/useDistill-21dZkXlT.js.map +1 -0
- package/dist/web/static/assets/useEffectiveProject-DQiyX54y.js +2 -0
- package/dist/web/static/assets/useEffectiveProject-DQiyX54y.js.map +1 -0
- package/dist/web/static/assets/useIssuesFeed-CFiyQkAL.js +2 -0
- package/dist/web/static/assets/useIssuesFeed-CFiyQkAL.js.map +1 -0
- package/dist/web/static/assets/useKbHits-xKXWgqh9.js +2 -0
- package/dist/web/static/assets/useKbHits-xKXWgqh9.js.map +1 -0
- package/dist/web/static/assets/useSkillStats-B5hbIwdf.js +2 -0
- package/dist/web/static/assets/useSkillStats-B5hbIwdf.js.map +1 -0
- package/dist/web/static/assets/vendor-DS-q4Eyc.js +36 -0
- package/dist/web/static/assets/vendor-DS-q4Eyc.js.map +1 -0
- package/dist/web/static/index.html +6 -6
- package/package.json +5 -3
- package/dist/core/storage/workflow-recommendations.d.ts +0 -124
- package/dist/core/storage/workflow-recommendations.d.ts.map +0 -1
- package/dist/core/storage/workflow-recommendations.js +0 -274
- package/dist/core/storage/workflow-recommendations.js.map +0 -1
- package/dist/daemon/services/experience-extractor.d.ts.map +0 -1
- package/dist/daemon/services/experience-extractor.js.map +0 -1
- package/dist/daemon/services/violation-reporter.d.ts.map +0 -1
- package/dist/daemon/services/violation-reporter.js.map +0 -1
- package/dist/daemon/templates/agents/harness-hotfix.md +0 -99
- package/dist/daemon/templates/agents/hybrid-feature-with-safety.md +0 -104
- package/dist/daemon/templates/agents/refactor-specialist.md +0 -98
- package/dist/skills/distill/claude-cli-resolver.d.ts.map +0 -1
- package/dist/skills/distill/claude-cli-resolver.js.map +0 -1
- package/dist/skills/distilled/distilled-defi-amm-security.md +0 -293
- package/dist/skills/keyword-score.d.ts +0 -29
- package/dist/skills/keyword-score.d.ts.map +0 -1
- package/dist/skills/keyword-score.js +0 -54
- package/dist/skills/keyword-score.js.map +0 -1
- package/dist/web/static/assets/AgentContentPage-DkeRNxok.js +0 -2
- package/dist/web/static/assets/AgentContentPage-DkeRNxok.js.map +0 -1
- package/dist/web/static/assets/AgentDelegationTable-ByBa0x1l.js +0 -2
- package/dist/web/static/assets/AgentDelegationTable-ByBa0x1l.js.map +0 -1
- package/dist/web/static/assets/ContextInsightsPage-oUk7_I8u.js +0 -3
- package/dist/web/static/assets/ContextInsightsPage-oUk7_I8u.js.map +0 -1
- package/dist/web/static/assets/DaemonHealthPage-DG2fyOP7.js +0 -2
- package/dist/web/static/assets/DaemonHealthPage-DG2fyOP7.js.map +0 -1
- package/dist/web/static/assets/DecisionsPage-CMAPEnKb.js +0 -2
- package/dist/web/static/assets/DecisionsPage-CMAPEnKb.js.map +0 -1
- package/dist/web/static/assets/DiagnosticsPage-DQd-Zm4r.js +0 -2
- package/dist/web/static/assets/DiagnosticsPage-DQd-Zm4r.js.map +0 -1
- package/dist/web/static/assets/DriftTab-DqpepOhI.js +0 -2
- package/dist/web/static/assets/DriftTab-DqpepOhI.js.map +0 -1
- package/dist/web/static/assets/HealthHomePage-CN6zNIie.js +0 -3
- package/dist/web/static/assets/HealthHomePage-CN6zNIie.js.map +0 -1
- package/dist/web/static/assets/KbHitRateTable-ByEIWujF.js +0 -2
- package/dist/web/static/assets/KbHitRateTable-ByEIWujF.js.map +0 -1
- package/dist/web/static/assets/NotFound-BQPh0vaF.js +0 -2
- package/dist/web/static/assets/ProjectSwitcher-D3lZMFd3.js +0 -2
- package/dist/web/static/assets/ProjectSwitcher-D3lZMFd3.js.map +0 -1
- package/dist/web/static/assets/SettingsPage-oLJBNzQj.js +0 -2
- package/dist/web/static/assets/SettingsPage-oLJBNzQj.js.map +0 -1
- package/dist/web/static/assets/SkillContentPage-DK5rgfgw.js +0 -2
- package/dist/web/static/assets/SkillContentPage-DK5rgfgw.js.map +0 -1
- package/dist/web/static/assets/SkillStatsTable-DYMzjEUV.js +0 -2
- package/dist/web/static/assets/SkillStatsTable-DYMzjEUV.js.map +0 -1
- package/dist/web/static/assets/SkillsDistillTab-C7qaG8q3.js +0 -2
- package/dist/web/static/assets/SkillsDistillTab-C7qaG8q3.js.map +0 -1
- package/dist/web/static/assets/TasksHubPage-03wsRRsJ.js +0 -6
- package/dist/web/static/assets/TasksHubPage-03wsRRsJ.js.map +0 -1
- package/dist/web/static/assets/ViolationsPage-DSiLr-9O.js +0 -3
- package/dist/web/static/assets/ViolationsPage-DSiLr-9O.js.map +0 -1
- package/dist/web/static/assets/arco-Bhi3a6Qp.js +0 -14
- package/dist/web/static/assets/arco-Bhi3a6Qp.js.map +0 -1
- package/dist/web/static/assets/charts-BuHQWDbQ.js +0 -37
- package/dist/web/static/assets/charts-BuHQWDbQ.js.map +0 -1
- package/dist/web/static/assets/index-BIYnq1Dx.js +0 -4
- package/dist/web/static/assets/index-BIYnq1Dx.js.map +0 -1
- package/dist/web/static/assets/useTabsParam-k8qte_0C.js +0 -2
- package/dist/web/static/assets/useTabsParam-k8qte_0C.js.map +0 -1
- package/dist/web/static/assets/vendor-DWgdB1eY.js +0 -65
- package/dist/web/static/assets/vendor-DWgdB1eY.js.map +0 -1
- /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;
|
|
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). */
|