@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
|
@@ -3,6 +3,7 @@
|
|
|
3
3
|
*/
|
|
4
4
|
|
|
5
5
|
import * as fs from 'fs';
|
|
6
|
+
import { captureIO, type CapturingIO } from '../../command-contract';
|
|
6
7
|
import * as path from 'path';
|
|
7
8
|
import { FailureRecorder } from '../../../failure/recorder';
|
|
8
9
|
import { ErrorType, FailureLevel } from '../../../failure/types';
|
|
@@ -11,10 +12,13 @@ import type { FailureRecord } from '../../../failure/types';
|
|
|
11
12
|
// Mock FailureRecorder
|
|
12
13
|
jest.mock('../../../failure/recorder');
|
|
13
14
|
|
|
15
|
+
let io: CapturingIO;
|
|
16
|
+
beforeEach(() => {
|
|
17
|
+
io = captureIO();
|
|
18
|
+
});
|
|
19
|
+
|
|
14
20
|
describe('failure CLI commands', () => {
|
|
15
21
|
const tempDir = path.join(process.cwd(), 'temp-test-failure-cli');
|
|
16
|
-
let consoleSpy: jest.SpyInstance;
|
|
17
|
-
let consoleErrorSpy: jest.SpyInstance;
|
|
18
22
|
let mockRecorderInstance: {
|
|
19
23
|
record: jest.Mock;
|
|
20
24
|
getHistory: jest.Mock;
|
|
@@ -48,8 +52,6 @@ describe('failure CLI commands', () => {
|
|
|
48
52
|
|
|
49
53
|
beforeEach(() => {
|
|
50
54
|
jest.clearAllMocks();
|
|
51
|
-
consoleSpy = jest.spyOn(console, 'log').mockImplementation();
|
|
52
|
-
consoleErrorSpy = jest.spyOn(console, 'error').mockImplementation();
|
|
53
55
|
|
|
54
56
|
// Setup mock instance methods
|
|
55
57
|
mockRecorderInstance = {
|
|
@@ -62,37 +64,32 @@ describe('failure CLI commands', () => {
|
|
|
62
64
|
(FailureRecorder as jest.Mock).mockImplementation(() => mockRecorderInstance);
|
|
63
65
|
});
|
|
64
66
|
|
|
65
|
-
afterEach(() => {
|
|
66
|
-
consoleSpy.mockRestore();
|
|
67
|
-
consoleErrorSpy.mockRestore();
|
|
68
|
-
});
|
|
69
|
-
|
|
70
67
|
describe('failureList', () => {
|
|
71
68
|
it('应该列出所有记录', async () => {
|
|
72
69
|
const { failureList } = await import('../failure');
|
|
73
|
-
await failureList({ projectPath: tempDir });
|
|
70
|
+
await failureList({ projectPath: tempDir }, io);
|
|
74
71
|
|
|
75
|
-
expect(
|
|
76
|
-
expect(
|
|
72
|
+
expect(io.outText()).toContain('失败记录');
|
|
73
|
+
expect(io.outText()).toContain('TEST_FAILED');
|
|
77
74
|
});
|
|
78
75
|
|
|
79
76
|
it('应该按类型过滤', async () => {
|
|
80
77
|
const { failureList } = await import('../failure');
|
|
81
|
-
await failureList({ projectPath: tempDir, type: 'TEST_FAILED' });
|
|
78
|
+
await failureList({ projectPath: tempDir, type: 'TEST_FAILED' }, io);
|
|
82
79
|
|
|
83
80
|
expect(mockRecorderInstance.getHistory).toHaveBeenCalled();
|
|
84
81
|
});
|
|
85
82
|
|
|
86
83
|
it('应该按等级过滤', async () => {
|
|
87
84
|
const { failureList } = await import('../failure');
|
|
88
|
-
await failureList({ projectPath: tempDir, level: 'L1' });
|
|
85
|
+
await failureList({ projectPath: tempDir, level: 'L1' }, io);
|
|
89
86
|
|
|
90
87
|
expect(mockRecorderInstance.getHistory).toHaveBeenCalled();
|
|
91
88
|
});
|
|
92
89
|
|
|
93
90
|
it('应该限制返回数量', async () => {
|
|
94
91
|
const { failureList } = await import('../failure');
|
|
95
|
-
await failureList({ projectPath: tempDir, limit: 2 });
|
|
92
|
+
await failureList({ projectPath: tempDir, limit: 2 }, io);
|
|
96
93
|
|
|
97
94
|
expect(mockRecorderInstance.getHistory).toHaveBeenCalled();
|
|
98
95
|
});
|
|
@@ -100,16 +97,16 @@ describe('failure CLI commands', () => {
|
|
|
100
97
|
it('空记录应该输出提示', async () => {
|
|
101
98
|
mockRecorderInstance.getHistory.mockResolvedValue([]);
|
|
102
99
|
const { failureList } = await import('../failure');
|
|
103
|
-
await failureList({ projectPath: tempDir });
|
|
100
|
+
await failureList({ projectPath: tempDir }, io);
|
|
104
101
|
|
|
105
|
-
expect(
|
|
102
|
+
expect(io.outText()).toContain('没有失败记录');
|
|
106
103
|
});
|
|
107
104
|
|
|
108
105
|
it('--json 模式应该输出 JSON', async () => {
|
|
109
106
|
const { failureList } = await import('../failure');
|
|
110
|
-
await failureList({ projectPath: tempDir, json: true });
|
|
107
|
+
await failureList({ projectPath: tempDir, json: true }, io);
|
|
111
108
|
|
|
112
|
-
const jsonCall =
|
|
109
|
+
const jsonCall = io.outRecords().map(chunk => [chunk] as string[]).find(
|
|
113
110
|
(call: unknown[]) => typeof call[0] === 'string' && call[0].startsWith('{')
|
|
114
111
|
);
|
|
115
112
|
expect(jsonCall).toBeDefined();
|
|
@@ -120,9 +117,9 @@ describe('failure CLI commands', () => {
|
|
|
120
117
|
it('--json 模式空记录应该输出 total:0', async () => {
|
|
121
118
|
mockRecorderInstance.getHistory.mockResolvedValue([]);
|
|
122
119
|
const { failureList } = await import('../failure');
|
|
123
|
-
await failureList({ projectPath: tempDir, json: true });
|
|
120
|
+
await failureList({ projectPath: tempDir, json: true }, io);
|
|
124
121
|
|
|
125
|
-
const jsonCall =
|
|
122
|
+
const jsonCall = io.outRecords().map(chunk => [chunk] as string[]).find(
|
|
126
123
|
(call: unknown[]) => typeof call[0] === 'string' && call[0].startsWith('{')
|
|
127
124
|
);
|
|
128
125
|
expect(jsonCall).toBeDefined();
|
|
@@ -134,17 +131,17 @@ describe('failure CLI commands', () => {
|
|
|
134
131
|
describe('failureStats', () => {
|
|
135
132
|
it('应该输出统计信息', async () => {
|
|
136
133
|
const { failureStats } = await import('../failure');
|
|
137
|
-
await failureStats({ projectPath: tempDir });
|
|
134
|
+
await failureStats({ projectPath: tempDir }, io);
|
|
138
135
|
|
|
139
|
-
expect(
|
|
140
|
-
expect(
|
|
136
|
+
expect(io.outText()).toContain('失败统计');
|
|
137
|
+
expect(io.outText()).toContain('TEST_FAILED');
|
|
141
138
|
});
|
|
142
139
|
|
|
143
140
|
it('--json 模式应该输出 JSON 统计', async () => {
|
|
144
141
|
const { failureStats } = await import('../failure');
|
|
145
|
-
await failureStats({ projectPath: tempDir, json: true });
|
|
142
|
+
await failureStats({ projectPath: tempDir, json: true }, io);
|
|
146
143
|
|
|
147
|
-
const jsonCall =
|
|
144
|
+
const jsonCall = io.outRecords().map(chunk => [chunk] as string[]).find(
|
|
148
145
|
(call: unknown[]) => typeof call[0] === 'string' && call[0].startsWith('{')
|
|
149
146
|
);
|
|
150
147
|
expect(jsonCall).toBeDefined();
|
|
@@ -155,17 +152,17 @@ describe('failure CLI commands', () => {
|
|
|
155
152
|
it('空记录应该输出绿色提示', async () => {
|
|
156
153
|
mockRecorderInstance.getStats.mockResolvedValue({ total: 0, byType: {}, byLevel: {} });
|
|
157
154
|
const { failureStats } = await import('../failure');
|
|
158
|
-
await failureStats({ projectPath: tempDir });
|
|
155
|
+
await failureStats({ projectPath: tempDir }, io);
|
|
159
156
|
|
|
160
|
-
expect(
|
|
157
|
+
expect(io.outText()).toContain('没有失败记录');
|
|
161
158
|
});
|
|
162
159
|
|
|
163
160
|
it('--json 模式空记录应该输出空统计', async () => {
|
|
164
161
|
mockRecorderInstance.getStats.mockResolvedValue({ total: 0, byType: {}, byLevel: {} });
|
|
165
162
|
const { failureStats } = await import('../failure');
|
|
166
|
-
await failureStats({ projectPath: tempDir, json: true });
|
|
163
|
+
await failureStats({ projectPath: tempDir, json: true }, io);
|
|
167
164
|
|
|
168
|
-
const jsonCall =
|
|
165
|
+
const jsonCall = io.outRecords().map(chunk => [chunk] as string[]).find(
|
|
169
166
|
(call: unknown[]) => typeof call[0] === 'string' && call[0].startsWith('{')
|
|
170
167
|
);
|
|
171
168
|
expect(jsonCall).toBeDefined();
|
|
@@ -177,17 +174,17 @@ describe('failure CLI commands', () => {
|
|
|
177
174
|
describe('failureClear', () => {
|
|
178
175
|
it('应该清空记录并输出结果', async () => {
|
|
179
176
|
const { failureClear } = await import('../failure');
|
|
180
|
-
await failureClear({ projectPath: tempDir });
|
|
177
|
+
await failureClear({ projectPath: tempDir }, io);
|
|
181
178
|
|
|
182
179
|
expect(mockRecorderInstance.clear).toHaveBeenCalled();
|
|
183
|
-
expect(
|
|
180
|
+
expect(io.outText()).toContain('已清空');
|
|
184
181
|
});
|
|
185
182
|
|
|
186
183
|
it('--json 模式应该输出清空的记录数', async () => {
|
|
187
184
|
const { failureClear } = await import('../failure');
|
|
188
|
-
await failureClear({ projectPath: tempDir, json: true });
|
|
185
|
+
await failureClear({ projectPath: tempDir, json: true }, io);
|
|
189
186
|
|
|
190
|
-
const jsonCall =
|
|
187
|
+
const jsonCall = io.outRecords().map(chunk => [chunk] as string[]).find(
|
|
191
188
|
(call: unknown[]) => typeof call[0] === 'string' && call[0].startsWith('{')
|
|
192
189
|
);
|
|
193
190
|
expect(jsonCall).toBeDefined();
|
|
@@ -7,6 +7,7 @@
|
|
|
7
7
|
*/
|
|
8
8
|
|
|
9
9
|
import { describe, it, expect, beforeEach, afterEach, jest } from '@jest/globals';
|
|
10
|
+
import { captureIO, type CapturingIO } from '../../command-contract';
|
|
10
11
|
import * as fs from 'fs';
|
|
11
12
|
import * as path from 'path';
|
|
12
13
|
import {
|
|
@@ -38,6 +39,11 @@ const makeConstraint = (overrides: Partial<Constraint>): Constraint => ({
|
|
|
38
39
|
...overrides,
|
|
39
40
|
});
|
|
40
41
|
|
|
42
|
+
let io: CapturingIO;
|
|
43
|
+
beforeEach(() => {
|
|
44
|
+
io = captureIO();
|
|
45
|
+
});
|
|
46
|
+
|
|
41
47
|
describe('renderConstraintsSection(纯函数)', () => {
|
|
42
48
|
it('按 level 分组渲染,含标记与版本行', () => {
|
|
43
49
|
const constraints = [
|
|
@@ -101,7 +107,7 @@ describe('setupClaudeMdConstraints(消费生效集)', () => {
|
|
|
101
107
|
});
|
|
102
108
|
|
|
103
109
|
it('CLAUDE.md 不存在时创建并写入约束段', async () => {
|
|
104
|
-
await setupClaudeMdConstraints(tempDir);
|
|
110
|
+
await setupClaudeMdConstraints(tempDir, io);
|
|
105
111
|
|
|
106
112
|
const content = fs.readFileSync(claudeMdPath, 'utf-8');
|
|
107
113
|
expect(content).toContain('## Governance Rules');
|
|
@@ -112,24 +118,32 @@ describe('setupClaudeMdConstraints(消费生效集)', () => {
|
|
|
112
118
|
});
|
|
113
119
|
|
|
114
120
|
it('连跑两次输出一致(幂等)', async () => {
|
|
115
|
-
await setupClaudeMdConstraints(tempDir);
|
|
121
|
+
await setupClaudeMdConstraints(tempDir, io);
|
|
116
122
|
const first = fs.readFileSync(claudeMdPath, 'utf-8');
|
|
117
|
-
await setupClaudeMdConstraints(tempDir);
|
|
123
|
+
await setupClaudeMdConstraints(tempDir, io);
|
|
118
124
|
const second = fs.readFileSync(claudeMdPath, 'utf-8');
|
|
119
125
|
expect(second).toBe(first);
|
|
120
126
|
});
|
|
121
127
|
|
|
122
128
|
it('标记区间外内容保持不动', async () => {
|
|
123
129
|
fs.writeFileSync(claudeMdPath, '# My Project\n\n用户自定义内容\n');
|
|
124
|
-
await setupClaudeMdConstraints(tempDir);
|
|
130
|
+
await setupClaudeMdConstraints(tempDir, io);
|
|
125
131
|
const content = fs.readFileSync(claudeMdPath, 'utf-8');
|
|
126
132
|
expect(content).toContain('# My Project');
|
|
127
133
|
expect(content).toContain('用户自定义内容');
|
|
128
134
|
});
|
|
129
135
|
|
|
136
|
+
it('标记残缺(只有单边):拒写不追加并告警(writer 半标记守护,候选1)', async () => {
|
|
137
|
+
const broken = `# My Project\n\n${CONSTRAINTS_START_MARKER}\n半残段\n`;
|
|
138
|
+
fs.writeFileSync(claudeMdPath, broken);
|
|
139
|
+
await setupClaudeMdConstraints(tempDir, io);
|
|
140
|
+
expect(fs.readFileSync(claudeMdPath, 'utf-8')).toBe(broken);
|
|
141
|
+
expect(io.outText()).toContain('残缺');
|
|
142
|
+
});
|
|
143
|
+
|
|
130
144
|
it('尊重 config.yml 禁用:注入段不含被禁条目', async () => {
|
|
131
145
|
writeConfig('constraints:\n no_fuzzy_completion_claim:\n enabled: false\n');
|
|
132
|
-
await setupClaudeMdConstraints(tempDir);
|
|
146
|
+
await setupClaudeMdConstraints(tempDir, io);
|
|
133
147
|
|
|
134
148
|
const content = fs.readFileSync(claudeMdPath, 'utf-8');
|
|
135
149
|
expect(content).not.toContain('no_fuzzy_completion_claim');
|
|
@@ -138,12 +152,12 @@ describe('setupClaudeMdConstraints(消费生效集)', () => {
|
|
|
138
152
|
|
|
139
153
|
it('scenes 缺省不注入场景专属 prompt;配置 scenes 后注入', async () => {
|
|
140
154
|
writeConfig('preset: standard\n');
|
|
141
|
-
await setupClaudeMdConstraints(tempDir);
|
|
155
|
+
await setupClaudeMdConstraints(tempDir, io);
|
|
142
156
|
let content = fs.readFileSync(claudeMdPath, 'utf-8');
|
|
143
157
|
expect(content).not.toContain('no_skill_without_test');
|
|
144
158
|
|
|
145
159
|
writeConfig('preset: standard\nscenes:\n - agent-skill\n');
|
|
146
|
-
await setupClaudeMdConstraints(tempDir);
|
|
160
|
+
await setupClaudeMdConstraints(tempDir, io);
|
|
147
161
|
content = fs.readFileSync(claudeMdPath, 'utf-8');
|
|
148
162
|
expect(content).toContain('- **no_skill_without_test**');
|
|
149
163
|
expect(content).not.toContain('no_model_for_deterministic');
|
|
@@ -151,7 +165,7 @@ describe('setupClaudeMdConstraints(消费生效集)', () => {
|
|
|
151
165
|
|
|
152
166
|
it('注入段文本与 renderConstraintsSection(getEffectiveConstraints()) 一致', async () => {
|
|
153
167
|
writeConfig('constraints:\n no_bypass_checkpoint:\n enabled: false\n');
|
|
154
|
-
await setupClaudeMdConstraints(tempDir);
|
|
168
|
+
await setupClaudeMdConstraints(tempDir, io);
|
|
155
169
|
|
|
156
170
|
const content = fs.readFileSync(claudeMdPath, 'utf-8');
|
|
157
171
|
const start = content.indexOf(CONSTRAINTS_START_MARKER);
|
|
@@ -179,13 +193,13 @@ describe('setupClaudeMdOutputStyle(标记化)', () => {
|
|
|
179
193
|
});
|
|
180
194
|
|
|
181
195
|
it('CLAUDE.md 不存在时不创建(由 constraints 注入负责创建)', async () => {
|
|
182
|
-
await setupClaudeMdOutputStyle(tempDir);
|
|
196
|
+
await setupClaudeMdOutputStyle(tempDir, io);
|
|
183
197
|
expect(fs.existsSync(claudeMdPath)).toBe(false);
|
|
184
198
|
});
|
|
185
199
|
|
|
186
200
|
it('无 Output Style 段:插入带标记段到文件顶部,二次运行幂等', async () => {
|
|
187
201
|
fs.writeFileSync(claudeMdPath, '# My Project\n\n正文\n');
|
|
188
|
-
await setupClaudeMdOutputStyle(tempDir);
|
|
202
|
+
await setupClaudeMdOutputStyle(tempDir, io);
|
|
189
203
|
|
|
190
204
|
const content = fs.readFileSync(claudeMdPath, 'utf-8');
|
|
191
205
|
expect(content.startsWith(OUTPUT_STYLE_START)).toBe(true);
|
|
@@ -193,7 +207,7 @@ describe('setupClaudeMdOutputStyle(标记化)', () => {
|
|
|
193
207
|
expect(content).toContain(OUTPUT_STYLE_END);
|
|
194
208
|
expect(content).toContain('# My Project');
|
|
195
209
|
|
|
196
|
-
await setupClaudeMdOutputStyle(tempDir);
|
|
210
|
+
await setupClaudeMdOutputStyle(tempDir, io);
|
|
197
211
|
expect(fs.readFileSync(claudeMdPath, 'utf-8')).toBe(content);
|
|
198
212
|
});
|
|
199
213
|
|
|
@@ -209,7 +223,7 @@ describe('setupClaudeMdOutputStyle(标记化)', () => {
|
|
|
209
223
|
].join('\n');
|
|
210
224
|
fs.writeFileSync(claudeMdPath, legacy);
|
|
211
225
|
|
|
212
|
-
await setupClaudeMdOutputStyle(tempDir);
|
|
226
|
+
await setupClaudeMdOutputStyle(tempDir, io);
|
|
213
227
|
const content = fs.readFileSync(claudeMdPath, 'utf-8');
|
|
214
228
|
|
|
215
229
|
expect(content).toContain(OUTPUT_STYLE_START);
|
|
@@ -219,19 +233,18 @@ describe('setupClaudeMdOutputStyle(标记化)', () => {
|
|
|
219
233
|
// 迁移后只剩一个 Output Style 标题
|
|
220
234
|
expect(content.match(/^## Output Style$/gm)).toHaveLength(1);
|
|
221
235
|
// 幂等
|
|
222
|
-
await setupClaudeMdOutputStyle(tempDir);
|
|
236
|
+
await setupClaudeMdOutputStyle(tempDir, io);
|
|
223
237
|
expect(fs.readFileSync(claudeMdPath, 'utf-8')).toBe(content);
|
|
224
238
|
});
|
|
225
239
|
|
|
226
240
|
it('用户自写 Output Style 段(特征串不匹配):不动、不追加、console 提示', async () => {
|
|
227
241
|
const userContent = '# My Project\n\n## Output Style\n\n用户自己的输出风格要求。\n';
|
|
228
242
|
fs.writeFileSync(claudeMdPath, userContent);
|
|
229
|
-
const logSpy = jest.spyOn(console, 'log');
|
|
230
243
|
|
|
231
|
-
await setupClaudeMdOutputStyle(tempDir);
|
|
244
|
+
await setupClaudeMdOutputStyle(tempDir, io);
|
|
232
245
|
|
|
233
246
|
expect(fs.readFileSync(claudeMdPath, 'utf-8')).toBe(userContent);
|
|
234
|
-
expect(
|
|
247
|
+
expect(io.outText()).toContain('跳过');
|
|
235
248
|
});
|
|
236
249
|
});
|
|
237
250
|
|
|
@@ -254,7 +267,7 @@ describe('setupAgentsMdConstraints(新落点模型:治理契约 → AGENTS.m
|
|
|
254
267
|
});
|
|
255
268
|
|
|
256
269
|
it('AGENTS.md 不存在时创建骨架并写入 PRESERVE:governance 段', async () => {
|
|
257
|
-
await setupAgentsMdConstraints(tempDir);
|
|
270
|
+
await setupAgentsMdConstraints(tempDir, io);
|
|
258
271
|
|
|
259
272
|
const content = fs.readFileSync(agentsMdPath, 'utf-8');
|
|
260
273
|
expect(content).toContain('# AGENTS.md');
|
|
@@ -270,9 +283,9 @@ describe('setupAgentsMdConstraints(新落点模型:治理契约 → AGENTS.m
|
|
|
270
283
|
});
|
|
271
284
|
|
|
272
285
|
it('连跑两次输出一致(幂等)', async () => {
|
|
273
|
-
await setupAgentsMdConstraints(tempDir);
|
|
286
|
+
await setupAgentsMdConstraints(tempDir, io);
|
|
274
287
|
const first = fs.readFileSync(agentsMdPath, 'utf-8');
|
|
275
|
-
await setupAgentsMdConstraints(tempDir);
|
|
288
|
+
await setupAgentsMdConstraints(tempDir, io);
|
|
276
289
|
expect(fs.readFileSync(agentsMdPath, 'utf-8')).toBe(first);
|
|
277
290
|
});
|
|
278
291
|
|
|
@@ -301,7 +314,7 @@ describe('setupAgentsMdConstraints(新落点模型:治理契约 → AGENTS.m
|
|
|
301
314
|
'',
|
|
302
315
|
].join('\n'));
|
|
303
316
|
|
|
304
|
-
await setupAgentsMdConstraints(tempDir);
|
|
317
|
+
await setupAgentsMdConstraints(tempDir, io);
|
|
305
318
|
|
|
306
319
|
const content = fs.readFileSync(agentsMdPath, 'utf-8');
|
|
307
320
|
expect(content).toContain('机器生成导读(保持不变)');
|
|
@@ -314,7 +327,7 @@ describe('setupAgentsMdConstraints(新落点模型:治理契约 → AGENTS.m
|
|
|
314
327
|
expect(content.indexOf(CONSTRAINTS_END_MARKER)).toBeLessThan(content.indexOf('治理契约引言(手写,保留)'));
|
|
315
328
|
expect(content.indexOf('### 治理变更流程(手写,保留)')).toBeLessThan(content.indexOf(GOVERNANCE_PRESERVE_END));
|
|
316
329
|
// 幂等
|
|
317
|
-
await setupAgentsMdConstraints(tempDir);
|
|
330
|
+
await setupAgentsMdConstraints(tempDir, io);
|
|
318
331
|
expect(fs.readFileSync(agentsMdPath, 'utf-8')).toBe(content);
|
|
319
332
|
});
|
|
320
333
|
|
|
@@ -330,7 +343,7 @@ describe('setupAgentsMdConstraints(新落点模型:治理契约 → AGENTS.m
|
|
|
330
343
|
'',
|
|
331
344
|
].join('\n'));
|
|
332
345
|
|
|
333
|
-
await setupAgentsMdConstraints(tempDir);
|
|
346
|
+
await setupAgentsMdConstraints(tempDir, io);
|
|
334
347
|
|
|
335
348
|
const content = fs.readFileSync(agentsMdPath, 'utf-8');
|
|
336
349
|
expect(content).toContain('治理契约引言(手写,保留)');
|
|
@@ -340,14 +353,14 @@ describe('setupAgentsMdConstraints(新落点模型:治理契约 → AGENTS.m
|
|
|
340
353
|
expect(content.indexOf('### 发布纪律(手写,保留)')).toBeLessThan(content.indexOf(CONSTRAINTS_START_MARKER));
|
|
341
354
|
expect(content.indexOf(CONSTRAINTS_END_MARKER)).toBeLessThan(content.indexOf(GOVERNANCE_PRESERVE_END));
|
|
342
355
|
// 幂等
|
|
343
|
-
await setupAgentsMdConstraints(tempDir);
|
|
356
|
+
await setupAgentsMdConstraints(tempDir, io);
|
|
344
357
|
expect(fs.readFileSync(agentsMdPath, 'utf-8')).toBe(content);
|
|
345
358
|
});
|
|
346
359
|
|
|
347
360
|
it('AGENTS.md 存在但无 PRESERVE:governance 段:末尾追加,既有内容不动', async () => {
|
|
348
361
|
fs.writeFileSync(agentsMdPath, '# AGENTS.md\n\n既有导读内容\n');
|
|
349
362
|
|
|
350
|
-
await setupAgentsMdConstraints(tempDir);
|
|
363
|
+
await setupAgentsMdConstraints(tempDir, io);
|
|
351
364
|
|
|
352
365
|
const content = fs.readFileSync(agentsMdPath, 'utf-8');
|
|
353
366
|
expect(content).toContain('既有导读内容');
|
|
@@ -358,16 +371,33 @@ describe('setupAgentsMdConstraints(新落点模型:治理契约 → AGENTS.m
|
|
|
358
371
|
it('PRESERVE:governance 标记残缺(只有单边):不写入并告警', async () => {
|
|
359
372
|
const original = `# AGENTS.md\n\n${GOVERNANCE_PRESERVE_BEGIN}\n残缺的段\n`;
|
|
360
373
|
fs.writeFileSync(agentsMdPath, original);
|
|
361
|
-
const logSpy = jest.spyOn(console, 'log');
|
|
362
374
|
|
|
363
|
-
await setupAgentsMdConstraints(tempDir);
|
|
375
|
+
await setupAgentsMdConstraints(tempDir, io);
|
|
364
376
|
|
|
365
377
|
expect(fs.readFileSync(agentsMdPath, 'utf-8')).toBe(original);
|
|
366
|
-
expect(
|
|
378
|
+
expect(io.outText()).toContain('残缺');
|
|
379
|
+
});
|
|
380
|
+
|
|
381
|
+
it('PRESERVE 段内 HARNESS 标记残缺(单边):拒写并告警(候选1 守护,旧行为会再追加一份注入段)', async () => {
|
|
382
|
+
const broken = [
|
|
383
|
+
'# AGENTS.md',
|
|
384
|
+
'',
|
|
385
|
+
GOVERNANCE_PRESERVE_BEGIN,
|
|
386
|
+
'手写契约',
|
|
387
|
+
'',
|
|
388
|
+
CONSTRAINTS_START_MARKER,
|
|
389
|
+
'半残注入',
|
|
390
|
+
GOVERNANCE_PRESERVE_END,
|
|
391
|
+
'',
|
|
392
|
+
].join('\n');
|
|
393
|
+
fs.writeFileSync(agentsMdPath, broken);
|
|
394
|
+
await setupAgentsMdConstraints(tempDir, io);
|
|
395
|
+
expect(fs.readFileSync(agentsMdPath, 'utf-8')).toBe(broken);
|
|
396
|
+
expect(io.outText()).toContain('残缺');
|
|
367
397
|
});
|
|
368
398
|
|
|
369
399
|
it('段内注入文本与 renderConstraintsSection(getEffectiveConstraints()) 一致', async () => {
|
|
370
|
-
await setupAgentsMdConstraints(tempDir);
|
|
400
|
+
await setupAgentsMdConstraints(tempDir, io);
|
|
371
401
|
|
|
372
402
|
const content = fs.readFileSync(agentsMdPath, 'utf-8');
|
|
373
403
|
const start = content.indexOf(CONSTRAINTS_START_MARKER);
|