@dommaker/harness 1.3.0 → 1.5.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/CHANGELOG.md +20 -0
- package/README.md +0 -2
- package/bin/harness.js +86 -32
- package/dist/cli/command-contract.d.ts +83 -0
- package/dist/cli/command-contract.d.ts.map +1 -0
- package/dist/cli/command-contract.js +66 -0
- package/dist/cli/command-contract.js.map +1 -0
- package/dist/cli/commands/acceptance.d.ts +3 -2
- package/dist/cli/commands/acceptance.d.ts.map +1 -1
- package/dist/cli/commands/acceptance.js +28 -24
- package/dist/cli/commands/acceptance.js.map +1 -1
- package/dist/cli/commands/analyze-sessions.d.ts +2 -1
- package/dist/cli/commands/analyze-sessions.d.ts.map +1 -1
- package/dist/cli/commands/analyze-sessions.js +25 -24
- package/dist/cli/commands/analyze-sessions.js.map +1 -1
- package/dist/cli/commands/check.d.ts +14 -2
- package/dist/cli/commands/check.d.ts.map +1 -1
- package/dist/cli/commands/check.js +104 -61
- package/dist/cli/commands/check.js.map +1 -1
- package/dist/cli/commands/command.d.ts +5 -1
- package/dist/cli/commands/command.d.ts.map +1 -1
- package/dist/cli/commands/command.js +26 -17
- package/dist/cli/commands/command.js.map +1 -1
- package/dist/cli/commands/constraints-report.d.ts +2 -1
- package/dist/cli/commands/constraints-report.d.ts.map +1 -1
- package/dist/cli/commands/constraints-report.js +37 -33
- package/dist/cli/commands/constraints-report.js.map +1 -1
- package/dist/cli/commands/constraints-retire.d.ts +6 -5
- package/dist/cli/commands/constraints-retire.d.ts.map +1 -1
- package/dist/cli/commands/constraints-retire.js +50 -52
- package/dist/cli/commands/constraints-retire.js.map +1 -1
- package/dist/cli/commands/constraints.d.ts +2 -1
- package/dist/cli/commands/constraints.d.ts.map +1 -1
- package/dist/cli/commands/constraints.js +10 -27
- package/dist/cli/commands/constraints.js.map +1 -1
- package/dist/cli/commands/contract.d.ts +3 -2
- package/dist/cli/commands/contract.d.ts.map +1 -1
- package/dist/cli/commands/contract.js +45 -42
- package/dist/cli/commands/contract.js.map +1 -1
- package/dist/cli/commands/definitions.d.ts +11 -11
- package/dist/cli/commands/definitions.d.ts.map +1 -1
- package/dist/cli/commands/definitions.js +27 -219
- package/dist/cli/commands/definitions.js.map +1 -1
- package/dist/cli/commands/failure.d.ts +5 -4
- package/dist/cli/commands/failure.d.ts.map +1 -1
- package/dist/cli/commands/failure.js +31 -25
- package/dist/cli/commands/failure.js.map +1 -1
- package/dist/cli/commands/init.d.ts +7 -5
- package/dist/cli/commands/init.d.ts.map +1 -1
- package/dist/cli/commands/init.js +147 -211
- package/dist/cli/commands/init.js.map +1 -1
- package/dist/cli/commands/knowledge.d.ts +17 -30
- package/dist/cli/commands/knowledge.d.ts.map +1 -1
- package/dist/cli/commands/knowledge.js +183 -273
- package/dist/cli/commands/knowledge.js.map +1 -1
- package/dist/cli/commands/passes-gate.d.ts +8 -2
- package/dist/cli/commands/passes-gate.d.ts.map +1 -1
- package/dist/cli/commands/passes-gate.js +44 -66
- package/dist/cli/commands/passes-gate.js.map +1 -1
- package/dist/cli/commands/performance.d.ts +2 -1
- package/dist/cli/commands/performance.d.ts.map +1 -1
- package/dist/cli/commands/performance.js +20 -18
- package/dist/cli/commands/performance.js.map +1 -1
- package/dist/cli/commands/posteval-plan.d.ts +5 -1
- package/dist/cli/commands/posteval-plan.d.ts.map +1 -1
- package/dist/cli/commands/posteval-plan.js +26 -15
- package/dist/cli/commands/posteval-plan.js.map +1 -1
- package/dist/cli/commands/release.d.ts +6 -1
- package/dist/cli/commands/release.d.ts.map +1 -1
- package/dist/cli/commands/release.js +69 -59
- package/dist/cli/commands/release.js.map +1 -1
- package/dist/cli/commands/report.d.ts +2 -1
- package/dist/cli/commands/report.d.ts.map +1 -1
- package/dist/cli/commands/report.js +9 -5
- package/dist/cli/commands/report.js.map +1 -1
- package/dist/cli/commands/review.d.ts +3 -2
- package/dist/cli/commands/review.d.ts.map +1 -1
- package/dist/cli/commands/review.js +33 -29
- package/dist/cli/commands/review.js.map +1 -1
- package/dist/cli/commands/sdd.d.ts +2 -1
- package/dist/cli/commands/sdd.d.ts.map +1 -1
- package/dist/cli/commands/sdd.js +7 -5
- package/dist/cli/commands/sdd.js.map +1 -1
- package/dist/cli/commands/security.d.ts +3 -2
- package/dist/cli/commands/security.d.ts.map +1 -1
- package/dist/cli/commands/security.js +29 -26
- package/dist/cli/commands/security.js.map +1 -1
- package/dist/cli/commands/spec-baseline-check.d.ts +2 -1
- package/dist/cli/commands/spec-baseline-check.d.ts.map +1 -1
- package/dist/cli/commands/spec-baseline-check.js +15 -11
- package/dist/cli/commands/spec-baseline-check.js.map +1 -1
- package/dist/cli/commands/spec.d.ts +7 -2
- package/dist/cli/commands/spec.d.ts.map +1 -1
- package/dist/cli/commands/spec.js +61 -51
- package/dist/cli/commands/spec.js.map +1 -1
- package/dist/cli/commands/status.d.ts +2 -1
- package/dist/cli/commands/status.d.ts.map +1 -1
- package/dist/cli/commands/status.js +57 -53
- package/dist/cli/commands/status.js.map +1 -1
- package/dist/cli/commands/sync-docs/agents-syncer.d.ts.map +1 -1
- package/dist/cli/commands/sync-docs/agents-syncer.js +5 -2
- package/dist/cli/commands/sync-docs/agents-syncer.js.map +1 -1
- package/dist/cli/commands/sync-docs/context-syncer.d.ts.map +1 -1
- package/dist/cli/commands/sync-docs/context-syncer.js +3 -2
- package/dist/cli/commands/sync-docs/context-syncer.js.map +1 -1
- package/dist/cli/commands/sync-docs/index.d.ts +2 -1
- package/dist/cli/commands/sync-docs/index.d.ts.map +1 -1
- package/dist/cli/commands/sync-docs/index.js +68 -88
- package/dist/cli/commands/sync-docs/index.js.map +1 -1
- package/dist/cli/commands/sync-docs/project-reader.d.ts +6 -1
- package/dist/cli/commands/sync-docs/project-reader.d.ts.map +1 -1
- package/dist/cli/commands/sync-docs/project-reader.js +14 -16
- package/dist/cli/commands/sync-docs/project-reader.js.map +1 -1
- package/dist/cli/commands/update-user-model.d.ts +9 -3
- package/dist/cli/commands/update-user-model.d.ts.map +1 -1
- package/dist/cli/commands/update-user-model.js +56 -61
- package/dist/cli/commands/update-user-model.js.map +1 -1
- package/dist/cli/commands/validate.d.ts +4 -3
- package/dist/cli/commands/validate.d.ts.map +1 -1
- package/dist/cli/commands/validate.js +28 -26
- package/dist/cli/commands/validate.js.map +1 -1
- package/dist/cli/session-mining/transcript.d.ts +7 -1
- package/dist/cli/session-mining/transcript.d.ts.map +1 -1
- package/dist/cli/session-mining/transcript.js +21 -14
- package/dist/cli/session-mining/transcript.js.map +1 -1
- package/dist/context/session-manager.d.ts.map +1 -1
- package/dist/context/session-manager.js +19 -32
- package/dist/context/session-manager.js.map +1 -1
- package/dist/core/constraints/agent-prompt-renderer.d.ts.map +1 -1
- package/dist/core/constraints/agent-prompt-renderer.js +1 -4
- package/dist/core/constraints/agent-prompt-renderer.js.map +1 -1
- package/dist/core/constraints/capabilities-parser.d.ts +24 -7
- package/dist/core/constraints/capabilities-parser.d.ts.map +1 -1
- package/dist/core/constraints/capabilities-parser.js +32 -28
- package/dist/core/constraints/capabilities-parser.js.map +1 -1
- package/dist/core/constraints/capabilities-reconcile.d.ts +67 -0
- package/dist/core/constraints/capabilities-reconcile.d.ts.map +1 -0
- package/dist/core/constraints/capabilities-reconcile.js +105 -0
- package/dist/core/constraints/capabilities-reconcile.js.map +1 -0
- package/dist/core/constraints/checker.d.ts +21 -43
- package/dist/core/constraints/checker.d.ts.map +1 -1
- package/dist/core/constraints/checker.js +68 -117
- package/dist/core/constraints/checker.js.map +1 -1
- package/dist/core/constraints/checkers/capability-sync.d.ts +20 -8
- package/dist/core/constraints/checkers/capability-sync.d.ts.map +1 -1
- package/dist/core/constraints/checkers/capability-sync.js +66 -77
- package/dist/core/constraints/checkers/capability-sync.js.map +1 -1
- package/dist/core/constraints/checkers/context-doc-sync.d.ts +4 -2
- package/dist/core/constraints/checkers/context-doc-sync.d.ts.map +1 -1
- package/dist/core/constraints/checkers/context-doc-sync.js +13 -22
- package/dist/core/constraints/checkers/context-doc-sync.js.map +1 -1
- package/dist/core/constraints/checkers/docs-freshness.d.ts.map +1 -1
- package/dist/core/constraints/checkers/docs-freshness.js +49 -66
- package/dist/core/constraints/checkers/docs-freshness.js.map +1 -1
- package/dist/core/constraints/checkers/governance-presence.d.ts +2 -2
- package/dist/core/constraints/checkers/governance-presence.d.ts.map +1 -1
- package/dist/core/constraints/checkers/governance-presence.js +7 -28
- package/dist/core/constraints/checkers/governance-presence.js.map +1 -1
- package/dist/core/constraints/checkers/index.d.ts +2 -2
- package/dist/core/constraints/checkers/index.d.ts.map +1 -1
- package/dist/core/constraints/checkers/index.js +2 -1
- package/dist/core/constraints/checkers/index.js.map +1 -1
- package/dist/core/constraints/checkers/no-test-simplification.d.ts.map +1 -1
- package/dist/core/constraints/checkers/no-test-simplification.js +4 -3
- package/dist/core/constraints/checkers/no-test-simplification.js.map +1 -1
- package/dist/core/constraints/checkers/types.d.ts +43 -4
- package/dist/core/constraints/checkers/types.d.ts.map +1 -1
- package/dist/core/constraints/checkers/types.js +33 -0
- package/dist/core/constraints/checkers/types.js.map +1 -1
- package/dist/core/constraints/context-builder.d.ts +15 -14
- package/dist/core/constraints/context-builder.d.ts.map +1 -1
- package/dist/core/constraints/context-builder.js +32 -96
- package/dist/core/constraints/context-builder.js.map +1 -1
- package/dist/core/constraints/doc-freshness/runner.d.ts.map +1 -1
- package/dist/core/constraints/doc-freshness/runner.js +2 -1
- package/dist/core/constraints/doc-freshness/runner.js.map +1 -1
- package/dist/core/constraints/git-evidence.d.ts +60 -0
- package/dist/core/constraints/git-evidence.d.ts.map +1 -0
- package/dist/core/constraints/git-evidence.js +88 -0
- package/dist/core/constraints/git-evidence.js.map +1 -0
- package/dist/core/constraints/injection-drift.d.ts +3 -20
- package/dist/core/constraints/injection-drift.d.ts.map +1 -1
- package/dist/core/constraints/injection-drift.js +10 -57
- package/dist/core/constraints/injection-drift.js.map +1 -1
- package/dist/core/constraints/injection-writer.d.ts +113 -0
- package/dist/core/constraints/injection-writer.d.ts.map +1 -0
- package/dist/core/constraints/injection-writer.js +228 -0
- package/dist/core/constraints/injection-writer.js.map +1 -0
- package/dist/core/constraints/usage-report.d.ts +22 -1
- package/dist/core/constraints/usage-report.d.ts.map +1 -1
- package/dist/core/constraints/usage-report.js +27 -20
- package/dist/core/constraints/usage-report.js.map +1 -1
- package/dist/core/index.d.ts +2 -2
- package/dist/core/index.d.ts.map +1 -1
- package/dist/core/index.js +4 -2
- package/dist/core/index.js.map +1 -1
- package/dist/core/project-config-loader.d.ts +32 -1
- package/dist/core/project-config-loader.d.ts.map +1 -1
- package/dist/core/project-config-loader.js +39 -9
- package/dist/core/project-config-loader.js.map +1 -1
- package/dist/core/validators/passes-gate.d.ts +15 -64
- package/dist/core/validators/passes-gate.d.ts.map +1 -1
- package/dist/core/validators/passes-gate.js +84 -222
- package/dist/core/validators/passes-gate.js.map +1 -1
- package/dist/core/validators/test-output.d.ts +58 -0
- package/dist/core/validators/test-output.d.ts.map +1 -0
- package/dist/core/validators/test-output.js +109 -0
- package/dist/core/validators/test-output.js.map +1 -0
- package/dist/failure/recorder.d.ts +6 -0
- package/dist/failure/recorder.d.ts.map +1 -1
- package/dist/failure/recorder.js +12 -8
- package/dist/failure/recorder.js.map +1 -1
- package/dist/gates/acceptance.d.ts +1 -48
- package/dist/gates/acceptance.d.ts.map +1 -1
- package/dist/gates/acceptance.js +6 -38
- package/dist/gates/acceptance.js.map +1 -1
- package/dist/gates/checker-gate.d.ts +2 -1
- package/dist/gates/checker-gate.d.ts.map +1 -1
- package/dist/gates/checker-gate.js +11 -13
- package/dist/gates/checker-gate.js.map +1 -1
- package/dist/gates/command.d.ts.map +1 -1
- package/dist/gates/command.js +10 -22
- package/dist/gates/command.js.map +1 -1
- package/dist/gates/contract.d.ts.map +1 -1
- package/dist/gates/contract.js +22 -61
- package/dist/gates/contract.js.map +1 -1
- package/dist/gates/performance.d.ts.map +1 -1
- package/dist/gates/performance.js +13 -31
- package/dist/gates/performance.js.map +1 -1
- package/dist/gates/review.d.ts.map +1 -1
- package/dist/gates/review.js +21 -53
- package/dist/gates/review.js.map +1 -1
- package/dist/gates/security.d.ts.map +1 -1
- package/dist/gates/security.js +14 -32
- package/dist/gates/security.js.map +1 -1
- package/dist/gates/types.d.ts +28 -5
- package/dist/gates/types.d.ts.map +1 -1
- package/dist/gates/types.js +38 -1
- package/dist/gates/types.js.map +1 -1
- package/dist/hooks/bootstrap.d.ts +2 -0
- package/dist/hooks/bootstrap.d.ts.map +1 -1
- package/dist/hooks/bootstrap.js +5 -2
- package/dist/hooks/bootstrap.js.map +1 -1
- package/dist/index.d.ts +1 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js.map +1 -1
- package/dist/knowledge/audit.d.ts +7 -2
- package/dist/knowledge/audit.d.ts.map +1 -1
- package/dist/knowledge/audit.js +59 -79
- package/dist/knowledge/audit.js.map +1 -1
- package/dist/knowledge/flywheel-metrics.d.ts +39 -0
- package/dist/knowledge/flywheel-metrics.d.ts.map +1 -0
- package/dist/knowledge/flywheel-metrics.js +47 -0
- package/dist/knowledge/flywheel-metrics.js.map +1 -0
- package/dist/knowledge/import.d.ts.map +1 -1
- package/dist/knowledge/import.js +4 -14
- package/dist/knowledge/import.js.map +1 -1
- package/dist/knowledge/index-generator.d.ts.map +1 -1
- package/dist/knowledge/index-generator.js +17 -14
- package/dist/knowledge/index-generator.js.map +1 -1
- package/dist/knowledge/ingest.d.ts.map +1 -1
- package/dist/knowledge/ingest.js +9 -4
- package/dist/knowledge/ingest.js.map +1 -1
- package/dist/knowledge/migration.d.ts.map +1 -1
- package/dist/knowledge/migration.js +11 -8
- package/dist/knowledge/migration.js.map +1 -1
- package/dist/knowledge/reference-tracker.d.ts.map +1 -1
- package/dist/knowledge/reference-tracker.js +12 -9
- package/dist/knowledge/reference-tracker.js.map +1 -1
- package/dist/knowledge/store.d.ts +15 -0
- package/dist/knowledge/store.d.ts.map +1 -1
- package/dist/knowledge/store.js +59 -10
- package/dist/knowledge/store.js.map +1 -1
- package/dist/monitoring/context-tracker.d.ts.map +1 -1
- package/dist/monitoring/context-tracker.js +11 -20
- package/dist/monitoring/context-tracker.js.map +1 -1
- package/dist/monitoring/index.d.ts +1 -1
- package/dist/monitoring/index.d.ts.map +1 -1
- package/dist/monitoring/index.js +1 -2
- package/dist/monitoring/index.js.map +1 -1
- package/dist/monitoring/trace-analyzer.d.ts +15 -0
- package/dist/monitoring/trace-analyzer.d.ts.map +1 -1
- package/dist/monitoring/trace-analyzer.js +19 -2
- package/dist/monitoring/trace-analyzer.js.map +1 -1
- package/dist/monitoring/traces.d.ts +21 -2
- package/dist/monitoring/traces.d.ts.map +1 -1
- package/dist/monitoring/traces.js +38 -29
- package/dist/monitoring/traces.js.map +1 -1
- package/dist/release/index.d.ts +2 -2
- package/dist/release/index.d.ts.map +1 -1
- package/dist/release/index.js +1 -5
- package/dist/release/index.js.map +1 -1
- package/dist/sdd/index-generator.js +10 -11
- package/dist/sdd/index-generator.js.map +1 -1
- package/dist/test-setup/project-fixture.d.ts +48 -0
- package/dist/test-setup/project-fixture.d.ts.map +1 -0
- package/dist/test-setup/project-fixture.js +106 -0
- package/dist/test-setup/project-fixture.js.map +1 -0
- package/dist/types/constraint.d.ts +8 -18
- package/dist/types/constraint.d.ts.map +1 -1
- package/dist/types/constraint.js +6 -1
- package/dist/types/constraint.js.map +1 -1
- package/dist/types/passes-gate.d.ts +10 -25
- package/dist/types/passes-gate.d.ts.map +1 -1
- package/dist/types/project-config.d.ts +1 -1
- package/dist/types/session.d.ts +6 -5
- package/dist/types/session.d.ts.map +1 -1
- package/dist/types/trace.d.ts +9 -0
- package/dist/types/trace.d.ts.map +1 -1
- package/dist/utils/exec.d.ts +10 -0
- package/dist/utils/exec.d.ts.map +1 -1
- package/dist/utils/exec.js +12 -0
- package/dist/utils/exec.js.map +1 -1
- package/dist/utils/file-walk.d.ts +9 -1
- package/dist/utils/file-walk.d.ts.map +1 -1
- package/dist/utils/file-walk.js +10 -1
- package/dist/utils/file-walk.js.map +1 -1
- package/dist/utils/frontmatter.d.ts +73 -0
- package/dist/utils/frontmatter.d.ts.map +1 -0
- package/dist/utils/frontmatter.js +141 -0
- package/dist/utils/frontmatter.js.map +1 -0
- package/dist/utils/jsonl.d.ts +92 -0
- package/dist/utils/jsonl.d.ts.map +1 -0
- package/dist/utils/jsonl.js +166 -0
- package/dist/utils/jsonl.js.map +1 -0
- package/dist/utils/package-version.d.ts +16 -0
- package/dist/utils/package-version.d.ts.map +1 -0
- package/dist/utils/package-version.js +63 -0
- package/dist/utils/package-version.js.map +1 -0
- package/package.json +1 -1
- package/src/CONTEXT.md +8 -2
- package/src/__tests__/acceptance-gate.test.ts +3 -1
- package/src/__tests__/checker-extra.test.ts +7 -1218
- package/src/__tests__/context-files-resolution.test.ts +116 -0
- package/src/__tests__/effective-constraints.test.ts +10 -13
- package/src/__tests__/exec.test.ts +35 -1
- package/src/__tests__/layering.test.ts +152 -0
- package/src/__tests__/passes-gate-extra.test.ts +0 -145
- package/src/__tests__/passes-gate.test.ts +130 -101
- package/src/__tests__/skip-semantics.test.ts +5 -9
- package/src/cli/__tests__/command-contract.test.ts +170 -0
- package/src/cli/command-contract.ts +108 -0
- package/src/cli/commands/CONTEXT.md +23 -8
- package/src/cli/commands/__tests__/acceptance.test.ts +40 -33
- package/src/cli/commands/__tests__/analyze-sessions.test.ts +35 -29
- package/src/cli/commands/__tests__/bin-exit-mapping.test.ts +107 -0
- package/src/cli/commands/__tests__/check-drift.test.ts +27 -34
- package/src/cli/commands/__tests__/check-skip-output.test.ts +21 -24
- package/src/cli/commands/__tests__/check.test.ts +448 -378
- package/src/cli/commands/__tests__/command.test.ts +85 -70
- package/src/cli/commands/__tests__/constraints-report.test.ts +100 -71
- package/src/cli/commands/__tests__/constraints-retire.test.ts +152 -95
- package/src/cli/commands/__tests__/contract.test.ts +27 -34
- package/src/cli/commands/__tests__/failure.test.ts +31 -34
- package/src/cli/commands/__tests__/init-injection.test.ts +58 -28
- package/src/cli/commands/__tests__/init.test.ts +77 -48
- package/src/cli/commands/__tests__/knowledge-flywheel-consistency.test.ts +108 -0
- package/src/cli/commands/__tests__/knowledge.test.ts +69 -43
- package/src/cli/commands/__tests__/passes-gate.test.ts +43 -45
- package/src/cli/commands/__tests__/performance.test.ts +22 -23
- package/src/cli/commands/__tests__/posteval-plan.test.ts +39 -38
- package/src/cli/commands/__tests__/project-path-anchoring.test.ts +157 -0
- package/src/cli/commands/__tests__/project-path-convention.test.ts +231 -0
- package/src/cli/commands/__tests__/registry.test.ts +75 -35
- package/src/cli/commands/__tests__/release.test.ts +209 -80
- package/src/cli/commands/__tests__/report-extra.test.ts +16 -16
- package/src/cli/commands/__tests__/report.test.ts +25 -25
- package/src/cli/commands/__tests__/review.test.ts +33 -31
- package/src/cli/commands/__tests__/security.test.ts +23 -27
- package/src/cli/commands/__tests__/spec-baseline-check.test.ts +20 -20
- package/src/cli/commands/__tests__/spec.test.ts +41 -29
- package/src/cli/commands/__tests__/status-extra.test.ts +18 -18
- package/src/cli/commands/__tests__/status-skipped-lines.test.ts +72 -0
- package/src/cli/commands/__tests__/status.test.ts +34 -34
- package/src/cli/commands/__tests__/sync-docs-agents.test.ts +77 -78
- package/src/cli/commands/__tests__/sync-docs.test.ts +72 -74
- package/src/cli/commands/__tests__/update-user-model.test.ts +97 -34
- package/src/cli/commands/__tests__/validate.test.ts +27 -29
- package/src/cli/commands/acceptance.ts +35 -24
- package/src/cli/commands/analyze-sessions.ts +25 -24
- package/src/cli/commands/check.ts +127 -66
- package/src/cli/commands/command.ts +30 -17
- package/src/cli/commands/constraints-report.ts +37 -34
- package/src/cli/commands/constraints-retire.ts +58 -55
- package/src/cli/commands/constraints.ts +10 -27
- package/src/cli/commands/contract.ts +51 -42
- package/src/cli/commands/definitions.ts +34 -227
- package/src/cli/commands/failure.ts +33 -26
- package/src/cli/commands/init.ts +166 -220
- package/src/cli/commands/knowledge.ts +192 -289
- package/src/cli/commands/passes-gate.ts +58 -68
- package/src/cli/commands/performance.ts +23 -18
- package/src/cli/commands/posteval-plan.ts +29 -15
- package/src/cli/commands/release.ts +70 -59
- package/src/cli/commands/report.ts +9 -5
- package/src/cli/commands/review.ts +39 -29
- package/src/cli/commands/sdd.ts +7 -5
- package/src/cli/commands/security.ts +35 -26
- package/src/cli/commands/spec-baseline-check.ts +16 -11
- package/src/cli/commands/spec.ts +66 -53
- package/src/cli/commands/status.ts +59 -53
- package/src/cli/commands/sync-docs/agents-syncer.ts +5 -2
- package/src/cli/commands/sync-docs/context-syncer.ts +3 -2
- package/src/cli/commands/sync-docs/index.ts +73 -100
- package/src/cli/commands/sync-docs/project-reader.ts +17 -18
- package/src/cli/commands/update-user-model.ts +64 -61
- package/src/cli/commands/validate.ts +31 -25
- package/src/cli/session-mining/__tests__/transcript.test.ts +118 -0
- package/src/cli/session-mining/transcript.ts +26 -8
- package/src/context/session-manager.ts +19 -33
- package/src/core/CONTEXT.md +10 -6
- package/src/core/constraints/__tests__/capabilities-reconcile.test.ts +200 -0
- package/src/core/constraints/__tests__/capability-counts.test.ts +94 -0
- package/src/core/constraints/__tests__/git-evidence.test.ts +208 -0
- package/src/core/constraints/__tests__/injection-drift.test.ts +3 -10
- package/src/core/constraints/__tests__/injection-writer.test.ts +231 -0
- package/src/core/constraints/__tests__/trace-injection.test.ts +71 -0
- package/src/core/constraints/__tests__/usage-report.test.ts +112 -0
- package/src/core/constraints/agent-prompt-renderer.ts +2 -6
- package/src/core/constraints/capabilities-parser.ts +53 -35
- package/src/core/constraints/capabilities-reconcile.ts +166 -0
- package/src/core/constraints/checker.ts +82 -133
- package/src/core/constraints/checkers/__tests__/capability-sync.test.ts +273 -0
- package/src/core/constraints/checkers/__tests__/check-outcome.test.ts +176 -0
- package/src/core/constraints/checkers/__tests__/context-doc-sync.test.ts +77 -0
- package/src/core/constraints/checkers/__tests__/docs-freshness.test.ts +126 -0
- package/src/{__tests__ → core/constraints/checkers/__tests__}/governance-presence.test.ts +83 -9
- package/src/core/constraints/checkers/__tests__/iron-flags.test.ts +50 -0
- package/src/core/constraints/checkers/__tests__/no-bypass-checkpoint.test.ts +76 -0
- package/src/{__tests__ → core/constraints/checkers/__tests__}/no-hardcoded-credentials.test.ts +4 -3
- package/src/core/constraints/checkers/__tests__/no-test-simplification.test.ts +58 -0
- package/src/core/constraints/checkers/__tests__/three-state-consistency.test.ts +153 -0
- package/src/core/constraints/checkers/capability-sync.ts +75 -96
- package/src/core/constraints/checkers/context-doc-sync.ts +15 -25
- package/src/core/constraints/checkers/docs-freshness.ts +54 -70
- package/src/core/constraints/checkers/governance-presence.ts +7 -25
- package/src/core/constraints/checkers/index.ts +9 -2
- package/src/core/constraints/checkers/no-test-simplification.ts +4 -3
- package/src/core/constraints/checkers/types.ts +60 -4
- package/src/core/constraints/context-builder.ts +39 -91
- package/src/core/constraints/doc-freshness/runner.ts +2 -1
- package/src/core/constraints/git-evidence.ts +120 -0
- package/src/core/constraints/injection-drift.ts +13 -60
- package/src/core/constraints/injection-writer.ts +212 -0
- package/src/core/constraints/usage-report.ts +36 -17
- package/src/core/index.ts +4 -2
- package/src/core/project-config-loader.ts +49 -9
- package/src/core/validators/__tests__/passes-gate.test.ts +2 -56
- package/src/core/validators/__tests__/test-output.test.ts +372 -0
- package/src/core/validators/passes-gate.ts +86 -248
- package/src/core/validators/test-output.ts +128 -0
- package/src/failure/__tests__/recorder.test.ts +168 -0
- package/src/failure/recorder.ts +12 -10
- package/src/gates/CONTEXT.md +7 -4
- package/src/gates/__tests__/acceptance-types-single-source.test.ts +68 -0
- package/src/gates/__tests__/acceptance.test.ts +4 -86
- package/src/gates/__tests__/checker-gate.test.ts +24 -0
- package/src/gates/__tests__/effective-gates.test.ts +3 -8
- package/src/gates/__tests__/test-verdict-consistency.test.ts +140 -0
- package/src/gates/acceptance.ts +19 -84
- package/src/gates/checker-gate.ts +12 -15
- package/src/gates/command.ts +10 -16
- package/src/gates/contract.ts +22 -61
- package/src/gates/performance.ts +10 -22
- package/src/gates/review.ts +21 -41
- package/src/gates/security.ts +10 -22
- package/src/gates/types.ts +70 -5
- package/src/hooks/CONTEXT.md +1 -1
- package/src/hooks/bootstrap.ts +5 -2
- package/src/index.ts +0 -4
- package/src/knowledge/CONTEXT.md +8 -3
- package/src/knowledge/__tests__/audit-labels.test.ts +44 -0
- package/src/knowledge/__tests__/flywheel-metrics.test.ts +135 -0
- package/src/knowledge/__tests__/import.test.ts +44 -0
- package/src/knowledge/__tests__/index-generator.test.ts +53 -0
- package/src/knowledge/__tests__/ingest.test.ts +85 -0
- package/src/knowledge/__tests__/migration.test.ts +47 -0
- package/src/knowledge/__tests__/reference-tracker.test.ts +16 -0
- package/src/knowledge/__tests__/store.test.ts +194 -0
- package/src/knowledge/audit.ts +67 -71
- package/src/knowledge/flywheel-metrics.ts +71 -0
- package/src/knowledge/import.ts +4 -18
- package/src/knowledge/index-generator.ts +19 -14
- package/src/knowledge/ingest.ts +9 -4
- package/src/knowledge/migration.ts +11 -8
- package/src/knowledge/reference-tracker.ts +12 -8
- package/src/knowledge/store.ts +64 -11
- package/src/monitoring/CONTEXT.md +8 -3
- package/src/monitoring/__tests__/skipped-lines-report.test.ts +178 -0
- package/src/monitoring/__tests__/traces.test.ts +57 -0
- package/src/monitoring/context-tracker.ts +11 -23
- package/src/monitoring/index.ts +1 -1
- package/src/monitoring/trace-analyzer.ts +21 -2
- package/src/monitoring/traces.ts +39 -36
- package/src/release/CONTEXT.md +1 -0
- package/src/release/__tests__/barrel.test.ts +60 -0
- package/src/release/index.ts +2 -13
- package/src/sdd/__tests__/index-generator.test.ts +71 -0
- package/src/sdd/index-generator.ts +9 -9
- package/src/test-setup/__tests__/project-fixture.test.ts +178 -0
- package/src/test-setup/project-fixture.ts +87 -0
- package/src/tools/CONTEXT.md +6 -0
- package/src/tools/__tests__/registry.test.ts +221 -0
- package/src/types/__tests__/types.test.ts +4 -5
- package/src/types/constraint.ts +16 -27
- package/src/types/passes-gate.ts +10 -30
- package/src/types/project-config.ts +1 -1
- package/src/types/session.ts +5 -5
- package/src/types/trace.ts +10 -0
- package/src/utils/__tests__/frontmatter.test.ts +206 -0
- package/src/utils/__tests__/jsonl-skip-disposition.test.ts +175 -0
- package/src/utils/__tests__/jsonl.test.ts +187 -0
- package/src/utils/__tests__/package-version.test.ts +97 -0
- package/src/utils/exec.ts +15 -0
- package/src/utils/file-walk.ts +11 -2
- package/src/utils/frontmatter.ts +121 -0
- package/src/utils/jsonl.ts +167 -0
- package/src/utils/package-version.ts +27 -0
- package/dist/cli/commands/doc-freshness-check.d.ts +0 -53
- package/dist/cli/commands/doc-freshness-check.d.ts.map +0 -1
- package/dist/cli/commands/doc-freshness-check.js +0 -352
- package/dist/cli/commands/doc-freshness-check.js.map +0 -1
- package/dist/types/index.d.ts +0 -14
- package/dist/types/index.d.ts.map +0 -1
- package/dist/types/index.js +0 -39
- package/dist/types/index.js.map +0 -1
- package/src/__tests__/long-running.test.ts +0 -17
- package/src/__tests__/passes-gate-extension.test.ts +0 -151
- package/src/cli/commands/__tests__/doc-freshness-check.test.ts +0 -168
- package/src/cli/commands/doc-freshness-check.ts +0 -386
- package/src/spec/CONTEXT.md +0 -11
- package/src/types/index.ts +0 -47
|
@@ -43,12 +43,11 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
43
43
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
44
44
|
exports.knowledgeList = knowledgeList;
|
|
45
45
|
exports.knowledgeSearch = knowledgeSearch;
|
|
46
|
+
exports.knowledgeSearchCommand = knowledgeSearchCommand;
|
|
46
47
|
exports.knowledgeImport = knowledgeImport;
|
|
47
48
|
exports.knowledgeDecay = knowledgeDecay;
|
|
48
49
|
exports.knowledgeStats = knowledgeStats;
|
|
49
|
-
exports.knowledgeUpsert = knowledgeUpsert;
|
|
50
50
|
exports.knowledgeSyncRag = knowledgeSyncRag;
|
|
51
|
-
exports.knowledgeSyncStatus = knowledgeSyncStatus;
|
|
52
51
|
exports.knowledgeHealth = knowledgeHealth;
|
|
53
52
|
exports.knowledgeAudit = knowledgeAudit;
|
|
54
53
|
exports.knowledgeSnapshot = knowledgeSnapshot;
|
|
@@ -63,13 +62,15 @@ const query_1 = require("../../knowledge/query");
|
|
|
63
62
|
const lifecycle_1 = require("../../knowledge/lifecycle");
|
|
64
63
|
const import_1 = require("../../knowledge/import");
|
|
65
64
|
const audit_1 = require("../../knowledge/audit");
|
|
65
|
+
const flywheel_metrics_1 = require("../../knowledge/flywheel-metrics");
|
|
66
66
|
const migration_1 = require("../../knowledge/migration");
|
|
67
67
|
const index_generator_1 = require("../../knowledge/index-generator");
|
|
68
|
+
const command_contract_1 = require("../command-contract");
|
|
68
69
|
/**
|
|
69
70
|
* 知识库列表
|
|
70
71
|
*/
|
|
71
|
-
async function knowledgeList(options) {
|
|
72
|
-
const store = new store_1.FileKnowledgeStore({ baseDir: getKnowledgeDir(options.projectPath) });
|
|
72
|
+
async function knowledgeList(options, io = command_contract_1.processIO) {
|
|
73
|
+
const store = new store_1.FileKnowledgeStore({ baseDir: getKnowledgeDir(options.projectPath, io) });
|
|
73
74
|
const filter = { excludeArchived: false };
|
|
74
75
|
if (options.type) {
|
|
75
76
|
filter.types = options.type.split(',');
|
|
@@ -82,54 +83,72 @@ async function knowledgeList(options) {
|
|
|
82
83
|
}
|
|
83
84
|
const entries = store.list(filter);
|
|
84
85
|
if (options.json) {
|
|
85
|
-
|
|
86
|
-
return;
|
|
86
|
+
(0, command_contract_1.log)(io, JSON.stringify({ total: entries.length, entries }, null, 2));
|
|
87
|
+
return { kind: 'ok' };
|
|
87
88
|
}
|
|
88
89
|
if (entries.length === 0) {
|
|
89
|
-
|
|
90
|
-
return;
|
|
90
|
+
(0, command_contract_1.log)(io, chalk_1.default.yellow('知识库为空'));
|
|
91
|
+
return { kind: 'ok' };
|
|
91
92
|
}
|
|
92
|
-
|
|
93
|
+
(0, command_contract_1.log)(io, chalk_1.default.blue(`📚 知识库 (${entries.length} 条)\n`));
|
|
93
94
|
for (const entry of entries) {
|
|
94
95
|
const maturityColor = entry.maturity === 'proven' ? chalk_1.default.green
|
|
95
96
|
: entry.maturity === 'verified' ? chalk_1.default.cyan
|
|
96
97
|
: entry.maturity === 'archived' ? chalk_1.default.gray
|
|
97
98
|
: chalk_1.default.yellow;
|
|
98
|
-
|
|
99
|
-
|
|
99
|
+
(0, command_contract_1.log)(io, ` ${maturityColor(`[${entry.maturity}]`)} ${chalk_1.default.bold(entry.title)}`);
|
|
100
|
+
(0, command_contract_1.log)(io, ` ${chalk_1.default.gray(`id: ${entry.id} | type: ${entry.type} | layer: ${entry.layer}`)}`);
|
|
100
101
|
if (entry.tags.length > 0) {
|
|
101
|
-
|
|
102
|
+
(0, command_contract_1.log)(io, ` ${chalk_1.default.gray(`tags: ${entry.tags.join(', ')}`)}`);
|
|
102
103
|
}
|
|
103
104
|
}
|
|
105
|
+
return { kind: 'ok' };
|
|
104
106
|
}
|
|
105
107
|
/**
|
|
106
108
|
* 知识库搜索
|
|
107
109
|
*/
|
|
108
|
-
async function knowledgeSearch(query, options) {
|
|
109
|
-
const store = new store_1.FileKnowledgeStore({ baseDir: getKnowledgeDir(options.projectPath) });
|
|
110
|
+
async function knowledgeSearch(query, options, io = command_contract_1.processIO) {
|
|
111
|
+
const store = new store_1.FileKnowledgeStore({ baseDir: getKnowledgeDir(options.projectPath, io) });
|
|
110
112
|
const queryEngine = new query_1.KnowledgeQuery(store);
|
|
111
113
|
const matched = queryEngine.search(query, { limit: options.limit || 20 });
|
|
112
114
|
if (options.json) {
|
|
113
|
-
|
|
114
|
-
return;
|
|
115
|
+
(0, command_contract_1.log)(io, JSON.stringify({ query, total: matched.length, entries: matched }, null, 2));
|
|
116
|
+
return { kind: 'ok' };
|
|
115
117
|
}
|
|
116
118
|
if (matched.length === 0) {
|
|
117
|
-
|
|
118
|
-
return;
|
|
119
|
+
(0, command_contract_1.log)(io, chalk_1.default.yellow(`未找到匹配 "${query}" 的知识条目`));
|
|
120
|
+
return { kind: 'ok' };
|
|
119
121
|
}
|
|
120
|
-
|
|
122
|
+
(0, command_contract_1.log)(io, chalk_1.default.blue(`🔍 搜索 "${query}" (${matched.length} 条结果)\n`));
|
|
121
123
|
for (const entry of matched) {
|
|
122
|
-
|
|
124
|
+
(0, command_contract_1.log)(io, ` ${chalk_1.default.bold(entry.title)} ${chalk_1.default.gray(`[${entry.maturity}]`)}`);
|
|
123
125
|
const preview = entry.content.slice(0, 100).replace(/\n/g, ' ');
|
|
124
|
-
|
|
126
|
+
(0, command_contract_1.log)(io, ` ${chalk_1.default.gray(preview)}${entry.content.length > 100 ? '...' : ''}`);
|
|
125
127
|
}
|
|
128
|
+
return { kind: 'ok' };
|
|
129
|
+
}
|
|
130
|
+
/**
|
|
131
|
+
* knowledge search 子命令入口(候选7):缺参闸门 + limit 强转编组,
|
|
132
|
+
* 自 definitions.ts 的 args 复印块移回命令模块(interface/测试面所在)。
|
|
133
|
+
*/
|
|
134
|
+
async function knowledgeSearchCommand(positionals, options, io = command_contract_1.processIO) {
|
|
135
|
+
const query = positionals[0];
|
|
136
|
+
if (!query) {
|
|
137
|
+
(0, command_contract_1.logError)(io, '请提供搜索关键词');
|
|
138
|
+
return { kind: 'usage-error', reason: 'knowledge search 缺少关键词位置参数' };
|
|
139
|
+
}
|
|
140
|
+
return knowledgeSearch(String(query), {
|
|
141
|
+
projectPath: options.projectPath,
|
|
142
|
+
json: options.json,
|
|
143
|
+
limit: parseInt(String(options.limit), 10),
|
|
144
|
+
});
|
|
126
145
|
}
|
|
127
146
|
/**
|
|
128
147
|
* 知识库导入(冷启动)
|
|
129
148
|
*/
|
|
130
|
-
async function knowledgeImport(options) {
|
|
149
|
+
async function knowledgeImport(options, io = command_contract_1.processIO) {
|
|
131
150
|
const projectPath = options.projectPath || process.cwd();
|
|
132
|
-
const store = new store_1.FileKnowledgeStore({ baseDir: getKnowledgeDir(options.projectPath) });
|
|
151
|
+
const store = new store_1.FileKnowledgeStore({ baseDir: getKnowledgeDir(options.projectPath, io) });
|
|
133
152
|
const sources = options.sources
|
|
134
153
|
? options.sources.split(',')
|
|
135
154
|
: ['code', 'git', 'docs'];
|
|
@@ -141,60 +160,62 @@ async function knowledgeImport(options) {
|
|
|
141
160
|
if (options.reset) {
|
|
142
161
|
importer.resetState();
|
|
143
162
|
if (!options.json) {
|
|
144
|
-
|
|
163
|
+
(0, command_contract_1.log)(io, chalk_1.default.yellow('🔄 已重置导入状态'));
|
|
145
164
|
}
|
|
146
165
|
}
|
|
147
166
|
if (!options.json) {
|
|
148
|
-
|
|
167
|
+
(0, command_contract_1.log)(io, chalk_1.default.blue(`📥 开始导入知识 (源: ${sources.join(', ')})...`));
|
|
149
168
|
}
|
|
150
169
|
const results = await importer.importAll();
|
|
151
170
|
const totalImported = results.reduce((sum, r) => sum + r.entries.length, 0);
|
|
152
171
|
const totalErrors = results.reduce((sum, r) => sum + r.errors.length, 0);
|
|
153
172
|
if (options.json) {
|
|
154
|
-
|
|
155
|
-
return;
|
|
173
|
+
(0, command_contract_1.log)(io, JSON.stringify({ totalImported, totalErrors, results }, null, 2));
|
|
174
|
+
return { kind: 'ok' };
|
|
156
175
|
}
|
|
157
176
|
for (const result of results) {
|
|
158
177
|
if (result.entries.length > 0) {
|
|
159
|
-
|
|
178
|
+
(0, command_contract_1.log)(io, chalk_1.default.green(` ✅ ${result.source.type}: ${result.entries.length} 条`));
|
|
160
179
|
}
|
|
161
180
|
if (result.errors.length > 0) {
|
|
162
181
|
for (const err of result.errors) {
|
|
163
|
-
|
|
182
|
+
(0, command_contract_1.log)(io, chalk_1.default.red(` ❌ ${result.source.type}: ${err.message}`));
|
|
164
183
|
}
|
|
165
184
|
}
|
|
166
185
|
}
|
|
167
|
-
|
|
186
|
+
(0, command_contract_1.log)(io, chalk_1.default.green(`\n✅ 导入完成: ${totalImported} 条,${totalErrors} 个错误`));
|
|
187
|
+
return { kind: 'ok' };
|
|
168
188
|
}
|
|
169
189
|
/**
|
|
170
190
|
* 知识库衰减周期
|
|
171
191
|
*/
|
|
172
|
-
async function knowledgeDecay(options) {
|
|
173
|
-
const store = new store_1.FileKnowledgeStore({ baseDir: getKnowledgeDir(options.projectPath) });
|
|
192
|
+
async function knowledgeDecay(options, io = command_contract_1.processIO) {
|
|
193
|
+
const store = new store_1.FileKnowledgeStore({ baseDir: getKnowledgeDir(options.projectPath, io) });
|
|
174
194
|
const lifecycle = new lifecycle_1.KnowledgeLifecycle(store);
|
|
175
195
|
if (!options.json) {
|
|
176
|
-
|
|
196
|
+
(0, command_contract_1.log)(io, chalk_1.default.blue('🔄 运行衰减周期...'));
|
|
177
197
|
}
|
|
178
198
|
const changes = lifecycle.runDecayCycle();
|
|
179
199
|
if (options.json) {
|
|
180
|
-
|
|
181
|
-
return;
|
|
200
|
+
(0, command_contract_1.log)(io, JSON.stringify({ changes }, null, 2));
|
|
201
|
+
return { kind: 'ok' };
|
|
182
202
|
}
|
|
183
203
|
if (changes.length === 0) {
|
|
184
|
-
|
|
185
|
-
return;
|
|
204
|
+
(0, command_contract_1.log)(io, chalk_1.default.green('✅ 没有需要衰减的知识条目'));
|
|
205
|
+
return { kind: 'ok' };
|
|
186
206
|
}
|
|
187
|
-
|
|
207
|
+
(0, command_contract_1.log)(io, chalk_1.default.yellow(`📉 ${changes.length} 条知识发生衰减:\n`));
|
|
188
208
|
for (const change of changes) {
|
|
189
|
-
|
|
190
|
-
|
|
209
|
+
(0, command_contract_1.log)(io, ` ${change.entryId}: ${chalk_1.default.red(change.from)} → ${chalk_1.default.green(change.to)}`);
|
|
210
|
+
(0, command_contract_1.log)(io, ` ${chalk_1.default.gray(change.reason)}`);
|
|
191
211
|
}
|
|
212
|
+
return { kind: 'ok' };
|
|
192
213
|
}
|
|
193
214
|
/**
|
|
194
215
|
* 知识库统计
|
|
195
216
|
*/
|
|
196
|
-
async function knowledgeStats(options) {
|
|
197
|
-
const store = new store_1.FileKnowledgeStore({ baseDir: getKnowledgeDir(options.projectPath) });
|
|
217
|
+
async function knowledgeStats(options, io = command_contract_1.processIO) {
|
|
218
|
+
const store = new store_1.FileKnowledgeStore({ baseDir: getKnowledgeDir(options.projectPath, io) });
|
|
198
219
|
const entries = store.list({ excludeArchived: false });
|
|
199
220
|
const active = entries.filter(e => e.maturity !== 'archived');
|
|
200
221
|
const byType = {};
|
|
@@ -205,179 +226,78 @@ async function knowledgeStats(options) {
|
|
|
205
226
|
byMaturity[entry.maturity] = (byMaturity[entry.maturity] || 0) + 1;
|
|
206
227
|
byLayer[entry.layer] = (byLayer[entry.layer] || 0) + 1;
|
|
207
228
|
}
|
|
208
|
-
//
|
|
209
|
-
|
|
210
|
-
const refCoverage = active.length > 0 ? Math.round(withRefs / active.length * 100) : 0;
|
|
211
|
-
const avgRefs = active.length > 0
|
|
212
|
-
? Math.round(active.reduce((sum, e) => sum + e.referencedBy.length, 0) / active.length * 10) / 10
|
|
213
|
-
: 0;
|
|
214
|
-
let consumptionHitRate = 0;
|
|
229
|
+
// 飞轮指标:计算唯一实现在 knowledge/flywheel-metrics,此处只做 fs 读取 + 展示层单位映射
|
|
230
|
+
let dailyConsumptionEvents = 0;
|
|
215
231
|
try {
|
|
216
232
|
const statsPath = path.join(store.getBaseDir(), '.consumption-stats.json');
|
|
217
233
|
if (fs.existsSync(statsPath)) {
|
|
218
234
|
const stats = JSON.parse(fs.readFileSync(statsPath, 'utf-8'));
|
|
219
|
-
|
|
220
|
-
consumptionHitRate = active.length > 0 ? Math.min(Math.round(dailyEvents / active.length * 100), 100) : 0;
|
|
235
|
+
dailyConsumptionEvents = stats.dailyEvents || 0;
|
|
221
236
|
}
|
|
222
237
|
}
|
|
223
238
|
catch { /* best-effort */ }
|
|
239
|
+
const metrics = (0, flywheel_metrics_1.evaluateFlywheel)({ entries: active, dailyConsumptionEvents });
|
|
240
|
+
const refCoverage = Math.round(metrics.refCoverage * 100);
|
|
241
|
+
const avgRefs = Math.round(metrics.avgRefs * 10) / 10;
|
|
242
|
+
const consumptionHitRate = Math.round(metrics.consumptionHitRate * 100);
|
|
224
243
|
const flywheel = { refCoverage, avgRefs, consumptionHitRate };
|
|
225
244
|
if (options.json) {
|
|
226
|
-
|
|
227
|
-
return;
|
|
245
|
+
(0, command_contract_1.log)(io, JSON.stringify({ total: entries.length, byType, byMaturity, byLayer, flywheel }, null, 2));
|
|
246
|
+
return { kind: 'ok' };
|
|
228
247
|
}
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
248
|
+
(0, command_contract_1.log)(io, chalk_1.default.blue(`📊 知识库统计\n`));
|
|
249
|
+
(0, command_contract_1.log)(io, chalk_1.default.bold(` 总计: ${entries.length} 条 (活跃: ${active.length})\n`));
|
|
250
|
+
(0, command_contract_1.log)(io, chalk_1.default.bold(' 按类型:'));
|
|
232
251
|
for (const [type, count] of Object.entries(byType)) {
|
|
233
|
-
|
|
252
|
+
(0, command_contract_1.log)(io, ` ${type}: ${count}`);
|
|
234
253
|
}
|
|
235
|
-
|
|
254
|
+
(0, command_contract_1.log)(io, chalk_1.default.bold('\n 按成熟度:'));
|
|
236
255
|
for (const [maturity, count] of Object.entries(byMaturity)) {
|
|
237
256
|
const color = maturity === 'proven' ? chalk_1.default.green : maturity === 'archived' ? chalk_1.default.gray : chalk_1.default.yellow;
|
|
238
|
-
|
|
257
|
+
(0, command_contract_1.log)(io, ` ${color(maturity)}: ${count}`);
|
|
239
258
|
}
|
|
240
|
-
|
|
259
|
+
(0, command_contract_1.log)(io, chalk_1.default.bold('\n 按层级:'));
|
|
241
260
|
for (const [layer, count] of Object.entries(byLayer)) {
|
|
242
|
-
|
|
243
|
-
}
|
|
244
|
-
console.log(chalk_1.default.bold('\n 飞轮指标:'));
|
|
245
|
-
console.log(` 引用覆盖: ${refCoverage}%`);
|
|
246
|
-
console.log(` 平均引用: ${avgRefs}`);
|
|
247
|
-
console.log(` 消费命中率: ${consumptionHitRate}%`);
|
|
248
|
-
}
|
|
249
|
-
/**
|
|
250
|
-
* 设计时知识沉淀:写入 KnowledgeStore + 同步 Prisma Document(Studio UI 可见)
|
|
251
|
-
*
|
|
252
|
-
* 调用 Studio API POST /api/knowledge/upsert(内部端点,无 auth)
|
|
253
|
-
*/
|
|
254
|
-
async function knowledgeUpsert(options) {
|
|
255
|
-
const apiPort = process.env.API_PORT || '3001';
|
|
256
|
-
const url = `http://localhost:${apiPort}/api/knowledge/upsert`;
|
|
257
|
-
// Read content from file if --file specified
|
|
258
|
-
let content = options.content || '';
|
|
259
|
-
if (options.file && !content) {
|
|
260
|
-
try {
|
|
261
|
-
content = fs.readFileSync(options.file, 'utf-8');
|
|
262
|
-
}
|
|
263
|
-
catch (e) {
|
|
264
|
-
console.error(chalk_1.default.red(`Failed to read file: ${options.file}`));
|
|
265
|
-
console.error(chalk_1.default.red(String(e)));
|
|
266
|
-
process.exit(1);
|
|
267
|
-
}
|
|
268
|
-
}
|
|
269
|
-
if (!options.scope || !options.title || !content) {
|
|
270
|
-
console.error(chalk_1.default.red('--scope, --title, and --content (or --file) are required'));
|
|
271
|
-
process.exit(1);
|
|
272
|
-
}
|
|
273
|
-
try {
|
|
274
|
-
const res = await fetch(url, {
|
|
275
|
-
method: 'POST',
|
|
276
|
-
headers: { 'Content-Type': 'application/json' },
|
|
277
|
-
body: JSON.stringify({
|
|
278
|
-
scope: options.scope,
|
|
279
|
-
title: options.title,
|
|
280
|
-
content,
|
|
281
|
-
type: options.type || 'architecture',
|
|
282
|
-
source: options.source || 'cli',
|
|
283
|
-
}),
|
|
284
|
-
});
|
|
285
|
-
if (!res.ok) {
|
|
286
|
-
const err = await res.json().catch(() => ({ error: res.statusText }));
|
|
287
|
-
console.error(chalk_1.default.red(`API error ${res.status}: ${err.error || res.statusText}`));
|
|
288
|
-
process.exit(1);
|
|
289
|
-
}
|
|
290
|
-
const result = await res.json();
|
|
291
|
-
console.log(chalk_1.default.green(`✅ Knowledge upserted`));
|
|
292
|
-
console.log(` KnowledgeStore: ${result.knowledgeStore?.action} → ${result.knowledgeStore?.entryId}`);
|
|
293
|
-
console.log(` Studio UI: ${result.prismaDocument?.action} → ${result.prismaDocument?.docId || 'skipped'}`);
|
|
294
|
-
}
|
|
295
|
-
catch (e) {
|
|
296
|
-
if (e?.code === 'ECONNREFUSED') {
|
|
297
|
-
console.error(chalk_1.default.red(`Cannot reach Studio API at ${url}. Is the API running?`));
|
|
298
|
-
}
|
|
299
|
-
else {
|
|
300
|
-
console.error(chalk_1.default.red(`Upsert failed: ${e.message}`));
|
|
301
|
-
}
|
|
302
|
-
process.exit(1);
|
|
261
|
+
(0, command_contract_1.log)(io, ` ${layer}: ${count}`);
|
|
303
262
|
}
|
|
263
|
+
(0, command_contract_1.log)(io, chalk_1.default.bold('\n 飞轮指标:'));
|
|
264
|
+
(0, command_contract_1.log)(io, ` 引用覆盖: ${refCoverage}%`);
|
|
265
|
+
(0, command_contract_1.log)(io, ` 平均引用: ${avgRefs}`);
|
|
266
|
+
(0, command_contract_1.log)(io, ` 消费命中率: ${consumptionHitRate}%`);
|
|
267
|
+
return { kind: 'ok' };
|
|
304
268
|
}
|
|
305
|
-
/**
|
|
306
269
|
/**
|
|
307
270
|
* RAG 同步:扫描 .harness/knowledge-docs/ 输出需要 ingest 的文件列表
|
|
308
271
|
*/
|
|
309
|
-
async function knowledgeSyncRag(options) {
|
|
272
|
+
async function knowledgeSyncRag(options, io = command_contract_1.processIO) {
|
|
310
273
|
const projectPath = options.projectPath || process.cwd();
|
|
311
274
|
const docsDir = `${projectPath}/.harness/knowledge-docs`;
|
|
312
275
|
if (!fs.existsSync(docsDir)) {
|
|
313
|
-
|
|
314
|
-
return;
|
|
276
|
+
(0, command_contract_1.log)(io, chalk_1.default.yellow('No .harness/knowledge-docs/ directory'));
|
|
277
|
+
return { kind: 'ok' };
|
|
315
278
|
}
|
|
316
279
|
const files = fs.readdirSync(docsDir).filter(f => f.endsWith('.md'));
|
|
317
280
|
if (files.length === 0) {
|
|
318
|
-
|
|
319
|
-
return;
|
|
281
|
+
(0, command_contract_1.log)(io, chalk_1.default.gray('No knowledge docs found'));
|
|
282
|
+
return { kind: 'ok' };
|
|
320
283
|
}
|
|
321
284
|
if (options.json) {
|
|
322
|
-
|
|
323
|
-
return;
|
|
285
|
+
(0, command_contract_1.log)(io, JSON.stringify({ directory: docsDir, files }, null, 2));
|
|
286
|
+
return { kind: 'ok' };
|
|
324
287
|
}
|
|
325
|
-
|
|
288
|
+
(0, command_contract_1.log)(io, chalk_1.default.blue(`📄 RAG sync candidates: ${files.length} files in ${docsDir}\n`));
|
|
326
289
|
for (const file of files) {
|
|
327
|
-
|
|
328
|
-
}
|
|
329
|
-
console.log();
|
|
330
|
-
console.log(chalk_1.default.gray('Run `mcp__local-rag__ingest_file` for each to sync to RAG'));
|
|
331
|
-
}
|
|
332
|
-
/**
|
|
333
|
-
* 知识同步状态:检测所有 tracked scope 的新鲜度
|
|
334
|
-
*/
|
|
335
|
-
async function knowledgeSyncStatus(options) {
|
|
336
|
-
const apiPort = process.env.API_PORT || '3001';
|
|
337
|
-
const url = `http://localhost:${apiPort}/api/knowledge/sync-status`;
|
|
338
|
-
try {
|
|
339
|
-
const res = await fetch(url);
|
|
340
|
-
if (!res.ok) {
|
|
341
|
-
const err = await res.json().catch(() => ({ error: res.statusText }));
|
|
342
|
-
console.error(chalk_1.default.red(`API error ${res.status}: ${err.error || res.statusText}`));
|
|
343
|
-
process.exit(1);
|
|
344
|
-
}
|
|
345
|
-
const data = await res.json();
|
|
346
|
-
if (options.json) {
|
|
347
|
-
console.log(JSON.stringify(data, null, 2));
|
|
348
|
-
return;
|
|
349
|
-
}
|
|
350
|
-
console.log(chalk_1.default.blue(`🔄 KnowledgeSync Status\n`));
|
|
351
|
-
console.log(chalk_1.default.bold(`Tracked scopes: ${data.trackedScopes?.join(', ') || 'none'}`));
|
|
352
|
-
console.log(chalk_1.default.bold(`Stale entries: ${data.stale?.length || 0}`));
|
|
353
|
-
if (data.stale?.length > 0) {
|
|
354
|
-
console.log(chalk_1.default.yellow(`\n⚠️ Stale knowledge:\n`));
|
|
355
|
-
for (const s of data.stale) {
|
|
356
|
-
console.log(chalk_1.default.yellow(` ${s.scope} (${s.title}): ${s.stalenessHours}h old, files changed: ${s.changedFiles.join(', ')}`));
|
|
357
|
-
}
|
|
358
|
-
}
|
|
359
|
-
else {
|
|
360
|
-
console.log(chalk_1.default.green('\n✅ All knowledge fresh'));
|
|
361
|
-
}
|
|
362
|
-
if (data.healed?.length > 0) {
|
|
363
|
-
console.log(chalk_1.default.cyan(`\n🩹 Auto-healed: ${data.healed.join(', ')}`));
|
|
364
|
-
}
|
|
365
|
-
}
|
|
366
|
-
catch (e) {
|
|
367
|
-
if (e?.code === 'ECONNREFUSED') {
|
|
368
|
-
console.error(chalk_1.default.red(`Cannot reach Studio API at ${url}`));
|
|
369
|
-
}
|
|
370
|
-
else {
|
|
371
|
-
console.error(chalk_1.default.red(`Sync check failed: ${e.message}`));
|
|
372
|
-
}
|
|
373
|
-
process.exit(1);
|
|
290
|
+
(0, command_contract_1.log)(io, chalk_1.default.cyan(` ${file}`));
|
|
374
291
|
}
|
|
292
|
+
(0, command_contract_1.log)(io);
|
|
293
|
+
(0, command_contract_1.log)(io, chalk_1.default.gray('Run `mcp__local-rag__ingest_file` for each to sync to RAG'));
|
|
294
|
+
return { kind: 'ok' };
|
|
375
295
|
}
|
|
376
296
|
/**
|
|
377
297
|
* 飞轮健康检查 — 零 token 检测知识飞轮数据流状态
|
|
378
298
|
*/
|
|
379
|
-
async function knowledgeHealth(options) {
|
|
380
|
-
const baseDir = options.dir || getKnowledgeDir(options.projectPath);
|
|
299
|
+
async function knowledgeHealth(options, io = command_contract_1.processIO) {
|
|
300
|
+
const baseDir = options.dir || getKnowledgeDir(options.projectPath, io);
|
|
381
301
|
const store = new store_1.FileKnowledgeStore({ baseDir });
|
|
382
302
|
const entries = store.list({ excludeArchived: true });
|
|
383
303
|
const issues = [];
|
|
@@ -409,18 +329,16 @@ async function knowledgeHealth(options) {
|
|
|
409
329
|
else {
|
|
410
330
|
issues.push({ severity: 'info', entry: '-', detail: `消费追踪数据不存在(${statsPath})` });
|
|
411
331
|
}
|
|
412
|
-
// D4:
|
|
413
|
-
const
|
|
414
|
-
const refCoverage =
|
|
415
|
-
const avgRefs =
|
|
416
|
-
? Math.round(entries.reduce((sum, e) => sum + e.referencedBy.length, 0) / entries.length * 10) / 10
|
|
417
|
-
: 0;
|
|
332
|
+
// D4: 飞轮指标(计算唯一实现在 knowledge/flywheel-metrics;人口为本命令的 excludeArchived 切片)
|
|
333
|
+
const metrics = (0, flywheel_metrics_1.evaluateFlywheel)({ entries });
|
|
334
|
+
const refCoverage = Math.round(metrics.refCoverage * 100);
|
|
335
|
+
const avgRefs = Math.round(metrics.avgRefs * 10) / 10;
|
|
418
336
|
// 健康分计算
|
|
419
337
|
const totalIssues = issues.filter(i => i.severity === 'error').length * 3
|
|
420
338
|
+ issues.filter(i => i.severity === 'warn').length * 1;
|
|
421
339
|
const healthScore = Math.max(0, 100 - totalIssues);
|
|
422
340
|
if (options.json) {
|
|
423
|
-
|
|
341
|
+
(0, command_contract_1.log)(io, JSON.stringify({
|
|
424
342
|
healthScore,
|
|
425
343
|
summary: {
|
|
426
344
|
total: entries.length,
|
|
@@ -432,36 +350,37 @@ async function knowledgeHealth(options) {
|
|
|
432
350
|
},
|
|
433
351
|
issues: issues.slice(0, 50),
|
|
434
352
|
}, null, 2));
|
|
435
|
-
return;
|
|
436
|
-
}
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
|
|
353
|
+
return { kind: 'ok' };
|
|
354
|
+
}
|
|
355
|
+
(0, command_contract_1.log)(io, chalk_1.default.blue('🏥 飞轮健康检查\n'));
|
|
356
|
+
(0, command_contract_1.log)(io, chalk_1.default.bold(` 健康分: ${healthScore >= 80 ? chalk_1.default.green(healthScore) : healthScore >= 60 ? chalk_1.default.yellow(healthScore) : chalk_1.default.red(healthScore)}/100`));
|
|
357
|
+
(0, command_contract_1.log)(io, chalk_1.default.bold(` 活跃条目: ${entries.length}`));
|
|
358
|
+
(0, command_contract_1.log)(io);
|
|
359
|
+
(0, command_contract_1.log)(io, chalk_1.default.bold(' 数据流状态:'));
|
|
360
|
+
(0, command_contract_1.log)(io, ` 引用密度: ${lowRefEntries === 0 ? chalk_1.default.green('✓') : chalk_1.default.yellow(`⚠ ${lowRefEntries} 个零引用 verified`)}`);
|
|
361
|
+
(0, command_contract_1.log)(io, ` 新鲜度: ${staleEntries === 0 ? chalk_1.default.green('✓') : chalk_1.default.yellow(`⚠ ${staleEntries} 个过期 draft`)}`);
|
|
362
|
+
(0, command_contract_1.log)(io, ` 消费追踪: ${consumptionData ? chalk_1.default.green('✓') : chalk_1.default.gray('○ 未启用')}`);
|
|
363
|
+
(0, command_contract_1.log)(io);
|
|
364
|
+
(0, command_contract_1.log)(io, chalk_1.default.bold(' 飞轮指标:'));
|
|
365
|
+
(0, command_contract_1.log)(io, ` 引用覆盖: ${refCoverage}%`);
|
|
366
|
+
(0, command_contract_1.log)(io, ` 平均引用: ${avgRefs}`);
|
|
367
|
+
(0, command_contract_1.log)(io);
|
|
450
368
|
if (issues.length > 0) {
|
|
451
|
-
|
|
369
|
+
(0, command_contract_1.log)(io, chalk_1.default.bold(` 问题 (前 20):`));
|
|
452
370
|
for (const issue of issues.slice(0, 20)) {
|
|
453
371
|
const sevColor = issue.severity === 'error' ? chalk_1.default.red
|
|
454
372
|
: issue.severity === 'warn' ? chalk_1.default.yellow
|
|
455
373
|
: chalk_1.default.gray;
|
|
456
|
-
|
|
374
|
+
(0, command_contract_1.log)(io, ` ${sevColor(`[${issue.severity}]`)} ${issue.entry}: ${issue.detail}`);
|
|
457
375
|
}
|
|
458
376
|
if (issues.length > 20) {
|
|
459
|
-
|
|
377
|
+
(0, command_contract_1.log)(io, chalk_1.default.gray(` ... 还有 ${issues.length - 20} 条`));
|
|
460
378
|
}
|
|
461
379
|
}
|
|
462
380
|
else {
|
|
463
|
-
|
|
381
|
+
(0, command_contract_1.log)(io, chalk_1.default.green(' ✓ 无问题'));
|
|
464
382
|
}
|
|
383
|
+
return { kind: 'ok' };
|
|
465
384
|
}
|
|
466
385
|
/** 缺省知识库数据根(相对用户 home) */
|
|
467
386
|
const KNOWLEDGE_DATA_DIR = path.join('.harness', 'knowledge');
|
|
@@ -476,7 +395,7 @@ function hasKnowledgeData(dir) {
|
|
|
476
395
|
return false;
|
|
477
396
|
}
|
|
478
397
|
}
|
|
479
|
-
function getKnowledgeDir(projectPath) {
|
|
398
|
+
function getKnowledgeDir(projectPath, io) {
|
|
480
399
|
if (projectPath)
|
|
481
400
|
return `${projectPath}/.harness/knowledge`;
|
|
482
401
|
if (process.env.KNOWLEDGE_BASE_DIR)
|
|
@@ -487,7 +406,7 @@ function getKnowledgeDir(projectPath) {
|
|
|
487
406
|
if (!legacyKnowledgeDirNotified) {
|
|
488
407
|
legacyKnowledgeDirNotified = true;
|
|
489
408
|
// stderr:不污染 --json 的 stdout 输出
|
|
490
|
-
|
|
409
|
+
(0, command_contract_1.logError)(io, chalk_1.default.yellow(`⚠ 缺省知识库根已改为 ${defaultDir};旧目录 ${legacyDir} 仍有数据,本次沿用(免迁移,可用 KNOWLEDGE_BASE_DIR 覆盖)`));
|
|
491
410
|
}
|
|
492
411
|
return legacyDir;
|
|
493
412
|
}
|
|
@@ -496,29 +415,29 @@ function getKnowledgeDir(projectPath) {
|
|
|
496
415
|
/**
|
|
497
416
|
* 知识库质量审计
|
|
498
417
|
*/
|
|
499
|
-
async function knowledgeAudit(options) {
|
|
418
|
+
async function knowledgeAudit(options, io = command_contract_1.processIO) {
|
|
500
419
|
const audit = new audit_1.KnowledgeAudit({
|
|
501
|
-
baseDir: options.dir || getKnowledgeDir(options.projectPath),
|
|
420
|
+
baseDir: options.dir || getKnowledgeDir(options.projectPath, io),
|
|
502
421
|
shortContentThreshold: options.threshold ? parseInt(options.threshold, 10) : undefined,
|
|
503
422
|
});
|
|
504
423
|
const isDryRun = options.dryRun && !options.fix;
|
|
505
424
|
if (!options.json && !isDryRun) {
|
|
506
|
-
|
|
425
|
+
(0, command_contract_1.log)(io, chalk_1.default.blue('🔍 知识库质量审计...\n'));
|
|
507
426
|
}
|
|
508
427
|
const report = audit.run({ autoFix: options.fix && !isDryRun });
|
|
509
428
|
if (options.json) {
|
|
510
|
-
|
|
511
|
-
return;
|
|
429
|
+
(0, command_contract_1.log)(io, JSON.stringify(report, null, 2));
|
|
430
|
+
return { kind: 'ok' };
|
|
512
431
|
}
|
|
513
432
|
// Summary
|
|
514
|
-
|
|
515
|
-
|
|
433
|
+
(0, command_contract_1.log)(io, chalk_1.default.bold(` 总条目: ${report.totalEntries}`));
|
|
434
|
+
(0, command_contract_1.log)(io, chalk_1.default.bold(` 健康分: ${report.healthScore.before}/100`));
|
|
516
435
|
if (report.autoFixed > 0) {
|
|
517
|
-
|
|
518
|
-
|
|
436
|
+
(0, command_contract_1.log)(io, chalk_1.default.green(` 自动修复: ${report.autoFixed} 条`));
|
|
437
|
+
(0, command_contract_1.log)(io, chalk_1.default.bold(` 修复后: ${report.healthScore.after}/100`));
|
|
519
438
|
}
|
|
520
|
-
|
|
521
|
-
// Dimension scores
|
|
439
|
+
(0, command_contract_1.log)(io);
|
|
440
|
+
// Dimension scores(Record 全键标注 → 编译期闭环,#109)
|
|
522
441
|
const dimLabels = {
|
|
523
442
|
structure: 'D1 结构完整性',
|
|
524
443
|
content: 'D2 内容质量',
|
|
@@ -526,105 +445,95 @@ async function knowledgeAudit(options) {
|
|
|
526
445
|
maturity: 'D4 成熟度健康',
|
|
527
446
|
freshness: 'D5 新鲜度',
|
|
528
447
|
flywheel: 'D6 飞轮验证',
|
|
448
|
+
incremental: 'D7 增量存活',
|
|
529
449
|
};
|
|
530
|
-
|
|
450
|
+
(0, command_contract_1.log)(io, chalk_1.default.bold(' 维度评分:'));
|
|
531
451
|
for (const [key, dim] of Object.entries(report.dimensions)) {
|
|
532
|
-
const label = dimLabels[key]
|
|
452
|
+
const label = dimLabels[key];
|
|
533
453
|
const scoreColor = dim.score >= 80 ? chalk_1.default.green : dim.score >= 60 ? chalk_1.default.yellow : chalk_1.default.red;
|
|
534
|
-
|
|
535
|
-
}
|
|
536
|
-
|
|
537
|
-
// Issues by rule
|
|
538
|
-
const ruleLabels = {
|
|
539
|
-
'frontmatter-missing': 'frontmatter 缺失',
|
|
540
|
-
'test-data-pollution': '测试数据污染',
|
|
541
|
-
'daily-audit-noise': '每日审计噪音',
|
|
542
|
-
'zero-content-proven': '零内容 proven',
|
|
543
|
-
'short-content': '短内容',
|
|
544
|
-
'maturity-inflation': '成熟度虚高',
|
|
545
|
-
'title-duplicate': '标题重复',
|
|
546
|
-
'source-refs-bloat': 'sourceReferences 膨胀',
|
|
547
|
-
'fragment-cluster': '碎片集群',
|
|
548
|
-
'promotion-blocked': 'promotion 受阻',
|
|
549
|
-
'orphan-draft': '孤儿 draft',
|
|
550
|
-
'stale-entry': '过期条目',
|
|
551
|
-
};
|
|
454
|
+
(0, command_contract_1.log)(io, ` ${label}: ${scoreColor(`${dim.score}/100`)} (${dim.issues} 问题)`);
|
|
455
|
+
}
|
|
456
|
+
(0, command_contract_1.log)(io);
|
|
457
|
+
// Issues by rule(label 正本在 audit.ts 规则定义,AUDIT_RULE_LABELS 编译期闭环,#109)
|
|
552
458
|
for (const [rule, count] of Object.entries(report.summary)) {
|
|
553
459
|
if (count === 0)
|
|
554
460
|
continue;
|
|
555
|
-
const label =
|
|
556
|
-
|
|
461
|
+
const label = audit_1.AUDIT_RULE_LABELS[rule];
|
|
462
|
+
(0, command_contract_1.log)(io, ` ${chalk_1.default.red(`${label}: ${count}`)}`);
|
|
557
463
|
}
|
|
558
464
|
// Detail (first 20)
|
|
559
465
|
if (report.issues.length > 0) {
|
|
560
|
-
|
|
466
|
+
(0, command_contract_1.log)(io, chalk_1.default.bold(`\n 问题详情 (前 20 条):\n`));
|
|
561
467
|
for (const issue of report.issues.slice(0, 20)) {
|
|
562
468
|
const severityColor = issue.severity === 'critical' ? chalk_1.default.red
|
|
563
469
|
: issue.severity === 'high' ? chalk_1.default.yellow
|
|
564
470
|
: chalk_1.default.gray;
|
|
565
|
-
|
|
566
|
-
|
|
471
|
+
(0, command_contract_1.log)(io, ` ${severityColor(`[${issue.severity}]`)} ${issue.entryId}: ${issue.title}`);
|
|
472
|
+
(0, command_contract_1.log)(io, ` ${chalk_1.default.gray(issue.detail)} → ${issue.action}`);
|
|
567
473
|
}
|
|
568
474
|
if (report.issues.length > 20) {
|
|
569
|
-
|
|
475
|
+
(0, command_contract_1.log)(io, chalk_1.default.gray(`\n ... 还有 ${report.issues.length - 20} 条`));
|
|
570
476
|
}
|
|
571
477
|
}
|
|
572
478
|
if (!options.fix && report.issues.length > 0) {
|
|
573
|
-
|
|
479
|
+
(0, command_contract_1.log)(io, chalk_1.default.yellow(`\n 使用 --fix 自动修复`));
|
|
574
480
|
}
|
|
575
481
|
// Auto-rebuild index after audit (files may have changed)
|
|
576
|
-
const baseDir = options.dir || getKnowledgeDir(options.projectPath);
|
|
482
|
+
const baseDir = options.dir || getKnowledgeDir(options.projectPath, io);
|
|
577
483
|
const idxGen = new index_generator_1.KnowledgeIndexGenerator(baseDir);
|
|
578
484
|
idxGen.regenerate();
|
|
579
485
|
if (!options.json) {
|
|
580
|
-
|
|
486
|
+
(0, command_contract_1.log)(io, chalk_1.default.gray(` 📇 索引已重建`));
|
|
581
487
|
}
|
|
488
|
+
return { kind: 'ok' };
|
|
582
489
|
}
|
|
583
490
|
/**
|
|
584
491
|
* 知识库快照(KR4 存活率追踪)
|
|
585
492
|
*/
|
|
586
|
-
function knowledgeSnapshot(options) {
|
|
587
|
-
const store = new store_1.FileKnowledgeStore({ baseDir: options.dir || getKnowledgeDir(options.projectPath) });
|
|
493
|
+
function knowledgeSnapshot(options, io = command_contract_1.processIO) {
|
|
494
|
+
const store = new store_1.FileKnowledgeStore({ baseDir: options.dir || getKnowledgeDir(options.projectPath, io) });
|
|
588
495
|
const snapPath = store.snapshot();
|
|
589
496
|
if (options.json) {
|
|
590
|
-
|
|
591
|
-
return;
|
|
497
|
+
(0, command_contract_1.log)(io, JSON.stringify({ snapshotPath: snapPath }));
|
|
498
|
+
return { kind: 'ok' };
|
|
592
499
|
}
|
|
593
|
-
|
|
500
|
+
(0, command_contract_1.log)(io, chalk_1.default.green(`✅ 快照已保存: ${snapPath}`));
|
|
501
|
+
return { kind: 'ok' };
|
|
594
502
|
}
|
|
595
503
|
/**
|
|
596
504
|
* 知识库迁移 — 为现有条目添加 AS-021 新字段
|
|
597
505
|
*/
|
|
598
|
-
function knowledgeMigrate(options) {
|
|
599
|
-
const baseDir = options.dir || getKnowledgeDir(options.projectPath);
|
|
506
|
+
function knowledgeMigrate(options, io = command_contract_1.processIO) {
|
|
507
|
+
const baseDir = options.dir || getKnowledgeDir(options.projectPath, io);
|
|
600
508
|
if (options.json) {
|
|
601
509
|
const result = (0, migration_1.migrateKnowledgeEntries)(baseDir);
|
|
602
|
-
|
|
603
|
-
return;
|
|
510
|
+
(0, command_contract_1.log)(io, JSON.stringify(result, null, 2));
|
|
511
|
+
return { kind: 'ok' };
|
|
604
512
|
}
|
|
605
|
-
|
|
513
|
+
(0, command_contract_1.log)(io, chalk_1.default.blue('🔄 迁移知识条目(添加 consumptionMode/origin 字段)\n'));
|
|
606
514
|
const result = (0, migration_1.migrateKnowledgeEntries)(baseDir);
|
|
607
|
-
|
|
608
|
-
|
|
609
|
-
|
|
515
|
+
(0, command_contract_1.log)(io, chalk_1.default.green(` 总计: ${result.total} 条`));
|
|
516
|
+
(0, command_contract_1.log)(io, chalk_1.default.green(` 已迁移: ${result.migrated} 条`));
|
|
517
|
+
(0, command_contract_1.log)(io, chalk_1.default.gray(` 已跳过: ${result.skipped} 条`));
|
|
610
518
|
if (result.errors.length > 0) {
|
|
611
|
-
|
|
519
|
+
(0, command_contract_1.log)(io, chalk_1.default.red(`\n 错误: ${result.errors.length} 条`));
|
|
612
520
|
for (const err of result.errors.slice(0, 5)) {
|
|
613
|
-
|
|
521
|
+
(0, command_contract_1.log)(io, chalk_1.default.red(` ${err}`));
|
|
614
522
|
}
|
|
615
523
|
}
|
|
616
524
|
if (result.migrated === 0 && result.errors.length === 0) {
|
|
617
|
-
|
|
525
|
+
(0, command_contract_1.log)(io, chalk_1.default.green('\n✅ 所有条目已是最新,无需迁移'));
|
|
618
526
|
}
|
|
619
527
|
else if (result.migrated > 0) {
|
|
620
|
-
|
|
528
|
+
(0, command_contract_1.log)(io, chalk_1.default.green(`\n✅ 迁移完成`));
|
|
621
529
|
}
|
|
530
|
+
return { kind: 'ok' };
|
|
622
531
|
}
|
|
623
532
|
/**
|
|
624
533
|
* 知识库索引重建 — 生成 _index.md 供 Agent grep 使用,同时同步 index.json
|
|
625
534
|
*/
|
|
626
|
-
function knowledgeIndex(options) {
|
|
627
|
-
const baseDir = options.dir || getKnowledgeDir(options.projectPath);
|
|
535
|
+
function knowledgeIndex(options, io = command_contract_1.processIO) {
|
|
536
|
+
const baseDir = options.dir || getKnowledgeDir(options.projectPath, io);
|
|
628
537
|
const gen = new index_generator_1.KnowledgeIndexGenerator(baseDir);
|
|
629
538
|
const beforeSize = (() => {
|
|
630
539
|
const indexPath = path.join(baseDir, '_index.md');
|
|
@@ -637,20 +546,21 @@ function knowledgeIndex(options) {
|
|
|
637
546
|
const afterSize = Buffer.byteLength(output, 'utf-8');
|
|
638
547
|
const lineCount = output.split('\n').filter(l => !l.startsWith('#')).length;
|
|
639
548
|
if (options.json) {
|
|
640
|
-
|
|
549
|
+
(0, command_contract_1.log)(io, JSON.stringify({
|
|
641
550
|
path: path.join(baseDir, '_index.md'),
|
|
642
551
|
entries: lineCount,
|
|
643
552
|
size: afterSize,
|
|
644
553
|
previousSize: beforeSize,
|
|
645
554
|
}));
|
|
646
|
-
return;
|
|
555
|
+
return { kind: 'ok' };
|
|
647
556
|
}
|
|
648
|
-
|
|
649
|
-
|
|
650
|
-
|
|
651
|
-
|
|
557
|
+
(0, command_contract_1.log)(io, chalk_1.default.blue(`📇 索引已重建`));
|
|
558
|
+
(0, command_contract_1.log)(io, chalk_1.default.gray(` 路径: ${path.join(baseDir, '_index.md')}`));
|
|
559
|
+
(0, command_contract_1.log)(io, chalk_1.default.green(` 条目: ${lineCount}`));
|
|
560
|
+
(0, command_contract_1.log)(io, chalk_1.default.green(` 大小: ${(afterSize / 1024).toFixed(1)} KB`));
|
|
652
561
|
if (beforeSize > 0) {
|
|
653
|
-
|
|
562
|
+
(0, command_contract_1.log)(io, chalk_1.default.gray(` 旧大小: ${(beforeSize / 1024).toFixed(1)} KB`));
|
|
654
563
|
}
|
|
564
|
+
return { kind: 'ok' };
|
|
655
565
|
}
|
|
656
566
|
//# sourceMappingURL=knowledge.js.map
|