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