@dommaker/harness 1.7.0 → 1.8.1
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 +44 -0
- package/bin/harness.js +17 -1
- package/dist/agents/index.d.ts +6 -2
- package/dist/agents/index.d.ts.map +1 -1
- package/dist/agents/index.js +6 -16
- package/dist/agents/index.js.map +1 -1
- package/dist/cli/commands/__tests__/gate-decision.d.ts +18 -0
- package/dist/cli/commands/__tests__/gate-decision.d.ts.map +1 -0
- package/dist/cli/commands/__tests__/gate-decision.js +26 -0
- package/dist/cli/commands/__tests__/gate-decision.js.map +1 -0
- package/dist/cli/commands/acceptance.d.ts.map +1 -1
- package/dist/cli/commands/acceptance.js +17 -28
- package/dist/cli/commands/acceptance.js.map +1 -1
- package/dist/cli/commands/check.d.ts +19 -3
- package/dist/cli/commands/check.d.ts.map +1 -1
- package/dist/cli/commands/check.js +36 -22
- package/dist/cli/commands/check.js.map +1 -1
- package/dist/cli/commands/command.d.ts +0 -1
- package/dist/cli/commands/command.d.ts.map +1 -1
- package/dist/cli/commands/command.js +8 -6
- package/dist/cli/commands/command.js.map +1 -1
- package/dist/cli/commands/constraints-retire.d.ts.map +1 -1
- package/dist/cli/commands/constraints-retire.js +36 -57
- package/dist/cli/commands/constraints-retire.js.map +1 -1
- package/dist/cli/commands/contract.d.ts.map +1 -1
- package/dist/cli/commands/contract.js +36 -42
- package/dist/cli/commands/contract.js.map +1 -1
- package/dist/cli/commands/definitions.d.ts +2 -0
- package/dist/cli/commands/definitions.d.ts.map +1 -1
- package/dist/cli/commands/definitions.js +11 -6
- package/dist/cli/commands/definitions.js.map +1 -1
- package/dist/cli/commands/failure.d.ts.map +1 -1
- package/dist/cli/commands/failure.js +16 -2
- package/dist/cli/commands/failure.js.map +1 -1
- package/dist/cli/commands/init.d.ts +14 -8
- package/dist/cli/commands/init.d.ts.map +1 -1
- package/dist/cli/commands/init.js +172 -364
- package/dist/cli/commands/init.js.map +1 -1
- package/dist/cli/commands/knowledge-view.d.ts +90 -0
- package/dist/cli/commands/knowledge-view.d.ts.map +1 -0
- package/dist/cli/commands/knowledge-view.js +198 -0
- package/dist/cli/commands/knowledge-view.js.map +1 -0
- package/dist/cli/commands/knowledge.d.ts +137 -52
- package/dist/cli/commands/knowledge.d.ts.map +1 -1
- package/dist/cli/commands/knowledge.js +534 -400
- package/dist/cli/commands/knowledge.js.map +1 -1
- package/dist/cli/commands/passes-gate.d.ts +4 -1
- package/dist/cli/commands/passes-gate.d.ts.map +1 -1
- package/dist/cli/commands/passes-gate.js +11 -2
- package/dist/cli/commands/passes-gate.js.map +1 -1
- package/dist/cli/commands/performance.d.ts.map +1 -1
- package/dist/cli/commands/performance.js +19 -31
- package/dist/cli/commands/performance.js.map +1 -1
- package/dist/cli/commands/report.d.ts.map +1 -1
- package/dist/cli/commands/report.js +2 -1
- package/dist/cli/commands/report.js.map +1 -1
- package/dist/cli/commands/review.d.ts.map +1 -1
- package/dist/cli/commands/review.js +13 -25
- package/dist/cli/commands/review.js.map +1 -1
- package/dist/cli/commands/scaffold-templates.d.ts +73 -0
- package/dist/cli/commands/scaffold-templates.d.ts.map +1 -0
- package/dist/cli/commands/scaffold-templates.js +424 -0
- package/dist/cli/commands/scaffold-templates.js.map +1 -0
- package/dist/cli/commands/scaffold.d.ts +105 -0
- package/dist/cli/commands/scaffold.d.ts.map +1 -0
- package/dist/cli/commands/scaffold.js +263 -0
- package/dist/cli/commands/scaffold.js.map +1 -0
- package/dist/cli/commands/security.d.ts.map +1 -1
- package/dist/cli/commands/security.js +22 -24
- package/dist/cli/commands/security.js.map +1 -1
- package/dist/cli/commands/spec-baseline-check.d.ts +43 -0
- package/dist/cli/commands/spec-baseline-check.d.ts.map +1 -1
- package/dist/cli/commands/spec-baseline-check.js +109 -34
- package/dist/cli/commands/spec-baseline-check.js.map +1 -1
- package/dist/cli/commands/status.d.ts +8 -0
- package/dist/cli/commands/status.d.ts.map +1 -1
- package/dist/cli/commands/status.js +5 -7
- package/dist/cli/commands/status.js.map +1 -1
- package/dist/cli/commands/sync-docs/context-syncer.d.ts +21 -2
- package/dist/cli/commands/sync-docs/context-syncer.d.ts.map +1 -1
- package/dist/cli/commands/sync-docs/context-syncer.js +112 -28
- package/dist/cli/commands/sync-docs/context-syncer.js.map +1 -1
- package/dist/cli/commands/sync-docs/index.d.ts +1 -1
- package/dist/cli/commands/sync-docs/index.d.ts.map +1 -1
- package/dist/cli/commands/sync-docs/index.js +86 -27
- package/dist/cli/commands/sync-docs/index.js.map +1 -1
- package/dist/cli/commands/sync-docs/project-reader.d.ts +24 -1
- package/dist/cli/commands/sync-docs/project-reader.d.ts.map +1 -1
- package/dist/cli/commands/sync-docs/project-reader.js +33 -7
- package/dist/cli/commands/sync-docs/project-reader.js.map +1 -1
- package/dist/cli/commands/validate.d.ts +0 -16
- package/dist/cli/commands/validate.d.ts.map +1 -1
- package/dist/cli/commands/validate.js +2 -97
- package/dist/cli/commands/validate.js.map +1 -1
- package/dist/cli/gate-command.d.ts +37 -0
- package/dist/cli/gate-command.d.ts.map +1 -0
- package/dist/cli/gate-command.js +64 -0
- package/dist/cli/gate-command.js.map +1 -0
- package/dist/cli/state-io.d.ts +34 -0
- package/dist/cli/state-io.d.ts.map +1 -0
- package/dist/cli/state-io.js +71 -0
- package/dist/cli/state-io.js.map +1 -0
- package/dist/completion-checkers/index.d.ts +1 -1
- package/dist/completion-checkers/index.d.ts.map +1 -1
- package/dist/completion-checkers/index.js +0 -15
- package/dist/completion-checkers/index.js.map +1 -1
- package/dist/context/knowledge-injector.d.ts +4 -2
- package/dist/context/knowledge-injector.d.ts.map +1 -1
- package/dist/context/knowledge-injector.js +13 -6
- package/dist/context/knowledge-injector.js.map +1 -1
- package/dist/core/constraints/agent-prompt-renderer.js +2 -2
- package/dist/core/constraints/agent-prompt-renderer.js.map +1 -1
- package/dist/core/constraints/capabilities-reconcile.d.ts +20 -0
- package/dist/core/constraints/capabilities-reconcile.d.ts.map +1 -1
- package/dist/core/constraints/capabilities-reconcile.js +26 -4
- package/dist/core/constraints/capabilities-reconcile.js.map +1 -1
- package/dist/core/constraints/check-cache.d.ts +1 -1
- package/dist/core/constraints/check-cache.js +1 -1
- package/dist/core/constraints/checker.d.ts +8 -3
- package/dist/core/constraints/checker.d.ts.map +1 -1
- package/dist/core/constraints/checker.js +30 -19
- package/dist/core/constraints/checker.js.map +1 -1
- package/dist/core/constraints/checkers/capability-sync.d.ts +3 -1
- package/dist/core/constraints/checkers/capability-sync.d.ts.map +1 -1
- package/dist/core/constraints/checkers/capability-sync.js +17 -24
- package/dist/core/constraints/checkers/capability-sync.js.map +1 -1
- package/dist/core/constraints/checkers/context-doc-sync.d.ts +1 -1
- package/dist/core/constraints/checkers/context-doc-sync.d.ts.map +1 -1
- package/dist/core/constraints/checkers/context-doc-sync.js +9 -6
- 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 +24 -30
- package/dist/core/constraints/checkers/docs-freshness.js.map +1 -1
- package/dist/core/constraints/checkers/governance-presence.d.ts.map +1 -1
- package/dist/core/constraints/checkers/governance-presence.js +10 -4
- package/dist/core/constraints/checkers/governance-presence.js.map +1 -1
- package/dist/core/constraints/checkers/types.d.ts +10 -6
- package/dist/core/constraints/checkers/types.d.ts.map +1 -1
- package/dist/core/constraints/checkers/types.js +7 -3
- package/dist/core/constraints/checkers/types.js.map +1 -1
- package/dist/core/constraints/context-builder.d.ts +11 -10
- package/dist/core/constraints/context-builder.d.ts.map +1 -1
- package/dist/core/constraints/context-builder.js +31 -27
- package/dist/core/constraints/context-builder.js.map +1 -1
- package/dist/core/constraints/context-reconcile.d.ts +75 -0
- package/dist/core/constraints/context-reconcile.d.ts.map +1 -0
- package/dist/core/constraints/context-reconcile.js +161 -0
- package/dist/core/constraints/context-reconcile.js.map +1 -0
- package/dist/core/constraints/doc-freshness/runner.d.ts +7 -0
- package/dist/core/constraints/doc-freshness/runner.d.ts.map +1 -1
- package/dist/core/constraints/doc-freshness/runner.js +8 -3
- package/dist/core/constraints/doc-freshness/runner.js.map +1 -1
- package/dist/core/constraints/git-evidence.js +1 -1
- package/dist/core/constraints/git-evidence.js.map +1 -1
- package/dist/core/constraints/injection-drift.d.ts +7 -2
- package/dist/core/constraints/injection-drift.d.ts.map +1 -1
- package/dist/core/constraints/injection-drift.js +13 -7
- package/dist/core/constraints/injection-drift.js.map +1 -1
- package/dist/core/constraints/run-env.d.ts +92 -0
- package/dist/core/constraints/run-env.d.ts.map +1 -0
- package/dist/core/constraints/run-env.js +175 -0
- package/dist/core/constraints/run-env.js.map +1 -0
- package/dist/core/constraints/triggers.d.ts +22 -0
- package/dist/core/constraints/triggers.d.ts.map +1 -0
- package/dist/core/constraints/triggers.js +31 -0
- package/dist/core/constraints/triggers.js.map +1 -0
- package/dist/core/effective-constraints.d.ts +13 -4
- package/dist/core/effective-constraints.d.ts.map +1 -1
- package/dist/core/effective-constraints.js +16 -6
- package/dist/core/effective-constraints.js.map +1 -1
- package/dist/core/effective-set.d.ts +8 -15
- package/dist/core/effective-set.d.ts.map +1 -1
- package/dist/core/effective-set.js +7 -12
- package/dist/core/effective-set.js.map +1 -1
- package/dist/core/index.d.ts +1 -0
- package/dist/core/index.d.ts.map +1 -1
- package/dist/core/index.js.map +1 -1
- package/dist/core/project-config-loader.d.ts +39 -17
- package/dist/core/project-config-loader.d.ts.map +1 -1
- package/dist/core/project-config-loader.js +51 -122
- package/dist/core/project-config-loader.js.map +1 -1
- package/dist/core/validators/check-handlers/http.d.ts +2 -2
- package/dist/core/validators/check-handlers/http.d.ts.map +1 -1
- package/dist/core/validators/check-handlers/http.js +12 -7
- package/dist/core/validators/check-handlers/http.js.map +1 -1
- package/dist/failure/classifier.d.ts +1 -1
- package/dist/failure/classifier.d.ts.map +1 -1
- package/dist/failure/classifier.js +8 -8
- package/dist/failure/classifier.js.map +1 -1
- package/dist/failure/index.d.ts +2 -1
- package/dist/failure/index.d.ts.map +1 -1
- package/dist/failure/index.js +9 -17
- package/dist/failure/index.js.map +1 -1
- package/dist/failure/recorder.d.ts +1 -1
- package/dist/failure/recorder.d.ts.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 +3 -2
- package/dist/gates/checker-gate.js.map +1 -1
- package/dist/gates/command.d.ts +10 -4
- package/dist/gates/command.d.ts.map +1 -1
- package/dist/gates/command.js +36 -62
- package/dist/gates/command.js.map +1 -1
- package/dist/gates/contract.d.ts.map +1 -1
- package/dist/gates/contract.js +0 -4
- package/dist/gates/contract.js.map +1 -1
- package/dist/gates/definitions.d.ts +2 -1
- package/dist/gates/definitions.d.ts.map +1 -1
- package/dist/gates/definitions.js +6 -5
- package/dist/gates/definitions.js.map +1 -1
- package/dist/gates/index.d.ts +0 -4
- package/dist/gates/index.d.ts.map +1 -1
- package/dist/gates/index.js +1 -6
- package/dist/gates/index.js.map +1 -1
- package/dist/gates/performance.d.ts.map +1 -1
- package/dist/gates/performance.js +0 -4
- package/dist/gates/performance.js.map +1 -1
- package/dist/gates/runner.d.ts +1 -1
- package/dist/gates/runner.js +1 -1
- package/dist/gates/security.d.ts +1 -1
- package/dist/gates/security.d.ts.map +1 -1
- package/dist/gates/security.js +5 -6
- package/dist/gates/security.js.map +1 -1
- package/dist/gates/types.d.ts +14 -17
- package/dist/gates/types.d.ts.map +1 -1
- package/dist/gates/types.js.map +1 -1
- package/dist/hooks/bootstrap.d.ts +6 -4
- package/dist/hooks/bootstrap.d.ts.map +1 -1
- package/dist/hooks/bootstrap.js +25 -13
- package/dist/hooks/bootstrap.js.map +1 -1
- package/dist/hooks/config.d.ts +6 -2
- package/dist/hooks/config.d.ts.map +1 -1
- package/dist/hooks/config.js +5 -1
- package/dist/hooks/config.js.map +1 -1
- package/dist/hooks/index.d.ts +1 -1
- package/dist/hooks/index.d.ts.map +1 -1
- package/dist/hooks/index.js +0 -15
- package/dist/hooks/index.js.map +1 -1
- package/dist/hooks/pipeline.d.ts +19 -1
- package/dist/hooks/pipeline.d.ts.map +1 -1
- package/dist/hooks/pipeline.js +42 -4
- package/dist/hooks/pipeline.js.map +1 -1
- package/dist/hooks/registry.d.ts +11 -8
- package/dist/hooks/registry.d.ts.map +1 -1
- package/dist/hooks/registry.js +22 -7
- package/dist/hooks/registry.js.map +1 -1
- package/dist/hooks/types.d.ts +25 -7
- package/dist/hooks/types.d.ts.map +1 -1
- package/dist/index.d.ts +3 -3
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +3 -4
- package/dist/index.js.map +1 -1
- package/dist/knowledge/audit-scoring.d.ts +87 -0
- package/dist/knowledge/audit-scoring.d.ts.map +1 -0
- package/dist/knowledge/audit-scoring.js +470 -0
- package/dist/knowledge/audit-scoring.js.map +1 -0
- package/dist/knowledge/audit.d.ts +11 -59
- package/dist/knowledge/audit.d.ts.map +1 -1
- package/dist/knowledge/audit.js +47 -522
- package/dist/knowledge/audit.js.map +1 -1
- package/dist/knowledge/import.d.ts.map +1 -1
- package/dist/knowledge/import.js +2 -0
- package/dist/knowledge/import.js.map +1 -1
- package/dist/knowledge/index-generator.d.ts.map +1 -1
- package/dist/knowledge/index-generator.js +4 -5
- package/dist/knowledge/index-generator.js.map +1 -1
- package/dist/knowledge/index.d.ts +3 -2
- package/dist/knowledge/index.d.ts.map +1 -1
- package/dist/knowledge/index.js +3 -16
- package/dist/knowledge/index.js.map +1 -1
- package/dist/knowledge/ingest.js +1 -1
- package/dist/knowledge/ingest.js.map +1 -1
- package/dist/knowledge/lifecycle.d.ts.map +1 -1
- package/dist/knowledge/lifecycle.js +4 -2
- package/dist/knowledge/lifecycle.js.map +1 -1
- package/dist/knowledge/migration.d.ts +3 -0
- package/dist/knowledge/migration.d.ts.map +1 -1
- package/dist/knowledge/migration.js +8 -2
- package/dist/knowledge/migration.js.map +1 -1
- package/dist/knowledge/query.d.ts +6 -0
- package/dist/knowledge/query.d.ts.map +1 -1
- package/dist/knowledge/query.js +8 -2
- package/dist/knowledge/query.js.map +1 -1
- package/dist/knowledge/reference-tracker.d.ts.map +1 -1
- package/dist/knowledge/reference-tracker.js +4 -6
- package/dist/knowledge/reference-tracker.js.map +1 -1
- package/dist/knowledge/store.d.ts +22 -16
- package/dist/knowledge/store.d.ts.map +1 -1
- package/dist/knowledge/store.js +53 -12
- package/dist/knowledge/store.js.map +1 -1
- package/dist/knowledge/tree-walker.d.ts +19 -0
- package/dist/knowledge/tree-walker.d.ts.map +1 -0
- package/dist/knowledge/tree-walker.js +30 -0
- package/dist/knowledge/tree-walker.js.map +1 -0
- package/dist/knowledge/types.d.ts +16 -0
- package/dist/knowledge/types.d.ts.map +1 -1
- package/dist/monitoring/traces.d.ts +5 -3
- package/dist/monitoring/traces.d.ts.map +1 -1
- package/dist/monitoring/traces.js +19 -5
- package/dist/monitoring/traces.js.map +1 -1
- package/dist/test-setup/jsonl-fake-fs.d.ts +30 -0
- package/dist/test-setup/jsonl-fake-fs.d.ts.map +1 -0
- package/dist/test-setup/jsonl-fake-fs.js +49 -0
- package/dist/test-setup/jsonl-fake-fs.js.map +1 -0
- package/dist/tools/index.d.ts +4 -1
- package/dist/tools/index.d.ts.map +1 -1
- package/dist/tools/index.js +7 -15
- package/dist/tools/index.js.map +1 -1
- package/dist/types/checkpoint.d.ts +5 -0
- package/dist/types/checkpoint.d.ts.map +1 -1
- package/dist/types/project-config.d.ts +18 -0
- package/dist/types/project-config.d.ts.map +1 -1
- package/dist/types/trace.d.ts +13 -4
- package/dist/types/trace.d.ts.map +1 -1
- package/dist/types/trace.js +4 -3
- package/dist/types/trace.js.map +1 -1
- package/dist/utils/exec.d.ts +4 -27
- package/dist/utils/exec.d.ts.map +1 -1
- package/dist/utils/exec.js +4 -94
- package/dist/utils/exec.js.map +1 -1
- package/dist/utils/jsonl.d.ts +17 -7
- package/dist/utils/jsonl.d.ts.map +1 -1
- package/dist/utils/jsonl.js +144 -17
- package/dist/utils/jsonl.js.map +1 -1
- package/dist/utils/numeric-flag.d.ts +44 -0
- package/dist/utils/numeric-flag.d.ts.map +1 -0
- package/dist/utils/numeric-flag.js +62 -0
- package/dist/utils/numeric-flag.js.map +1 -0
- package/package.json +1 -1
- package/src/CONTEXT.md +5 -2
- package/src/__tests__/acceptance-gate.test.ts +7 -4
- package/src/__tests__/checker-extra.test.ts +3 -2
- package/src/__tests__/checker.test.ts +4 -3
- package/src/__tests__/checkpoint.test.ts +26 -9
- package/src/__tests__/context-files-resolution.test.ts +29 -15
- package/src/__tests__/contract-gate.test.ts +19 -40
- package/src/__tests__/error-classifier.test.ts +1 -1
- package/src/__tests__/exec.test.ts +45 -107
- package/src/__tests__/failure-recorder.test.ts +7 -5
- package/src/__tests__/hooks-pipeline.test.ts +34 -47
- package/src/__tests__/layering.test.ts +217 -25
- package/src/__tests__/passes-gate.test.ts +9 -4
- package/src/__tests__/performance-gate.test.ts +3 -15
- package/src/__tests__/project-config-loader-extra.test.ts +31 -57
- package/src/__tests__/project-config-loader.test.ts +6 -3
- package/src/__tests__/public-exports.test.ts +0 -1
- package/src/__tests__/public-type-surface.test.ts +5 -4
- package/src/__tests__/public-value-surface.test.ts +182 -0
- package/src/__tests__/review-gate.test.ts +4 -6
- package/src/__tests__/security-gate.test.ts +5 -20
- package/src/__tests__/skip-semantics.test.ts +5 -3
- package/src/__tests__/spec-validator.test.ts +3 -2
- package/src/__tests__/sub-barrels-explicit.test.ts +87 -0
- package/src/__tests__/test-fixture-hygiene.test.ts +53 -0
- package/src/__tests__/trace-analyzer-extra.test.ts +5 -3
- package/src/__tests__/trace-analyzer.test.ts +5 -3
- package/src/__tests__/trace-collector.test.ts +5 -3
- package/src/agents/index.ts +13 -2
- package/src/cli/__tests__/gate-command.test.ts +162 -0
- package/src/cli/__tests__/state-io.test.ts +50 -0
- package/src/cli/commands/CONTEXT.md +30 -5
- package/src/cli/commands/__tests__/acceptance.test.ts +24 -25
- package/src/cli/commands/__tests__/bin-exit-mapping.test.ts +15 -0
- package/src/cli/commands/__tests__/check-drift.test.ts +42 -1
- package/src/cli/commands/__tests__/check-read-count.test.ts +170 -0
- package/src/cli/commands/__tests__/check-skip-output.test.ts +4 -1
- package/src/cli/commands/__tests__/check.test.ts +63 -44
- package/src/cli/commands/__tests__/command-gate-dead-options.test.ts +60 -0
- package/src/cli/commands/__tests__/command.test.ts +33 -17
- package/src/cli/commands/__tests__/constraints-retire.test.ts +52 -0
- package/src/cli/commands/__tests__/context-syncer.test.ts +141 -0
- package/src/cli/commands/__tests__/contract.test.ts +20 -20
- package/src/cli/commands/__tests__/failure.test.ts +5 -4
- package/src/cli/commands/__tests__/gate-decision.ts +30 -0
- package/src/cli/commands/__tests__/init-dead-options.test.ts +50 -0
- package/src/cli/commands/__tests__/init-governance-io.test.ts +139 -0
- package/src/cli/commands/__tests__/init-injection.test.ts +3 -3
- package/src/cli/commands/__tests__/init-ondisk.test.ts +867 -0
- package/src/cli/commands/__tests__/init.test.ts +82 -6
- package/src/cli/commands/__tests__/knowledge-audit-threshold.test.ts +146 -0
- package/src/cli/commands/__tests__/knowledge-flywheel-consistency.test.ts +1 -1
- package/src/cli/commands/__tests__/knowledge-tone-mapping.test.ts +244 -0
- package/src/cli/commands/__tests__/knowledge-view.test.ts +839 -0
- package/src/cli/commands/__tests__/knowledge.test.ts +33 -15
- package/src/cli/commands/__tests__/numeric-flag-assembly.test.ts +368 -0
- package/src/cli/commands/__tests__/performance.test.ts +19 -21
- package/src/cli/commands/__tests__/posteval-plan.test.ts +5 -3
- package/src/cli/commands/__tests__/pre-push-hook.test.ts +181 -0
- package/src/cli/commands/__tests__/project-path-anchoring.test.ts +95 -2
- package/src/cli/commands/__tests__/project-path-convention.test.ts +103 -25
- package/src/cli/commands/__tests__/registry.test.ts +2 -0
- package/src/cli/commands/__tests__/report.test.ts +23 -1
- package/src/cli/commands/__tests__/review.test.ts +10 -17
- package/src/cli/commands/__tests__/scaffold.test.ts +505 -0
- package/src/cli/commands/__tests__/security-default-scan.test.ts +75 -0
- package/src/cli/commands/__tests__/security.test.ts +21 -24
- package/src/cli/commands/__tests__/spec-baseline-check.test.ts +3 -2
- package/src/cli/commands/__tests__/spec-baseline-index-cap.test.ts +131 -0
- package/src/cli/commands/__tests__/spec-baseline-read-count.test.ts +325 -0
- package/src/cli/commands/__tests__/status-extra.test.ts +25 -8
- package/src/cli/commands/__tests__/status.test.ts +46 -18
- package/src/cli/commands/__tests__/sync-docs-agents.test.ts +19 -4
- package/src/cli/commands/__tests__/sync-docs-context-drift.test.ts +232 -0
- package/src/cli/commands/__tests__/sync-docs-module-order.test.ts +111 -0
- package/src/cli/commands/__tests__/sync-docs-read-count.test.ts +192 -0
- package/src/cli/commands/__tests__/sync-docs.test.ts +3 -2
- package/src/cli/commands/__tests__/validate.test.ts +1 -48
- package/src/cli/commands/acceptance.ts +24 -29
- package/src/cli/commands/check.ts +60 -35
- package/src/cli/commands/command.ts +9 -8
- package/src/cli/commands/constraints-retire.ts +57 -70
- package/src/cli/commands/contract.ts +44 -47
- package/src/cli/commands/definitions.ts +12 -6
- package/src/cli/commands/failure.ts +16 -3
- package/src/cli/commands/init.ts +242 -389
- package/src/cli/commands/knowledge-view.ts +224 -0
- package/src/cli/commands/knowledge.ts +643 -448
- package/src/cli/commands/passes-gate.ts +12 -3
- package/src/cli/commands/performance.ts +31 -38
- package/src/cli/commands/report.ts +3 -2
- package/src/cli/commands/review.ts +22 -28
- package/src/cli/commands/scaffold-templates.ts +406 -0
- package/src/cli/commands/scaffold.ts +302 -0
- package/src/cli/commands/security.ts +27 -23
- package/src/cli/commands/spec-baseline-check.ts +158 -33
- package/src/cli/commands/status.ts +12 -7
- package/src/cli/commands/sync-docs/__tests__/context-export-surface.test.ts +102 -0
- package/src/cli/commands/sync-docs/__tests__/module-descriptions.test.ts +196 -0
- package/src/cli/commands/sync-docs/context-syncer.ts +137 -31
- package/src/cli/commands/sync-docs/index.ts +103 -28
- package/src/cli/commands/sync-docs/project-reader.ts +51 -7
- package/src/cli/commands/validate.ts +1 -104
- package/src/cli/gate-command.ts +87 -0
- package/src/cli/state-io.ts +53 -0
- package/src/completion-checkers/index.ts +10 -1
- package/src/context/CONTEXT.md +2 -1
- package/src/context/__tests__/knowledge-injector.test.ts +27 -0
- package/src/context/__tests__/session-manager.test.ts +19 -12
- package/src/context/knowledge-injector.ts +14 -7
- package/src/core/CONTEXT.md +10 -7
- package/src/core/__tests__/effective-set.test.ts +36 -60
- package/src/core/constraints/__tests__/context-reconcile.test.ts +246 -0
- package/src/core/constraints/__tests__/run-env.test.ts +377 -0
- package/src/core/constraints/__tests__/triggers.test.ts +70 -0
- package/src/core/constraints/agent-prompt-renderer.ts +1 -1
- package/src/core/constraints/capabilities-reconcile.ts +28 -4
- package/src/core/constraints/check-cache.ts +1 -1
- package/src/core/constraints/checker.ts +30 -14
- package/src/core/constraints/checkers/__tests__/context-doc-sync.test.ts +8 -3
- package/src/core/constraints/checkers/__tests__/governance-presence.test.ts +16 -7
- package/src/core/constraints/checkers/__tests__/no-hardcoded-credentials.test.ts +2 -1
- package/src/core/constraints/checkers/capability-sync.ts +27 -28
- package/src/core/constraints/checkers/context-doc-sync.ts +9 -7
- package/src/core/constraints/checkers/docs-freshness.ts +28 -33
- package/src/core/constraints/checkers/governance-presence.ts +10 -6
- package/src/core/constraints/checkers/types.ts +14 -8
- package/src/core/constraints/context-builder.ts +35 -26
- package/src/core/constraints/context-reconcile.ts +200 -0
- package/src/core/constraints/doc-freshness/__tests__/runner.test.ts +25 -0
- package/src/core/constraints/doc-freshness/runner.ts +18 -4
- package/src/core/constraints/git-evidence.ts +1 -1
- package/src/core/constraints/injection-drift.ts +19 -8
- package/src/core/constraints/run-env.ts +207 -0
- package/src/core/constraints/triggers.ts +33 -0
- package/src/core/effective-constraints.ts +17 -6
- package/src/core/effective-set.ts +8 -24
- package/src/core/index.ts +2 -0
- package/src/core/project-config-loader.ts +54 -102
- package/src/core/validators/__tests__/http-retry-sleep.test.ts +231 -0
- package/src/core/validators/check-handlers/http.ts +18 -7
- package/src/failure/CONTEXT.md +2 -1
- package/src/failure/classifier.ts +2 -2
- package/src/failure/index.ts +14 -2
- package/src/failure/recorder.ts +1 -1
- package/src/gates/CONTEXT.md +13 -7
- package/src/gates/__tests__/checker-gate.test.ts +1 -1
- package/src/gates/__tests__/command-single-predicate.test.ts +135 -0
- package/src/gates/__tests__/command.test.ts +8 -15
- package/src/gates/__tests__/contract.test.ts +5 -5
- package/src/gates/__tests__/gate-interface.test.ts +0 -17
- package/src/gates/__tests__/performance.test.ts +0 -13
- package/src/gates/__tests__/review.test.ts +0 -1
- package/src/gates/__tests__/runner.test.ts +1 -1
- package/src/gates/__tests__/security-default-scan.test.ts +97 -0
- package/src/gates/__tests__/security.test.ts +0 -13
- package/src/gates/checker-gate.ts +3 -2
- package/src/gates/command.ts +51 -74
- package/src/gates/contract.ts +0 -5
- package/src/gates/definitions.ts +6 -5
- package/src/gates/index.ts +0 -5
- package/src/gates/performance.ts +1 -6
- package/src/gates/runner.ts +1 -1
- package/src/gates/security.ts +9 -11
- package/src/gates/types.ts +20 -23
- package/src/hooks/CONTEXT.md +10 -9
- package/src/hooks/__tests__/bootstrap.test.ts +29 -6
- package/src/hooks/__tests__/pipeline.test.ts +133 -17
- package/src/hooks/__tests__/registry.test.ts +51 -3
- package/src/hooks/bootstrap.ts +35 -15
- package/src/hooks/config.ts +6 -2
- package/src/hooks/index.ts +10 -1
- package/src/hooks/pipeline.ts +51 -6
- package/src/hooks/registry.ts +31 -12
- package/src/hooks/types.ts +26 -7
- package/src/index.ts +1 -2
- package/src/knowledge/CONTEXT.md +14 -7
- package/src/knowledge/__tests__/audit-labels.test.ts +8 -5
- package/src/knowledge/__tests__/audit-scoring.test.ts +230 -0
- package/src/knowledge/__tests__/audit-write-count.test.ts +131 -0
- package/src/knowledge/__tests__/audit.test.ts +291 -208
- package/src/knowledge/__tests__/doctor.test.ts +3 -2
- package/src/knowledge/__tests__/ingest.test.ts +3 -2
- package/src/knowledge/__tests__/lifecycle.test.ts +57 -2
- package/src/knowledge/__tests__/migration.test.ts +35 -6
- package/src/knowledge/__tests__/query.test.ts +3 -2
- package/src/knowledge/__tests__/reference-tracker.test.ts +23 -2
- package/src/knowledge/__tests__/store.test.ts +149 -4
- package/src/knowledge/__tests__/tree-walker.test.ts +132 -0
- package/src/knowledge/audit-scoring.ts +589 -0
- package/src/knowledge/audit.ts +55 -599
- package/src/knowledge/import.ts +2 -0
- package/src/knowledge/index-generator.ts +4 -6
- package/src/knowledge/index.ts +27 -2
- package/src/knowledge/ingest.ts +1 -1
- package/src/knowledge/lifecycle.ts +5 -2
- package/src/knowledge/migration.ts +8 -2
- package/src/knowledge/query.ts +8 -1
- package/src/knowledge/reference-tracker.ts +5 -7
- package/src/knowledge/store.ts +75 -16
- package/src/knowledge/tree-walker.ts +29 -0
- package/src/knowledge/types.ts +19 -0
- package/src/monitoring/CONTEXT.md +5 -2
- package/src/monitoring/__tests__/context-tracker.test.ts +16 -8
- package/src/monitoring/__tests__/trace-file-anchoring.test.ts +80 -0
- package/src/monitoring/traces.ts +19 -5
- package/src/release/CONTEXT.md +1 -1
- package/src/release/__tests__/integrity.test.ts +21 -12
- package/src/test-setup/__tests__/jsonl-fake-fs.test.ts +98 -0
- package/src/test-setup/jsonl-fake-fs.ts +59 -0
- package/src/tools/index.ts +5 -1
- package/src/types/checkpoint.ts +6 -0
- package/src/types/project-config.ts +21 -0
- package/src/types/trace.ts +14 -4
- package/src/utils/__tests__/file-walk.test.ts +3 -2
- package/src/utils/__tests__/jsonl-bounded-read.test.ts +106 -0
- package/src/utils/__tests__/jsonl-skip-disposition.test.ts +10 -6
- package/src/utils/__tests__/jsonl.test.ts +61 -14
- package/src/utils/__tests__/numeric-flag.test.ts +80 -0
- package/src/utils/__tests__/package-version.test.ts +2 -2
- package/src/utils/exec.ts +4 -64
- package/src/utils/jsonl.ts +159 -20
- package/src/utils/numeric-flag.ts +64 -0
- package/dist/failure/types.d.ts +0 -9
- package/dist/failure/types.d.ts.map +0 -1
- package/dist/failure/types.js +0 -25
- package/dist/failure/types.js.map +0 -1
- package/dist/gates/effective-gates.d.ts +0 -30
- package/dist/gates/effective-gates.d.ts.map +0 -1
- package/dist/gates/effective-gates.js +0 -81
- package/dist/gates/effective-gates.js.map +0 -1
- package/src/failure/types.ts +0 -9
- package/src/gates/__tests__/effective-gates.test.ts +0 -77
- package/src/gates/effective-gates.ts +0 -99
|
@@ -50,13 +50,67 @@ const chalk_1 = __importDefault(require("chalk"));
|
|
|
50
50
|
const fs = __importStar(require("fs/promises"));
|
|
51
51
|
const path = __importStar(require("path"));
|
|
52
52
|
const yaml = __importStar(require("js-yaml"));
|
|
53
|
-
const validate_1 = require("./validate");
|
|
54
53
|
const detect_source_roots_1 = require("../../utils/detect-source-roots");
|
|
55
54
|
const package_version_1 = require("../../utils/package-version");
|
|
56
55
|
const effective_constraints_1 = require("../../core/effective-constraints");
|
|
56
|
+
const project_config_loader_1 = require("../../core/project-config-loader");
|
|
57
57
|
const injection_renderer_1 = require("../../core/constraints/injection-renderer");
|
|
58
58
|
const injection_writer_1 = require("../../core/constraints/injection-writer");
|
|
59
59
|
const command_contract_1 = require("../command-contract");
|
|
60
|
+
const scaffold_1 = require("./scaffold");
|
|
61
|
+
const scaffold_templates_1 = require("./scaffold-templates");
|
|
62
|
+
/** `--ci` 的可取值域(`none` = 不创建任何服务端 CI 文件,治理 CI 面亦不建,即旧 `--no-github-actions`) */
|
|
63
|
+
const CI_FLAG_VALUES = ['github', 'gitlab', 'none'];
|
|
64
|
+
/**
|
|
65
|
+
* 解析 CI 平台(harness#143 决议 ①④):flag > config.yml 的 `ci.platform` > `github`
|
|
66
|
+
*
|
|
67
|
+
* 不做 remote URL 自动检测:init 常跑在首次 push 之前无 remote 可测,而检测错的代价是
|
|
68
|
+
* 静默写错文件。`--no-github-actions` 保留为 `--ci none` 的废弃别名;它与显式
|
|
69
|
+
* `--ci <非 none>` 同时出现时不猜用户意图,判用法错误。
|
|
70
|
+
*/
|
|
71
|
+
function resolveCiPlatform(options, configured) {
|
|
72
|
+
const flag = options.ci;
|
|
73
|
+
if (flag !== undefined && !CI_FLAG_VALUES.includes(flag)) {
|
|
74
|
+
return {
|
|
75
|
+
kind: 'error',
|
|
76
|
+
reason: `--ci 取值非法: ${String(flag)}(可取 ${CI_FLAG_VALUES.join(' | ')})`,
|
|
77
|
+
};
|
|
78
|
+
}
|
|
79
|
+
if (options.githubActions === false) {
|
|
80
|
+
if (flag !== undefined && flag !== 'none') {
|
|
81
|
+
return {
|
|
82
|
+
kind: 'error',
|
|
83
|
+
reason: `--ci ${flag} 与 --no-github-actions(即 --ci none 的废弃别名)冲突,二选一`,
|
|
84
|
+
};
|
|
85
|
+
}
|
|
86
|
+
return {
|
|
87
|
+
kind: 'ok',
|
|
88
|
+
platform: 'none',
|
|
89
|
+
warning: '⚠️ --no-github-actions 已废弃,请改用 --ci none',
|
|
90
|
+
};
|
|
91
|
+
}
|
|
92
|
+
return { kind: 'ok', platform: flag ?? configured ?? 'github' };
|
|
93
|
+
}
|
|
94
|
+
/**
|
|
95
|
+
* 读 config.yml 已持久化的 `ci.platform`(解析链第二级)
|
|
96
|
+
*
|
|
97
|
+
* 缺失 / 解析失败 / 形状不符一律按未配置处理(与 `getGovernanceConfig` 同一口径:
|
|
98
|
+
* 脏配置不替调用方做决定)。
|
|
99
|
+
*/
|
|
100
|
+
function readConfiguredCiPlatform(projectPath) {
|
|
101
|
+
let raw;
|
|
102
|
+
try {
|
|
103
|
+
raw = (0, project_config_loader_1.loadRawProjectConfig)(projectPath);
|
|
104
|
+
}
|
|
105
|
+
catch {
|
|
106
|
+
return undefined;
|
|
107
|
+
}
|
|
108
|
+
const ci = raw?.ci;
|
|
109
|
+
if (ci === null || typeof ci !== 'object')
|
|
110
|
+
return undefined;
|
|
111
|
+
const platform = ci.platform;
|
|
112
|
+
return platform !== undefined && CI_FLAG_VALUES.includes(platform) ? platform : undefined;
|
|
113
|
+
}
|
|
60
114
|
/**
|
|
61
115
|
* 默认配置
|
|
62
116
|
*
|
|
@@ -155,13 +209,31 @@ const GOVERNANCE_PRESETS = {
|
|
|
155
209
|
* 初始化项目
|
|
156
210
|
*/
|
|
157
211
|
async function init(options, io = command_contract_1.processIO) {
|
|
212
|
+
const projectPath = options.projectPath || process.cwd();
|
|
213
|
+
// CI 平台先解析:用法错误不落任何盘,且 `--print-snippets` 也要按解析出的平台出形
|
|
214
|
+
const ci = resolveCiPlatform(options, readConfiguredCiPlatform(projectPath));
|
|
215
|
+
if (ci.kind === 'error') {
|
|
216
|
+
(0, command_contract_1.logError)(io, chalk_1.default.red(`❌ 用法错误: ${ci.reason}`));
|
|
217
|
+
return { kind: 'usage-error', reason: ci.reason };
|
|
218
|
+
}
|
|
219
|
+
if (ci.warning)
|
|
220
|
+
(0, command_contract_1.log)(io, chalk_1.default.yellow(ci.warning));
|
|
221
|
+
// `-g` 值域校验在命令入口(harness#156 裁决 F2,与 #152 脏输入 fail-loud 同判据):
|
|
222
|
+
// 非法值 usage-error、先于任何落盘;合法值域与装配共用同一份 GOVERNANCE_PRESETS 表,
|
|
223
|
+
// github / gitlab / none 三平台同判(bin 把用户敲的字符串原样递进来)。
|
|
224
|
+
// 用 Object.hasOwn 而非 `in`(harness#164):`in` 走原型链,`-g constructor`/`toString`
|
|
225
|
+
// 会穿透校验、把 Object 构造函数写进 configData 并在 yaml.dump 炸成 YAMLException。
|
|
226
|
+
if (options.governance !== undefined && !Object.hasOwn(GOVERNANCE_PRESETS, options.governance)) {
|
|
227
|
+
const reason = `-g/--governance 取值非法: ${String(options.governance)}(可取 ${Object.keys(GOVERNANCE_PRESETS).join(' | ')})`;
|
|
228
|
+
(0, command_contract_1.logError)(io, chalk_1.default.red(`❌ 用法错误: ${reason}`));
|
|
229
|
+
return { kind: 'usage-error', reason };
|
|
230
|
+
}
|
|
158
231
|
// 只输出代码片段
|
|
159
232
|
if (options.printSnippets) {
|
|
160
|
-
printSnippets(io);
|
|
233
|
+
printSnippets(io, ci.platform, options.governance);
|
|
161
234
|
return { kind: 'ok' };
|
|
162
235
|
}
|
|
163
236
|
(0, command_contract_1.log)(io, chalk_1.default.blue('🚀 初始化 harness 配置...'));
|
|
164
|
-
const projectPath = options.projectPath || process.cwd();
|
|
165
237
|
const configDir = path.join(projectPath, '.harness');
|
|
166
238
|
// 创建配置目录
|
|
167
239
|
await fs.mkdir(configDir, { recursive: true });
|
|
@@ -175,6 +247,12 @@ async function init(options, io = command_contract_1.processIO) {
|
|
|
175
247
|
configData.governance = GOVERNANCE_PRESETS[options.governance];
|
|
176
248
|
(0, command_contract_1.log)(io, chalk_1.default.gray(`治理级别: ${options.governance}`));
|
|
177
249
|
}
|
|
250
|
+
// 非默认平台才持久化:缺省即 github(旧配置零迁移),裸 init 重写 config.yml 时
|
|
251
|
+
// 也因此不会丢掉已选定的平台
|
|
252
|
+
if (ci.platform !== 'github') {
|
|
253
|
+
configData.ci = { platform: ci.platform };
|
|
254
|
+
(0, command_contract_1.log)(io, chalk_1.default.gray(`CI 平台: ${ci.platform}`));
|
|
255
|
+
}
|
|
178
256
|
// 写入 harness 版本
|
|
179
257
|
const pkgVersion = (0, package_version_1.getHarnessPackageVersion)();
|
|
180
258
|
configData.harness = { version: pkgVersion };
|
|
@@ -183,24 +261,20 @@ async function init(options, io = command_contract_1.processIO) {
|
|
|
183
261
|
const configContent = yaml.dump(configData, { indent: 2 });
|
|
184
262
|
await fs.writeFile(configPath, configContent, 'utf-8');
|
|
185
263
|
(0, command_contract_1.log)(io, chalk_1.default.green(`✅ 已创建配置文件: ${configPath} (v${pkgVersion})`));
|
|
186
|
-
//
|
|
187
|
-
await (0,
|
|
188
|
-
// 创建 Resolutions(RKB 狗粮 — 约束 → 已知解法映射)
|
|
189
|
-
await (0, validate_1.createExampleResolutions)(projectPath, io);
|
|
190
|
-
// 创建自定义约束示例
|
|
191
|
-
await createCustomConstraintsExample(projectPath, io);
|
|
264
|
+
// 受管示例文件:检查点 / Resolutions(RKB 狗粮)/ 自定义约束
|
|
265
|
+
await (0, scaffold_1.runPlan)([(0, scaffold_1.checkpointsFile)(projectPath), (0, scaffold_1.resolutionsFile)(projectPath), (0, scaffold_1.customConstraintsFile)(projectPath)], io);
|
|
192
266
|
// CAPABILITIES.md / CHANGELOG.md 由 sync-docs(AI 治理)管理,init 不创建
|
|
193
267
|
// 创建 Git hooks
|
|
194
268
|
if (options.gitHooks !== false) {
|
|
195
269
|
await setupGitHooks(projectPath, io);
|
|
196
270
|
}
|
|
197
|
-
//
|
|
198
|
-
if (
|
|
199
|
-
await
|
|
271
|
+
// 服务端 CI 门禁接线(平台维度):`none` = CI 站点干脆不进 plan
|
|
272
|
+
if (ci.platform !== 'none') {
|
|
273
|
+
await setupCiWiring(projectPath, ci.platform, options.governance, io);
|
|
200
274
|
}
|
|
201
275
|
// 治理相关文件生成
|
|
202
276
|
if (options.governance) {
|
|
203
|
-
await setupGovernance(projectPath, options.governance, io);
|
|
277
|
+
await setupGovernance(projectPath, options.governance, io, ci.platform);
|
|
204
278
|
}
|
|
205
279
|
(0, command_contract_1.log)(io);
|
|
206
280
|
(0, command_contract_1.log)(io, chalk_1.default.green('✅ harness 初始化完成!'));
|
|
@@ -208,164 +282,71 @@ async function init(options, io = command_contract_1.processIO) {
|
|
|
208
282
|
(0, command_contract_1.log)(io, chalk_1.default.gray('下一步:'));
|
|
209
283
|
(0, command_contract_1.log)(io, chalk_1.default.gray(' 1. 编辑 .harness/config.yml 自定义配置'));
|
|
210
284
|
(0, command_contract_1.log)(io, chalk_1.default.gray(' 2. 编辑 .harness/custom-constraints.yml 添加项目约束'));
|
|
211
|
-
(0, command_contract_1.log)(io, chalk_1.default.gray(' 3.
|
|
285
|
+
(0, command_contract_1.log)(io, chalk_1.default.gray(' 3. 正常开发:每次 git commit 查暂存的(增量快反馈),每次 git push 查整仓的(全量兜底)——重复是设计使然'));
|
|
212
286
|
(0, command_contract_1.log)(io, chalk_1.default.gray(' 4. 运行 harness status 查看状态'));
|
|
213
287
|
(0, command_contract_1.log)(io);
|
|
214
288
|
(0, command_contract_1.log)(io, chalk_1.default.blue('💡 提示: 使用 harness init --print-snippets 查看配置代码片段'));
|
|
215
289
|
return { kind: 'ok' };
|
|
216
290
|
}
|
|
217
291
|
/**
|
|
218
|
-
*
|
|
292
|
+
* 输出代码片段(CI 片段按解析出的平台出形,harness#143)
|
|
293
|
+
*
|
|
294
|
+
* gitlab 形打 `renderGitLabCiJobs(governanceLevel)`——与落盘 / 冲突分支同一个函数
|
|
295
|
+
* 的正本(harness#157:曾打无 level 的 GITLAB_CI_SNIPPET,`-g` 档照抄的用户少拿
|
|
296
|
+
* 治理与 docs 新鲜度两个任务)。
|
|
219
297
|
*/
|
|
220
|
-
function printSnippets(io) {
|
|
298
|
+
function printSnippets(io, platform, governanceLevel) {
|
|
221
299
|
(0, command_contract_1.log)(io, chalk_1.default.blue('📄 Harness 配置代码片段'));
|
|
222
300
|
(0, command_contract_1.log)(io);
|
|
223
301
|
(0, command_contract_1.log)(io, chalk_1.default.yellow('Git pre-commit hook:'));
|
|
224
302
|
(0, command_contract_1.log)(io, chalk_1.default.gray('添加到 .git/hooks/pre-commit'));
|
|
225
303
|
(0, command_contract_1.log)(io);
|
|
226
|
-
(0, command_contract_1.log)(io, chalk_1.default.cyan(PRE_COMMIT_SNIPPET));
|
|
227
|
-
(0, command_contract_1.log)(io, chalk_1.default.yellow('
|
|
228
|
-
(0, command_contract_1.log)(io, chalk_1.default.gray('添加到 .
|
|
304
|
+
(0, command_contract_1.log)(io, chalk_1.default.cyan(scaffold_templates_1.PRE_COMMIT_SNIPPET));
|
|
305
|
+
(0, command_contract_1.log)(io, chalk_1.default.yellow('Git pre-push hook:'));
|
|
306
|
+
(0, command_contract_1.log)(io, chalk_1.default.gray('添加到 .git/hooks/pre-push(pre-commit 查暂存的、快反馈,这道查整仓的、全量兜底——重复是设计使然)'));
|
|
229
307
|
(0, command_contract_1.log)(io);
|
|
230
|
-
(0, command_contract_1.log)(io, chalk_1.default.cyan(
|
|
308
|
+
(0, command_contract_1.log)(io, chalk_1.default.cyan(scaffold_templates_1.PRE_PUSH_SNIPPET));
|
|
309
|
+
if (platform === 'gitlab') {
|
|
310
|
+
(0, command_contract_1.log)(io, chalk_1.default.yellow('GitLab CI:'));
|
|
311
|
+
(0, command_contract_1.log)(io, chalk_1.default.gray('添加到 .gitlab-ci.yml'));
|
|
312
|
+
(0, command_contract_1.log)(io);
|
|
313
|
+
(0, command_contract_1.log)(io, chalk_1.default.cyan((0, scaffold_templates_1.renderGitLabCiJobs)(governanceLevel)));
|
|
314
|
+
}
|
|
315
|
+
else {
|
|
316
|
+
(0, command_contract_1.log)(io, chalk_1.default.yellow('GitHub Actions:'));
|
|
317
|
+
(0, command_contract_1.log)(io, chalk_1.default.gray('添加到 .github/workflows/*.yml 的 jobs 下(以下正文取自 harness-check.yml 的 job 段)'));
|
|
318
|
+
(0, command_contract_1.log)(io);
|
|
319
|
+
(0, command_contract_1.log)(io, chalk_1.default.cyan(scaffold_templates_1.GITHUB_ACTIONS_SNIPPET));
|
|
320
|
+
}
|
|
231
321
|
(0, command_contract_1.log)(io, chalk_1.default.blue('💡 提示: 运行 npx @dommaker/harness init 自动创建配置文件'));
|
|
232
322
|
}
|
|
233
323
|
/**
|
|
234
|
-
* Git
|
|
235
|
-
*
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
echo "🔍 Running harness checks..."
|
|
239
|
-
|
|
240
|
-
STAGED=$(git diff --cached --name-only --diff-filter=ACMR 2>/dev/null || true)
|
|
241
|
-
|
|
242
|
-
# Harness 约束检查
|
|
243
|
-
npx @dommaker/harness check --staged
|
|
244
|
-
if [ $? -ne 0 ]; then
|
|
245
|
-
echo "❌ Iron law check failed"
|
|
246
|
-
exit 1
|
|
247
|
-
fi
|
|
248
|
-
|
|
249
|
-
# Plan coverage check (via PostEval)
|
|
250
|
-
if command -v npx > /dev/null 2>&1; then
|
|
251
|
-
PLAN_FILES=$(echo "$STAGED" | grep -E 'plans/.*\\.md$|\\.plan\\.md$' || true)
|
|
252
|
-
if [ -n "$PLAN_FILES" ]; then
|
|
253
|
-
echo "📋 Checking plan coverage..."
|
|
254
|
-
for plan in $PLAN_FILES; do
|
|
255
|
-
npx @dommaker/harness posteval-plan "$plan" || {
|
|
256
|
-
echo "🛑 Plan coverage incomplete. See above for missed items."
|
|
257
|
-
exit 1
|
|
258
|
-
}
|
|
259
|
-
done
|
|
260
|
-
fi
|
|
261
|
-
fi
|
|
262
|
-
|
|
263
|
-
echo "✅ All checks passed"
|
|
264
|
-
`;
|
|
265
|
-
/**
|
|
266
|
-
* GitHub Actions 代码片段
|
|
267
|
-
*/
|
|
268
|
-
const GITHUB_ACTIONS_SNIPPET = `
|
|
269
|
-
harness-check:
|
|
270
|
-
runs-on: ubuntu-latest
|
|
271
|
-
steps:
|
|
272
|
-
- uses: actions/checkout@v4
|
|
273
|
-
- uses: actions/setup-node@v4
|
|
274
|
-
with:
|
|
275
|
-
node-version: '20'
|
|
276
|
-
- run: npm ci
|
|
277
|
-
- run: npx @dommaker/harness check
|
|
278
|
-
`;
|
|
279
|
-
/**
|
|
280
|
-
* 设置 Git hooks
|
|
324
|
+
* 设置 Git hooks(无 .git 即整站跳过;落盘语义在 scaffold plan)
|
|
325
|
+
*
|
|
326
|
+
* 两道:pre-commit 查暂存的(增量、快反馈),pre-push 查整仓的(全量、兜底,
|
|
327
|
+
* harness#144)。跳过旗帜 `--no-git-hooks` 在命令层翻成「本站点不进 plan」。
|
|
281
328
|
*/
|
|
282
329
|
async function setupGitHooks(projectPath, io) {
|
|
283
|
-
|
|
284
|
-
const hooksDir = path.join(gitDir, 'hooks');
|
|
285
|
-
const preCommitPath = path.join(hooksDir, 'pre-commit');
|
|
286
|
-
try {
|
|
287
|
-
await fs.access(gitDir);
|
|
288
|
-
}
|
|
289
|
-
catch {
|
|
330
|
+
if (!(await scaffold_1.nodeScaffoldFs.exists(path.join(projectPath, '.git')))) {
|
|
290
331
|
(0, command_contract_1.log)(io, chalk_1.default.yellow('⚠️ 未检测到 Git 仓库,跳过 Git hooks'));
|
|
291
332
|
(0, command_contract_1.log)(io, chalk_1.default.gray('💡 初始化 Git 后可运行 npx @dommaker/harness init --print-snippets 查看配置'));
|
|
292
333
|
return;
|
|
293
334
|
}
|
|
294
|
-
await
|
|
295
|
-
// 检查 pre-commit 是否已存在
|
|
296
|
-
try {
|
|
297
|
-
await fs.access(preCommitPath);
|
|
298
|
-
// 已存在,输出代码片段
|
|
299
|
-
(0, command_contract_1.log)(io, chalk_1.default.yellow('⚠️ .git/hooks/pre-commit 已存在'));
|
|
300
|
-
(0, command_contract_1.log)(io, chalk_1.default.gray('💡 请手动添加以下内容到文件末尾:'));
|
|
301
|
-
(0, command_contract_1.log)(io);
|
|
302
|
-
(0, command_contract_1.log)(io, chalk_1.default.cyan(PRE_COMMIT_SNIPPET));
|
|
303
|
-
}
|
|
304
|
-
catch {
|
|
305
|
-
// 不存在,创建文件:shebang 头 + 共享片段(#103 同源,无第二份文本)
|
|
306
|
-
const preCommitContent = `#!/bin/sh
|
|
307
|
-
# Harness pre-commit hook
|
|
308
|
-
${PRE_COMMIT_SNIPPET}`;
|
|
309
|
-
await fs.writeFile(preCommitPath, preCommitContent, 'utf-8');
|
|
310
|
-
await fs.chmod(preCommitPath, 0o755);
|
|
311
|
-
(0, command_contract_1.log)(io, chalk_1.default.green(`✅ 已创建 .git/hooks/pre-commit`));
|
|
312
|
-
}
|
|
335
|
+
await (0, scaffold_1.runPlan)([(0, scaffold_1.preCommitHookFile)(projectPath), (0, scaffold_1.prePushHookFile)(projectPath)], io);
|
|
313
336
|
}
|
|
314
337
|
/**
|
|
315
|
-
*
|
|
338
|
+
* 设置服务端 CI 接线(站点形状与冲突面由 scaffold 按平台给)
|
|
339
|
+
*
|
|
340
|
+
* gitlab 只有一个 `.gitlab-ci.yml`,治理任务已在正文里(`governanceLevel` 传给工厂);
|
|
341
|
+
* github 的冲突判定宽到整个 workflows 目录,需先扫一遍。
|
|
316
342
|
*/
|
|
317
|
-
async function
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
// 检查是否已有 CI 配置
|
|
321
|
-
const existingFiles = await findCiWorkflows(workflowsDir);
|
|
322
|
-
if (existingFiles.length > 0) {
|
|
323
|
-
// 已有 CI 配置,输出代码片段
|
|
324
|
-
(0, command_contract_1.log)(io, chalk_1.default.yellow('⚠️ 检测到已存在的 CI 配置:'));
|
|
325
|
-
existingFiles.forEach(f => {
|
|
326
|
-
(0, command_contract_1.log)(io, chalk_1.default.gray(` - .github/workflows/${f}`));
|
|
327
|
-
});
|
|
328
|
-
(0, command_contract_1.log)(io, chalk_1.default.gray('💡 请手动添加以下内容到 jobs 中:'));
|
|
329
|
-
(0, command_contract_1.log)(io);
|
|
330
|
-
(0, command_contract_1.log)(io, chalk_1.default.cyan(GITHUB_ACTIONS_SNIPPET));
|
|
343
|
+
async function setupCiWiring(projectPath, platform, governanceLevel, io) {
|
|
344
|
+
if (platform === 'gitlab') {
|
|
345
|
+
await (0, scaffold_1.runPlan)([(0, scaffold_1.harnessCheckCiFile)(projectPath, 'gitlab', [], governanceLevel)], io);
|
|
331
346
|
return;
|
|
332
347
|
}
|
|
333
|
-
|
|
334
|
-
await
|
|
335
|
-
const workflowContent = `name: Harness Check
|
|
336
|
-
|
|
337
|
-
on:
|
|
338
|
-
push:
|
|
339
|
-
branches: [main, master]
|
|
340
|
-
pull_request:
|
|
341
|
-
branches: [main, master]
|
|
342
|
-
|
|
343
|
-
jobs:
|
|
344
|
-
harness-check:
|
|
345
|
-
runs-on: ubuntu-latest
|
|
346
|
-
|
|
347
|
-
steps:
|
|
348
|
-
- uses: actions/checkout@v4
|
|
349
|
-
|
|
350
|
-
- name: Setup Node.js
|
|
351
|
-
uses: actions/setup-node@v4
|
|
352
|
-
with:
|
|
353
|
-
node-version: '20'
|
|
354
|
-
|
|
355
|
-
- name: Install dependencies
|
|
356
|
-
run: npm ci
|
|
357
|
-
|
|
358
|
-
- name: Run harness check
|
|
359
|
-
run: npx @dommaker/harness check
|
|
360
|
-
|
|
361
|
-
- name: Run harness validate
|
|
362
|
-
run: npx @dommaker/harness validate
|
|
363
|
-
|
|
364
|
-
- name: Run harness passes-gate
|
|
365
|
-
run: npx @dommaker/harness passes-gate
|
|
366
|
-
`;
|
|
367
|
-
await fs.writeFile(workflowPath, workflowContent, 'utf-8');
|
|
368
|
-
(0, command_contract_1.log)(io, chalk_1.default.green(`✅ 已创建 .github/workflows/harness-check.yml`));
|
|
348
|
+
const workflowsDir = path.join(projectPath, '.github', 'workflows');
|
|
349
|
+
await (0, scaffold_1.runPlan)([(0, scaffold_1.harnessCheckCiFile)(projectPath, 'github', await findCiWorkflows(workflowsDir))], io);
|
|
369
350
|
}
|
|
370
351
|
/**
|
|
371
352
|
* 查找已存在的 CI 工作流文件
|
|
@@ -381,58 +362,6 @@ async function findCiWorkflows(workflowsDir) {
|
|
|
381
362
|
return [];
|
|
382
363
|
}
|
|
383
364
|
}
|
|
384
|
-
/**
|
|
385
|
-
* 创建自定义约束示例
|
|
386
|
-
*/
|
|
387
|
-
async function createCustomConstraintsExample(projectPath, io) {
|
|
388
|
-
const configDir = path.join(projectPath, '.harness');
|
|
389
|
-
const customConstraintsPath = path.join(configDir, 'custom-constraints.yml');
|
|
390
|
-
// 如果已存在,不覆盖
|
|
391
|
-
try {
|
|
392
|
-
await fs.access(customConstraintsPath);
|
|
393
|
-
(0, command_contract_1.log)(io, chalk_1.default.gray(`custom-constraints.yml 已存在`));
|
|
394
|
-
return;
|
|
395
|
-
}
|
|
396
|
-
catch {
|
|
397
|
-
// 文件不存在,创建
|
|
398
|
-
}
|
|
399
|
-
const content = `# 自定义约束配置
|
|
400
|
-
#
|
|
401
|
-
# 此文件定义项目特定的约束,扩展或覆盖 harness 内置约束
|
|
402
|
-
|
|
403
|
-
# ========================================
|
|
404
|
-
# 自定义约束示例
|
|
405
|
-
# ========================================
|
|
406
|
-
|
|
407
|
-
custom_constraints:
|
|
408
|
-
# 示例 1:禁止 console.log
|
|
409
|
-
# my_project_no_console_log:
|
|
410
|
-
# id: my_project_no_console_log
|
|
411
|
-
# level: guideline
|
|
412
|
-
# rule: "NO CONSOLE.LOG IN PRODUCTION CODE"
|
|
413
|
-
# message: "生产代码禁止使用 console.log,请使用 logger 模块"
|
|
414
|
-
# trigger: ["code_implementation"]
|
|
415
|
-
# description: "使用项目统一的 logger 模块代替 console.log"
|
|
416
|
-
|
|
417
|
-
# 示例 2:禁止特定的导入
|
|
418
|
-
# my_project_no_moment_js:
|
|
419
|
-
# id: my_project_no_moment_js
|
|
420
|
-
# level: guideline
|
|
421
|
-
# rule: "NO MOMENT.JS IMPORTS"
|
|
422
|
-
# message: "禁止使用 moment.js,请使用 date-fns 或 dayjs"
|
|
423
|
-
# trigger: ["code_implementation"]
|
|
424
|
-
|
|
425
|
-
# 示例 3:要求特定的文件命名
|
|
426
|
-
# my_project_component_naming:
|
|
427
|
-
# id: my_project_component_naming
|
|
428
|
-
# level: tip
|
|
429
|
-
# rule: "REACT COMPONENTS SHOULD BE PASCAL CASE"
|
|
430
|
-
# message: "React 组件文件名应使用 PascalCase"
|
|
431
|
-
# trigger: ["file_creation"]
|
|
432
|
-
`;
|
|
433
|
-
await fs.writeFile(customConstraintsPath, content, 'utf-8');
|
|
434
|
-
(0, command_contract_1.log)(io, chalk_1.default.green(`✅ 已创建自定义约束示例: custom-constraints.yml`));
|
|
435
|
-
}
|
|
436
365
|
/**
|
|
437
366
|
* Output Style 段标记(ADR-0001:init 只写标记区间内,标记外只读)
|
|
438
367
|
*/
|
|
@@ -462,7 +391,7 @@ function renderOutputStyleSection() {
|
|
|
462
391
|
* - 无标记且 `## Output Style` 段为用户自写(特征串不匹配):跳过并提示,不重复追加
|
|
463
392
|
* - 完全没有该段:在文件顶部插入标记版
|
|
464
393
|
*/
|
|
465
|
-
async function setupClaudeMdOutputStyle(projectPath, io
|
|
394
|
+
async function setupClaudeMdOutputStyle(projectPath, io) {
|
|
466
395
|
const claudeMdPath = path.join(projectPath, 'CLAUDE.md');
|
|
467
396
|
let content;
|
|
468
397
|
try {
|
|
@@ -528,7 +457,7 @@ const GOVERNANCE_PRESERVE_END = '<!-- /PRESERVE:governance -->';
|
|
|
528
457
|
* - 无该段:在文件末尾追加
|
|
529
458
|
* - 段标记残缺(外层或段内 HARNESS_CONSTRAINTS 单边/乱序):不写入,告警交由人工修复(防二次损坏)
|
|
530
459
|
*/
|
|
531
|
-
async function setupAgentsMdConstraints(projectPath, io
|
|
460
|
+
async function setupAgentsMdConstraints(projectPath, io) {
|
|
532
461
|
const agentsMdPath = path.join(projectPath, 'AGENTS.md');
|
|
533
462
|
const version = (0, package_version_1.getHarnessPackageVersion)();
|
|
534
463
|
const constraints = (0, effective_constraints_1.getEffectiveConstraints)(projectPath);
|
|
@@ -591,7 +520,7 @@ async function setupAgentsMdConstraints(projectPath, io = command_contract_1.pro
|
|
|
591
520
|
* - 如果存在 HARNESS_CONSTRAINTS_START/END 标记,替换标记间内容
|
|
592
521
|
* - 如果不存在标记,在文件末尾追加约束段
|
|
593
522
|
*/
|
|
594
|
-
async function setupClaudeMdConstraints(projectPath, io
|
|
523
|
+
async function setupClaudeMdConstraints(projectPath, io) {
|
|
595
524
|
const claudeMdPath = path.join(projectPath, 'CLAUDE.md');
|
|
596
525
|
const version = (0, package_version_1.getHarnessPackageVersion)();
|
|
597
526
|
// 生效约束集 → 渲染期望段(纯函数,与写文件分离)
|
|
@@ -638,135 +567,54 @@ async function setupClaudeMdConstraints(projectPath, io = command_contract_1.pro
|
|
|
638
567
|
* 继续写 CLAUDE.md——init 幂等重跑不破坏既有仓,不制造双份约束正本
|
|
639
568
|
* - 其余(新仓初始化):写 AGENTS.md PRESERVE:governance 段(入库公共面正本)
|
|
640
569
|
*/
|
|
641
|
-
async function setupGovernanceConstraints(projectPath) {
|
|
570
|
+
async function setupGovernanceConstraints(projectPath, io) {
|
|
642
571
|
const { target } = (0, injection_writer_1.resolveGovernanceLanding)(projectPath);
|
|
643
572
|
return target === 'claude-md'
|
|
644
|
-
? setupClaudeMdConstraints(projectPath)
|
|
645
|
-
: setupAgentsMdConstraints(projectPath);
|
|
573
|
+
? setupClaudeMdConstraints(projectPath, io)
|
|
574
|
+
: setupAgentsMdConstraints(projectPath, io);
|
|
646
575
|
}
|
|
647
576
|
/**
|
|
648
577
|
* 设置治理相关文件
|
|
649
578
|
*/
|
|
650
|
-
async function setupGovernance(projectPath, level, io) {
|
|
579
|
+
async function setupGovernance(projectPath, level, io, platform) {
|
|
651
580
|
const governance = GOVERNANCE_PRESETS[level];
|
|
652
581
|
if (!governance)
|
|
653
582
|
return;
|
|
654
583
|
(0, command_contract_1.log)(io);
|
|
655
584
|
(0, command_contract_1.log)(io, chalk_1.default.blue('📋 设置治理文件...'));
|
|
656
585
|
// 1. 生成 CHANGELOG.md
|
|
657
|
-
await
|
|
586
|
+
await (0, scaffold_1.runPlan)([(0, scaffold_1.changelogFile)(projectPath, governance.changelog?.format || 'keep-a-changelog')], io);
|
|
658
587
|
// 2. 在 CLAUDE.md 中写入 Output Style 段(仅在不存在时创建)
|
|
659
|
-
await setupClaudeMdOutputStyle(projectPath);
|
|
588
|
+
await setupClaudeMdOutputStyle(projectPath, io);
|
|
660
589
|
// 3. 写入/更新 Governance Rules 约束段(新仓 → AGENTS.md PRESERVE:governance;
|
|
661
590
|
// 旧模型仓 → CLAUDE.md,落点路由见 setupGovernanceConstraints)
|
|
662
|
-
await setupGovernanceConstraints(projectPath);
|
|
591
|
+
await setupGovernanceConstraints(projectPath, io);
|
|
663
592
|
// 4. 生成 CONTEXT.md 文件(预设形状即 GovernanceConfig,无需再 cast)
|
|
664
|
-
|
|
665
|
-
|
|
666
|
-
|
|
667
|
-
if (requiredDirs.length === 0) {
|
|
668
|
-
requiredDirs = (0, detect_source_roots_1.detectSourceRoots)(projectPath);
|
|
669
|
-
}
|
|
670
|
-
for (const dir of requiredDirs) {
|
|
671
|
-
await createContextMd(projectPath, dir, io);
|
|
672
|
-
}
|
|
673
|
-
}
|
|
674
|
-
// 4. 生成治理 CI workflow
|
|
675
|
-
await setupGovernanceWorkflow(projectPath, level, io);
|
|
676
|
-
}
|
|
677
|
-
/**
|
|
678
|
-
* 创建 CHANGELOG.md
|
|
679
|
-
*/
|
|
680
|
-
async function createChangelog(projectPath, governance, io) {
|
|
681
|
-
const changelogPath = path.join(projectPath, 'CHANGELOG.md');
|
|
682
|
-
try {
|
|
683
|
-
await fs.access(changelogPath);
|
|
684
|
-
(0, command_contract_1.log)(io, chalk_1.default.gray(`CHANGELOG.md 已存在`));
|
|
685
|
-
return;
|
|
686
|
-
}
|
|
687
|
-
catch {
|
|
688
|
-
// 文件不存在,创建
|
|
689
|
-
}
|
|
690
|
-
const format = governance.changelog?.format || 'keep-a-changelog';
|
|
691
|
-
let content;
|
|
692
|
-
if (format === 'keep-a-changelog') {
|
|
693
|
-
content = `# Changelog
|
|
694
|
-
|
|
695
|
-
All notable changes to this project will be documented in this file.
|
|
696
|
-
|
|
697
|
-
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
|
|
698
|
-
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
|
699
|
-
|
|
700
|
-
## [Unreleased]
|
|
701
|
-
|
|
702
|
-
### Added
|
|
703
|
-
- Initial project setup with harness governance
|
|
704
|
-
|
|
705
|
-
---
|
|
706
|
-
|
|
707
|
-
> 此文件可由 \`harness sync-docs\` 辅助维护
|
|
708
|
-
`;
|
|
709
|
-
}
|
|
710
|
-
else {
|
|
711
|
-
content = `# Changelog
|
|
712
|
-
|
|
713
|
-
## [Unreleased]
|
|
714
|
-
|
|
715
|
-
- Initial project setup with harness governance
|
|
716
|
-
|
|
717
|
-
---
|
|
718
|
-
|
|
719
|
-
> 此文件可由 \`harness sync-docs\` 辅助维护
|
|
720
|
-
`;
|
|
721
|
-
}
|
|
722
|
-
await fs.writeFile(changelogPath, content, 'utf-8');
|
|
723
|
-
(0, command_contract_1.log)(io, chalk_1.default.green(`✅ 已创建 CHANGELOG.md`));
|
|
593
|
+
await (0, scaffold_1.runPlan)(await contextDocPlan(projectPath, governance, io), io);
|
|
594
|
+
// 5. 生成治理 CI 面(仅 github 形;gitlab 已并入 .gitlab-ci.yml 正文,none 不建,harness#156)
|
|
595
|
+
await setupGovernanceWorkflow(projectPath, level, io, platform);
|
|
724
596
|
}
|
|
725
597
|
/**
|
|
726
|
-
*
|
|
598
|
+
* 目录 CONTEXT.md 骨架的 plan:required_dirs 缺省时按源码根探测,
|
|
599
|
+
* 探测出来的目录不在场就不进 plan(告知由本函数负责)
|
|
727
600
|
*/
|
|
728
|
-
async function
|
|
729
|
-
const
|
|
730
|
-
|
|
731
|
-
|
|
732
|
-
|
|
733
|
-
|
|
734
|
-
|
|
735
|
-
|
|
736
|
-
|
|
737
|
-
|
|
738
|
-
|
|
739
|
-
|
|
740
|
-
|
|
741
|
-
|
|
742
|
-
|
|
743
|
-
catch {
|
|
744
|
-
(0, command_contract_1.log)(io, chalk_1.default.yellow(`⚠️ 目录 ${dir} 不存在,跳过 CONTEXT.md`));
|
|
745
|
-
return;
|
|
601
|
+
async function contextDocPlan(projectPath, governance, io) {
|
|
602
|
+
const contextConfig = governance.context_files;
|
|
603
|
+
if (!contextConfig?.enabled)
|
|
604
|
+
return [];
|
|
605
|
+
let requiredDirs = contextConfig.required_dirs ?? [];
|
|
606
|
+
if (requiredDirs.length === 0) {
|
|
607
|
+
requiredDirs = (0, detect_source_roots_1.detectSourceRoots)(projectPath);
|
|
608
|
+
}
|
|
609
|
+
const plan = [];
|
|
610
|
+
for (const dir of requiredDirs) {
|
|
611
|
+
if (!(await scaffold_1.nodeScaffoldFs.exists(path.join(projectPath, dir)))) {
|
|
612
|
+
(0, command_contract_1.log)(io, chalk_1.default.yellow(`⚠️ 目录 ${dir} 不存在,跳过 CONTEXT.md`));
|
|
613
|
+
continue;
|
|
614
|
+
}
|
|
615
|
+
plan.push((0, scaffold_1.contextDocFile)(projectPath, dir));
|
|
746
616
|
}
|
|
747
|
-
|
|
748
|
-
const content = `# ${dirName}
|
|
749
|
-
|
|
750
|
-
> 此文件描述 ${dir} 目录的职责和上下文
|
|
751
|
-
|
|
752
|
-
## 职责
|
|
753
|
-
|
|
754
|
-
<!-- 本目录的核心职责是什么 -->
|
|
755
|
-
|
|
756
|
-
## 核心导出
|
|
757
|
-
|
|
758
|
-
<!-- 本目录对外暴露的主要模块/函数 -->
|
|
759
|
-
|
|
760
|
-
## 依赖关系
|
|
761
|
-
|
|
762
|
-
<!-- 本目录依赖哪些其他模块,谁依赖本目录 -->
|
|
763
|
-
|
|
764
|
-
## 注意事项
|
|
765
|
-
|
|
766
|
-
<!-- 开发时需要注意的约束或约定 -->
|
|
767
|
-
`;
|
|
768
|
-
await fs.writeFile(contextPath, content, 'utf-8');
|
|
769
|
-
(0, command_contract_1.log)(io, chalk_1.default.green(`✅ 已创建 ${dir}/CONTEXT.md`));
|
|
617
|
+
return plan;
|
|
770
618
|
}
|
|
771
619
|
/**
|
|
772
620
|
* 检测已有 workflow 是否已覆盖 harness 治理命令
|
|
@@ -788,64 +636,24 @@ async function findGovernanceCoverage(workflowsDir) {
|
|
|
788
636
|
return undefined;
|
|
789
637
|
}
|
|
790
638
|
/**
|
|
791
|
-
* 设置治理 CI workflow
|
|
639
|
+
* 设置治理 CI workflow(目标已在场,或已有 workflow 覆盖治理命令时不新建 CI 面)
|
|
640
|
+
*
|
|
641
|
+
* 仅 github 形有本站点:gitlab 的治理任务已并入 `.gitlab-ci.yml` 正文(一个平台一份
|
|
642
|
+
* CI 文件,harness#143);`none` = 不创建任何 CI 文件,治理 CI 面随之不建
|
|
643
|
+
* (harness#156 裁决 F1;治理文档面不受影响,见 setupGovernance 1–4)。
|
|
792
644
|
*/
|
|
793
|
-
async function setupGovernanceWorkflow(projectPath, level, io) {
|
|
794
|
-
|
|
795
|
-
const workflowPath = path.join(workflowsDir, 'harness-governance.yml');
|
|
796
|
-
// 检查是否已存在
|
|
797
|
-
try {
|
|
798
|
-
await fs.access(workflowPath);
|
|
799
|
-
(0, command_contract_1.log)(io, chalk_1.default.gray(`harness-governance.yml 已存在`));
|
|
800
|
-
return;
|
|
801
|
-
}
|
|
802
|
-
catch {
|
|
803
|
-
// 不存在,继续创建
|
|
804
|
-
}
|
|
805
|
-
// 能力检测:已有 workflow 已跑 harness 治理命令时跳过,避免重复 CI 面
|
|
806
|
-
const coveredBy = await findGovernanceCoverage(workflowsDir);
|
|
807
|
-
if (coveredBy) {
|
|
808
|
-
(0, command_contract_1.log)(io, chalk_1.default.gray(`治理检查已由 ${coveredBy} 覆盖,跳过创建 harness-governance.yml`));
|
|
645
|
+
async function setupGovernanceWorkflow(projectPath, level, io, platform) {
|
|
646
|
+
if (platform !== 'github')
|
|
809
647
|
return;
|
|
648
|
+
const workflowsDir = path.join(projectPath, '.github', 'workflows');
|
|
649
|
+
const file = (0, scaffold_1.governanceWorkflowFile)(projectPath, level);
|
|
650
|
+
if (!(await scaffold_1.nodeScaffoldFs.exists(file.target))) {
|
|
651
|
+
const coveredBy = await findGovernanceCoverage(workflowsDir);
|
|
652
|
+
if (coveredBy) {
|
|
653
|
+
(0, command_contract_1.log)(io, chalk_1.default.gray(`治理检查已由 ${coveredBy} 覆盖,跳过创建 harness-governance.yml`));
|
|
654
|
+
return;
|
|
655
|
+
}
|
|
810
656
|
}
|
|
811
|
-
await
|
|
812
|
-
const docsCheckStep = level !== 'minimal'
|
|
813
|
-
? `
|
|
814
|
-
- name: Check docs freshness
|
|
815
|
-
run: npx @dommaker/harness sync-docs --check
|
|
816
|
-
continue-on-error: true`
|
|
817
|
-
: '';
|
|
818
|
-
const workflowContent = `name: Harness Governance
|
|
819
|
-
|
|
820
|
-
on:
|
|
821
|
-
push:
|
|
822
|
-
branches: [main, master]
|
|
823
|
-
pull_request:
|
|
824
|
-
branches: [main, master]
|
|
825
|
-
|
|
826
|
-
jobs:
|
|
827
|
-
governance:
|
|
828
|
-
runs-on: ubuntu-latest
|
|
829
|
-
|
|
830
|
-
steps:
|
|
831
|
-
- uses: actions/checkout@v4
|
|
832
|
-
|
|
833
|
-
- name: Setup Node.js
|
|
834
|
-
uses: actions/setup-node@v4
|
|
835
|
-
with:
|
|
836
|
-
node-version: '20'
|
|
837
|
-
|
|
838
|
-
- name: Install dependencies
|
|
839
|
-
run: npm ci
|
|
840
|
-
|
|
841
|
-
- name: Constraint check
|
|
842
|
-
run: npx @dommaker/harness check
|
|
843
|
-
|
|
844
|
-
- name: Quality gate
|
|
845
|
-
run: npx @dommaker/harness passes-gate
|
|
846
|
-
${docsCheckStep}
|
|
847
|
-
`;
|
|
848
|
-
await fs.writeFile(workflowPath, workflowContent, 'utf-8');
|
|
849
|
-
(0, command_contract_1.log)(io, chalk_1.default.green(`✅ 已创建 .github/workflows/harness-governance.yml`));
|
|
657
|
+
await (0, scaffold_1.runPlan)([file], io);
|
|
850
658
|
}
|
|
851
659
|
//# sourceMappingURL=init.js.map
|