@winspan/claude-forge 8.54.4 → 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 +723 -46
- package/README.md +166 -21
- package/dist/catalogs/agents.json +67 -0
- package/dist/catalogs/skills.json +306 -0
- package/dist/claudemd/claudemd-generator.d.ts +45 -45
- package/dist/claudemd/claudemd-generator.d.ts.map +1 -1
- package/dist/claudemd/claudemd-generator.js +128 -449
- package/dist/claudemd/claudemd-generator.js.map +1 -1
- package/dist/claudemd/index.d.ts +14 -4
- package/dist/claudemd/index.d.ts.map +1 -1
- package/dist/claudemd/index.js +15 -4
- package/dist/claudemd/index.js.map +1 -1
- package/dist/claudemd/resume-manager.d.ts.map +1 -1
- package/dist/claudemd/resume-manager.js +37 -9
- package/dist/claudemd/resume-manager.js.map +1 -1
- package/dist/claudemd/templates/swarm-protocol.md +35 -186
- package/dist/claudemd/violations-manager.d.ts +40 -0
- package/dist/claudemd/violations-manager.d.ts.map +1 -0
- package/dist/claudemd/violations-manager.js +106 -0
- package/dist/claudemd/violations-manager.js.map +1 -0
- package/dist/cli/commands/admin.d.ts +15 -0
- package/dist/cli/commands/admin.d.ts.map +1 -0
- package/dist/cli/commands/admin.js +177 -0
- package/dist/cli/commands/admin.js.map +1 -0
- 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/agents.d.ts +18 -0
- package/dist/cli/commands/agents.d.ts.map +1 -0
- package/dist/cli/commands/agents.js +160 -0
- package/dist/cli/commands/agents.js.map +1 -0
- package/dist/cli/commands/bypass.d.ts +18 -0
- package/dist/cli/commands/bypass.d.ts.map +1 -0
- package/dist/cli/commands/bypass.js +87 -0
- package/dist/cli/commands/bypass.js.map +1 -0
- package/dist/cli/commands/claudemd.d.ts +60 -0
- package/dist/cli/commands/claudemd.d.ts.map +1 -1
- package/dist/cli/commands/claudemd.js +174 -37
- package/dist/cli/commands/claudemd.js.map +1 -1
- 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/config.d.ts.map +1 -1
- package/dist/cli/commands/config.js +94 -1
- package/dist/cli/commands/config.js.map +1 -1
- package/dist/cli/commands/daemon.d.ts +39 -0
- package/dist/cli/commands/daemon.d.ts.map +1 -1
- package/dist/cli/commands/daemon.js +167 -20
- package/dist/cli/commands/daemon.js.map +1 -1
- package/dist/cli/commands/decisions.d.ts +129 -0
- package/dist/cli/commands/decisions.d.ts.map +1 -0
- package/dist/cli/commands/decisions.js +706 -0
- package/dist/cli/commands/decisions.js.map +1 -0
- package/dist/cli/commands/doctor.d.ts +29 -0
- package/dist/cli/commands/doctor.d.ts.map +1 -0
- package/dist/cli/commands/doctor.js +124 -0
- package/dist/cli/commands/doctor.js.map +1 -0
- package/dist/cli/commands/entropy.d.ts +35 -0
- package/dist/cli/commands/entropy.d.ts.map +1 -0
- package/dist/cli/commands/entropy.js +121 -0
- package/dist/cli/commands/entropy.js.map +1 -0
- package/dist/cli/commands/executions.d.ts +1 -0
- package/dist/cli/commands/executions.d.ts.map +1 -1
- package/dist/cli/commands/executions.js +12 -2
- package/dist/cli/commands/executions.js.map +1 -1
- package/dist/cli/commands/fix.d.ts +31 -0
- package/dist/cli/commands/fix.d.ts.map +1 -0
- package/dist/cli/commands/fix.js +108 -0
- package/dist/cli/commands/fix.js.map +1 -0
- package/dist/cli/commands/governance.d.ts +21 -0
- package/dist/cli/commands/governance.d.ts.map +1 -0
- package/dist/cli/commands/governance.js +60 -0
- package/dist/cli/commands/governance.js.map +1 -0
- package/dist/cli/commands/init.d.ts +27 -0
- package/dist/cli/commands/init.d.ts.map +1 -1
- package/dist/cli/commands/init.js +158 -146
- package/dist/cli/commands/init.js.map +1 -1
- package/dist/cli/commands/insights-goal-check.d.ts +54 -0
- package/dist/cli/commands/insights-goal-check.d.ts.map +1 -0
- package/dist/cli/commands/insights-goal-check.js +318 -0
- package/dist/cli/commands/insights-goal-check.js.map +1 -0
- package/dist/cli/commands/insights.d.ts +15 -0
- package/dist/cli/commands/insights.d.ts.map +1 -0
- package/dist/cli/commands/insights.js +127 -0
- package/dist/cli/commands/insights.js.map +1 -0
- package/dist/cli/commands/knowledge.d.ts +117 -0
- package/dist/cli/commands/knowledge.d.ts.map +1 -0
- package/dist/cli/commands/knowledge.js +1070 -0
- package/dist/cli/commands/knowledge.js.map +1 -0
- 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 +22 -11
- package/dist/cli/commands/mcp.d.ts.map +1 -1
- package/dist/cli/commands/mcp.js +93 -5
- package/dist/cli/commands/mcp.js.map +1 -1
- package/dist/cli/commands/menu.d.ts.map +1 -1
- package/dist/cli/commands/menu.js +10 -184
- package/dist/cli/commands/menu.js.map +1 -1
- package/dist/cli/commands/project.d.ts +98 -0
- package/dist/cli/commands/project.d.ts.map +1 -0
- package/dist/cli/commands/project.js +382 -0
- package/dist/cli/commands/project.js.map +1 -0
- 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 +404 -118
- package/dist/cli/commands/skills.js.map +1 -1
- package/dist/cli/commands/spec.d.ts +40 -0
- package/dist/cli/commands/spec.d.ts.map +1 -0
- package/dist/cli/commands/spec.js +49 -0
- package/dist/cli/commands/spec.js.map +1 -0
- package/dist/cli/commands/stats.d.ts.map +1 -1
- package/dist/cli/commands/stats.js +11 -3
- package/dist/cli/commands/stats.js.map +1 -1
- package/dist/cli/commands/status.d.ts.map +1 -1
- package/dist/cli/commands/status.js +17 -2
- package/dist/cli/commands/status.js.map +1 -1
- package/dist/cli/commands/trace.d.ts.map +1 -1
- package/dist/cli/commands/trace.js +4 -9
- package/dist/cli/commands/trace.js.map +1 -1
- package/dist/cli/commands/violations.d.ts +14 -0
- package/dist/cli/commands/violations.d.ts.map +1 -0
- package/dist/cli/commands/violations.js +43 -0
- package/dist/cli/commands/violations.js.map +1 -0
- package/dist/cli/index.js +34 -0
- package/dist/cli/index.js.map +1 -1
- package/dist/cli/init/hook-manager.d.ts +1 -1
- package/dist/cli/init/hook-manager.d.ts.map +1 -1
- package/dist/cli/init/hook-manager.js +6 -0
- package/dist/cli/init/hook-manager.js.map +1 -1
- package/dist/cli/utils/resolve-session.d.ts +32 -0
- package/dist/cli/utils/resolve-session.d.ts.map +1 -0
- package/dist/cli/utils/resolve-session.js +39 -0
- package/dist/cli/utils/resolve-session.js.map +1 -0
- package/dist/core/config.d.ts +4 -1
- package/dist/core/config.d.ts.map +1 -1
- package/dist/core/config.js +11 -23
- package/dist/core/config.js.map +1 -1
- package/dist/core/constants.d.ts +51 -13
- package/dist/core/constants.d.ts.map +1 -1
- package/dist/core/constants.js +63 -13
- package/dist/core/constants.js.map +1 -1
- package/dist/core/diagnostics/checks.d.ts +151 -0
- package/dist/core/diagnostics/checks.d.ts.map +1 -0
- package/dist/core/diagnostics/checks.js +766 -0
- package/dist/core/diagnostics/checks.js.map +1 -0
- package/dist/core/diagnostics/daemon-status.d.ts +77 -0
- package/dist/core/diagnostics/daemon-status.d.ts.map +1 -0
- package/dist/core/diagnostics/daemon-status.js +113 -0
- package/dist/core/diagnostics/daemon-status.js.map +1 -0
- package/dist/core/diagnostics/entropy-checks.d.ts +83 -0
- package/dist/core/diagnostics/entropy-checks.d.ts.map +1 -0
- package/dist/core/diagnostics/entropy-checks.js +400 -0
- package/dist/core/diagnostics/entropy-checks.js.map +1 -0
- package/dist/core/diagnostics/fix-runner.d.ts +54 -0
- package/dist/core/diagnostics/fix-runner.d.ts.map +1 -0
- package/dist/core/diagnostics/fix-runner.js +90 -0
- package/dist/core/diagnostics/fix-runner.js.map +1 -0
- 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/diagnostics/knip-runner.d.ts +49 -0
- package/dist/core/diagnostics/knip-runner.d.ts.map +1 -0
- package/dist/core/diagnostics/knip-runner.js +100 -0
- package/dist/core/diagnostics/knip-runner.js.map +1 -0
- package/dist/core/diagnostics/markers.d.ts +96 -0
- package/dist/core/diagnostics/markers.d.ts.map +1 -0
- package/dist/core/diagnostics/markers.js +153 -0
- package/dist/core/diagnostics/markers.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 +90 -0
- package/dist/core/governance/global-inject.d.ts.map +1 -0
- package/dist/core/governance/global-inject.js +184 -0
- package/dist/core/governance/global-inject.js.map +1 -0
- 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/core/insights/experience-extractor.d.ts +60 -0
- package/dist/core/insights/experience-extractor.d.ts.map +1 -0
- package/dist/core/insights/experience-extractor.js +319 -0
- package/dist/core/insights/experience-extractor.js.map +1 -0
- package/dist/core/insights/violation-reporter.d.ts +149 -0
- package/dist/core/insights/violation-reporter.d.ts.map +1 -0
- package/dist/core/insights/violation-reporter.js +391 -0
- 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 +16 -3
- package/dist/core/queue/index.d.ts.map +1 -1
- package/dist/core/queue/index.js +16 -4
- package/dist/core/queue/index.js.map +1 -1
- package/dist/core/storage/base.d.ts +317 -0
- package/dist/core/storage/base.d.ts.map +1 -1
- package/dist/core/storage/base.js +1093 -0
- package/dist/core/storage/base.js.map +1 -1
- package/dist/core/storage/codec/tool-input-codec.d.ts +93 -0
- package/dist/core/storage/codec/tool-input-codec.d.ts.map +1 -0
- package/dist/core/storage/codec/tool-input-codec.js +159 -0
- package/dist/core/storage/codec/tool-input-codec.js.map +1 -0
- 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 +387 -0
- package/dist/core/storage/decisions.d.ts.map +1 -0
- package/dist/core/storage/decisions.js +534 -0
- package/dist/core/storage/decisions.js.map +1 -0
- package/dist/core/storage/events.d.ts +239 -8
- package/dist/core/storage/events.d.ts.map +1 -1
- package/dist/core/storage/events.js +705 -39
- package/dist/core/storage/events.js.map +1 -1
- package/dist/core/storage/feedback.d.ts +111 -0
- package/dist/core/storage/feedback.d.ts.map +1 -0
- package/dist/core/storage/feedback.js +186 -0
- package/dist/core/storage/feedback.js.map +1 -0
- package/dist/core/storage/forge-config.d.ts +40 -0
- package/dist/core/storage/forge-config.d.ts.map +1 -0
- package/dist/core/storage/forge-config.js +65 -0
- package/dist/core/storage/forge-config.js.map +1 -0
- package/dist/core/storage/injections.d.ts +68 -0
- package/dist/core/storage/injections.d.ts.map +1 -1
- package/dist/core/storage/injections.js +131 -5
- package/dist/core/storage/injections.js.map +1 -1
- package/dist/core/storage/knowledge.d.ts +332 -0
- package/dist/core/storage/knowledge.d.ts.map +1 -0
- package/dist/core/storage/knowledge.js +589 -0
- package/dist/core/storage/knowledge.js.map +1 -0
- package/dist/core/storage/maintenance.d.ts +36 -9
- package/dist/core/storage/maintenance.d.ts.map +1 -1
- package/dist/core/storage/maintenance.js +56 -24
- package/dist/core/storage/maintenance.js.map +1 -1
- package/dist/core/storage/pipeline-rollup.d.ts +111 -0
- package/dist/core/storage/pipeline-rollup.d.ts.map +1 -0
- package/dist/core/storage/pipeline-rollup.js +432 -0
- package/dist/core/storage/pipeline-rollup.js.map +1 -0
- package/dist/core/storage/routing.d.ts +50 -3
- package/dist/core/storage/routing.d.ts.map +1 -1
- package/dist/core/storage/routing.js +131 -10
- package/dist/core/storage/routing.js.map +1 -1
- package/dist/core/storage/rows.d.ts +31 -8
- package/dist/core/storage/rows.d.ts.map +1 -1
- package/dist/core/storage/schema.sql +367 -23
- package/dist/core/storage/sessions.d.ts +136 -0
- package/dist/core/storage/sessions.d.ts.map +1 -1
- package/dist/core/storage/sessions.js +352 -15
- package/dist/core/storage/sessions.js.map +1 -1
- package/dist/core/storage/skills.d.ts +160 -0
- package/dist/core/storage/skills.d.ts.map +1 -1
- package/dist/core/storage/skills.js +368 -7
- package/dist/core/storage/skills.js.map +1 -1
- package/dist/core/storage/sqlite.d.ts +309 -20
- package/dist/core/storage/sqlite.d.ts.map +1 -1
- package/dist/core/storage/sqlite.js +523 -16
- package/dist/core/storage/sqlite.js.map +1 -1
- package/dist/core/storage/tasks.d.ts +744 -2
- package/dist/core/storage/tasks.d.ts.map +1 -1
- package/dist/core/storage/tasks.js +1691 -17
- package/dist/core/storage/tasks.js.map +1 -1
- package/dist/core/storage/tool-intercepts.d.ts +69 -0
- package/dist/core/storage/tool-intercepts.d.ts.map +1 -0
- package/dist/core/storage/tool-intercepts.js +116 -0
- package/dist/core/storage/tool-intercepts.js.map +1 -0
- package/dist/core/types.d.ts +136 -18
- package/dist/core/types.d.ts.map +1 -1
- package/dist/core/types.js +10 -0
- package/dist/core/types.js.map +1 -1
- package/dist/core/utils/backup.d.ts +81 -0
- package/dist/core/utils/backup.d.ts.map +1 -0
- package/dist/core/utils/backup.js +98 -0
- package/dist/core/utils/backup.js.map +1 -0
- package/dist/core/utils/binary-paths.d.ts +124 -0
- package/dist/core/utils/binary-paths.d.ts.map +1 -0
- package/dist/core/utils/binary-paths.js +218 -0
- package/dist/core/utils/binary-paths.js.map +1 -0
- package/dist/core/utils/bypass-token.d.ts +75 -0
- package/dist/core/utils/bypass-token.d.ts.map +1 -0
- package/dist/core/utils/bypass-token.js +133 -0
- package/dist/core/utils/bypass-token.js.map +1 -0
- package/dist/core/utils/cc-builtin-agents.d.ts +3 -0
- package/dist/core/utils/cc-builtin-agents.d.ts.map +1 -0
- package/dist/core/utils/cc-builtin-agents.js +29 -0
- package/dist/core/utils/cc-builtin-agents.js.map +1 -0
- package/dist/core/utils/claude-cli-resolver.d.ts +26 -0
- package/dist/core/utils/claude-cli-resolver.d.ts.map +1 -0
- package/dist/core/utils/claude-cli-resolver.js +115 -0
- package/dist/core/utils/claude-cli-resolver.js.map +1 -0
- package/dist/core/utils/claude-cli-spawn.d.ts +106 -0
- package/dist/core/utils/claude-cli-spawn.d.ts.map +1 -0
- package/dist/core/utils/claude-cli-spawn.js +219 -0
- package/dist/core/utils/claude-cli-spawn.js.map +1 -0
- package/dist/core/utils/forge-resume-block.d.ts.map +1 -1
- package/dist/core/utils/forge-resume-block.js +3 -2
- package/dist/core/utils/forge-resume-block.js.map +1 -1
- package/dist/core/utils/logger.d.ts +15 -3
- package/dist/core/utils/logger.d.ts.map +1 -1
- package/dist/core/utils/logger.js +20 -2
- package/dist/core/utils/logger.js.map +1 -1
- package/dist/core/utils/noise-prompt.d.ts +97 -0
- package/dist/core/utils/noise-prompt.d.ts.map +1 -0
- package/dist/core/utils/noise-prompt.js +127 -0
- package/dist/core/utils/noise-prompt.js.map +1 -0
- package/dist/core/utils/path.d.ts +0 -4
- package/dist/core/utils/path.d.ts.map +1 -1
- package/dist/core/utils/path.js +0 -7
- package/dist/core/utils/path.js.map +1 -1
- package/dist/core/utils/time.d.ts +67 -0
- package/dist/core/utils/time.d.ts.map +1 -1
- package/dist/core/utils/time.js +147 -0
- package/dist/core/utils/time.js.map +1 -1
- package/dist/daemon/agent-sync.d.ts +24 -0
- package/dist/daemon/agent-sync.d.ts.map +1 -0
- package/dist/daemon/agent-sync.js +114 -0
- package/dist/daemon/agent-sync.js.map +1 -0
- package/dist/daemon/config-store.d.ts +55 -0
- package/dist/daemon/config-store.d.ts.map +1 -0
- package/dist/daemon/config-store.js +146 -0
- package/dist/daemon/config-store.js.map +1 -0
- package/dist/daemon/event-parser.d.ts +22 -0
- package/dist/daemon/event-parser.d.ts.map +1 -1
- package/dist/daemon/event-parser.js +54 -3
- package/dist/daemon/event-parser.js.map +1 -1
- package/dist/daemon/handlers/history-exporter.d.ts.map +1 -1
- package/dist/daemon/handlers/history-exporter.js +9 -8
- package/dist/daemon/handlers/history-exporter.js.map +1 -1
- package/dist/daemon/handlers/post-tool-use.d.ts +66 -4
- package/dist/daemon/handlers/post-tool-use.d.ts.map +1 -1
- package/dist/daemon/handlers/post-tool-use.js +221 -8
- package/dist/daemon/handlers/post-tool-use.js.map +1 -1
- package/dist/daemon/handlers/pre-tool-use.d.ts +181 -0
- package/dist/daemon/handlers/pre-tool-use.d.ts.map +1 -0
- package/dist/daemon/handlers/pre-tool-use.js +618 -0
- package/dist/daemon/handlers/pre-tool-use.js.map +1 -0
- package/dist/daemon/handlers/stop.d.ts +55 -7
- package/dist/daemon/handlers/stop.d.ts.map +1 -1
- package/dist/daemon/handlers/stop.js +245 -8
- package/dist/daemon/handlers/stop.js.map +1 -1
- package/dist/daemon/handlers/user-prompt.d.ts +51 -14
- package/dist/daemon/handlers/user-prompt.d.ts.map +1 -1
- package/dist/daemon/handlers/user-prompt.js +223 -95
- 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/hook-sync.d.ts.map +1 -1
- package/dist/daemon/hook-sync.js +2 -1
- package/dist/daemon/hook-sync.js.map +1 -1
- package/dist/daemon/index.d.ts +19 -0
- package/dist/daemon/index.d.ts.map +1 -1
- package/dist/daemon/index.js +439 -86
- package/dist/daemon/index.js.map +1 -1
- package/dist/daemon/lifecycle.d.ts +48 -1
- package/dist/daemon/lifecycle.d.ts.map +1 -1
- package/dist/daemon/lifecycle.js +98 -2
- package/dist/daemon/lifecycle.js.map +1 -1
- package/dist/daemon/router.d.ts +4 -1
- package/dist/daemon/router.d.ts.map +1 -1
- package/dist/daemon/router.js +4 -2
- package/dist/daemon/router.js.map +1 -1
- package/dist/daemon/rules/defaults.d.ts +20 -0
- package/dist/daemon/rules/defaults.d.ts.map +1 -0
- package/dist/daemon/rules/defaults.js +779 -0
- package/dist/daemon/rules/defaults.js.map +1 -0
- package/dist/daemon/rules/registry.d.ts +47 -0
- package/dist/daemon/rules/registry.d.ts.map +1 -0
- package/dist/daemon/rules/registry.js +84 -0
- package/dist/daemon/rules/registry.js.map +1 -0
- package/dist/daemon/rules/types.d.ts +176 -0
- package/dist/daemon/rules/types.d.ts.map +1 -0
- package/dist/daemon/rules/types.js +15 -0
- package/dist/daemon/rules/types.js.map +1 -0
- package/dist/daemon/rules/whitelist.d.ts +101 -0
- package/dist/daemon/rules/whitelist.d.ts.map +1 -0
- package/dist/daemon/rules/whitelist.js +210 -0
- package/dist/daemon/rules/whitelist.js.map +1 -0
- package/dist/daemon/rules/workflow-defaults.d.ts +52 -0
- package/dist/daemon/rules/workflow-defaults.d.ts.map +1 -0
- package/dist/daemon/rules/workflow-defaults.js +521 -0
- package/dist/daemon/rules/workflow-defaults.js.map +1 -0
- package/dist/daemon/server.d.ts +11 -1
- package/dist/daemon/server.d.ts.map +1 -1
- package/dist/daemon/server.js +7 -1
- package/dist/daemon/server.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/context-injector.d.ts +34 -0
- package/dist/daemon/services/context-injector.d.ts.map +1 -0
- package/dist/daemon/services/context-injector.js +61 -0
- package/dist/daemon/services/context-injector.js.map +1 -0
- package/dist/daemon/services/decision-hint.d.ts +240 -0
- package/dist/daemon/services/decision-hint.d.ts.map +1 -0
- package/dist/daemon/services/decision-hint.js +562 -0
- package/dist/daemon/services/decision-hint.js.map +1 -0
- package/dist/daemon/services/event-ttl-sweep.d.ts +86 -0
- package/dist/daemon/services/event-ttl-sweep.d.ts.map +1 -0
- package/dist/daemon/services/event-ttl-sweep.js +124 -0
- package/dist/daemon/services/event-ttl-sweep.js.map +1 -0
- package/dist/daemon/services/feedback-aggregator.d.ts +167 -0
- package/dist/daemon/services/feedback-aggregator.d.ts.map +1 -0
- package/dist/daemon/services/feedback-aggregator.js +415 -0
- package/dist/daemon/services/feedback-aggregator.js.map +1 -0
- package/dist/daemon/services/heartbeat-writer.d.ts +46 -0
- package/dist/daemon/services/heartbeat-writer.d.ts.map +1 -0
- package/dist/daemon/services/heartbeat-writer.js +82 -0
- package/dist/daemon/services/heartbeat-writer.js.map +1 -0
- package/dist/daemon/services/idle-session-sweeper.d.ts +61 -0
- package/dist/daemon/services/idle-session-sweeper.d.ts.map +1 -0
- package/dist/daemon/services/idle-session-sweeper.js +94 -0
- package/dist/daemon/services/idle-session-sweeper.js.map +1 -0
- package/dist/daemon/services/idle-task-budget.d.ts +50 -0
- package/dist/daemon/services/idle-task-budget.d.ts.map +1 -0
- package/dist/daemon/services/idle-task-budget.js +72 -0
- package/dist/daemon/services/idle-task-budget.js.map +1 -0
- package/dist/daemon/services/intercept-revive.d.ts +60 -0
- package/dist/daemon/services/intercept-revive.d.ts.map +1 -0
- package/dist/daemon/services/intercept-revive.js +86 -0
- package/dist/daemon/services/intercept-revive.js.map +1 -0
- package/dist/daemon/services/intercept-rollback-guard.d.ts +105 -0
- package/dist/daemon/services/intercept-rollback-guard.d.ts.map +1 -0
- package/dist/daemon/services/intercept-rollback-guard.js +152 -0
- package/dist/daemon/services/intercept-rollback-guard.js.map +1 -0
- package/dist/daemon/services/intercept-timeout-sweeper.d.ts +58 -0
- package/dist/daemon/services/intercept-timeout-sweeper.d.ts.map +1 -0
- package/dist/daemon/services/intercept-timeout-sweeper.js +83 -0
- package/dist/daemon/services/intercept-timeout-sweeper.js.map +1 -0
- package/dist/daemon/services/kb-injector.d.ts +57 -0
- package/dist/daemon/services/kb-injector.d.ts.map +1 -0
- package/dist/daemon/services/kb-injector.js +148 -0
- package/dist/daemon/services/kb-injector.js.map +1 -0
- 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.d.ts +49 -0
- package/dist/daemon/services/outcome-classification-service.d.ts.map +1 -0
- package/dist/daemon/services/outcome-classification-service.js +214 -0
- package/dist/daemon/services/outcome-classification-service.js.map +1 -0
- package/dist/daemon/services/outcome-classifier.d.ts +136 -0
- package/dist/daemon/services/outcome-classifier.d.ts.map +1 -0
- package/dist/daemon/services/outcome-classifier.js +178 -0
- package/dist/daemon/services/outcome-classifier.js.map +1 -0
- package/dist/daemon/services/outcome-nudge.d.ts +107 -0
- package/dist/daemon/services/outcome-nudge.d.ts.map +1 -0
- package/dist/daemon/services/outcome-nudge.js +242 -0
- package/dist/daemon/services/outcome-nudge.js.map +1 -0
- package/dist/daemon/services/spec-approval.d.ts +127 -0
- package/dist/daemon/services/spec-approval.d.ts.map +1 -0
- package/dist/daemon/services/spec-approval.js +216 -0
- package/dist/daemon/services/spec-approval.js.map +1 -0
- package/dist/daemon/services/spec-gate.d.ts +54 -0
- package/dist/daemon/services/spec-gate.d.ts.map +1 -0
- package/dist/daemon/services/spec-gate.js +113 -0
- package/dist/daemon/services/spec-gate.js.map +1 -0
- package/dist/daemon/services/task-boundary-classifier.d.ts +78 -0
- package/dist/daemon/services/task-boundary-classifier.d.ts.map +1 -0
- package/dist/daemon/services/task-boundary-classifier.js +202 -0
- package/dist/daemon/services/task-boundary-classifier.js.map +1 -0
- package/dist/daemon/services/task-segmenter.d.ts +230 -1
- package/dist/daemon/services/task-segmenter.d.ts.map +1 -1
- package/dist/daemon/services/task-segmenter.js +527 -17
- package/dist/daemon/services/task-segmenter.js.map +1 -1
- package/dist/daemon/skill-sync.d.ts +7 -2
- package/dist/daemon/skill-sync.d.ts.map +1 -1
- package/dist/daemon/skill-sync.js +114 -9
- package/dist/daemon/skill-sync.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 +102 -0
- package/dist/daemon/templates/agents/coder.md +262 -0
- package/dist/daemon/templates/agents/decision-maker.md +546 -0
- package/dist/daemon/templates/agents/doc-reviewer.md +118 -0
- package/dist/daemon/templates/agents/harness-debug-full.md +196 -0
- package/dist/daemon/templates/agents/knowledge-builder.md +120 -0
- package/dist/daemon/templates/agents/patch-applier.md +145 -0
- package/dist/daemon/templates/agents/planner.md +217 -0
- package/dist/daemon/templates/agents/safety-net-implementer.md +278 -0
- package/dist/daemon/templates/agents/skill-distiller.md +114 -0
- package/dist/daemon/templates/agents/task-boundary-classifier.md +65 -0
- package/dist/daemon/templates/agents/verify-agent.md +259 -0
- package/dist/daemon/utils/inject-block.d.ts +39 -0
- package/dist/daemon/utils/inject-block.d.ts.map +1 -0
- package/dist/daemon/utils/inject-block.js +25 -0
- package/dist/daemon/utils/inject-block.js.map +1 -0
- package/dist/hooks/hook-lib.sh +8 -0
- package/dist/hooks/notification.sh +19 -8
- package/dist/hooks/post-tool-use.sh +41 -23
- package/dist/hooks/pre-tool-use.sh +54 -23
- package/dist/hooks/session-start.sh +68 -0
- package/dist/hooks/stop.sh +31 -11
- package/dist/hooks/user-prompt-submit.sh +37 -21
- package/dist/knowledge/adapters/go-adapter.d.ts +65 -0
- package/dist/knowledge/adapters/go-adapter.d.ts.map +1 -0
- package/dist/knowledge/adapters/go-adapter.js +294 -0
- package/dist/knowledge/adapters/go-adapter.js.map +1 -0
- package/dist/knowledge/adapters/index.d.ts +41 -0
- package/dist/knowledge/adapters/index.d.ts.map +1 -0
- package/dist/knowledge/adapters/index.js +71 -0
- package/dist/knowledge/adapters/index.js.map +1 -0
- package/dist/knowledge/adapters/java-adapter.d.ts +66 -0
- package/dist/knowledge/adapters/java-adapter.d.ts.map +1 -0
- package/dist/knowledge/adapters/java-adapter.js +260 -0
- package/dist/knowledge/adapters/java-adapter.js.map +1 -0
- package/dist/knowledge/adapters/js-vue-adapter.d.ts +56 -0
- package/dist/knowledge/adapters/js-vue-adapter.d.ts.map +1 -0
- package/dist/knowledge/adapters/js-vue-adapter.js +203 -0
- package/dist/knowledge/adapters/js-vue-adapter.js.map +1 -0
- package/dist/knowledge/adapters/kotlin-adapter.d.ts +55 -0
- package/dist/knowledge/adapters/kotlin-adapter.d.ts.map +1 -0
- package/dist/knowledge/adapters/kotlin-adapter.js +209 -0
- package/dist/knowledge/adapters/kotlin-adapter.js.map +1 -0
- package/dist/knowledge/adapters/monorepo-adapter.d.ts +77 -0
- package/dist/knowledge/adapters/monorepo-adapter.d.ts.map +1 -0
- package/dist/knowledge/adapters/monorepo-adapter.js +170 -0
- package/dist/knowledge/adapters/monorepo-adapter.js.map +1 -0
- package/dist/knowledge/adapters/python-adapter.d.ts +89 -0
- package/dist/knowledge/adapters/python-adapter.d.ts.map +1 -0
- package/dist/knowledge/adapters/python-adapter.js +358 -0
- package/dist/knowledge/adapters/python-adapter.js.map +1 -0
- package/dist/knowledge/adapters/rust-adapter.d.ts +73 -0
- package/dist/knowledge/adapters/rust-adapter.d.ts.map +1 -0
- package/dist/knowledge/adapters/rust-adapter.js +329 -0
- package/dist/knowledge/adapters/rust-adapter.js.map +1 -0
- package/dist/knowledge/adapters/types.d.ts +99 -0
- package/dist/knowledge/adapters/types.d.ts.map +1 -0
- package/dist/knowledge/adapters/types.js +17 -0
- package/dist/knowledge/adapters/types.js.map +1 -0
- package/dist/knowledge/adapters/typescript-adapter.d.ts +57 -0
- package/dist/knowledge/adapters/typescript-adapter.d.ts.map +1 -0
- package/dist/knowledge/adapters/typescript-adapter.js +171 -0
- package/dist/knowledge/adapters/typescript-adapter.js.map +1 -0
- package/dist/knowledge/audit-applier.d.ts +70 -0
- package/dist/knowledge/audit-applier.d.ts.map +1 -0
- package/dist/knowledge/audit-applier.js +251 -0
- package/dist/knowledge/audit-applier.js.map +1 -0
- package/dist/knowledge/builder.d.ts +261 -0
- package/dist/knowledge/builder.d.ts.map +1 -0
- package/dist/knowledge/builder.js +966 -0
- package/dist/knowledge/builder.js.map +1 -0
- package/dist/knowledge/cli-provider.d.ts +151 -0
- package/dist/knowledge/cli-provider.d.ts.map +1 -0
- package/dist/knowledge/cli-provider.js +313 -0
- package/dist/knowledge/cli-provider.js.map +1 -0
- package/dist/knowledge/constants.d.ts +78 -0
- package/dist/knowledge/constants.d.ts.map +1 -0
- package/dist/knowledge/constants.js +98 -0
- package/dist/knowledge/constants.js.map +1 -0
- package/dist/knowledge/cross-module.d.ts +139 -0
- package/dist/knowledge/cross-module.d.ts.map +1 -0
- package/dist/knowledge/cross-module.js +370 -0
- package/dist/knowledge/cross-module.js.map +1 -0
- package/dist/knowledge/git-hooks.d.ts +67 -0
- package/dist/knowledge/git-hooks.d.ts.map +1 -0
- package/dist/knowledge/git-hooks.js +258 -0
- package/dist/knowledge/git-hooks.js.map +1 -0
- 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/module-hash.d.ts +88 -0
- package/dist/knowledge/module-hash.d.ts.map +1 -0
- package/dist/knowledge/module-hash.js +162 -0
- package/dist/knowledge/module-hash.js.map +1 -0
- package/dist/knowledge/project-detector.d.ts +101 -0
- package/dist/knowledge/project-detector.d.ts.map +1 -0
- package/dist/knowledge/project-detector.js +223 -0
- package/dist/knowledge/project-detector.js.map +1 -0
- package/dist/knowledge/prompt.d.ts +237 -0
- package/dist/knowledge/prompt.d.ts.map +1 -0
- package/dist/knowledge/prompt.js +416 -0
- package/dist/knowledge/prompt.js.map +1 -0
- package/dist/knowledge/query.d.ts +118 -0
- package/dist/knowledge/query.d.ts.map +1 -0
- package/dist/knowledge/query.js +438 -0
- package/dist/knowledge/query.js.map +1 -0
- package/dist/knowledge/repo-map.d.ts +97 -0
- package/dist/knowledge/repo-map.d.ts.map +1 -0
- package/dist/knowledge/repo-map.js +447 -0
- package/dist/knowledge/repo-map.js.map +1 -0
- package/dist/knowledge/tools/index.d.ts +14 -0
- package/dist/knowledge/tools/index.d.ts.map +1 -0
- package/dist/knowledge/tools/index.js +11 -0
- package/dist/knowledge/tools/index.js.map +1 -0
- package/dist/knowledge/tools/knowledge-get-page.d.ts +46 -0
- package/dist/knowledge/tools/knowledge-get-page.d.ts.map +1 -0
- package/dist/knowledge/tools/knowledge-get-page.js +101 -0
- package/dist/knowledge/tools/knowledge-get-page.js.map +1 -0
- package/dist/knowledge/tools/knowledge-query.d.ts +77 -0
- package/dist/knowledge/tools/knowledge-query.d.ts.map +1 -0
- package/dist/knowledge/tools/knowledge-query.js +104 -0
- package/dist/knowledge/tools/knowledge-query.js.map +1 -0
- package/dist/knowledge/tools/repo-map-lookup.d.ts +45 -0
- package/dist/knowledge/tools/repo-map-lookup.d.ts.map +1 -0
- package/dist/knowledge/tools/repo-map-lookup.js +82 -0
- package/dist/knowledge/tools/repo-map-lookup.js.map +1 -0
- package/dist/knowledge/types.d.ts +269 -0
- package/dist/knowledge/types.d.ts.map +1 -0
- package/dist/knowledge/types.js +10 -0
- package/dist/knowledge/types.js.map +1 -0
- package/dist/knowledge/validator.d.ts +90 -0
- package/dist/knowledge/validator.d.ts.map +1 -0
- package/dist/knowledge/validator.js +355 -0
- package/dist/knowledge/validator.js.map +1 -0
- package/dist/mcp/server.d.ts +64 -8
- package/dist/mcp/server.d.ts.map +1 -1
- package/dist/mcp/server.js +448 -12
- package/dist/mcp/server.js.map +1 -1
- package/dist/skills/builtin-skills.d.ts +35 -0
- package/dist/skills/builtin-skills.d.ts.map +1 -0
- package/dist/skills/builtin-skills.js +68 -0
- package/dist/skills/builtin-skills.js.map +1 -0
- package/dist/skills/distill/attribution.d.ts +59 -0
- package/dist/skills/distill/attribution.d.ts.map +1 -0
- package/dist/skills/distill/attribution.js +101 -0
- package/dist/skills/distill/attribution.js.map +1 -0
- package/dist/skills/distill/distiller.d.ts +161 -0
- package/dist/skills/distill/distiller.d.ts.map +1 -0
- package/dist/skills/distill/distiller.js +461 -0
- package/dist/skills/distill/distiller.js.map +1 -0
- package/dist/skills/distill/index.d.ts +223 -0
- package/dist/skills/distill/index.d.ts.map +1 -0
- package/dist/skills/distill/index.js +466 -0
- package/dist/skills/distill/index.js.map +1 -0
- package/dist/skills/distill/project-anchor-guard.d.ts +116 -0
- package/dist/skills/distill/project-anchor-guard.d.ts.map +1 -0
- package/dist/skills/distill/project-anchor-guard.js +334 -0
- package/dist/skills/distill/project-anchor-guard.js.map +1 -0
- package/dist/skills/distill/topic-deduper.d.ts +77 -0
- package/dist/skills/distill/topic-deduper.d.ts.map +1 -0
- package/dist/skills/distill/topic-deduper.js +119 -0
- package/dist/skills/distill/topic-deduper.js.map +1 -0
- package/dist/skills/distill/upstream-fetcher.d.ts +71 -0
- package/dist/skills/distill/upstream-fetcher.d.ts.map +1 -0
- package/dist/skills/distill/upstream-fetcher.js +202 -0
- package/dist/skills/distill/upstream-fetcher.js.map +1 -0
- package/dist/skills/distilled/distilled-api-design.md +495 -0
- package/dist/skills/distilled/distilled-architecture-decision.md +173 -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 +181 -0
- package/dist/skills/distilled/distilled-db-schema-design.md +245 -0
- 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 +148 -0
- 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 +242 -0
- package/dist/skills/distilled/distilled-karpathy-guidelines.md +104 -0
- package/dist/skills/distilled/distilled-performance-optimization.md +175 -0
- package/dist/skills/distilled/distilled-receiving-code-review.md +185 -0
- package/dist/skills/distilled/distilled-spec-driven-design.md +193 -0
- package/dist/skills/distilled/distilled-subagent-driven-development.md +124 -0
- package/dist/skills/distilled/distilled-systematic-debugging.md +154 -0
- 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 +213 -0
- package/dist/skills/distilled/distilled-writing-skills.md +175 -0
- package/dist/skills/registry.d.ts +55 -51
- package/dist/skills/registry.d.ts.map +1 -1
- package/dist/skills/registry.js +82 -196
- package/dist/skills/registry.js.map +1 -1
- package/dist/skills/tools/pipeline-suggest.js +14 -14
- package/dist/skills/tools/pipeline-suggest.js.map +1 -1
- package/dist/skills/tools/skill-invoke.d.ts +3 -2
- package/dist/skills/tools/skill-invoke.d.ts.map +1 -1
- package/dist/skills/tools/skill-invoke.js +4 -2
- 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-content.d.ts +30 -0
- package/dist/web/routes/agent-content.d.ts.map +1 -0
- package/dist/web/routes/agent-content.js +139 -0
- package/dist/web/routes/agent-content.js.map +1 -0
- 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.d.ts +15 -0
- package/dist/web/routes/decisions.d.ts.map +1 -0
- package/dist/web/routes/decisions.js +181 -0
- package/dist/web/routes/decisions.js.map +1 -0
- package/dist/web/routes/diagnostics.d.ts +61 -0
- package/dist/web/routes/diagnostics.d.ts.map +1 -0
- package/dist/web/routes/diagnostics.js +203 -0
- package/dist/web/routes/diagnostics.js.map +1 -0
- 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 +26 -1
- package/dist/web/routes/events.js.map +1 -1
- package/dist/web/routes/health.d.ts +33 -0
- package/dist/web/routes/health.d.ts.map +1 -0
- package/dist/web/routes/health.js +37 -0
- package/dist/web/routes/health.js.map +1 -0
- package/dist/web/routes/insights.d.ts +0 -5
- 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 +57 -0
- package/dist/web/routes/knowledge.d.ts.map +1 -0
- package/dist/web/routes/knowledge.js +772 -0
- package/dist/web/routes/knowledge.js.map +1 -0
- package/dist/web/routes/patch.d.ts +60 -1
- package/dist/web/routes/patch.d.ts.map +1 -1
- package/dist/web/routes/patch.js +170 -64
- package/dist/web/routes/patch.js.map +1 -1
- package/dist/web/routes/pipeline.d.ts +28 -0
- package/dist/web/routes/pipeline.d.ts.map +1 -0
- package/dist/web/routes/pipeline.js +145 -0
- package/dist/web/routes/pipeline.js.map +1 -0
- package/dist/web/routes/rules.d.ts.map +1 -1
- package/dist/web/routes/rules.js +26 -7
- 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 +17 -8
- package/dist/web/routes/sessions.js.map +1 -1
- package/dist/web/routes/skill-content.d.ts +30 -0
- package/dist/web/routes/skill-content.d.ts.map +1 -0
- package/dist/web/routes/skill-content.js +117 -0
- package/dist/web/routes/skill-content.js.map +1 -0
- 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.d.ts +29 -0
- package/dist/web/routes/skills-distill.d.ts.map +1 -0
- package/dist/web/routes/skills-distill.js +552 -0
- package/dist/web/routes/skills-distill.js.map +1 -0
- package/dist/web/routes/skills.js +7 -7
- package/dist/web/routes/skills.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 +178 -0
- package/dist/web/routes/task-timeline.d.ts.map +1 -0
- package/dist/web/routes/task-timeline.js +530 -0
- package/dist/web/routes/task-timeline.js.map +1 -0
- package/dist/web/routes/tasks.d.ts.map +1 -1
- package/dist/web/routes/tasks.js +377 -8
- package/dist/web/routes/tasks.js.map +1 -1
- package/dist/web/routes/trace.d.ts.map +1 -1
- package/dist/web/routes/trace.js +3 -2
- package/dist/web/routes/trace.js.map +1 -1
- package/dist/web/routes/types.d.ts +0 -4
- package/dist/web/routes/types.d.ts.map +1 -1
- package/dist/web/routes/types.js +1 -1
- package/dist/web/routes/types.js.map +1 -1
- package/dist/web/routes/violations.d.ts +14 -0
- package/dist/web/routes/violations.d.ts.map +1 -0
- package/dist/web/routes/violations.js +112 -0
- package/dist/web/routes/violations.js.map +1 -0
- package/dist/web/server.d.ts.map +1 -1
- package/dist/web/server.js +99 -19
- 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/build-manager.d.ts +72 -0
- package/dist/web/services/build-manager.d.ts.map +1 -0
- package/dist/web/services/build-manager.js +189 -0
- package/dist/web/services/build-manager.js.map +1 -0
- package/dist/web/services/distill-manager.d.ts +172 -0
- package/dist/web/services/distill-manager.d.ts.map +1 -0
- package/dist/web/services/distill-manager.js +411 -0
- package/dist/web/services/distill-manager.js.map +1 -0
- 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-DlDQNihj.js +3 -0
- package/dist/web/static/assets/MarkdownRenderer-DlDQNihj.js.map +1 -0
- package/dist/web/static/assets/NotFound-LMzbP51V.js +2 -0
- package/dist/web/static/assets/NotFound-LMzbP51V.js.map +1 -0
- 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-DFQA6dO_.css +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/date-fns-sbWH3_uq.js +2 -0
- package/dist/web/static/assets/date-fns-sbWH3_uq.js.map +1 -0
- package/dist/web/static/assets/index-B_v_MKlb.css +1 -0
- 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/lucide-CnlPQoG8.js +72 -0
- package/dist/web/static/assets/lucide-CnlPQoG8.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-BKGy9azt.js +2 -0
- package/dist/web/static/assets/outcome-BKGy9azt.js.map +1 -0
- package/dist/web/static/assets/query-CgCOpYWf.js +2 -0
- package/dist/web/static/assets/{query-C99w429o.js.map → query-CgCOpYWf.js.map} +1 -1
- package/dist/web/static/assets/{react-router-r79dBVy4.js → react-router-Cxmg8RuL.js} +3 -3
- package/dist/web/static/assets/{react-router-r79dBVy4.js.map → react-router-Cxmg8RuL.js.map} +1 -1
- package/dist/web/static/assets/react-vendor-tkvCrao7.js +57 -0
- package/dist/web/static/assets/react-vendor-tkvCrao7.js.map +1 -0
- package/dist/web/static/assets/syntax-highlighter-BDYycNja.js +6 -0
- package/dist/web/static/assets/syntax-highlighter-BDYycNja.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 +12 -8
- package/package.json +18 -5
- package/dist/core/ai/provider.d.ts +0 -63
- package/dist/core/ai/provider.d.ts.map +0 -1
- package/dist/core/ai/provider.js +0 -241
- package/dist/core/ai/provider.js.map +0 -1
- package/dist/core/ai/types.d.ts +0 -43
- package/dist/core/ai/types.d.ts.map +0 -1
- package/dist/core/ai/types.js +0 -5
- package/dist/core/ai/types.js.map +0 -1
- package/dist/core/storage/token-usage.d.ts +0 -36
- package/dist/core/storage/token-usage.d.ts.map +0 -1
- package/dist/core/storage/token-usage.js +0 -59
- package/dist/core/storage/token-usage.js.map +0 -1
- package/dist/core/utils/token-tracker.d.ts +0 -39
- package/dist/core/utils/token-tracker.d.ts.map +0 -1
- package/dist/core/utils/token-tracker.js +0 -69
- package/dist/core/utils/token-tracker.js.map +0 -1
- package/dist/skills/index.d.ts +0 -3
- package/dist/skills/index.d.ts.map +0 -1
- package/dist/skills/index.js +0 -3
- package/dist/skills/index.js.map +0 -1
- package/dist/skills/matcher.d.ts +0 -26
- package/dist/skills/matcher.d.ts.map +0 -1
- package/dist/skills/matcher.js +0 -113
- package/dist/skills/matcher.js.map +0 -1
- package/dist/skills/official/code-simplifier.md +0 -52
- package/dist/skills/official/find-skills.md +0 -142
- package/dist/skills/official/official-api-design.md +0 -30
- package/dist/skills/official/official-architecture-decision.md +0 -41
- package/dist/skills/official/official-bmad.md +0 -118
- package/dist/skills/official/official-db-schema-design.md +0 -34
- package/dist/skills/official/official-debug.md +0 -25
- package/dist/skills/official/official-doc-driven.md +0 -31
- package/dist/skills/official/official-harness-engineering.md +0 -108
- package/dist/skills/official/official-openspec.md +0 -89
- package/dist/skills/official/official-performance-optimization.md +0 -30
- package/dist/skills/official/official-pr-review.md +0 -35
- package/dist/skills/official/official-release-checklist.md +0 -30
- package/dist/skills/official/official-security-hardening.md +0 -32
- package/dist/skills/official/official-spec-driven-design.md +0 -31
- package/dist/skills/official/planning-with-files.md +0 -241
- package/dist/skills/official/ui-ux-pro-max.md +0 -105
- package/dist/skills/official/webapp-testing.md +0 -96
- package/dist/skills/official-skills.d.ts +0 -26
- package/dist/skills/official-skills.d.ts.map +0 -1
- package/dist/skills/official-skills.js +0 -74
- package/dist/skills/official-skills.js.map +0 -1
- package/dist/skills/semantic-matcher.d.ts +0 -60
- package/dist/skills/semantic-matcher.d.ts.map +0 -1
- package/dist/skills/semantic-matcher.js +0 -192
- package/dist/skills/semantic-matcher.js.map +0 -1
- package/dist/skills/upgrade-engine.d.ts +0 -93
- package/dist/skills/upgrade-engine.d.ts.map +0 -1
- package/dist/skills/upgrade-engine.js +0 -447
- package/dist/skills/upgrade-engine.js.map +0 -1
- package/dist/skills/upgrade-prompt.d.ts +0 -20
- package/dist/skills/upgrade-prompt.d.ts.map +0 -1
- package/dist/skills/upgrade-prompt.js +0 -75
- package/dist/skills/upgrade-prompt.js.map +0 -1
- package/dist/web/routes/ai.d.ts +0 -10
- package/dist/web/routes/ai.d.ts.map +0 -1
- package/dist/web/routes/ai.js +0 -186
- package/dist/web/routes/ai.js.map +0 -1
- package/dist/web/routes/token-usage.d.ts +0 -7
- package/dist/web/routes/token-usage.d.ts.map +0 -1
- package/dist/web/routes/token-usage.js +0 -18
- package/dist/web/routes/token-usage.js.map +0 -1
- package/dist/web/ssrf-guard.d.ts +0 -35
- package/dist/web/ssrf-guard.d.ts.map +0 -1
- package/dist/web/ssrf-guard.js +0 -93
- package/dist/web/ssrf-guard.js.map +0 -1
- package/dist/web/static/assets/AIConfig-CdDWzJyO.js +0 -2
- package/dist/web/static/assets/AIConfig-CdDWzJyO.js.map +0 -1
- package/dist/web/static/assets/Dashboard-CoEmmIDt.js +0 -2
- package/dist/web/static/assets/Dashboard-CoEmmIDt.js.map +0 -1
- package/dist/web/static/assets/Drawer-DdRTzlLB.js +0 -2
- package/dist/web/static/assets/Drawer-DdRTzlLB.js.map +0 -1
- package/dist/web/static/assets/Events-DrIq1SUS.js +0 -2
- package/dist/web/static/assets/Events-DrIq1SUS.js.map +0 -1
- package/dist/web/static/assets/Reports-DFBM3MDK.js +0 -2
- package/dist/web/static/assets/Reports-DFBM3MDK.js.map +0 -1
- package/dist/web/static/assets/SearchInput-qCj_jAcf.js +0 -2
- package/dist/web/static/assets/SearchInput-qCj_jAcf.js.map +0 -1
- package/dist/web/static/assets/SessionDetail-CCzwdoT7.js +0 -2
- package/dist/web/static/assets/SessionDetail-CCzwdoT7.js.map +0 -1
- package/dist/web/static/assets/Sessions-FfLYkAw9.js +0 -2
- package/dist/web/static/assets/Sessions-FfLYkAw9.js.map +0 -1
- package/dist/web/static/assets/Skills-C8Gvs3Qa.js +0 -2
- package/dist/web/static/assets/Skills-C8Gvs3Qa.js.map +0 -1
- package/dist/web/static/assets/TaskDetail-BS8pYhaR.js +0 -2
- package/dist/web/static/assets/TaskDetail-BS8pYhaR.js.map +0 -1
- package/dist/web/static/assets/Tasks-CyuhizG8.js +0 -2
- package/dist/web/static/assets/Tasks-CyuhizG8.js.map +0 -1
- package/dist/web/static/assets/charts-CLrM0_uM.js +0 -37
- package/dist/web/static/assets/charts-CLrM0_uM.js.map +0 -1
- package/dist/web/static/assets/date-fns-CZ_bHujz.js +0 -2
- package/dist/web/static/assets/date-fns-CZ_bHujz.js.map +0 -1
- package/dist/web/static/assets/export-L_VBD2p1.js +0 -4
- package/dist/web/static/assets/export-L_VBD2p1.js.map +0 -1
- package/dist/web/static/assets/index-CBX47X8l.js +0 -3
- package/dist/web/static/assets/index-CBX47X8l.js.map +0 -1
- package/dist/web/static/assets/index-DjIoMdoR.css +0 -1
- package/dist/web/static/assets/lucide-Bs_edTLa.js +0 -232
- package/dist/web/static/assets/lucide-Bs_edTLa.js.map +0 -1
- package/dist/web/static/assets/query-C99w429o.js +0 -2
- package/dist/web/static/assets/react-vendor-CSp-GLFF.js +0 -49
- package/dist/web/static/assets/react-vendor-CSp-GLFF.js.map +0 -1
- package/dist/web/static/assets/syntax-highlighter-44FakypI.js +0 -9
- package/dist/web/static/assets/syntax-highlighter-44FakypI.js.map +0 -1
- package/dist/web/static/assets/time-Bxuk0M-C.js +0 -2
- package/dist/web/static/assets/time-Bxuk0M-C.js.map +0 -1
- package/dist/web/static/assets/vendor-CMMjVdZs.js +0 -64
- package/dist/web/static/assets/vendor-CMMjVdZs.js.map +0 -1
|
@@ -0,0 +1,1070 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @file knowledge.ts
|
|
3
|
+
* CLI commands for the v9.0 Knowledge Base (KB) subsystem.
|
|
4
|
+
*
|
|
5
|
+
* Commands registered under `cf knowledge` (alias: `cf kb`):
|
|
6
|
+
* init — One-shot: build + apply + install git hook (recommended for new projects)
|
|
7
|
+
* build — Compile KB from source (dry-run by default)
|
|
8
|
+
* update — Incremental rebuild based on git diff
|
|
9
|
+
* query — Keyword + repo-map search
|
|
10
|
+
* fetch — Format KB hits as a ready-to-paste Markdown prompt block
|
|
11
|
+
* list — List all KB pages
|
|
12
|
+
* audit — Validate all page refs
|
|
13
|
+
* clean — Delete KB directory and uninstall git hook
|
|
14
|
+
* rollback — Restore from a backup timestamp
|
|
15
|
+
* hook-status — Show git hook installation state
|
|
16
|
+
*/
|
|
17
|
+
import path from 'node:path';
|
|
18
|
+
import fs from 'node:fs';
|
|
19
|
+
import { execSync } from 'node:child_process';
|
|
20
|
+
import chalk from 'chalk';
|
|
21
|
+
import { buildKnowledge } from '../../knowledge/builder.js';
|
|
22
|
+
import { KbBlockMissingError } from '../../knowledge/cli-provider.js';
|
|
23
|
+
import { ClaudeCliMissingError, ClaudeCliExitError, ClaudeCliTimeoutError, ClaudeCliCancelledError, } from '../../core/utils/claude-cli-spawn.js';
|
|
24
|
+
import { queryKnowledge, listKnowledge, isKnowledgeBuilt } from '../../knowledge/query.js';
|
|
25
|
+
import { SQLiteStorage } from '../../core/storage/sqlite.js';
|
|
26
|
+
import { FORGE_PATHS } from '../../core/constants.js';
|
|
27
|
+
import { resolveSessionId } from '../utils/resolve-session.js';
|
|
28
|
+
import { installGitHook, uninstallGitHook, getHookStatus } from '../../knowledge/git-hooks.js';
|
|
29
|
+
import { validatePage } from '../../knowledge/validator.js';
|
|
30
|
+
import { loadRepoMap } from '../../knowledge/repo-map.js';
|
|
31
|
+
import { applyAuditResult, deriveAuditStatus, } from '../../knowledge/audit-applier.js';
|
|
32
|
+
import * as K from '../../knowledge/constants.js';
|
|
33
|
+
import { detectMonorepo, listCandidateSubdirs } from '../../knowledge/project-detector.js';
|
|
34
|
+
import { getAdapter } from '../../knowledge/adapters/index.js';
|
|
35
|
+
// ─────────────────────────────────────────────────────────────────────────────
|
|
36
|
+
// Friendly error reporter (shared by build/init/update action handlers)
|
|
37
|
+
// ─────────────────────────────────────────────────────────────────────────────
|
|
38
|
+
/**
|
|
39
|
+
* Map the errors that `buildKnowledge` (via `CliKnowledgeProvider`) can raise
|
|
40
|
+
* into operator-friendly stderr output. Pattern-matches the typed errors from
|
|
41
|
+
* `claude-cli-spawn` + `cli-provider` so the user sees actionable hints
|
|
42
|
+
* instead of raw stack traces.
|
|
43
|
+
*
|
|
44
|
+
* Falls back to the legacy `console.error(label, err.message)` shape for any
|
|
45
|
+
* unrecognised error, preserving R-A behaviour for unknown failure modes.
|
|
46
|
+
*/
|
|
47
|
+
function reportKnowledgeBuildError(label, err) {
|
|
48
|
+
if (err instanceof ClaudeCliMissingError) {
|
|
49
|
+
console.error(chalk.red(label), err.message);
|
|
50
|
+
console.error(chalk.dim('Install Claude Code: https://docs.anthropic.com/en/docs/claude-code or `npm i -g @anthropic-ai/claude-code`.'));
|
|
51
|
+
return;
|
|
52
|
+
}
|
|
53
|
+
if (err instanceof ClaudeCliCancelledError) {
|
|
54
|
+
console.error(chalk.yellow('[cf knowledge] cancelled.'));
|
|
55
|
+
return;
|
|
56
|
+
}
|
|
57
|
+
if (err instanceof ClaudeCliTimeoutError) {
|
|
58
|
+
console.error(chalk.red(label), `claude CLI timeout after ${err.timeoutMs}ms. Re-run with a faster network or split into smaller modules.`);
|
|
59
|
+
return;
|
|
60
|
+
}
|
|
61
|
+
if (err instanceof ClaudeCliExitError) {
|
|
62
|
+
console.error(chalk.red(label), `claude CLI exit ${err.exitCode}: ${err.stderrSnippet}`);
|
|
63
|
+
return;
|
|
64
|
+
}
|
|
65
|
+
if (err instanceof KbBlockMissingError) {
|
|
66
|
+
console.error(chalk.red(label), err.message);
|
|
67
|
+
console.error(chalk.dim('The knowledge-builder agent returned text but no `---KB---...---END---` envelope. This usually means the agent is on an older revision; pull the latest `.claude/agents/knowledge-builder.md` and retry.'));
|
|
68
|
+
console.error(chalk.dim(`Snippet: ${err.rawSnippet}`));
|
|
69
|
+
return;
|
|
70
|
+
}
|
|
71
|
+
console.error(chalk.red(label), err instanceof Error ? err.message : String(err));
|
|
72
|
+
}
|
|
73
|
+
async function buildCmd(options) {
|
|
74
|
+
console.log(chalk.cyan('Building knowledge base...'));
|
|
75
|
+
const buildOptions = {
|
|
76
|
+
apply: !!options.apply,
|
|
77
|
+
force: !!options.force,
|
|
78
|
+
modules: options.module ? [options.module] : undefined,
|
|
79
|
+
skipCrossModule: !!options.skipCrossModule,
|
|
80
|
+
};
|
|
81
|
+
const result = await buildKnowledge(buildOptions);
|
|
82
|
+
const { built, cached, total, crossModuleBuilt, crossModuleCached } = result.stats;
|
|
83
|
+
console.log(chalk.green(`✓ ${built} built, ${cached} cached (${total} total)`));
|
|
84
|
+
if (!options.skipCrossModule) {
|
|
85
|
+
const moduleBuilt = built - (crossModuleBuilt ?? 0);
|
|
86
|
+
const moduleCached = cached - (crossModuleCached ?? 0);
|
|
87
|
+
console.log(chalk.dim(` ├─ Module pages: ${moduleBuilt} built, ${moduleCached} cached`));
|
|
88
|
+
console.log(chalk.dim(` └─ Cross-module pages: ${crossModuleBuilt ?? 0} built, ${crossModuleCached ?? 0} cached`));
|
|
89
|
+
}
|
|
90
|
+
console.log(`Report: ${result.reportPath}`);
|
|
91
|
+
if (result.mode === 'dry-run') {
|
|
92
|
+
console.log(chalk.yellow('\nNext: review the report, then run:'));
|
|
93
|
+
console.log(chalk.bold(' cf knowledge build --apply'));
|
|
94
|
+
}
|
|
95
|
+
else {
|
|
96
|
+
if (result.appliedTo) {
|
|
97
|
+
console.log(chalk.green(`✓ Applied to ${result.appliedTo}`));
|
|
98
|
+
}
|
|
99
|
+
// KB-ADR-006: auto-install git hook on first --apply
|
|
100
|
+
const installResult = installGitHook({ silent: true });
|
|
101
|
+
switch (installResult.action) {
|
|
102
|
+
case 'created':
|
|
103
|
+
console.log(chalk.green('✓ git post-commit hook installed (auto-update on commit)'));
|
|
104
|
+
break;
|
|
105
|
+
case 'appended':
|
|
106
|
+
console.log(chalk.green('✓ cf section appended to existing hook (user hook preserved)'));
|
|
107
|
+
break;
|
|
108
|
+
case 'already-installed':
|
|
109
|
+
console.log(chalk.dim('i cf hook already present'));
|
|
110
|
+
break;
|
|
111
|
+
case 'skipped-non-git':
|
|
112
|
+
console.log(chalk.yellow("i Not a git repo, KB auto-update disabled. Use 'cf knowledge update' manually."));
|
|
113
|
+
break;
|
|
114
|
+
}
|
|
115
|
+
console.log(chalk.dim("\nTip: add `.forge-knowledge/backups/` to .gitignore if you don't want to track them."));
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
/**
|
|
119
|
+
* Spec ed8cf2db §5: exposed so `cf project init` can directly drive the same
|
|
120
|
+
* one-shot KB build path without spawning a child `cf knowledge init`
|
|
121
|
+
* subprocess.
|
|
122
|
+
*
|
|
123
|
+
* Spec 2026-06-04/1200 (decision e0eb1695): no longer `process.exit(1)` on an
|
|
124
|
+
* unsupported project type. Monorepo roots build a single aggregate KB;
|
|
125
|
+
* true-generic projects return `{ skipped: 'generic' }` so the caller can mark
|
|
126
|
+
* the step `skipped` and exit 0.
|
|
127
|
+
*/
|
|
128
|
+
export async function initCmd(options) {
|
|
129
|
+
const projectRoot = process.cwd();
|
|
130
|
+
// ── Pre-check 1: Check if project is supported by adapter system ───────
|
|
131
|
+
//
|
|
132
|
+
// Band-aid + monorepo resolution (spec 2026-06-04/1200, decision e0eb1695):
|
|
133
|
+
// - single-language adapter matches → continue (unchanged path)
|
|
134
|
+
// - no root adapter but ≥2 sub-projects each have one → monorepo. Print the
|
|
135
|
+
// detected sub-projects and continue; `buildKnowledge` constructs the
|
|
136
|
+
// `MonorepoAdapter` internally (one KB at the monorepo root).
|
|
137
|
+
// - no root adapter and no sub-projects (true-generic) → warn + RETURN
|
|
138
|
+
// (NO `process.exit(1)`). The caller (`cf project init`) sees a clean
|
|
139
|
+
// resolve and marks the knowledge step `skipped`, exit 0.
|
|
140
|
+
const adapter = getAdapter(projectRoot);
|
|
141
|
+
if (!adapter) {
|
|
142
|
+
const monorepoInfo = detectMonorepo(projectRoot);
|
|
143
|
+
if (monorepoInfo) {
|
|
144
|
+
console.log(chalk.dim(`Detected monorepo with ${monorepoInfo.subprojects.length} sub-projects: ` +
|
|
145
|
+
monorepoInfo.subprojects.map((s) => s.name).join(', ')));
|
|
146
|
+
// adapter (MonorepoAdapter) is created inside buildKnowledge — no exit.
|
|
147
|
+
}
|
|
148
|
+
else {
|
|
149
|
+
const subdirs = listCandidateSubdirs(projectRoot);
|
|
150
|
+
console.warn(chalk.yellow('⚠ No supported project type detected (generic project). ' +
|
|
151
|
+
'Knowledge base skipped.'));
|
|
152
|
+
console.warn(chalk.gray('Hint: cd into a sub-project and run `cf project init`, or use a ' +
|
|
153
|
+
'supported manifest (package.json / pom.xml / build.gradle / ' +
|
|
154
|
+
'pyproject.toml / go.mod / Cargo.toml).\n' +
|
|
155
|
+
`Sub-directories found: ${subdirs.length > 0 ? subdirs.join(', ') : 'none'}`));
|
|
156
|
+
return { skipped: 'generic' }; // graceful skip — no process.exit(1)
|
|
157
|
+
}
|
|
158
|
+
}
|
|
159
|
+
else {
|
|
160
|
+
console.log(chalk.dim(`Detected ${adapter.name} project`));
|
|
161
|
+
}
|
|
162
|
+
// ── Pre-check 2: KB already initialized? ───────────────────────────────
|
|
163
|
+
if (isKnowledgeBuilt() && !options.force) {
|
|
164
|
+
console.error(chalk.red('Knowledge base already initialized at .forge-knowledge/'));
|
|
165
|
+
console.error(chalk.gray('Use `cf knowledge init --force` to rebuild, or `cf knowledge clean --confirm` first.'));
|
|
166
|
+
process.exit(1);
|
|
167
|
+
}
|
|
168
|
+
// ── Pre-check 3: REMOVED (sub-spec B, decision f5a5b030) ──────────────
|
|
169
|
+
// The legacy `config.ai.api_key` / `ANTHROPIC_API_KEY` probe is gone. The
|
|
170
|
+
// CLI delegates straight to `buildKnowledge()`, which spawns the
|
|
171
|
+
// `knowledge-builder` agent via `CliKnowledgeProvider`. Any subprocess
|
|
172
|
+
// failures (CLI missing, exit, timeout, envelope missing) bubble up and
|
|
173
|
+
// are mapped to friendly stderr output by `reportKnowledgeBuildError`.
|
|
174
|
+
// ── Build & apply ──────────────────────────────────────────────────────
|
|
175
|
+
console.log(chalk.cyan('Initializing knowledge base...'));
|
|
176
|
+
const result = await buildKnowledge({
|
|
177
|
+
apply: true,
|
|
178
|
+
force: !!options.force,
|
|
179
|
+
skipCrossModule: !!options.skipCrossModule,
|
|
180
|
+
});
|
|
181
|
+
// ── Install git hook (unless --no-hook) ────────────────────────────────
|
|
182
|
+
// commander's `--no-hook` flag sets `options.hook === false`. Default = true.
|
|
183
|
+
const shouldInstallHook = options.hook !== false;
|
|
184
|
+
let hookInstalled = false;
|
|
185
|
+
let hookAlreadyPresent = false;
|
|
186
|
+
let hookSkippedNonGit = false;
|
|
187
|
+
if (shouldInstallHook) {
|
|
188
|
+
try {
|
|
189
|
+
const hookResult = installGitHook({ silent: true });
|
|
190
|
+
switch (hookResult.action) {
|
|
191
|
+
case 'created':
|
|
192
|
+
case 'appended':
|
|
193
|
+
hookInstalled = true;
|
|
194
|
+
break;
|
|
195
|
+
case 'already-installed':
|
|
196
|
+
hookAlreadyPresent = true;
|
|
197
|
+
break;
|
|
198
|
+
case 'skipped-non-git':
|
|
199
|
+
hookSkippedNonGit = true;
|
|
200
|
+
break;
|
|
201
|
+
}
|
|
202
|
+
}
|
|
203
|
+
catch (err) {
|
|
204
|
+
console.log(chalk.yellow(`⚠ Could not install git hook: ${err instanceof Error ? err.message : String(err)}`));
|
|
205
|
+
}
|
|
206
|
+
}
|
|
207
|
+
// ── Friendly summary ───────────────────────────────────────────────────
|
|
208
|
+
const { built, cached, total } = result.stats;
|
|
209
|
+
console.log('');
|
|
210
|
+
console.log(chalk.green(`✓ Knowledge base initialized at .forge-knowledge/`));
|
|
211
|
+
console.log(chalk.green(`✓ Built ${built}, cached ${cached}, total ${total} pages`));
|
|
212
|
+
if (hookInstalled) {
|
|
213
|
+
console.log(chalk.green('✓ Git post-commit hook installed'));
|
|
214
|
+
}
|
|
215
|
+
else if (hookAlreadyPresent) {
|
|
216
|
+
console.log(chalk.dim(' Git hook already installed'));
|
|
217
|
+
}
|
|
218
|
+
else if (hookSkippedNonGit) {
|
|
219
|
+
console.log(chalk.dim(' Not a git repo — skipped post-commit hook install'));
|
|
220
|
+
}
|
|
221
|
+
else if (!shouldInstallHook) {
|
|
222
|
+
console.log(chalk.dim(' Git hook install skipped (--no-hook)'));
|
|
223
|
+
}
|
|
224
|
+
console.log('');
|
|
225
|
+
console.log(chalk.bold('Next steps:'));
|
|
226
|
+
console.log(chalk.gray(' cf knowledge query <topic> # Search KB'));
|
|
227
|
+
console.log(chalk.gray(' cf knowledge list # List all pages'));
|
|
228
|
+
console.log(chalk.gray(' cf knowledge audit # Validate refs'));
|
|
229
|
+
}
|
|
230
|
+
async function updateCmd(options) {
|
|
231
|
+
if (!isKnowledgeBuilt()) {
|
|
232
|
+
console.error(chalk.red('Knowledge base not built yet. Run: cf knowledge build --apply'));
|
|
233
|
+
process.exit(1);
|
|
234
|
+
}
|
|
235
|
+
let modulesToUpdate = options.module ? [options.module] : undefined;
|
|
236
|
+
if (!modulesToUpdate) {
|
|
237
|
+
try {
|
|
238
|
+
const diffOutput = execSync('git diff --name-only HEAD~1 HEAD -- src/', {
|
|
239
|
+
stdio: ['ignore', 'pipe', 'ignore'],
|
|
240
|
+
}).toString();
|
|
241
|
+
const changedFiles = diffOutput.trim().split('\n').filter(Boolean);
|
|
242
|
+
const moduleSet = new Set();
|
|
243
|
+
for (const f of changedFiles) {
|
|
244
|
+
const m = f.match(/^src\/([^/]+)\//);
|
|
245
|
+
if (m)
|
|
246
|
+
moduleSet.add(m[1]);
|
|
247
|
+
}
|
|
248
|
+
modulesToUpdate = [...moduleSet];
|
|
249
|
+
}
|
|
250
|
+
catch {
|
|
251
|
+
console.error(chalk.yellow('git diff failed — falling back to full rebuild'));
|
|
252
|
+
modulesToUpdate = undefined;
|
|
253
|
+
}
|
|
254
|
+
}
|
|
255
|
+
if (modulesToUpdate && modulesToUpdate.length === 0) {
|
|
256
|
+
console.log(chalk.dim('No src/ modules affected by recent commits'));
|
|
257
|
+
return;
|
|
258
|
+
}
|
|
259
|
+
console.log(chalk.cyan(`Updating modules: ${modulesToUpdate ? modulesToUpdate.join(', ') : 'ALL'}`));
|
|
260
|
+
await buildKnowledge({ apply: true, modules: modulesToUpdate, force: !!options.force });
|
|
261
|
+
console.log(chalk.green('✓ Update complete'));
|
|
262
|
+
}
|
|
263
|
+
// Sentinel agent id used when no real session can be resolved (bare CLI call
|
|
264
|
+
// outside any Claude session). Keeps the kb_query_log attribution non-empty.
|
|
265
|
+
const CLI_KB_SESSION_FALLBACK = 'cli-no-session';
|
|
266
|
+
/**
|
|
267
|
+
* Build the kb_query_log attribution context (decision d24cd3a2 Task B).
|
|
268
|
+
*
|
|
269
|
+
* Opens (or reuses an injected) storage handle + resolves the agent/session id
|
|
270
|
+
* so a deliberate `cf knowledge query --reason` pull records source='cli',
|
|
271
|
+
* verbatim reason, and an agent_id — distinguishable from the daemon's
|
|
272
|
+
* automatic per-prompt probe (source='daemon-probe'). Fail-soft: a DB hiccup
|
|
273
|
+
* yields `{ storage: undefined }` so the query's printed output is never broken.
|
|
274
|
+
*
|
|
275
|
+
* Returns the storage handle to thread into queryKnowledge plus an `ownStorage`
|
|
276
|
+
* flag so the caller knows whether to close it.
|
|
277
|
+
*/
|
|
278
|
+
function buildKbTelemetryContext(options, deps) {
|
|
279
|
+
const ownStorage = !deps.storage;
|
|
280
|
+
let storage;
|
|
281
|
+
try {
|
|
282
|
+
storage = deps.storage ?? new SQLiteStorage(FORGE_PATHS.database());
|
|
283
|
+
}
|
|
284
|
+
catch {
|
|
285
|
+
storage = undefined; // telemetry must never break the query's output
|
|
286
|
+
}
|
|
287
|
+
const projectPath = deps.projectRoot ?? options.project ?? process.cwd();
|
|
288
|
+
let agentId = deps.sessionId ?? options.sessionId ?? '';
|
|
289
|
+
if (storage && !agentId) {
|
|
290
|
+
try {
|
|
291
|
+
agentId = resolveSessionId(storage, {
|
|
292
|
+
sessionId: options.sessionId,
|
|
293
|
+
projectPath,
|
|
294
|
+
}).sessionId;
|
|
295
|
+
}
|
|
296
|
+
catch {
|
|
297
|
+
agentId = '';
|
|
298
|
+
}
|
|
299
|
+
}
|
|
300
|
+
if (!agentId)
|
|
301
|
+
agentId = CLI_KB_SESSION_FALLBACK;
|
|
302
|
+
return { storage, ownStorage, source: 'cli', agentId };
|
|
303
|
+
}
|
|
304
|
+
export async function queryCmd(topic, options, deps = {}) {
|
|
305
|
+
const log = deps.io?.log ?? ((m) => console.log(m));
|
|
306
|
+
const projectRoot = deps.projectRoot;
|
|
307
|
+
if (!isKnowledgeBuilt(projectRoot)) {
|
|
308
|
+
console.error(chalk.red('Knowledge base not built yet. Run: cf knowledge build --apply'));
|
|
309
|
+
process.exit(1);
|
|
310
|
+
}
|
|
311
|
+
const maxResults = options.max ? parseInt(options.max, 10) : 3;
|
|
312
|
+
const tele = buildKbTelemetryContext(options, deps);
|
|
313
|
+
const queryOptions = {
|
|
314
|
+
maxResults,
|
|
315
|
+
...(projectRoot ? { projectRoot } : {}),
|
|
316
|
+
storage: tele.storage,
|
|
317
|
+
reason: options.reason,
|
|
318
|
+
source: tele.source,
|
|
319
|
+
agentId: tele.agentId,
|
|
320
|
+
};
|
|
321
|
+
try {
|
|
322
|
+
const result = await queryKnowledge(topic, queryOptions);
|
|
323
|
+
if (options.json) {
|
|
324
|
+
log(JSON.stringify(result, null, 2));
|
|
325
|
+
return;
|
|
326
|
+
}
|
|
327
|
+
printQueryResult(topic, result, log);
|
|
328
|
+
}
|
|
329
|
+
finally {
|
|
330
|
+
if (tele.ownStorage && tele.storage) {
|
|
331
|
+
try {
|
|
332
|
+
tele.storage.close();
|
|
333
|
+
}
|
|
334
|
+
catch { /* ignore */ }
|
|
335
|
+
}
|
|
336
|
+
}
|
|
337
|
+
}
|
|
338
|
+
// ─────────────────────────────────────────────────────────────────────────────
|
|
339
|
+
// KB usefulness feedback (decision 096309e4 batch 1 item ①)
|
|
340
|
+
// ─────────────────────────────────────────────────────────────────────────────
|
|
341
|
+
const KB_USEFULNESS_RATINGS = ['helped', 'partial', 'not-actionable'];
|
|
342
|
+
/**
|
|
343
|
+
* `cf knowledge feedback --rating <helped|partial|not-actionable>`:
|
|
344
|
+
* POST-USE self-assessment for a KB pull. Mirrors `cf skill feedback` — after an
|
|
345
|
+
* agent pulled KB via `cf knowledge query/fetch --reason` and used the content,
|
|
346
|
+
* it rates whether that content actually helped on THIS task. Stamps the
|
|
347
|
+
* most-recent un-rated `source='cli'` kb_query_log row for this project.
|
|
348
|
+
*
|
|
349
|
+
* Telemetry discipline: advisory, must NEVER throw into the agent's main flow.
|
|
350
|
+
* Invalid rating → exit 1 (the one hard validation). DB-open failure / 0-row →
|
|
351
|
+
* soft path, exit 0.
|
|
352
|
+
*/
|
|
353
|
+
export async function feedbackCmd(options, deps = {}) {
|
|
354
|
+
const log = deps.io?.log ?? ((m) => console.log(m));
|
|
355
|
+
const error = deps.io?.error ?? ((m) => console.error(m));
|
|
356
|
+
const rating = options.rating?.trim();
|
|
357
|
+
if (!rating || !KB_USEFULNESS_RATINGS.includes(rating)) {
|
|
358
|
+
error(`Error: --rating must be one of ${KB_USEFULNESS_RATINGS.join(' | ')} (got: ${rating ?? '<none>'})`);
|
|
359
|
+
process.exit(1);
|
|
360
|
+
return;
|
|
361
|
+
}
|
|
362
|
+
const ownStorage = !deps.storage;
|
|
363
|
+
let storage;
|
|
364
|
+
try {
|
|
365
|
+
storage = deps.storage ?? new SQLiteStorage(FORGE_PATHS.database());
|
|
366
|
+
}
|
|
367
|
+
catch {
|
|
368
|
+
// Fail-soft: never break the agent's flow over a missing DB.
|
|
369
|
+
error('Warning: could not open storage; KB usefulness feedback skipped');
|
|
370
|
+
return;
|
|
371
|
+
}
|
|
372
|
+
try {
|
|
373
|
+
const projectPath = deps.projectRoot ?? options.project ?? process.cwd();
|
|
374
|
+
const stamped = storage.writeKbUsefulness({
|
|
375
|
+
project_path: projectPath,
|
|
376
|
+
usefulness: rating,
|
|
377
|
+
note: options.note ?? null,
|
|
378
|
+
reasonPrefix: options.reasonPrefix ?? null,
|
|
379
|
+
});
|
|
380
|
+
if (stamped > 0) {
|
|
381
|
+
log(`recorded KB usefulness=${rating} (${stamped} pull stamped)`);
|
|
382
|
+
}
|
|
383
|
+
else {
|
|
384
|
+
// Soft warning — do NOT fail the agent's flow over a missing pull row.
|
|
385
|
+
log(`no un-rated KB pull found for ${projectPath} (nothing stamped)`);
|
|
386
|
+
}
|
|
387
|
+
}
|
|
388
|
+
catch (err) {
|
|
389
|
+
const msg = err instanceof Error ? err.message : String(err);
|
|
390
|
+
error(`Warning: KB usefulness feedback failed: ${msg}`);
|
|
391
|
+
}
|
|
392
|
+
finally {
|
|
393
|
+
if (ownStorage && storage) {
|
|
394
|
+
try {
|
|
395
|
+
storage.close();
|
|
396
|
+
}
|
|
397
|
+
catch { /* ignore */ }
|
|
398
|
+
}
|
|
399
|
+
}
|
|
400
|
+
}
|
|
401
|
+
function printQueryResult(topic, result, log) {
|
|
402
|
+
const pagesScanned = 'total_pages_scanned' in result ? result.total_pages_scanned : '?';
|
|
403
|
+
log(chalk.bold(`\nQuery: "${topic}"`));
|
|
404
|
+
log(chalk.dim(`Scanned ${pagesScanned} pages, found ${result.pages.length} hits\n`));
|
|
405
|
+
if (result.pages.length === 0) {
|
|
406
|
+
log(chalk.yellow('No matching pages found.'));
|
|
407
|
+
return;
|
|
408
|
+
}
|
|
409
|
+
for (const hit of result.pages) {
|
|
410
|
+
log(chalk.cyan(`## ${hit.page.name} (score: ${hit.score})`));
|
|
411
|
+
log(chalk.dim(` matched: ${hit.matched_keywords.join(', ')} in ${hit.matched_in.join(', ')}`));
|
|
412
|
+
const preview = hit.page.content.substring(0, 300);
|
|
413
|
+
const ellipsis = hit.page.content.length > 300 ? '...' : '';
|
|
414
|
+
log(`${preview}${ellipsis}`);
|
|
415
|
+
log('');
|
|
416
|
+
}
|
|
417
|
+
if (result.repo_map_hits &&
|
|
418
|
+
Array.isArray(result.repo_map_hits) &&
|
|
419
|
+
result.repo_map_hits.length > 0) {
|
|
420
|
+
log(chalk.bold('Symbol hits:'));
|
|
421
|
+
for (const s of result.repo_map_hits.slice(0, 5)) {
|
|
422
|
+
log(` - ${s.name} (${s.file}:${s.line})`);
|
|
423
|
+
}
|
|
424
|
+
}
|
|
425
|
+
}
|
|
426
|
+
/** Maximum characters to keep from a page's overview section. */
|
|
427
|
+
const FETCH_OVERVIEW_MAX_CHARS = 200;
|
|
428
|
+
/** Maximum number of key-file lines to surface per page. */
|
|
429
|
+
const FETCH_KEY_FILES_PER_PAGE = 5;
|
|
430
|
+
/** Maximum number of repo-map symbol hits to surface in the trailer. */
|
|
431
|
+
const FETCH_REPO_MAP_MAX = 5;
|
|
432
|
+
/**
|
|
433
|
+
* Pull a short overview blurb out of a KB page's markdown body.
|
|
434
|
+
*
|
|
435
|
+
* Strategy:
|
|
436
|
+
* 1. Prefer the body of a `## 概述` (or `## Overview`) section, stopping at
|
|
437
|
+
* the next `## ` heading.
|
|
438
|
+
* 2. Fall back to the first non-metadata paragraph (skip `# title` and the
|
|
439
|
+
* `> Generated:` line).
|
|
440
|
+
* 3. Truncate to `FETCH_OVERVIEW_MAX_CHARS` with an ellipsis when needed.
|
|
441
|
+
*/
|
|
442
|
+
function extractOverview(content) {
|
|
443
|
+
const lines = content.split('\n');
|
|
444
|
+
// ── Try the dedicated 概述/Overview section first ──────────────────────────
|
|
445
|
+
const headerIdx = lines.findIndex((l) => /^##\s+(概述|Overview)\b/i.test(l));
|
|
446
|
+
if (headerIdx !== -1) {
|
|
447
|
+
const body = [];
|
|
448
|
+
for (let i = headerIdx + 1; i < lines.length; i++) {
|
|
449
|
+
if (lines[i].startsWith('## '))
|
|
450
|
+
break;
|
|
451
|
+
body.push(lines[i]);
|
|
452
|
+
}
|
|
453
|
+
const text = body.join(' ').replace(/\s+/g, ' ').trim();
|
|
454
|
+
if (text.length > 0)
|
|
455
|
+
return truncate(text, FETCH_OVERVIEW_MAX_CHARS);
|
|
456
|
+
}
|
|
457
|
+
// ── Fallback: first prose paragraph after the metadata block ──────────────
|
|
458
|
+
for (const line of lines) {
|
|
459
|
+
const trimmed = line.trim();
|
|
460
|
+
if (!trimmed)
|
|
461
|
+
continue;
|
|
462
|
+
if (trimmed.startsWith('#'))
|
|
463
|
+
continue;
|
|
464
|
+
if (trimmed.startsWith('>'))
|
|
465
|
+
continue;
|
|
466
|
+
return truncate(trimmed, FETCH_OVERVIEW_MAX_CHARS);
|
|
467
|
+
}
|
|
468
|
+
return '';
|
|
469
|
+
}
|
|
470
|
+
function truncate(s, max) {
|
|
471
|
+
if (s.length <= max)
|
|
472
|
+
return s;
|
|
473
|
+
return `${s.slice(0, max).trimEnd()}...`;
|
|
474
|
+
}
|
|
475
|
+
/**
|
|
476
|
+
* Pick a small set of representative `file:line — symbol` lines from a page's
|
|
477
|
+
* refs. Refs are deduplicated by `file:lineStart` and refs carrying a symbol
|
|
478
|
+
* are preferred over plain ranges.
|
|
479
|
+
*/
|
|
480
|
+
function formatKeyFiles(refs) {
|
|
481
|
+
const seen = new Set();
|
|
482
|
+
const ordered = [];
|
|
483
|
+
// Pass 1: refs with symbols (most informative).
|
|
484
|
+
for (const r of refs) {
|
|
485
|
+
if (!r.symbol)
|
|
486
|
+
continue;
|
|
487
|
+
const key = `${r.file}:${r.lineStart}`;
|
|
488
|
+
if (seen.has(key))
|
|
489
|
+
continue;
|
|
490
|
+
seen.add(key);
|
|
491
|
+
ordered.push(r);
|
|
492
|
+
if (ordered.length >= FETCH_KEY_FILES_PER_PAGE)
|
|
493
|
+
break;
|
|
494
|
+
}
|
|
495
|
+
// Pass 2: fill remaining slots with non-symbol refs.
|
|
496
|
+
if (ordered.length < FETCH_KEY_FILES_PER_PAGE) {
|
|
497
|
+
for (const r of refs) {
|
|
498
|
+
if (r.symbol)
|
|
499
|
+
continue;
|
|
500
|
+
const key = `${r.file}:${r.lineStart}`;
|
|
501
|
+
if (seen.has(key))
|
|
502
|
+
continue;
|
|
503
|
+
seen.add(key);
|
|
504
|
+
ordered.push(r);
|
|
505
|
+
if (ordered.length >= FETCH_KEY_FILES_PER_PAGE)
|
|
506
|
+
break;
|
|
507
|
+
}
|
|
508
|
+
}
|
|
509
|
+
return ordered.map((r) => {
|
|
510
|
+
const loc = `\`${r.file}:${r.lineStart}\``;
|
|
511
|
+
return r.symbol ? `- ${loc} — \`${r.symbol}\`` : `- ${loc}`;
|
|
512
|
+
});
|
|
513
|
+
}
|
|
514
|
+
/**
|
|
515
|
+
* Render a `QueryResultExtended` as a Markdown block ready to paste into an
|
|
516
|
+
* agent prompt. Public for unit testing; not re-exported from index.
|
|
517
|
+
*/
|
|
518
|
+
export function formatFetchPrompt(result) {
|
|
519
|
+
const parts = ['## 项目背景(来自 .forge-knowledge/)', ''];
|
|
520
|
+
for (const hit of result.pages) {
|
|
521
|
+
const matched = hit.matched_keywords.length > 0
|
|
522
|
+
? `, matched: ${hit.matched_keywords.join(', ')}`
|
|
523
|
+
: '';
|
|
524
|
+
parts.push(`### ${hit.page.name} (score: ${hit.score}${matched})`);
|
|
525
|
+
parts.push('');
|
|
526
|
+
const overview = extractOverview(hit.page.content);
|
|
527
|
+
if (overview) {
|
|
528
|
+
parts.push(overview);
|
|
529
|
+
parts.push('');
|
|
530
|
+
}
|
|
531
|
+
const keyFiles = formatKeyFiles(hit.page.refs);
|
|
532
|
+
if (keyFiles.length > 0) {
|
|
533
|
+
parts.push('**关键文件**:');
|
|
534
|
+
parts.push(...keyFiles);
|
|
535
|
+
parts.push('');
|
|
536
|
+
}
|
|
537
|
+
}
|
|
538
|
+
if (result.repo_map_hits && result.repo_map_hits.length > 0) {
|
|
539
|
+
parts.push(`**Repo-map 命中(symbols 含 '${result.query}')**:`);
|
|
540
|
+
for (const s of result.repo_map_hits.slice(0, FETCH_REPO_MAP_MAX)) {
|
|
541
|
+
parts.push(`- \`${s.file}:${s.line}\` — \`${s.name}\``);
|
|
542
|
+
}
|
|
543
|
+
parts.push('');
|
|
544
|
+
}
|
|
545
|
+
// Trim trailing empty lines for tidy output.
|
|
546
|
+
while (parts.length > 0 && parts[parts.length - 1] === '')
|
|
547
|
+
parts.pop();
|
|
548
|
+
return parts.join('\n');
|
|
549
|
+
}
|
|
550
|
+
async function fetchCmd(topic, options, deps = {}) {
|
|
551
|
+
const log = deps.io?.log ?? ((m) => console.log(m));
|
|
552
|
+
const projectRoot = deps.projectRoot;
|
|
553
|
+
if (!isKnowledgeBuilt(projectRoot)) {
|
|
554
|
+
console.error(chalk.red('Knowledge base not built yet. Run: cf knowledge build --apply'));
|
|
555
|
+
process.exit(1);
|
|
556
|
+
}
|
|
557
|
+
const format = options.format ?? 'prompt';
|
|
558
|
+
if (format !== 'prompt' && format !== 'json') {
|
|
559
|
+
console.error(chalk.red(`Invalid --format: "${format}" (expected "prompt" or "json")`));
|
|
560
|
+
process.exit(1);
|
|
561
|
+
}
|
|
562
|
+
const maxResults = options.max ? parseInt(options.max, 10) : 3;
|
|
563
|
+
const tele = buildKbTelemetryContext(options, deps);
|
|
564
|
+
const queryOptions = {
|
|
565
|
+
maxResults,
|
|
566
|
+
...(projectRoot ? { projectRoot } : {}),
|
|
567
|
+
storage: tele.storage,
|
|
568
|
+
reason: options.reason,
|
|
569
|
+
source: tele.source,
|
|
570
|
+
agentId: tele.agentId,
|
|
571
|
+
};
|
|
572
|
+
try {
|
|
573
|
+
const result = await queryKnowledge(topic, queryOptions);
|
|
574
|
+
if (format === 'json') {
|
|
575
|
+
log(JSON.stringify(result, null, 2));
|
|
576
|
+
return;
|
|
577
|
+
}
|
|
578
|
+
// Prompt format
|
|
579
|
+
const hasPages = result.pages.length > 0;
|
|
580
|
+
const hasRepoMap = !!(result.repo_map_hits && result.repo_map_hits.length > 0);
|
|
581
|
+
if (!hasPages && !hasRepoMap) {
|
|
582
|
+
console.error(chalk.yellow(`No matches found for "${topic}". Try simpler keywords.`));
|
|
583
|
+
process.exit(1);
|
|
584
|
+
}
|
|
585
|
+
log(formatFetchPrompt(result));
|
|
586
|
+
}
|
|
587
|
+
finally {
|
|
588
|
+
if (tele.ownStorage && tele.storage) {
|
|
589
|
+
try {
|
|
590
|
+
tele.storage.close();
|
|
591
|
+
}
|
|
592
|
+
catch { /* ignore */ }
|
|
593
|
+
}
|
|
594
|
+
}
|
|
595
|
+
}
|
|
596
|
+
async function listCmd(options) {
|
|
597
|
+
if (!isKnowledgeBuilt()) {
|
|
598
|
+
console.log(chalk.yellow('No knowledge pages found. Run: cf knowledge build --apply'));
|
|
599
|
+
return;
|
|
600
|
+
}
|
|
601
|
+
const pages = await listKnowledge();
|
|
602
|
+
if (options.json) {
|
|
603
|
+
console.log(JSON.stringify(pages.map((p) => ({
|
|
604
|
+
name: p.name,
|
|
605
|
+
title: p.title,
|
|
606
|
+
refs: p.refs.length,
|
|
607
|
+
kind: p.name.includes('/') ? 'module' : 'cross',
|
|
608
|
+
})), null, 2));
|
|
609
|
+
return;
|
|
610
|
+
}
|
|
611
|
+
if (pages.length === 0) {
|
|
612
|
+
console.log(chalk.yellow('No knowledge pages found. Run: cf knowledge build --apply'));
|
|
613
|
+
return;
|
|
614
|
+
}
|
|
615
|
+
// Sort: cross-module pages first (alpha), then module pages (alpha).
|
|
616
|
+
const sorted = [...pages].sort((a, b) => {
|
|
617
|
+
const aCross = !a.name.includes('/');
|
|
618
|
+
const bCross = !b.name.includes('/');
|
|
619
|
+
if (aCross !== bCross)
|
|
620
|
+
return aCross ? -1 : 1;
|
|
621
|
+
return a.name.localeCompare(b.name);
|
|
622
|
+
});
|
|
623
|
+
for (const p of sorted) {
|
|
624
|
+
const isCross = !p.name.includes('/');
|
|
625
|
+
const tag = isCross ? chalk.magenta('[cross] ') : chalk.blue('[module]');
|
|
626
|
+
const refsCol = isCross ? '' : ` (${p.refs.length} refs)`;
|
|
627
|
+
console.log(`${tag} ${chalk.cyan(p.name)}: ${p.title}${refsCol}`);
|
|
628
|
+
}
|
|
629
|
+
}
|
|
630
|
+
async function auditCmd(options) {
|
|
631
|
+
if (!isKnowledgeBuilt()) {
|
|
632
|
+
console.error(chalk.red('Knowledge base not built yet. Run: cf knowledge build --apply'));
|
|
633
|
+
process.exit(1);
|
|
634
|
+
}
|
|
635
|
+
const pages = await listKnowledge();
|
|
636
|
+
if (pages.length === 0) {
|
|
637
|
+
console.log(chalk.yellow('No knowledge pages to audit.'));
|
|
638
|
+
return;
|
|
639
|
+
}
|
|
640
|
+
const kbDir = path.join(process.cwd(), K.KB_DIRNAME);
|
|
641
|
+
const repoMap = loadRepoMap(kbDir);
|
|
642
|
+
let totalRefs = 0;
|
|
643
|
+
let validRefs = 0;
|
|
644
|
+
let staleRefs = 0;
|
|
645
|
+
let errorCount = 0;
|
|
646
|
+
const auditResults = [];
|
|
647
|
+
for (const page of pages) {
|
|
648
|
+
const result = validatePage(page, { repoMap: repoMap?.symbols });
|
|
649
|
+
totalRefs += result.refsTotal;
|
|
650
|
+
validRefs += result.refsValid;
|
|
651
|
+
const status = deriveAuditStatus(result.issues);
|
|
652
|
+
auditResults.push({ name: page.name, status, issues: result.issues });
|
|
653
|
+
const isCross = !page.name.includes('/');
|
|
654
|
+
if (!result.valid) {
|
|
655
|
+
errorCount++;
|
|
656
|
+
console.log(chalk.yellow(`⚠ ${page.name}: ${result.issues.length} issues`));
|
|
657
|
+
for (const issue of result.issues) {
|
|
658
|
+
const icon = issue.severity === 'error' ? chalk.red('✗') : chalk.yellow('⚠');
|
|
659
|
+
console.log(` ${icon} ${issue.msg}`);
|
|
660
|
+
if (issue.severity === 'warn')
|
|
661
|
+
staleRefs++;
|
|
662
|
+
}
|
|
663
|
+
}
|
|
664
|
+
else if (isCross && result.refsTotal === 0) {
|
|
665
|
+
console.log(chalk.green(`✓ ${page.name}`) +
|
|
666
|
+
chalk.gray(' (cross-module, no refs to validate)'));
|
|
667
|
+
}
|
|
668
|
+
else {
|
|
669
|
+
console.log(chalk.green(`✓ ${page.name}`));
|
|
670
|
+
}
|
|
671
|
+
}
|
|
672
|
+
console.log(chalk.bold(`\nTotal: ${validRefs}/${totalRefs} refs valid, ${staleRefs} stale, ${errorCount} pages with errors`));
|
|
673
|
+
if (options.fix) {
|
|
674
|
+
try {
|
|
675
|
+
const sourceHash = getGitShortHash();
|
|
676
|
+
const outcome = applyAuditResult({
|
|
677
|
+
kbDir,
|
|
678
|
+
results: auditResults,
|
|
679
|
+
sourceHash,
|
|
680
|
+
now: new Date(),
|
|
681
|
+
});
|
|
682
|
+
if (outcome.metaUpdated) {
|
|
683
|
+
console.log(chalk.green(`\n✓ Audit results written to ${path.relative(process.cwd(), outcome.metaPath)}`));
|
|
684
|
+
}
|
|
685
|
+
if (outcome.logAppended) {
|
|
686
|
+
console.log(chalk.green(`✓ Audit log appended at ${path.relative(process.cwd(), outcome.logPath)}`));
|
|
687
|
+
}
|
|
688
|
+
}
|
|
689
|
+
catch (err) {
|
|
690
|
+
console.error(chalk.red('Audit fix failed:'), err instanceof Error ? err.message : String(err));
|
|
691
|
+
process.exit(1);
|
|
692
|
+
}
|
|
693
|
+
}
|
|
694
|
+
else if (staleRefs > 0 || errorCount > 0) {
|
|
695
|
+
console.log(chalk.yellow('\nRun with --fix to record this audit'));
|
|
696
|
+
}
|
|
697
|
+
}
|
|
698
|
+
function getGitShortHash() {
|
|
699
|
+
try {
|
|
700
|
+
return execSync('git rev-parse --short HEAD', {
|
|
701
|
+
stdio: ['ignore', 'pipe', 'ignore'],
|
|
702
|
+
})
|
|
703
|
+
.toString()
|
|
704
|
+
.trim();
|
|
705
|
+
}
|
|
706
|
+
catch {
|
|
707
|
+
return 'no-git';
|
|
708
|
+
}
|
|
709
|
+
}
|
|
710
|
+
/**
|
|
711
|
+
* `cf kb fix [--dry-run]` — Detect broken (`source_hash === 'build-failed'`) and
|
|
712
|
+
* orphan (on-disk page without meta.json entry) module pages, then rebuild them.
|
|
713
|
+
*
|
|
714
|
+
* Contract: spec docs/design/2026-06-01/1451-kb-data-fix-spec.md §5.3.
|
|
715
|
+
*
|
|
716
|
+
* Out of scope: stale/error audit_status (use `cf kb audit --fix`).
|
|
717
|
+
*/
|
|
718
|
+
export async function fixCmd(options) {
|
|
719
|
+
if (!isKnowledgeBuilt()) {
|
|
720
|
+
console.error(chalk.red('Knowledge base not built yet. Run: cf knowledge build --apply'));
|
|
721
|
+
process.exit(1);
|
|
722
|
+
}
|
|
723
|
+
const kbDir = path.join(process.cwd(), K.KB_DIRNAME);
|
|
724
|
+
const metaPath = path.join(kbDir, '.meta.json');
|
|
725
|
+
const modulesDir = path.join(kbDir, K.KB_MODULES_DIR);
|
|
726
|
+
// ── 1. Read meta.json ─────────────────────────────────────────────────────
|
|
727
|
+
let meta = { pages: {} };
|
|
728
|
+
try {
|
|
729
|
+
if (fs.existsSync(metaPath)) {
|
|
730
|
+
const raw = fs.readFileSync(metaPath, 'utf8');
|
|
731
|
+
meta = JSON.parse(raw);
|
|
732
|
+
if (!meta.pages)
|
|
733
|
+
meta.pages = {};
|
|
734
|
+
}
|
|
735
|
+
}
|
|
736
|
+
catch (err) {
|
|
737
|
+
console.error(chalk.red('Failed to read .meta.json:'), err instanceof Error ? err.message : String(err));
|
|
738
|
+
process.exit(1);
|
|
739
|
+
}
|
|
740
|
+
const pagesBefore = Object.keys(meta.pages).length;
|
|
741
|
+
const toFix = [];
|
|
742
|
+
// 2a. build-failed entries
|
|
743
|
+
for (const [pageKey, entry] of Object.entries(meta.pages)) {
|
|
744
|
+
if (entry?.source_hash === 'build-failed') {
|
|
745
|
+
const m = pageKey.match(/^modules\/(.+)\.md$/);
|
|
746
|
+
if (m) {
|
|
747
|
+
toFix.push({
|
|
748
|
+
page: pageKey,
|
|
749
|
+
module: m[1],
|
|
750
|
+
reason: 'build-failed (last LLM call errored)',
|
|
751
|
+
});
|
|
752
|
+
}
|
|
753
|
+
}
|
|
754
|
+
}
|
|
755
|
+
// 2b. orphans (on-disk module page without meta entry)
|
|
756
|
+
if (fs.existsSync(modulesDir)) {
|
|
757
|
+
const onDisk = fs
|
|
758
|
+
.readdirSync(modulesDir)
|
|
759
|
+
.filter((f) => f.endsWith('.md'));
|
|
760
|
+
for (const file of onDisk) {
|
|
761
|
+
const pageKey = `modules/${file}`;
|
|
762
|
+
const moduleName = file.replace(/\.md$/, '');
|
|
763
|
+
if (!meta.pages[pageKey]) {
|
|
764
|
+
// Skip if already counted as build-failed above (defensive — shouldn't
|
|
765
|
+
// happen since build-failed entries live IN meta.pages by definition).
|
|
766
|
+
if (toFix.some((e) => e.page === pageKey))
|
|
767
|
+
continue;
|
|
768
|
+
toFix.push({
|
|
769
|
+
page: pageKey,
|
|
770
|
+
module: moduleName,
|
|
771
|
+
reason: 'orphan (on disk, not in meta.json)',
|
|
772
|
+
});
|
|
773
|
+
}
|
|
774
|
+
}
|
|
775
|
+
}
|
|
776
|
+
// ── 3. Report ──────────────────────────────────────────────────────────────
|
|
777
|
+
if (toFix.length === 0) {
|
|
778
|
+
console.log(chalk.green('✅ KB is healthy. 0 pages to fix.'));
|
|
779
|
+
return;
|
|
780
|
+
}
|
|
781
|
+
console.log(chalk.bold(`\nTo fix (${toFix.length} pages):`));
|
|
782
|
+
for (const entry of toFix) {
|
|
783
|
+
console.log(` ${entry.page.padEnd(28)} — ${entry.reason}`);
|
|
784
|
+
}
|
|
785
|
+
if (options.dryRun) {
|
|
786
|
+
console.log(chalk.dim(`\nUse 'cf kb fix' (without --dry-run) to rebuild.`));
|
|
787
|
+
return;
|
|
788
|
+
}
|
|
789
|
+
// ── 4. Real run: invoke buildKnowledge once with module list ─────────────
|
|
790
|
+
const modules = [...new Set(toFix.map((e) => e.module))];
|
|
791
|
+
console.log('');
|
|
792
|
+
console.log(chalk.cyan(`Rebuilding ${modules.length} module(s): ${modules.join(', ')}`));
|
|
793
|
+
try {
|
|
794
|
+
await buildKnowledge({ modules, force: true, apply: true });
|
|
795
|
+
}
|
|
796
|
+
catch (err) {
|
|
797
|
+
reportKnowledgeBuildError('Fix failed:', err);
|
|
798
|
+
process.exit(1);
|
|
799
|
+
}
|
|
800
|
+
// ── 5. Completion print ───────────────────────────────────────────────────
|
|
801
|
+
let pagesAfter = pagesBefore;
|
|
802
|
+
try {
|
|
803
|
+
if (fs.existsSync(metaPath)) {
|
|
804
|
+
const raw = fs.readFileSync(metaPath, 'utf8');
|
|
805
|
+
const updated = JSON.parse(raw);
|
|
806
|
+
pagesAfter = Object.keys(updated.pages ?? {}).length;
|
|
807
|
+
}
|
|
808
|
+
}
|
|
809
|
+
catch {
|
|
810
|
+
// Non-fatal — print without delta.
|
|
811
|
+
}
|
|
812
|
+
console.log('');
|
|
813
|
+
console.log(chalk.green(`✅ Fixed ${modules.length} pages: ${modules.join(', ')}`));
|
|
814
|
+
if (pagesAfter !== pagesBefore) {
|
|
815
|
+
console.log(chalk.dim(`meta.json pages: ${pagesBefore} → ${pagesAfter}`));
|
|
816
|
+
}
|
|
817
|
+
}
|
|
818
|
+
async function cleanCmd(options) {
|
|
819
|
+
const kbDir = path.join(process.cwd(), K.KB_DIRNAME);
|
|
820
|
+
if (!fs.existsSync(kbDir)) {
|
|
821
|
+
console.log(chalk.yellow('No knowledge base found — nothing to clean'));
|
|
822
|
+
return;
|
|
823
|
+
}
|
|
824
|
+
if (!options.confirm) {
|
|
825
|
+
console.log(chalk.red(`Will delete: ${kbDir}`));
|
|
826
|
+
console.log(chalk.red('Will also uninstall the git post-commit hook.'));
|
|
827
|
+
console.log(chalk.red('\nRun with --confirm to proceed.'));
|
|
828
|
+
return;
|
|
829
|
+
}
|
|
830
|
+
fs.rmSync(kbDir, { recursive: true, force: true });
|
|
831
|
+
console.log(chalk.green(`✓ Removed ${kbDir}`));
|
|
832
|
+
const uninstallResult = uninstallGitHook({ silent: true });
|
|
833
|
+
switch (uninstallResult.action) {
|
|
834
|
+
case 'removed':
|
|
835
|
+
if (uninstallResult.preservedUserContent) {
|
|
836
|
+
console.log(chalk.green('✓ git hook uninstalled (user hook content preserved)'));
|
|
837
|
+
}
|
|
838
|
+
else {
|
|
839
|
+
console.log(chalk.green('✓ git hook file removed (no remaining user content)'));
|
|
840
|
+
}
|
|
841
|
+
break;
|
|
842
|
+
case 'not-installed':
|
|
843
|
+
console.log(chalk.dim('i No git hook to uninstall'));
|
|
844
|
+
break;
|
|
845
|
+
case 'skipped-no-cf-section':
|
|
846
|
+
console.log(chalk.yellow('⚠ git hook exists but has no cf section — left untouched'));
|
|
847
|
+
break;
|
|
848
|
+
case 'skipped-non-git':
|
|
849
|
+
console.log(chalk.dim('i Not a git repo — nothing to uninstall'));
|
|
850
|
+
break;
|
|
851
|
+
}
|
|
852
|
+
}
|
|
853
|
+
// ─────────────────────────────────────────────────────────────────────────────
|
|
854
|
+
// rollback
|
|
855
|
+
// ─────────────────────────────────────────────────────────────────────────────
|
|
856
|
+
async function rollbackCmd(ts) {
|
|
857
|
+
const backupDir = path.join(process.cwd(), K.KB_DIRNAME, K.KB_BACKUPS_DIR, ts);
|
|
858
|
+
if (!fs.existsSync(backupDir)) {
|
|
859
|
+
console.error(chalk.red(`Backup not found: ${backupDir}`));
|
|
860
|
+
console.error(chalk.dim(`Available backups:\n ${listBackups(path.join(process.cwd(), K.KB_DIRNAME, K.KB_BACKUPS_DIR))}`));
|
|
861
|
+
process.exit(1);
|
|
862
|
+
}
|
|
863
|
+
const srcModulesBackup = path.join(backupDir, 'modules');
|
|
864
|
+
const hasModulesBackup = fs.existsSync(srcModulesBackup);
|
|
865
|
+
// v9.2: cross-module root pages — only rollback what exists in the snapshot.
|
|
866
|
+
const crossNames = ['overview.md', 'architecture.md', 'decisions.md', 'glossary.md', 'tech-stack.md'];
|
|
867
|
+
const crossBackupPresent = crossNames.filter((n) => fs.existsSync(path.join(backupDir, n)));
|
|
868
|
+
if (!hasModulesBackup && crossBackupPresent.length === 0) {
|
|
869
|
+
console.error(chalk.red(`Backup is empty (no modules/ or cross-module pages): ${backupDir}`));
|
|
870
|
+
process.exit(1);
|
|
871
|
+
}
|
|
872
|
+
if (hasModulesBackup) {
|
|
873
|
+
const modulesDir = path.join(process.cwd(), K.KB_DIRNAME, K.KB_MODULES_DIR);
|
|
874
|
+
if (fs.existsSync(modulesDir)) {
|
|
875
|
+
fs.rmSync(modulesDir, { recursive: true, force: true });
|
|
876
|
+
}
|
|
877
|
+
fs.cpSync(srcModulesBackup, modulesDir, { recursive: true });
|
|
878
|
+
}
|
|
879
|
+
for (const name of crossBackupPresent) {
|
|
880
|
+
const srcBackup = path.join(backupDir, name);
|
|
881
|
+
const dst = path.join(process.cwd(), K.KB_DIRNAME, name);
|
|
882
|
+
fs.copyFileSync(srcBackup, dst);
|
|
883
|
+
}
|
|
884
|
+
console.log(chalk.green(`✓ Rolled back to backup: ${ts}` +
|
|
885
|
+
(crossBackupPresent.length > 0
|
|
886
|
+
? ` (modules${hasModulesBackup ? '/' : ' skipped'} + ${crossBackupPresent.length} cross-module page${crossBackupPresent.length > 1 ? 's' : ''})`
|
|
887
|
+
: '')));
|
|
888
|
+
}
|
|
889
|
+
function listBackups(backupsDir) {
|
|
890
|
+
if (!fs.existsSync(backupsDir))
|
|
891
|
+
return '(none)';
|
|
892
|
+
const entries = fs.readdirSync(backupsDir).sort().reverse();
|
|
893
|
+
return entries.length > 0 ? entries.join('\n ') : '(none)';
|
|
894
|
+
}
|
|
895
|
+
// ─────────────────────────────────────────────────────────────────────────────
|
|
896
|
+
// hook-status
|
|
897
|
+
// ─────────────────────────────────────────────────────────────────────────────
|
|
898
|
+
async function hookStatusCmd() {
|
|
899
|
+
const status = getHookStatus();
|
|
900
|
+
if (!status.isGitRepo) {
|
|
901
|
+
console.log(chalk.yellow('Not a git repository — git hook is not applicable'));
|
|
902
|
+
return;
|
|
903
|
+
}
|
|
904
|
+
if (status.installed) {
|
|
905
|
+
console.log(chalk.green(`✓ cf hook installed: ${status.hookPath}`));
|
|
906
|
+
if (status.userHasOwnHook) {
|
|
907
|
+
console.log(chalk.dim(' (user has own hook content too — coexisting)'));
|
|
908
|
+
}
|
|
909
|
+
}
|
|
910
|
+
else {
|
|
911
|
+
console.log(chalk.yellow('✗ cf hook NOT installed'));
|
|
912
|
+
console.log(` Path: ${status.hookPath ?? 'N/A'}`);
|
|
913
|
+
if (status.userHasOwnHook) {
|
|
914
|
+
console.log(chalk.dim(' (user has own hook content — no cf section yet)'));
|
|
915
|
+
}
|
|
916
|
+
console.log(chalk.dim('\n Run: cf knowledge build --apply to auto-install'));
|
|
917
|
+
}
|
|
918
|
+
}
|
|
919
|
+
// ─────────────────────────────────────────────────────────────────────────────
|
|
920
|
+
// Registration
|
|
921
|
+
// ─────────────────────────────────────────────────────────────────────────────
|
|
922
|
+
function registerSubcommands(knowledge) {
|
|
923
|
+
knowledge
|
|
924
|
+
.command('build')
|
|
925
|
+
.description('Compile knowledge base from source (default: dry-run)')
|
|
926
|
+
.option('--apply', 'Write pages to .forge-knowledge/ and install git hook')
|
|
927
|
+
.option('--force', 'Force rebuild ignoring source_hash cache')
|
|
928
|
+
.option('--module <name>', 'Build only a specific src/ module')
|
|
929
|
+
.option('--skip-cross-module', 'Skip overview/architecture/decisions/glossary/tech-stack pages')
|
|
930
|
+
.action((options) => {
|
|
931
|
+
buildCmd(options).catch((err) => {
|
|
932
|
+
reportKnowledgeBuildError('Build failed:', err);
|
|
933
|
+
process.exit(1);
|
|
934
|
+
});
|
|
935
|
+
});
|
|
936
|
+
knowledge
|
|
937
|
+
.command('init')
|
|
938
|
+
.description('Initialize knowledge base in current project (build + apply + git hook in one shot)')
|
|
939
|
+
.option('--force', 'Force rebuild even if KB already exists')
|
|
940
|
+
.option('--skip-cross-module', 'Skip overview/architecture/decisions/glossary/tech-stack pages')
|
|
941
|
+
.option('--no-hook', 'Do not install the git post-commit hook')
|
|
942
|
+
.action((options) => {
|
|
943
|
+
initCmd(options).catch((err) => {
|
|
944
|
+
reportKnowledgeBuildError('Init failed:', err);
|
|
945
|
+
process.exit(1);
|
|
946
|
+
});
|
|
947
|
+
});
|
|
948
|
+
knowledge
|
|
949
|
+
.command('update')
|
|
950
|
+
.description('Incremental update based on git diff (requires prior build --apply)')
|
|
951
|
+
.option('--module <name>', 'Update only a specific src/ module')
|
|
952
|
+
.option('--force', 'Bypass module hash cache and rebuild every affected module')
|
|
953
|
+
.action((options) => {
|
|
954
|
+
updateCmd(options).catch((err) => {
|
|
955
|
+
reportKnowledgeBuildError('Update failed:', err);
|
|
956
|
+
process.exit(1);
|
|
957
|
+
});
|
|
958
|
+
});
|
|
959
|
+
knowledge
|
|
960
|
+
.command('query <topic>')
|
|
961
|
+
.description('Keyword search across knowledge pages and repo-map symbols')
|
|
962
|
+
.option('--max <N>', 'Maximum number of result pages', '3')
|
|
963
|
+
.option('--json', 'Output results as JSON')
|
|
964
|
+
.option('--reason <reason>', 'Reason for this pull (recorded in kb_query_log; use "coder/<phase>" / "verify/<phase>" prefix for follow-through telemetry)')
|
|
965
|
+
.option('--session-id <id>', 'Session id for the audit row (defaults to $CLAUDE_SESSION_ID env → DB lookup)')
|
|
966
|
+
.option('--project <path>', 'Project path for session DB lookup (defaults to cwd)')
|
|
967
|
+
.action((topic, options) => {
|
|
968
|
+
queryCmd(topic, options).catch((err) => {
|
|
969
|
+
console.error(chalk.red('Query failed:'), err instanceof Error ? err.message : String(err));
|
|
970
|
+
process.exit(1);
|
|
971
|
+
});
|
|
972
|
+
});
|
|
973
|
+
knowledge
|
|
974
|
+
.command('fetch <topic>')
|
|
975
|
+
.description('Format KB hits as a Markdown prompt block ready to paste into a sub-agent')
|
|
976
|
+
.option('--max <N>', 'Maximum number of result pages', '3')
|
|
977
|
+
.option('--format <prompt|json>', 'Output format: "prompt" (Markdown, default) or "json"', 'prompt')
|
|
978
|
+
.option('--reason <reason>', 'Reason for this pull (recorded in kb_query_log; use "coder/<phase>" / "verify/<phase>" prefix for follow-through telemetry)')
|
|
979
|
+
.option('--session-id <id>', 'Session id for the audit row (defaults to $CLAUDE_SESSION_ID env → DB lookup)')
|
|
980
|
+
.option('--project <path>', 'Project path for session DB lookup (defaults to cwd)')
|
|
981
|
+
.action((topic, options) => {
|
|
982
|
+
fetchCmd(topic, options).catch((err) => {
|
|
983
|
+
console.error(chalk.red('Fetch failed:'), err instanceof Error ? err.message : String(err));
|
|
984
|
+
process.exit(1);
|
|
985
|
+
});
|
|
986
|
+
});
|
|
987
|
+
// KB usefulness feedback (decision 096309e4 batch 1 item ①). After an agent
|
|
988
|
+
// PULLED KB (query/fetch --reason) and USED the content, it rates how much the
|
|
989
|
+
// content actually helped on THIS task — the real "KB used AND helped" signal.
|
|
990
|
+
knowledge
|
|
991
|
+
.command('feedback')
|
|
992
|
+
.description('Record post-use usefulness for a KB pull (helped|partial|not-actionable)')
|
|
993
|
+
.option('--rating <rating>', 'helped | partial | not-actionable (required)')
|
|
994
|
+
.option('--note <text>', 'One line: what was / was not applicable to THIS task')
|
|
995
|
+
.option('--reason-prefix <prefix>', 'Only stamp pulls whose reason starts with this (e.g. "coder/")')
|
|
996
|
+
.option('--session-id <id>', 'Session id (defaults to $CLAUDE_SESSION_ID env → DB lookup)')
|
|
997
|
+
.option('--project <path>', 'Project path for the pull lookup (defaults to cwd)')
|
|
998
|
+
.action((options) => {
|
|
999
|
+
feedbackCmd(options).catch((err) => {
|
|
1000
|
+
console.error(chalk.red('Feedback failed:'), err instanceof Error ? err.message : String(err));
|
|
1001
|
+
process.exit(1);
|
|
1002
|
+
});
|
|
1003
|
+
});
|
|
1004
|
+
knowledge
|
|
1005
|
+
.command('list')
|
|
1006
|
+
.description('List all compiled knowledge pages')
|
|
1007
|
+
.option('--json', 'Output as JSON')
|
|
1008
|
+
.action((options) => {
|
|
1009
|
+
listCmd(options).catch((err) => {
|
|
1010
|
+
console.error(chalk.red('List failed:'), err instanceof Error ? err.message : String(err));
|
|
1011
|
+
process.exit(1);
|
|
1012
|
+
});
|
|
1013
|
+
});
|
|
1014
|
+
knowledge
|
|
1015
|
+
.command('audit')
|
|
1016
|
+
.description('Validate all page refs against current source tree')
|
|
1017
|
+
.option('--fix', 'Mark audit_status in meta.json and write .audit-log.md')
|
|
1018
|
+
.action((options) => {
|
|
1019
|
+
auditCmd(options).catch((err) => {
|
|
1020
|
+
console.error(chalk.red('Audit failed:'), err instanceof Error ? err.message : String(err));
|
|
1021
|
+
process.exit(1);
|
|
1022
|
+
});
|
|
1023
|
+
});
|
|
1024
|
+
knowledge
|
|
1025
|
+
.command('fix')
|
|
1026
|
+
.description('Detect and rebuild broken/orphan KB pages (one-shot maintenance)')
|
|
1027
|
+
.option('--dry-run', 'List broken pages without rebuilding')
|
|
1028
|
+
.action((options) => {
|
|
1029
|
+
fixCmd(options).catch((err) => {
|
|
1030
|
+
reportKnowledgeBuildError('Fix failed:', err);
|
|
1031
|
+
process.exit(1);
|
|
1032
|
+
});
|
|
1033
|
+
});
|
|
1034
|
+
knowledge
|
|
1035
|
+
.command('clean')
|
|
1036
|
+
.description('Delete .forge-knowledge/ and uninstall git hook')
|
|
1037
|
+
.option('--confirm', 'Required to proceed (prevents accidental deletion)')
|
|
1038
|
+
.action((options) => {
|
|
1039
|
+
cleanCmd(options).catch((err) => {
|
|
1040
|
+
console.error(chalk.red('Clean failed:'), err instanceof Error ? err.message : String(err));
|
|
1041
|
+
process.exit(1);
|
|
1042
|
+
});
|
|
1043
|
+
});
|
|
1044
|
+
knowledge
|
|
1045
|
+
.command('rollback <ts>')
|
|
1046
|
+
.description('Restore pages from a backup snapshot (e.g. 20260519-1500)')
|
|
1047
|
+
.action((ts) => {
|
|
1048
|
+
rollbackCmd(ts).catch((err) => {
|
|
1049
|
+
console.error(chalk.red('Rollback failed:'), err instanceof Error ? err.message : String(err));
|
|
1050
|
+
process.exit(1);
|
|
1051
|
+
});
|
|
1052
|
+
});
|
|
1053
|
+
knowledge
|
|
1054
|
+
.command('hook-status')
|
|
1055
|
+
.description('Show git post-commit hook installation status')
|
|
1056
|
+
.action(() => {
|
|
1057
|
+
hookStatusCmd().catch((err) => {
|
|
1058
|
+
console.error(chalk.red('hook-status failed:'), err instanceof Error ? err.message : String(err));
|
|
1059
|
+
process.exit(1);
|
|
1060
|
+
});
|
|
1061
|
+
});
|
|
1062
|
+
}
|
|
1063
|
+
export function register(program) {
|
|
1064
|
+
const knowledge = program
|
|
1065
|
+
.command('knowledge')
|
|
1066
|
+
.alias('kb')
|
|
1067
|
+
.description('Project knowledge base — build / update / query / audit (v9.0)');
|
|
1068
|
+
registerSubcommands(knowledge);
|
|
1069
|
+
}
|
|
1070
|
+
//# sourceMappingURL=knowledge.js.map
|