@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,9 +3,15 @@
|
|
|
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 { syncDocs } from '../sync-docs';
|
|
8
9
|
|
|
10
|
+
let io: CapturingIO;
|
|
11
|
+
beforeEach(() => {
|
|
12
|
+
io = captureIO();
|
|
13
|
+
});
|
|
14
|
+
|
|
9
15
|
describe('sync-docs --agents', () => {
|
|
10
16
|
const tempDir = path.join(process.cwd(), 'temp-test-sync-docs-agents');
|
|
11
17
|
|
|
@@ -21,15 +27,8 @@ describe('sync-docs --agents', () => {
|
|
|
21
27
|
}
|
|
22
28
|
});
|
|
23
29
|
|
|
24
|
-
let consoleSpy: jest.SpyInstance;
|
|
25
|
-
|
|
26
30
|
beforeEach(() => {
|
|
27
31
|
jest.clearAllMocks();
|
|
28
|
-
consoleSpy = jest.spyOn(console, 'log').mockImplementation();
|
|
29
|
-
});
|
|
30
|
-
|
|
31
|
-
afterEach(() => {
|
|
32
|
-
consoleSpy.mockRestore();
|
|
33
32
|
});
|
|
34
33
|
|
|
35
34
|
/**
|
|
@@ -90,7 +89,7 @@ describe('sync-docs --agents', () => {
|
|
|
90
89
|
const testDir = path.join(tempDir, 'gen-pnpm');
|
|
91
90
|
createFixture(testDir, { pnpm: true });
|
|
92
91
|
|
|
93
|
-
await syncDocs({ projectPath: testDir, agents: true });
|
|
92
|
+
await syncDocs({ projectPath: testDir, agents: true }, io);
|
|
94
93
|
|
|
95
94
|
const agentsPath = path.join(testDir, 'AGENTS.md');
|
|
96
95
|
expect(fs.existsSync(agentsPath)).toBe(true);
|
|
@@ -126,7 +125,7 @@ describe('sync-docs --agents', () => {
|
|
|
126
125
|
const testDir = path.join(tempDir, 'gen-npm');
|
|
127
126
|
createFixture(testDir);
|
|
128
127
|
|
|
129
|
-
await syncDocs({ projectPath: testDir, agents: true });
|
|
128
|
+
await syncDocs({ projectPath: testDir, agents: true }, io);
|
|
130
129
|
|
|
131
130
|
const content = fs.readFileSync(path.join(testDir, 'AGENTS.md'), 'utf-8');
|
|
132
131
|
expect(content).toContain('npm run build');
|
|
@@ -141,18 +140,18 @@ describe('sync-docs --agents', () => {
|
|
|
141
140
|
const testDir = path.join(tempDir, 'idempotent');
|
|
142
141
|
createFixture(testDir, { pnpm: true, withCapabilities: true });
|
|
143
142
|
|
|
144
|
-
await syncDocs({ projectPath: testDir, agents: true });
|
|
143
|
+
await syncDocs({ projectPath: testDir, agents: true }, io);
|
|
145
144
|
const first = fs.readFileSync(path.join(testDir, 'AGENTS.md'), 'utf-8');
|
|
146
145
|
|
|
147
146
|
// 第二次运行:无任何差异
|
|
148
|
-
const secondRun = await syncDocs({ projectPath: testDir, agents: true });
|
|
147
|
+
const secondRun = await syncDocs({ projectPath: testDir, agents: true }, io);
|
|
149
148
|
const second = fs.readFileSync(path.join(testDir, 'AGENTS.md'), 'utf-8');
|
|
150
149
|
expect(second).toBe(first);
|
|
151
|
-
expect(secondRun).
|
|
150
|
+
expect(secondRun).toEqual({ kind: 'ok' });
|
|
152
151
|
|
|
153
152
|
// --check 模式应通过
|
|
154
|
-
const checkResult = await syncDocs({ projectPath: testDir, agents: true, check: true });
|
|
155
|
-
expect(checkResult).
|
|
153
|
+
const checkResult = await syncDocs({ projectPath: testDir, agents: true, check: true }, io);
|
|
154
|
+
expect(checkResult).toEqual({ kind: 'ok' });
|
|
156
155
|
|
|
157
156
|
fs.rmSync(testDir, { recursive: true, force: true });
|
|
158
157
|
});
|
|
@@ -161,9 +160,9 @@ describe('sync-docs --agents', () => {
|
|
|
161
160
|
const testDir = path.join(tempDir, 'check-missing');
|
|
162
161
|
createFixture(testDir, { withCapabilities: true });
|
|
163
162
|
|
|
164
|
-
const result = await syncDocs({ projectPath: testDir, agents: true, check: true });
|
|
165
|
-
expect(result).
|
|
166
|
-
expect(
|
|
163
|
+
const result = await syncDocs({ projectPath: testDir, agents: true, check: true }, io);
|
|
164
|
+
expect(result).toEqual({ kind: 'fail', reason: expect.stringContaining('文档不是最新') });
|
|
165
|
+
expect(io.outText()).toContain('缺少 AGENTS.md');
|
|
167
166
|
// check 模式不写入
|
|
168
167
|
expect(fs.existsSync(path.join(testDir, 'AGENTS.md'))).toBe(false);
|
|
169
168
|
|
|
@@ -175,22 +174,22 @@ describe('sync-docs --agents', () => {
|
|
|
175
174
|
createFixture(testDir, { pnpm: true, withCapabilities: true });
|
|
176
175
|
|
|
177
176
|
// 先生成
|
|
178
|
-
await syncDocs({ projectPath: testDir, agents: true });
|
|
177
|
+
await syncDocs({ projectPath: testDir, agents: true }, io);
|
|
179
178
|
|
|
180
179
|
// 漂移 1:手改 AGENTS.md
|
|
181
180
|
fs.appendFileSync(path.join(testDir, 'AGENTS.md'), '\n手动追加的一行\n');
|
|
182
|
-
expect(await syncDocs({ projectPath: testDir, agents: true, check: true })).
|
|
181
|
+
expect(await syncDocs({ projectPath: testDir, agents: true, check: true }, io)).toEqual({ kind: 'fail', reason: expect.stringContaining('文档不是最新') });
|
|
183
182
|
|
|
184
183
|
// 重新生成恢复
|
|
185
|
-
await syncDocs({ projectPath: testDir, agents: true });
|
|
186
|
-
expect(await syncDocs({ projectPath: testDir, agents: true, check: true })).
|
|
184
|
+
await syncDocs({ projectPath: testDir, agents: true }, io);
|
|
185
|
+
expect(await syncDocs({ projectPath: testDir, agents: true, check: true }, io)).toEqual({ kind: 'ok' });
|
|
187
186
|
|
|
188
187
|
// 漂移 2:package.json 删除一个 curated 脚本
|
|
189
188
|
const pkgPath = path.join(testDir, 'package.json');
|
|
190
189
|
const pkg = JSON.parse(fs.readFileSync(pkgPath, 'utf-8'));
|
|
191
190
|
delete pkg.scripts.lint;
|
|
192
191
|
fs.writeFileSync(pkgPath, JSON.stringify(pkg, null, 2));
|
|
193
|
-
expect(await syncDocs({ projectPath: testDir, agents: true, check: true })).
|
|
192
|
+
expect(await syncDocs({ projectPath: testDir, agents: true, check: true }, io)).toEqual({ kind: 'fail', reason: expect.stringContaining('文档不是最新') });
|
|
194
193
|
|
|
195
194
|
fs.rmSync(testDir, { recursive: true, force: true });
|
|
196
195
|
});
|
|
@@ -199,8 +198,8 @@ describe('sync-docs --agents', () => {
|
|
|
199
198
|
const testDir = path.join(tempDir, 'no-agents');
|
|
200
199
|
createFixture(testDir, { withCapabilities: true });
|
|
201
200
|
|
|
202
|
-
const result = await syncDocs({ projectPath: testDir });
|
|
203
|
-
expect(result).
|
|
201
|
+
const result = await syncDocs({ projectPath: testDir }, io);
|
|
202
|
+
expect(result).toEqual({ kind: 'ok' });
|
|
204
203
|
expect(fs.existsSync(path.join(testDir, 'AGENTS.md'))).toBe(false);
|
|
205
204
|
|
|
206
205
|
fs.rmSync(testDir, { recursive: true, force: true });
|
|
@@ -210,10 +209,10 @@ describe('sync-docs --agents', () => {
|
|
|
210
209
|
const testDir = path.join(tempDir, 'json-agents');
|
|
211
210
|
createFixture(testDir, { withCapabilities: true });
|
|
212
211
|
|
|
213
|
-
const result = await syncDocs({ projectPath: testDir, agents: true, check: true, json: true });
|
|
214
|
-
expect(result).
|
|
212
|
+
const result = await syncDocs({ projectPath: testDir, agents: true, check: true, json: true }, io);
|
|
213
|
+
expect(result).toEqual({ kind: 'fail', reason: expect.stringContaining('文档不是最新') });
|
|
215
214
|
|
|
216
|
-
const jsonCall =
|
|
215
|
+
const jsonCall = io.outRecords().map(chunk => [chunk] as string[]).find(
|
|
217
216
|
(call: unknown[]) => typeof call[0] === 'string' && call[0].startsWith('{')
|
|
218
217
|
);
|
|
219
218
|
expect(jsonCall).toBeDefined();
|
|
@@ -230,7 +229,7 @@ describe('sync-docs --agents', () => {
|
|
|
230
229
|
createFixture(testDir);
|
|
231
230
|
fs.writeFileSync(path.join(testDir, 'yarn.lock'), '# yarn lockfile v1\n');
|
|
232
231
|
|
|
233
|
-
await syncDocs({ projectPath: testDir, agents: true });
|
|
232
|
+
await syncDocs({ projectPath: testDir, agents: true }, io);
|
|
234
233
|
|
|
235
234
|
const content = fs.readFileSync(path.join(testDir, 'AGENTS.md'), 'utf-8');
|
|
236
235
|
expect(content).toContain('yarn dev');
|
|
@@ -250,7 +249,7 @@ describe('sync-docs --agents', () => {
|
|
|
250
249
|
fs.mkdirSync(path.join(testDir, '.harness'), { recursive: true });
|
|
251
250
|
fs.writeFileSync(path.join(testDir, '.harness', 'CONTEXT.md'), '# 模块上下文\n\n## src\n\n职责:夹具\n');
|
|
252
251
|
|
|
253
|
-
await syncDocs({ projectPath: testDir, agents: true });
|
|
252
|
+
await syncDocs({ projectPath: testDir, agents: true }, io);
|
|
254
253
|
|
|
255
254
|
const content = fs.readFileSync(path.join(testDir, 'AGENTS.md'), 'utf-8');
|
|
256
255
|
expect(content).toContain('模块上下文正本:`.harness/CONTEXT.md`(模块锚点组织),改动代码时同步更新');
|
|
@@ -260,9 +259,9 @@ describe('sync-docs --agents', () => {
|
|
|
260
259
|
expect(content).toContain('项目知识库,用 `harness knowledge` 查询');
|
|
261
260
|
|
|
262
261
|
// 幂等 + --check 通过(正本模型下无漂移)
|
|
263
|
-
const second = await syncDocs({ projectPath: testDir, agents: true });
|
|
264
|
-
expect(second).
|
|
265
|
-
expect(await syncDocs({ projectPath: testDir, agents: true, check: true })).
|
|
262
|
+
const second = await syncDocs({ projectPath: testDir, agents: true }, io);
|
|
263
|
+
expect(second).toEqual({ kind: 'ok' });
|
|
264
|
+
expect(await syncDocs({ projectPath: testDir, agents: true, check: true }, io)).toEqual({ kind: 'ok' });
|
|
266
265
|
|
|
267
266
|
fs.rmSync(testDir, { recursive: true, force: true });
|
|
268
267
|
});
|
|
@@ -272,7 +271,7 @@ describe('sync-docs --agents', () => {
|
|
|
272
271
|
createFixture(legacyDir, { pnpm: true, withCapabilities: true });
|
|
273
272
|
fs.mkdirSync(path.join(legacyDir, '.studio'), { recursive: true });
|
|
274
273
|
fs.writeFileSync(path.join(legacyDir, '.studio', 'CONTEXT.md'), '# 模块上下文\n\n## src\n\n职责:夹具\n');
|
|
275
|
-
await syncDocs({ projectPath: legacyDir, agents: true });
|
|
274
|
+
await syncDocs({ projectPath: legacyDir, agents: true }, io);
|
|
276
275
|
expect(fs.readFileSync(path.join(legacyDir, 'AGENTS.md'), 'utf-8'))
|
|
277
276
|
.toContain('模块上下文正本:`.studio/CONTEXT.md`(模块锚点组织),改动代码时同步更新');
|
|
278
277
|
fs.rmSync(legacyDir, { recursive: true, force: true });
|
|
@@ -283,7 +282,7 @@ describe('sync-docs --agents', () => {
|
|
|
283
282
|
fs.writeFileSync(path.join(bothDir, '.studio', 'CONTEXT.md'), '# 旧\n');
|
|
284
283
|
fs.mkdirSync(path.join(bothDir, '.harness'), { recursive: true });
|
|
285
284
|
fs.writeFileSync(path.join(bothDir, '.harness', 'CONTEXT.md'), '# 新\n');
|
|
286
|
-
await syncDocs({ projectPath: bothDir, agents: true });
|
|
285
|
+
await syncDocs({ projectPath: bothDir, agents: true }, io);
|
|
287
286
|
const content = fs.readFileSync(path.join(bothDir, 'AGENTS.md'), 'utf-8');
|
|
288
287
|
expect(content).toContain('模块上下文正本:`.harness/CONTEXT.md`');
|
|
289
288
|
expect(content).not.toContain('.studio/CONTEXT.md');
|
|
@@ -294,13 +293,13 @@ describe('sync-docs --agents', () => {
|
|
|
294
293
|
const testDir = path.join(tempDir, 'scattered-context-model');
|
|
295
294
|
createFixture(testDir, { pnpm: true, withCapabilities: true });
|
|
296
295
|
|
|
297
|
-
await syncDocs({ projectPath: testDir, agents: true });
|
|
296
|
+
await syncDocs({ projectPath: testDir, agents: true }, io);
|
|
298
297
|
|
|
299
298
|
const content = fs.readFileSync(path.join(testDir, 'AGENTS.md'), 'utf-8');
|
|
300
299
|
expect(content).toContain('各源码目录的 `CONTEXT.md` 是权威模块文档(现有 1 个),改动代码时同步更新');
|
|
301
300
|
expect(content).not.toContain('模块上下文正本');
|
|
302
301
|
|
|
303
|
-
expect(await syncDocs({ projectPath: testDir, agents: true, check: true })).
|
|
302
|
+
expect(await syncDocs({ projectPath: testDir, agents: true, check: true }, io)).toEqual({ kind: 'ok' });
|
|
304
303
|
|
|
305
304
|
fs.rmSync(testDir, { recursive: true, force: true });
|
|
306
305
|
});
|
|
@@ -310,7 +309,7 @@ describe('sync-docs --agents', () => {
|
|
|
310
309
|
createFixture(testDir, { pnpm: true, withCapabilities: true });
|
|
311
310
|
fs.mkdirSync(path.join(testDir, '.harness', 'CONTEXT.md'), { recursive: true });
|
|
312
311
|
|
|
313
|
-
await syncDocs({ projectPath: testDir, agents: true });
|
|
312
|
+
await syncDocs({ projectPath: testDir, agents: true }, io);
|
|
314
313
|
|
|
315
314
|
const content = fs.readFileSync(path.join(testDir, 'AGENTS.md'), 'utf-8');
|
|
316
315
|
expect(content).toContain('各源码目录的 `CONTEXT.md` 是权威模块文档');
|
|
@@ -328,8 +327,8 @@ describe('sync-docs --agents', () => {
|
|
|
328
327
|
fs.mkdirSync(path.join(testDir, '.next'), { recursive: true });
|
|
329
328
|
fs.mkdirSync(path.join(testDir, '.vscode'), { recursive: true });
|
|
330
329
|
|
|
331
|
-
const result = await syncDocs({ projectPath: testDir, agents: true });
|
|
332
|
-
expect(result).
|
|
330
|
+
const result = await syncDocs({ projectPath: testDir, agents: true }, io);
|
|
331
|
+
expect(result).toEqual({ kind: 'ok' }); // AGENTS.md 缺失 → 有问题,但已生成
|
|
333
332
|
|
|
334
333
|
const content = fs.readFileSync(path.join(testDir, 'AGENTS.md'), 'utf-8');
|
|
335
334
|
// 项目名回退到目录名,无 description
|
|
@@ -359,8 +358,8 @@ describe('sync-docs --agents', () => {
|
|
|
359
358
|
'',
|
|
360
359
|
].join('\n'));
|
|
361
360
|
|
|
362
|
-
const result = await syncDocs({ projectPath: testDir, agents: true });
|
|
363
|
-
expect(result).
|
|
361
|
+
const result = await syncDocs({ projectPath: testDir, agents: true }, io);
|
|
362
|
+
expect(result).toEqual({ kind: 'ok' });
|
|
364
363
|
|
|
365
364
|
// src 目录不存在:扫描/统计静默跳过,不中断生成
|
|
366
365
|
const content = fs.readFileSync(path.join(testDir, 'AGENTS.md'), 'utf-8');
|
|
@@ -397,8 +396,8 @@ describe('sync-docs --agents', () => {
|
|
|
397
396
|
scripts: { test: 'jest' },
|
|
398
397
|
}));
|
|
399
398
|
|
|
400
|
-
const result = await syncDocs({ projectPath: testDir, agents: true });
|
|
401
|
-
expect(result).
|
|
399
|
+
const result = await syncDocs({ projectPath: testDir, agents: true }, io);
|
|
400
|
+
expect(result).toEqual({ kind: 'ok' }); // CAPABILITIES.md/AGENTS.md 缺失 → 已生成
|
|
402
401
|
|
|
403
402
|
const content = fs.readFileSync(path.join(testDir, 'AGENTS.md'), 'utf-8');
|
|
404
403
|
expect(content).toContain('| `apps/` | monorepo 应用:api、web |');
|
|
@@ -419,7 +418,7 @@ describe('sync-docs --agents', () => {
|
|
|
419
418
|
createFixture(testDir, { withCapabilities: true });
|
|
420
419
|
fs.writeFileSync(path.join(testDir, 'CLAUDE.md'), '# CLAUDE.md\n\n## Governance Rules\n\n(尚未配置约束)\n');
|
|
421
420
|
|
|
422
|
-
await syncDocs({ projectPath: testDir, agents: true });
|
|
421
|
+
await syncDocs({ projectPath: testDir, agents: true }, io);
|
|
423
422
|
|
|
424
423
|
const content = fs.readFileSync(path.join(testDir, 'AGENTS.md'), 'utf-8');
|
|
425
424
|
expect(content).toContain('Governance Rules 块');
|
|
@@ -432,12 +431,12 @@ describe('sync-docs --agents', () => {
|
|
|
432
431
|
const testDir = path.join(tempDir, 'json-idempotent');
|
|
433
432
|
createFixture(testDir, { pnpm: true, withCapabilities: true });
|
|
434
433
|
|
|
435
|
-
await syncDocs({ projectPath: testDir, agents: true });
|
|
434
|
+
await syncDocs({ projectPath: testDir, agents: true }, io);
|
|
436
435
|
|
|
437
|
-
const result = await syncDocs({ projectPath: testDir, agents: true, json: true });
|
|
438
|
-
expect(result).
|
|
436
|
+
const result = await syncDocs({ projectPath: testDir, agents: true, json: true }, io);
|
|
437
|
+
expect(result).toEqual({ kind: 'ok' });
|
|
439
438
|
|
|
440
|
-
const jsonCall =
|
|
439
|
+
const jsonCall = io.outRecords().map(chunk => [chunk] as string[]).find(
|
|
441
440
|
(call: unknown[]) => typeof call[0] === 'string' && call[0].startsWith('{')
|
|
442
441
|
);
|
|
443
442
|
expect(jsonCall).toBeDefined();
|
|
@@ -475,9 +474,9 @@ describe('sync-docs --agents', () => {
|
|
|
475
474
|
fs.utimesSync(path.join(testDir, 'src', 'modules', 'CONTEXT.md'), past, past);
|
|
476
475
|
|
|
477
476
|
// json 模式:结构化输出缺失/过时
|
|
478
|
-
const jsonResult = await syncDocs({ projectPath: testDir, agents: true, check: true, json: true });
|
|
479
|
-
expect(jsonResult).
|
|
480
|
-
const jsonCall =
|
|
477
|
+
const jsonResult = await syncDocs({ projectPath: testDir, agents: true, check: true, json: true }, io);
|
|
478
|
+
expect(jsonResult).toEqual({ kind: 'fail', reason: expect.stringContaining('文档不是最新') });
|
|
479
|
+
const jsonCall = io.outRecords().map(chunk => [chunk] as string[]).find(
|
|
481
480
|
(call: unknown[]) => typeof call[0] === 'string' && call[0].startsWith('{')
|
|
482
481
|
);
|
|
483
482
|
expect(jsonCall).toBeDefined();
|
|
@@ -491,11 +490,11 @@ describe('sync-docs --agents', () => {
|
|
|
491
490
|
expect(parsed.agentsMd).toEqual({ file: 'AGENTS.md', exists: false, stale: true });
|
|
492
491
|
|
|
493
492
|
// 人读模式:输出过时提示
|
|
494
|
-
|
|
495
|
-
const humanResult = await syncDocs({ projectPath: testDir, agents: true, check: true });
|
|
496
|
-
expect(humanResult).
|
|
497
|
-
expect(
|
|
498
|
-
expect(
|
|
493
|
+
io = captureIO();
|
|
494
|
+
const humanResult = await syncDocs({ projectPath: testDir, agents: true, check: true }, io);
|
|
495
|
+
expect(humanResult).toEqual({ kind: 'fail', reason: expect.stringContaining('文档不是最新') });
|
|
496
|
+
expect(io.outText()).toContain('可能过时');
|
|
497
|
+
expect(io.outText()).toContain('缺少 CONTEXT.md');
|
|
499
498
|
|
|
500
499
|
fs.rmSync(testDir, { recursive: true, force: true });
|
|
501
500
|
});
|
|
@@ -517,18 +516,18 @@ describe('sync-docs --agents', () => {
|
|
|
517
516
|
const testDir = path.join(tempDir, 'preserve-basic');
|
|
518
517
|
createFixture(testDir, { pnpm: true, withCapabilities: true });
|
|
519
518
|
|
|
520
|
-
await syncDocs({ projectPath: testDir, agents: true });
|
|
519
|
+
await syncDocs({ projectPath: testDir, agents: true }, io);
|
|
521
520
|
appendBlock(testDir, MANUAL_BLOCK);
|
|
522
521
|
|
|
523
522
|
// 追加块后构成漂移 → 写入模式重组:生成部分 + PRESERVE 块
|
|
524
|
-
await syncDocs({ projectPath: testDir, agents: true });
|
|
523
|
+
await syncDocs({ projectPath: testDir, agents: true }, io);
|
|
525
524
|
const content = fs.readFileSync(path.join(testDir, 'AGENTS.md'), 'utf-8');
|
|
526
525
|
expect(content).toContain(MANUAL_BLOCK);
|
|
527
526
|
// 块位于生成内容之后
|
|
528
527
|
expect(content.indexOf('## 知识入口')).toBeLessThan(content.indexOf('<!-- PRESERVE:manual -->'));
|
|
529
528
|
|
|
530
529
|
// 重组后幂等:--check 通过
|
|
531
|
-
expect(await syncDocs({ projectPath: testDir, agents: true, check: true })).
|
|
530
|
+
expect(await syncDocs({ projectPath: testDir, agents: true, check: true }, io)).toEqual({ kind: 'ok' });
|
|
532
531
|
|
|
533
532
|
fs.rmSync(testDir, { recursive: true, force: true });
|
|
534
533
|
});
|
|
@@ -537,10 +536,10 @@ describe('sync-docs --agents', () => {
|
|
|
537
536
|
const testDir = path.join(tempDir, 'preserve-order');
|
|
538
537
|
createFixture(testDir, { pnpm: true, withCapabilities: true });
|
|
539
538
|
|
|
540
|
-
await syncDocs({ projectPath: testDir, agents: true });
|
|
539
|
+
await syncDocs({ projectPath: testDir, agents: true }, io);
|
|
541
540
|
appendBlock(testDir, '<!-- PRESERVE:one -->\n第一块\n<!-- /PRESERVE:one -->');
|
|
542
541
|
appendBlock(testDir, '<!-- PRESERVE:two -->\n第二块\n<!-- /PRESERVE:two -->');
|
|
543
|
-
await syncDocs({ projectPath: testDir, agents: true });
|
|
542
|
+
await syncDocs({ projectPath: testDir, agents: true }, io);
|
|
544
543
|
|
|
545
544
|
const content = fs.readFileSync(path.join(testDir, 'AGENTS.md'), 'utf-8');
|
|
546
545
|
expect(content.indexOf('PRESERVE:one')).toBeLessThan(content.indexOf('PRESERVE:two'));
|
|
@@ -554,20 +553,20 @@ describe('sync-docs --agents', () => {
|
|
|
554
553
|
const testDir = path.join(tempDir, 'preserve-drift');
|
|
555
554
|
createFixture(testDir, { pnpm: true, withCapabilities: true });
|
|
556
555
|
|
|
557
|
-
await syncDocs({ projectPath: testDir, agents: true });
|
|
556
|
+
await syncDocs({ projectPath: testDir, agents: true }, io);
|
|
558
557
|
appendBlock(testDir, MANUAL_BLOCK);
|
|
559
|
-
await syncDocs({ projectPath: testDir, agents: true }); // 重组为规范形态
|
|
558
|
+
await syncDocs({ projectPath: testDir, agents: true }, io); // 重组为规范形态
|
|
560
559
|
|
|
561
560
|
// 块内手改 → 不报漂移
|
|
562
561
|
const agentsPath = path.join(testDir, 'AGENTS.md');
|
|
563
562
|
const edited = fs.readFileSync(agentsPath, 'utf-8').replace('使用者自有内容', '改过的内容');
|
|
564
563
|
fs.writeFileSync(agentsPath, edited);
|
|
565
|
-
expect(await syncDocs({ projectPath: testDir, agents: true, check: true })).
|
|
564
|
+
expect(await syncDocs({ projectPath: testDir, agents: true, check: true }, io)).toEqual({ kind: 'ok' });
|
|
566
565
|
|
|
567
566
|
// 块外手改(生成部分) → 报漂移;重生成后块仍在、块外改动被还原
|
|
568
567
|
fs.appendFileSync(agentsPath, '\n块外手动追加\n');
|
|
569
|
-
expect(await syncDocs({ projectPath: testDir, agents: true, check: true })).
|
|
570
|
-
await syncDocs({ projectPath: testDir, agents: true });
|
|
568
|
+
expect(await syncDocs({ projectPath: testDir, agents: true, check: true }, io)).toEqual({ kind: 'fail', reason: expect.stringContaining('文档不是最新') });
|
|
569
|
+
await syncDocs({ projectPath: testDir, agents: true }, io);
|
|
571
570
|
const regenerated = fs.readFileSync(agentsPath, 'utf-8');
|
|
572
571
|
expect(regenerated).toContain('改过的内容');
|
|
573
572
|
expect(regenerated).not.toContain('块外手动追加');
|
|
@@ -579,11 +578,11 @@ describe('sync-docs --agents', () => {
|
|
|
579
578
|
const testDir = path.join(tempDir, 'preserve-malformed');
|
|
580
579
|
createFixture(testDir, { pnpm: true, withCapabilities: true });
|
|
581
580
|
|
|
582
|
-
await syncDocs({ projectPath: testDir, agents: true });
|
|
581
|
+
await syncDocs({ projectPath: testDir, agents: true }, io);
|
|
583
582
|
appendBlock(testDir, '<!-- PRESERVE:broken -->\n没有结束标记');
|
|
584
|
-
await syncDocs({ projectPath: testDir, agents: true });
|
|
583
|
+
await syncDocs({ projectPath: testDir, agents: true }, io);
|
|
585
584
|
|
|
586
|
-
expect(
|
|
585
|
+
expect(io.outText()).toContain('未闭合');
|
|
587
586
|
const content = fs.readFileSync(path.join(testDir, 'AGENTS.md'), 'utf-8');
|
|
588
587
|
expect(content).not.toContain('PRESERVE:broken');
|
|
589
588
|
expect(content).not.toContain('没有结束标记');
|
|
@@ -595,9 +594,9 @@ describe('sync-docs --agents', () => {
|
|
|
595
594
|
const testDir = path.join(tempDir, 'preserve-repo-change');
|
|
596
595
|
createFixture(testDir, { pnpm: true, withCapabilities: true });
|
|
597
596
|
|
|
598
|
-
await syncDocs({ projectPath: testDir, agents: true });
|
|
597
|
+
await syncDocs({ projectPath: testDir, agents: true }, io);
|
|
599
598
|
appendBlock(testDir, MANUAL_BLOCK);
|
|
600
|
-
await syncDocs({ projectPath: testDir, agents: true });
|
|
599
|
+
await syncDocs({ projectPath: testDir, agents: true }, io);
|
|
601
600
|
|
|
602
601
|
// package.json 删除一个 curated 脚本 → 生成部分变化
|
|
603
602
|
const pkgPath = path.join(testDir, 'package.json');
|
|
@@ -605,13 +604,13 @@ describe('sync-docs --agents', () => {
|
|
|
605
604
|
delete pkg.scripts.lint;
|
|
606
605
|
fs.writeFileSync(pkgPath, JSON.stringify(pkg, null, 2));
|
|
607
606
|
|
|
608
|
-
expect(await syncDocs({ projectPath: testDir, agents: true, check: true })).
|
|
609
|
-
await syncDocs({ projectPath: testDir, agents: true });
|
|
607
|
+
expect(await syncDocs({ projectPath: testDir, agents: true, check: true }, io)).toEqual({ kind: 'fail', reason: expect.stringContaining('文档不是最新') });
|
|
608
|
+
await syncDocs({ projectPath: testDir, agents: true }, io);
|
|
610
609
|
|
|
611
610
|
const content = fs.readFileSync(path.join(testDir, 'AGENTS.md'), 'utf-8');
|
|
612
611
|
expect(content).not.toContain('pnpm lint');
|
|
613
612
|
expect(content).toContain(MANUAL_BLOCK);
|
|
614
|
-
expect(await syncDocs({ projectPath: testDir, agents: true, check: true })).
|
|
613
|
+
expect(await syncDocs({ projectPath: testDir, agents: true, check: true }, io)).toEqual({ kind: 'ok' });
|
|
615
614
|
|
|
616
615
|
fs.rmSync(testDir, { recursive: true, force: true });
|
|
617
616
|
});
|
|
@@ -630,16 +629,16 @@ describe('sync-docs --agents', () => {
|
|
|
630
629
|
'<!-- /PRESERVE:governance -->',
|
|
631
630
|
].join('\n');
|
|
632
631
|
|
|
633
|
-
await syncDocs({ projectPath: testDir, agents: true });
|
|
632
|
+
await syncDocs({ projectPath: testDir, agents: true }, io);
|
|
634
633
|
appendBlock(testDir, GOVERNANCE_BLOCK);
|
|
635
|
-
await syncDocs({ projectPath: testDir, agents: true });
|
|
634
|
+
await syncDocs({ projectPath: testDir, agents: true }, io);
|
|
636
635
|
|
|
637
636
|
const content = fs.readFileSync(path.join(testDir, 'AGENTS.md'), 'utf-8');
|
|
638
637
|
expect(content).toContain(GOVERNANCE_BLOCK);
|
|
639
638
|
|
|
640
639
|
// 幂等 + --check 通过(块内含 HARNESS_CONSTRAINTS 标记不影响漂移比对)
|
|
641
|
-
expect(await syncDocs({ projectPath: testDir, agents: true })).
|
|
642
|
-
expect(await syncDocs({ projectPath: testDir, agents: true, check: true })).
|
|
640
|
+
expect(await syncDocs({ projectPath: testDir, agents: true }, io)).toEqual({ kind: 'ok' });
|
|
641
|
+
expect(await syncDocs({ projectPath: testDir, agents: true, check: true }, io)).toEqual({ kind: 'ok' });
|
|
643
642
|
|
|
644
643
|
fs.rmSync(testDir, { recursive: true, force: true });
|
|
645
644
|
});
|