mustflow 1.18.16 → 1.30.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/README.md +16 -6
- package/dist/cli/commands/adapters.js +90 -0
- package/dist/cli/commands/classify.js +3 -4
- package/dist/cli/commands/contract-lint.js +26 -6
- package/dist/cli/commands/dashboard.js +103 -4
- package/dist/cli/commands/explain-verify.js +213 -0
- package/dist/cli/commands/explain.js +48 -4
- package/dist/cli/commands/handoff.js +136 -0
- package/dist/cli/commands/run.js +97 -136
- package/dist/cli/commands/update.js +91 -61
- package/dist/cli/commands/verify.js +230 -137
- package/dist/cli/i18n/en.js +65 -4
- package/dist/cli/i18n/es.js +65 -4
- package/dist/cli/i18n/fr.js +65 -4
- package/dist/cli/i18n/hi.js +65 -4
- package/dist/cli/i18n/ko.js +65 -4
- package/dist/cli/i18n/zh.js +65 -4
- package/dist/cli/index.js +11 -0
- package/dist/cli/lib/command-registry.js +10 -0
- package/dist/cli/lib/dashboard-export.js +775 -0
- package/dist/cli/lib/local-index.js +22 -6
- package/dist/cli/lib/run-plan.js +222 -0
- package/dist/cli/lib/templates.js +18 -3
- package/dist/cli/lib/update-diff-preview.js +163 -0
- package/dist/cli/lib/validation.js +22 -0
- package/dist/core/adapter-compatibility.js +235 -0
- package/dist/core/change-classification.js +9 -0
- package/dist/core/change-verification.js +10 -3
- package/dist/core/check-issues.js +4 -0
- package/dist/core/command-contract-validation.js +14 -0
- package/dist/core/command-cwd.js +18 -6
- package/dist/core/command-env.js +91 -0
- package/dist/core/contract-lint.js +165 -3
- package/dist/core/contract-models.js +172 -0
- package/dist/core/dashboard-verification.js +2 -0
- package/dist/core/doc-review-triage.js +1 -0
- package/dist/core/handoff-record.js +376 -0
- package/dist/core/public-json-contracts.js +16 -0
- package/dist/core/run-receipt.js +46 -7
- package/dist/core/run-write-drift.js +180 -0
- package/dist/core/secret-redaction.js +39 -0
- package/dist/core/source-anchors.js +3 -5
- package/dist/core/verification-decision-graph.js +223 -0
- package/package.json +3 -1
- package/schemas/README.md +11 -4
- package/schemas/adapter-compatibility-report.schema.json +184 -0
- package/schemas/change-verification-report.schema.json +133 -1
- package/schemas/commands.schema.json +8 -1
- package/schemas/contract-lint-report.schema.json +48 -0
- package/schemas/explain-report.schema.json +265 -2
- package/schemas/handoff-validation-report.schema.json +68 -0
- package/schemas/run-receipt.schema.json +74 -1
- package/templates/default/common/.mustflow/config/commands.toml +2 -0
- package/templates/default/i18n.toml +78 -234
- package/templates/default/locales/en/.mustflow/skills/INDEX.md +7 -3
- package/templates/default/locales/en/.mustflow/skills/architecture-deepening-review/SKILL.md +154 -0
- package/templates/default/locales/en/.mustflow/skills/behavior-preserving-refactor/SKILL.md +8 -3
- package/templates/default/locales/en/.mustflow/skills/code-review/SKILL.md +9 -4
- package/templates/default/locales/en/.mustflow/skills/date-number-audit/SKILL.md +19 -4
- package/templates/default/locales/en/.mustflow/skills/diff-risk-review/SKILL.md +4 -2
- package/templates/default/locales/en/.mustflow/skills/external-skill-intake/SKILL.md +141 -0
- package/templates/default/locales/en/.mustflow/skills/release-notes-authoring/SKILL.md +143 -0
- package/templates/default/locales/en/.mustflow/skills/repro-first-debug/SKILL.md +22 -8
- package/templates/default/locales/en/.mustflow/skills/skill-authoring/SKILL.md +3 -3
- package/templates/default/locales/en/.mustflow/skills/source-freshness-check/SKILL.md +22 -9
- package/templates/default/locales/en/.mustflow/skills/ui-quality-gate/SKILL.md +21 -13
- package/templates/default/locales/en/.mustflow/skills/vertical-slice-tdd/SKILL.md +167 -0
- package/templates/default/manifest.toml +16 -1
- package/templates/default/locales/es/.mustflow/skills/INDEX.md +0 -75
- package/templates/default/locales/es/.mustflow/skills/adapter-boundary/SKILL.md +0 -193
- package/templates/default/locales/es/.mustflow/skills/artifact-integrity-check/SKILL.md +0 -114
- package/templates/default/locales/es/.mustflow/skills/behavior-preserving-refactor/SKILL.md +0 -182
- package/templates/default/locales/es/.mustflow/skills/code-review/SKILL.md +0 -115
- package/templates/default/locales/es/.mustflow/skills/codebase-orientation/SKILL.md +0 -115
- package/templates/default/locales/es/.mustflow/skills/command-pattern/SKILL.md +0 -247
- package/templates/default/locales/es/.mustflow/skills/composition-over-inheritance/SKILL.md +0 -176
- package/templates/default/locales/es/.mustflow/skills/contract-sync-check/SKILL.md +0 -116
- package/templates/default/locales/es/.mustflow/skills/database-change-safety/SKILL.md +0 -155
- package/templates/default/locales/es/.mustflow/skills/date-number-audit/SKILL.md +0 -116
- package/templates/default/locales/es/.mustflow/skills/dependency-injection/SKILL.md +0 -161
- package/templates/default/locales/es/.mustflow/skills/dependency-reality-check/SKILL.md +0 -115
- package/templates/default/locales/es/.mustflow/skills/diff-risk-review/SKILL.md +0 -136
- package/templates/default/locales/es/.mustflow/skills/docs-prose-review/SKILL.md +0 -119
- package/templates/default/locales/es/.mustflow/skills/docs-update/SKILL.md +0 -97
- package/templates/default/locales/es/.mustflow/skills/external-prompt-injection-defense/SKILL.md +0 -116
- package/templates/default/locales/es/.mustflow/skills/facade-pattern/SKILL.md +0 -210
- package/templates/default/locales/es/.mustflow/skills/failure-triage/SKILL.md +0 -97
- package/templates/default/locales/es/.mustflow/skills/instruction-conflict-scope-check/SKILL.md +0 -118
- package/templates/default/locales/es/.mustflow/skills/line-ending-hygiene/SKILL.md +0 -111
- package/templates/default/locales/es/.mustflow/skills/migration-safety-check/SKILL.md +0 -117
- package/templates/default/locales/es/.mustflow/skills/multi-agent-work-coordination/SKILL.md +0 -260
- package/templates/default/locales/es/.mustflow/skills/null-object-pattern/SKILL.md +0 -196
- package/templates/default/locales/es/.mustflow/skills/pattern-scout/SKILL.md +0 -110
- package/templates/default/locales/es/.mustflow/skills/performance-budget-check/SKILL.md +0 -121
- package/templates/default/locales/es/.mustflow/skills/project-context-authoring/SKILL.md +0 -107
- package/templates/default/locales/es/.mustflow/skills/pure-core-imperative-shell/SKILL.md +0 -212
- package/templates/default/locales/es/.mustflow/skills/readme-authoring/SKILL.md +0 -115
- package/templates/default/locales/es/.mustflow/skills/repo-improvement-loop/SKILL.md +0 -150
- package/templates/default/locales/es/.mustflow/skills/repro-first-debug/SKILL.md +0 -112
- package/templates/default/locales/es/.mustflow/skills/requirement-regression-guard/SKILL.md +0 -152
- package/templates/default/locales/es/.mustflow/skills/result-option/SKILL.md +0 -186
- package/templates/default/locales/es/.mustflow/skills/security-privacy-review/SKILL.md +0 -116
- package/templates/default/locales/es/.mustflow/skills/security-regression-tests/SKILL.md +0 -131
- package/templates/default/locales/es/.mustflow/skills/skill-authoring/SKILL.md +0 -110
- package/templates/default/locales/es/.mustflow/skills/source-freshness-check/SKILL.md +0 -111
- package/templates/default/locales/es/.mustflow/skills/state-machine-pattern/SKILL.md +0 -214
- package/templates/default/locales/es/.mustflow/skills/strategy-pattern/SKILL.md +0 -215
- package/templates/default/locales/es/.mustflow/skills/structure-discovery-gate/SKILL.md +0 -159
- package/templates/default/locales/es/.mustflow/skills/test-design-guard/SKILL.md +0 -162
- package/templates/default/locales/es/.mustflow/skills/test-maintenance/SKILL.md +0 -122
- package/templates/default/locales/es/.mustflow/skills/ui-quality-gate/SKILL.md +0 -117
- package/templates/default/locales/es/.mustflow/skills/visual-review-artifact/SKILL.md +0 -127
- package/templates/default/locales/es/.mustflow/skills/visual-review-artifact/assets/review-template.html +0 -286
- package/templates/default/locales/es/.mustflow/skills/visual-review-artifact/resources.toml +0 -7
- package/templates/default/locales/es/.mustflow/skills/web-asset-optimization/SKILL.md +0 -108
- package/templates/default/locales/fr/.mustflow/skills/INDEX.md +0 -75
- package/templates/default/locales/fr/.mustflow/skills/adapter-boundary/SKILL.md +0 -193
- package/templates/default/locales/fr/.mustflow/skills/artifact-integrity-check/SKILL.md +0 -114
- package/templates/default/locales/fr/.mustflow/skills/behavior-preserving-refactor/SKILL.md +0 -182
- package/templates/default/locales/fr/.mustflow/skills/code-review/SKILL.md +0 -115
- package/templates/default/locales/fr/.mustflow/skills/codebase-orientation/SKILL.md +0 -115
- package/templates/default/locales/fr/.mustflow/skills/command-pattern/SKILL.md +0 -247
- package/templates/default/locales/fr/.mustflow/skills/composition-over-inheritance/SKILL.md +0 -176
- package/templates/default/locales/fr/.mustflow/skills/contract-sync-check/SKILL.md +0 -116
- package/templates/default/locales/fr/.mustflow/skills/database-change-safety/SKILL.md +0 -155
- package/templates/default/locales/fr/.mustflow/skills/date-number-audit/SKILL.md +0 -116
- package/templates/default/locales/fr/.mustflow/skills/dependency-injection/SKILL.md +0 -161
- package/templates/default/locales/fr/.mustflow/skills/dependency-reality-check/SKILL.md +0 -115
- package/templates/default/locales/fr/.mustflow/skills/diff-risk-review/SKILL.md +0 -136
- package/templates/default/locales/fr/.mustflow/skills/docs-prose-review/SKILL.md +0 -119
- package/templates/default/locales/fr/.mustflow/skills/docs-update/SKILL.md +0 -97
- package/templates/default/locales/fr/.mustflow/skills/external-prompt-injection-defense/SKILL.md +0 -116
- package/templates/default/locales/fr/.mustflow/skills/facade-pattern/SKILL.md +0 -210
- package/templates/default/locales/fr/.mustflow/skills/failure-triage/SKILL.md +0 -97
- package/templates/default/locales/fr/.mustflow/skills/instruction-conflict-scope-check/SKILL.md +0 -118
- package/templates/default/locales/fr/.mustflow/skills/line-ending-hygiene/SKILL.md +0 -111
- package/templates/default/locales/fr/.mustflow/skills/migration-safety-check/SKILL.md +0 -117
- package/templates/default/locales/fr/.mustflow/skills/multi-agent-work-coordination/SKILL.md +0 -260
- package/templates/default/locales/fr/.mustflow/skills/null-object-pattern/SKILL.md +0 -196
- package/templates/default/locales/fr/.mustflow/skills/pattern-scout/SKILL.md +0 -110
- package/templates/default/locales/fr/.mustflow/skills/performance-budget-check/SKILL.md +0 -121
- package/templates/default/locales/fr/.mustflow/skills/project-context-authoring/SKILL.md +0 -107
- package/templates/default/locales/fr/.mustflow/skills/pure-core-imperative-shell/SKILL.md +0 -212
- package/templates/default/locales/fr/.mustflow/skills/readme-authoring/SKILL.md +0 -115
- package/templates/default/locales/fr/.mustflow/skills/repo-improvement-loop/SKILL.md +0 -150
- package/templates/default/locales/fr/.mustflow/skills/repro-first-debug/SKILL.md +0 -112
- package/templates/default/locales/fr/.mustflow/skills/requirement-regression-guard/SKILL.md +0 -152
- package/templates/default/locales/fr/.mustflow/skills/result-option/SKILL.md +0 -186
- package/templates/default/locales/fr/.mustflow/skills/security-privacy-review/SKILL.md +0 -116
- package/templates/default/locales/fr/.mustflow/skills/security-regression-tests/SKILL.md +0 -131
- package/templates/default/locales/fr/.mustflow/skills/skill-authoring/SKILL.md +0 -110
- package/templates/default/locales/fr/.mustflow/skills/source-freshness-check/SKILL.md +0 -111
- package/templates/default/locales/fr/.mustflow/skills/state-machine-pattern/SKILL.md +0 -214
- package/templates/default/locales/fr/.mustflow/skills/strategy-pattern/SKILL.md +0 -215
- package/templates/default/locales/fr/.mustflow/skills/structure-discovery-gate/SKILL.md +0 -159
- package/templates/default/locales/fr/.mustflow/skills/test-design-guard/SKILL.md +0 -162
- package/templates/default/locales/fr/.mustflow/skills/test-maintenance/SKILL.md +0 -122
- package/templates/default/locales/fr/.mustflow/skills/ui-quality-gate/SKILL.md +0 -117
- package/templates/default/locales/fr/.mustflow/skills/visual-review-artifact/SKILL.md +0 -127
- package/templates/default/locales/fr/.mustflow/skills/visual-review-artifact/assets/review-template.html +0 -286
- package/templates/default/locales/fr/.mustflow/skills/visual-review-artifact/resources.toml +0 -7
- package/templates/default/locales/fr/.mustflow/skills/web-asset-optimization/SKILL.md +0 -108
- package/templates/default/locales/hi/.mustflow/skills/INDEX.md +0 -75
- package/templates/default/locales/hi/.mustflow/skills/adapter-boundary/SKILL.md +0 -193
- package/templates/default/locales/hi/.mustflow/skills/artifact-integrity-check/SKILL.md +0 -114
- package/templates/default/locales/hi/.mustflow/skills/behavior-preserving-refactor/SKILL.md +0 -182
- package/templates/default/locales/hi/.mustflow/skills/code-review/SKILL.md +0 -115
- package/templates/default/locales/hi/.mustflow/skills/codebase-orientation/SKILL.md +0 -115
- package/templates/default/locales/hi/.mustflow/skills/command-pattern/SKILL.md +0 -247
- package/templates/default/locales/hi/.mustflow/skills/composition-over-inheritance/SKILL.md +0 -176
- package/templates/default/locales/hi/.mustflow/skills/contract-sync-check/SKILL.md +0 -116
- package/templates/default/locales/hi/.mustflow/skills/database-change-safety/SKILL.md +0 -155
- package/templates/default/locales/hi/.mustflow/skills/date-number-audit/SKILL.md +0 -116
- package/templates/default/locales/hi/.mustflow/skills/dependency-injection/SKILL.md +0 -161
- package/templates/default/locales/hi/.mustflow/skills/dependency-reality-check/SKILL.md +0 -115
- package/templates/default/locales/hi/.mustflow/skills/diff-risk-review/SKILL.md +0 -136
- package/templates/default/locales/hi/.mustflow/skills/docs-prose-review/SKILL.md +0 -119
- package/templates/default/locales/hi/.mustflow/skills/docs-update/SKILL.md +0 -97
- package/templates/default/locales/hi/.mustflow/skills/external-prompt-injection-defense/SKILL.md +0 -116
- package/templates/default/locales/hi/.mustflow/skills/facade-pattern/SKILL.md +0 -210
- package/templates/default/locales/hi/.mustflow/skills/failure-triage/SKILL.md +0 -97
- package/templates/default/locales/hi/.mustflow/skills/instruction-conflict-scope-check/SKILL.md +0 -118
- package/templates/default/locales/hi/.mustflow/skills/line-ending-hygiene/SKILL.md +0 -111
- package/templates/default/locales/hi/.mustflow/skills/migration-safety-check/SKILL.md +0 -117
- package/templates/default/locales/hi/.mustflow/skills/multi-agent-work-coordination/SKILL.md +0 -260
- package/templates/default/locales/hi/.mustflow/skills/null-object-pattern/SKILL.md +0 -196
- package/templates/default/locales/hi/.mustflow/skills/pattern-scout/SKILL.md +0 -110
- package/templates/default/locales/hi/.mustflow/skills/performance-budget-check/SKILL.md +0 -121
- package/templates/default/locales/hi/.mustflow/skills/project-context-authoring/SKILL.md +0 -107
- package/templates/default/locales/hi/.mustflow/skills/pure-core-imperative-shell/SKILL.md +0 -212
- package/templates/default/locales/hi/.mustflow/skills/readme-authoring/SKILL.md +0 -115
- package/templates/default/locales/hi/.mustflow/skills/repo-improvement-loop/SKILL.md +0 -150
- package/templates/default/locales/hi/.mustflow/skills/repro-first-debug/SKILL.md +0 -112
- package/templates/default/locales/hi/.mustflow/skills/requirement-regression-guard/SKILL.md +0 -152
- package/templates/default/locales/hi/.mustflow/skills/result-option/SKILL.md +0 -186
- package/templates/default/locales/hi/.mustflow/skills/security-privacy-review/SKILL.md +0 -116
- package/templates/default/locales/hi/.mustflow/skills/security-regression-tests/SKILL.md +0 -131
- package/templates/default/locales/hi/.mustflow/skills/skill-authoring/SKILL.md +0 -110
- package/templates/default/locales/hi/.mustflow/skills/source-freshness-check/SKILL.md +0 -111
- package/templates/default/locales/hi/.mustflow/skills/state-machine-pattern/SKILL.md +0 -214
- package/templates/default/locales/hi/.mustflow/skills/strategy-pattern/SKILL.md +0 -215
- package/templates/default/locales/hi/.mustflow/skills/structure-discovery-gate/SKILL.md +0 -159
- package/templates/default/locales/hi/.mustflow/skills/test-design-guard/SKILL.md +0 -162
- package/templates/default/locales/hi/.mustflow/skills/test-maintenance/SKILL.md +0 -122
- package/templates/default/locales/hi/.mustflow/skills/ui-quality-gate/SKILL.md +0 -117
- package/templates/default/locales/hi/.mustflow/skills/visual-review-artifact/SKILL.md +0 -127
- package/templates/default/locales/hi/.mustflow/skills/visual-review-artifact/assets/review-template.html +0 -286
- package/templates/default/locales/hi/.mustflow/skills/visual-review-artifact/resources.toml +0 -7
- package/templates/default/locales/hi/.mustflow/skills/web-asset-optimization/SKILL.md +0 -108
- package/templates/default/locales/ko/.mustflow/skills/INDEX.md +0 -80
- package/templates/default/locales/ko/.mustflow/skills/adapter-boundary/SKILL.md +0 -193
- package/templates/default/locales/ko/.mustflow/skills/artifact-integrity-check/SKILL.md +0 -114
- package/templates/default/locales/ko/.mustflow/skills/behavior-preserving-refactor/SKILL.md +0 -182
- package/templates/default/locales/ko/.mustflow/skills/code-review/SKILL.md +0 -118
- package/templates/default/locales/ko/.mustflow/skills/codebase-orientation/SKILL.md +0 -115
- package/templates/default/locales/ko/.mustflow/skills/command-pattern/SKILL.md +0 -247
- package/templates/default/locales/ko/.mustflow/skills/composition-over-inheritance/SKILL.md +0 -176
- package/templates/default/locales/ko/.mustflow/skills/contract-sync-check/SKILL.md +0 -116
- package/templates/default/locales/ko/.mustflow/skills/database-change-safety/SKILL.md +0 -155
- package/templates/default/locales/ko/.mustflow/skills/date-number-audit/SKILL.md +0 -116
- package/templates/default/locales/ko/.mustflow/skills/dependency-injection/SKILL.md +0 -161
- package/templates/default/locales/ko/.mustflow/skills/dependency-reality-check/SKILL.md +0 -115
- package/templates/default/locales/ko/.mustflow/skills/diff-risk-review/SKILL.md +0 -136
- package/templates/default/locales/ko/.mustflow/skills/docs-prose-review/SKILL.md +0 -119
- package/templates/default/locales/ko/.mustflow/skills/docs-update/SKILL.md +0 -107
- package/templates/default/locales/ko/.mustflow/skills/external-prompt-injection-defense/SKILL.md +0 -116
- package/templates/default/locales/ko/.mustflow/skills/facade-pattern/SKILL.md +0 -210
- package/templates/default/locales/ko/.mustflow/skills/failure-triage/SKILL.md +0 -119
- package/templates/default/locales/ko/.mustflow/skills/instruction-conflict-scope-check/SKILL.md +0 -118
- package/templates/default/locales/ko/.mustflow/skills/line-ending-hygiene/SKILL.md +0 -111
- package/templates/default/locales/ko/.mustflow/skills/migration-safety-check/SKILL.md +0 -117
- package/templates/default/locales/ko/.mustflow/skills/multi-agent-work-coordination/SKILL.md +0 -259
- package/templates/default/locales/ko/.mustflow/skills/null-object-pattern/SKILL.md +0 -196
- package/templates/default/locales/ko/.mustflow/skills/pattern-scout/SKILL.md +0 -110
- package/templates/default/locales/ko/.mustflow/skills/performance-budget-check/SKILL.md +0 -121
- package/templates/default/locales/ko/.mustflow/skills/project-context-authoring/SKILL.md +0 -107
- package/templates/default/locales/ko/.mustflow/skills/pure-core-imperative-shell/SKILL.md +0 -212
- package/templates/default/locales/ko/.mustflow/skills/readme-authoring/SKILL.md +0 -115
- package/templates/default/locales/ko/.mustflow/skills/repo-improvement-loop/SKILL.md +0 -150
- package/templates/default/locales/ko/.mustflow/skills/repro-first-debug/SKILL.md +0 -112
- package/templates/default/locales/ko/.mustflow/skills/requirement-regression-guard/SKILL.md +0 -152
- package/templates/default/locales/ko/.mustflow/skills/result-option/SKILL.md +0 -186
- package/templates/default/locales/ko/.mustflow/skills/security-privacy-review/SKILL.md +0 -116
- package/templates/default/locales/ko/.mustflow/skills/security-regression-tests/SKILL.md +0 -131
- package/templates/default/locales/ko/.mustflow/skills/skill-authoring/SKILL.md +0 -110
- package/templates/default/locales/ko/.mustflow/skills/source-freshness-check/SKILL.md +0 -111
- package/templates/default/locales/ko/.mustflow/skills/state-machine-pattern/SKILL.md +0 -214
- package/templates/default/locales/ko/.mustflow/skills/strategy-pattern/SKILL.md +0 -215
- package/templates/default/locales/ko/.mustflow/skills/structure-discovery-gate/SKILL.md +0 -159
- package/templates/default/locales/ko/.mustflow/skills/test-design-guard/SKILL.md +0 -162
- package/templates/default/locales/ko/.mustflow/skills/test-maintenance/SKILL.md +0 -130
- package/templates/default/locales/ko/.mustflow/skills/ui-quality-gate/SKILL.md +0 -117
- package/templates/default/locales/ko/.mustflow/skills/visual-review-artifact/SKILL.md +0 -127
- package/templates/default/locales/ko/.mustflow/skills/visual-review-artifact/assets/review-template.html +0 -286
- package/templates/default/locales/ko/.mustflow/skills/visual-review-artifact/resources.toml +0 -7
- package/templates/default/locales/ko/.mustflow/skills/web-asset-optimization/SKILL.md +0 -108
- package/templates/default/locales/zh/.mustflow/skills/INDEX.md +0 -74
- package/templates/default/locales/zh/.mustflow/skills/adapter-boundary/SKILL.md +0 -193
- package/templates/default/locales/zh/.mustflow/skills/artifact-integrity-check/SKILL.md +0 -114
- package/templates/default/locales/zh/.mustflow/skills/behavior-preserving-refactor/SKILL.md +0 -182
- package/templates/default/locales/zh/.mustflow/skills/code-review/SKILL.md +0 -115
- package/templates/default/locales/zh/.mustflow/skills/codebase-orientation/SKILL.md +0 -115
- package/templates/default/locales/zh/.mustflow/skills/command-pattern/SKILL.md +0 -247
- package/templates/default/locales/zh/.mustflow/skills/composition-over-inheritance/SKILL.md +0 -176
- package/templates/default/locales/zh/.mustflow/skills/contract-sync-check/SKILL.md +0 -116
- package/templates/default/locales/zh/.mustflow/skills/database-change-safety/SKILL.md +0 -155
- package/templates/default/locales/zh/.mustflow/skills/date-number-audit/SKILL.md +0 -116
- package/templates/default/locales/zh/.mustflow/skills/dependency-injection/SKILL.md +0 -161
- package/templates/default/locales/zh/.mustflow/skills/dependency-reality-check/SKILL.md +0 -115
- package/templates/default/locales/zh/.mustflow/skills/diff-risk-review/SKILL.md +0 -136
- package/templates/default/locales/zh/.mustflow/skills/docs-prose-review/SKILL.md +0 -119
- package/templates/default/locales/zh/.mustflow/skills/docs-update/SKILL.md +0 -97
- package/templates/default/locales/zh/.mustflow/skills/external-prompt-injection-defense/SKILL.md +0 -116
- package/templates/default/locales/zh/.mustflow/skills/facade-pattern/SKILL.md +0 -210
- package/templates/default/locales/zh/.mustflow/skills/failure-triage/SKILL.md +0 -96
- package/templates/default/locales/zh/.mustflow/skills/instruction-conflict-scope-check/SKILL.md +0 -118
- package/templates/default/locales/zh/.mustflow/skills/line-ending-hygiene/SKILL.md +0 -111
- package/templates/default/locales/zh/.mustflow/skills/migration-safety-check/SKILL.md +0 -117
- package/templates/default/locales/zh/.mustflow/skills/multi-agent-work-coordination/SKILL.md +0 -260
- package/templates/default/locales/zh/.mustflow/skills/null-object-pattern/SKILL.md +0 -196
- package/templates/default/locales/zh/.mustflow/skills/pattern-scout/SKILL.md +0 -110
- package/templates/default/locales/zh/.mustflow/skills/performance-budget-check/SKILL.md +0 -121
- package/templates/default/locales/zh/.mustflow/skills/project-context-authoring/SKILL.md +0 -107
- package/templates/default/locales/zh/.mustflow/skills/pure-core-imperative-shell/SKILL.md +0 -212
- package/templates/default/locales/zh/.mustflow/skills/readme-authoring/SKILL.md +0 -115
- package/templates/default/locales/zh/.mustflow/skills/repo-improvement-loop/SKILL.md +0 -150
- package/templates/default/locales/zh/.mustflow/skills/repro-first-debug/SKILL.md +0 -112
- package/templates/default/locales/zh/.mustflow/skills/requirement-regression-guard/SKILL.md +0 -152
- package/templates/default/locales/zh/.mustflow/skills/result-option/SKILL.md +0 -186
- package/templates/default/locales/zh/.mustflow/skills/security-privacy-review/SKILL.md +0 -116
- package/templates/default/locales/zh/.mustflow/skills/security-regression-tests/SKILL.md +0 -131
- package/templates/default/locales/zh/.mustflow/skills/skill-authoring/SKILL.md +0 -110
- package/templates/default/locales/zh/.mustflow/skills/source-freshness-check/SKILL.md +0 -111
- package/templates/default/locales/zh/.mustflow/skills/state-machine-pattern/SKILL.md +0 -214
- package/templates/default/locales/zh/.mustflow/skills/strategy-pattern/SKILL.md +0 -215
- package/templates/default/locales/zh/.mustflow/skills/structure-discovery-gate/SKILL.md +0 -159
- package/templates/default/locales/zh/.mustflow/skills/test-design-guard/SKILL.md +0 -162
- package/templates/default/locales/zh/.mustflow/skills/test-maintenance/SKILL.md +0 -122
- package/templates/default/locales/zh/.mustflow/skills/ui-quality-gate/SKILL.md +0 -117
- package/templates/default/locales/zh/.mustflow/skills/visual-review-artifact/SKILL.md +0 -127
- package/templates/default/locales/zh/.mustflow/skills/visual-review-artifact/assets/review-template.html +0 -286
- package/templates/default/locales/zh/.mustflow/skills/visual-review-artifact/resources.toml +0 -7
- package/templates/default/locales/zh/.mustflow/skills/web-asset-optimization/SKILL.md +0 -108
|
@@ -0,0 +1,235 @@
|
|
|
1
|
+
import { existsSync, lstatSync, readFileSync, readdirSync } from 'node:fs';
|
|
2
|
+
import path from 'node:path';
|
|
3
|
+
const ADAPTER_SCHEMA_VERSION = '1';
|
|
4
|
+
const MAX_HOST_INSTRUCTION_BYTES = 256 * 1024;
|
|
5
|
+
const MAX_CURSOR_RULE_FILES = 100;
|
|
6
|
+
const HOST_INSTRUCTION_FILES = [
|
|
7
|
+
{ host: 'claude_code', path: 'CLAUDE.md' },
|
|
8
|
+
{ host: 'gemini_cli', path: 'GEMINI.md' },
|
|
9
|
+
{ host: 'github_copilot', path: '.github/copilot-instructions.md' },
|
|
10
|
+
];
|
|
11
|
+
const ADAPTER_SURFACE_DEFINITIONS = [
|
|
12
|
+
{ host: 'claude_code', path: 'CLAUDE.md', kind: 'host_instruction_file' },
|
|
13
|
+
{ host: 'gemini_cli', path: 'GEMINI.md', kind: 'host_instruction_file' },
|
|
14
|
+
{ host: 'github_copilot', path: '.github/copilot-instructions.md', kind: 'host_instruction_file' },
|
|
15
|
+
{ host: 'cursor', path: '.cursor/rules/', kind: 'host_instruction_file' },
|
|
16
|
+
{ host: 'generic', path: '.vscode/settings.json', kind: 'editor_settings' },
|
|
17
|
+
{ host: 'generic', path: '.github/workflows/', kind: 'ci_configuration' },
|
|
18
|
+
{ host: 'generic', path: 'Makefile', kind: 'command_adapter' },
|
|
19
|
+
{ host: 'generic', path: 'justfile', kind: 'command_adapter' },
|
|
20
|
+
{ host: 'generic', path: 'Justfile', kind: 'command_adapter' },
|
|
21
|
+
{ host: 'generic', path: 'Taskfile.yml', kind: 'command_adapter' },
|
|
22
|
+
{ host: 'generic', path: 'package.json#scripts', kind: 'package_manager_scripts' },
|
|
23
|
+
];
|
|
24
|
+
const HOST_AGENT_CONFLICT_PATTERNS = [
|
|
25
|
+
/\bignore\s+AGENTS\.md\b/iu,
|
|
26
|
+
/\bdo\s+not\s+(?:read|follow|use)\s+AGENTS\.md\b/iu,
|
|
27
|
+
/\boverride\s+AGENTS\.md\b/iu,
|
|
28
|
+
/\binstead\s+of\s+AGENTS\.md\b/iu,
|
|
29
|
+
/\bAGENTS\.md\s+(?:does\s+not|doesn't)\s+apply\b/iu,
|
|
30
|
+
];
|
|
31
|
+
const DIRECT_COMMAND_PATTERNS = [
|
|
32
|
+
/\b(?:npm|pnpm|bun|yarn)\s+(?:run\s+)?(?:test|build|lint|check)\b/iu,
|
|
33
|
+
/\bdeno\s+task\b/iu,
|
|
34
|
+
/\bcargo\s+(?:test|build|check|clippy)\b/iu,
|
|
35
|
+
/\bgo\s+test\b/iu,
|
|
36
|
+
/\bmake\s+[A-Za-z0-9_-]+\b/iu,
|
|
37
|
+
/\bjust\s+[A-Za-z0-9_-]+\b/iu,
|
|
38
|
+
];
|
|
39
|
+
function toPosixPath(value) {
|
|
40
|
+
return value.split(path.sep).join('/');
|
|
41
|
+
}
|
|
42
|
+
function resolveProjectPath(projectRoot, relativePath) {
|
|
43
|
+
return path.join(projectRoot, ...relativePath.split('/'));
|
|
44
|
+
}
|
|
45
|
+
function fileExists(projectRoot, relativePath) {
|
|
46
|
+
return existsSync(resolveProjectPath(projectRoot, relativePath));
|
|
47
|
+
}
|
|
48
|
+
function packageScriptsExist(projectRoot) {
|
|
49
|
+
const packageJsonPath = resolveProjectPath(projectRoot, 'package.json');
|
|
50
|
+
if (!existsSync(packageJsonPath)) {
|
|
51
|
+
return false;
|
|
52
|
+
}
|
|
53
|
+
try {
|
|
54
|
+
const parsed = JSON.parse(readFileSync(packageJsonPath, 'utf8'));
|
|
55
|
+
return !!parsed.scripts && typeof parsed.scripts === 'object';
|
|
56
|
+
}
|
|
57
|
+
catch {
|
|
58
|
+
return false;
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
function surfaceExists(projectRoot, surfacePath) {
|
|
62
|
+
if (surfacePath === 'package.json#scripts') {
|
|
63
|
+
return packageScriptsExist(projectRoot);
|
|
64
|
+
}
|
|
65
|
+
const relativePath = surfacePath.endsWith('/') ? surfacePath.slice(0, -1) : surfacePath;
|
|
66
|
+
return fileExists(projectRoot, relativePath);
|
|
67
|
+
}
|
|
68
|
+
function makeHostFile(definition, status) {
|
|
69
|
+
return {
|
|
70
|
+
host: definition.host,
|
|
71
|
+
path: definition.path,
|
|
72
|
+
status,
|
|
73
|
+
instruction_role: 'host_instruction',
|
|
74
|
+
authority: 'host_specific',
|
|
75
|
+
mustflow_authority: 'advisory',
|
|
76
|
+
lifecycle: 'user_editable',
|
|
77
|
+
generated_by_mustflow: false,
|
|
78
|
+
binding_to_host: status === 'present',
|
|
79
|
+
mustflow_command_authority: false,
|
|
80
|
+
};
|
|
81
|
+
}
|
|
82
|
+
function makeFinding(severity, code, pathValue, message, requiredChange) {
|
|
83
|
+
return {
|
|
84
|
+
severity,
|
|
85
|
+
code,
|
|
86
|
+
path: pathValue,
|
|
87
|
+
message,
|
|
88
|
+
required_change: requiredChange,
|
|
89
|
+
};
|
|
90
|
+
}
|
|
91
|
+
function readHostInstruction(projectRoot, relativePath) {
|
|
92
|
+
const fullPath = resolveProjectPath(projectRoot, relativePath);
|
|
93
|
+
if (!existsSync(fullPath)) {
|
|
94
|
+
return { status: 'absent', text: null };
|
|
95
|
+
}
|
|
96
|
+
try {
|
|
97
|
+
const stat = lstatSync(fullPath);
|
|
98
|
+
if (stat.isSymbolicLink()) {
|
|
99
|
+
return {
|
|
100
|
+
status: 'symlink_not_read',
|
|
101
|
+
text: null,
|
|
102
|
+
finding: makeFinding('warning', 'host_instruction_symlink_not_read', relativePath, 'Host instruction path is a symbolic link, so mustflow did not read its target.', false),
|
|
103
|
+
};
|
|
104
|
+
}
|
|
105
|
+
if (!stat.isFile()) {
|
|
106
|
+
return {
|
|
107
|
+
status: 'unreadable',
|
|
108
|
+
text: null,
|
|
109
|
+
finding: makeFinding('warning', 'host_instruction_not_regular_file', relativePath, 'Host instruction path exists but is not a regular file.', false),
|
|
110
|
+
};
|
|
111
|
+
}
|
|
112
|
+
if (stat.size > MAX_HOST_INSTRUCTION_BYTES) {
|
|
113
|
+
return {
|
|
114
|
+
status: 'too_large_not_read',
|
|
115
|
+
text: null,
|
|
116
|
+
finding: makeFinding('warning', 'host_instruction_too_large_not_read', relativePath, 'Host instruction file is larger than the read limit, so mustflow reported metadata only.', false),
|
|
117
|
+
};
|
|
118
|
+
}
|
|
119
|
+
return { status: 'present', text: readFileSync(fullPath, 'utf8') };
|
|
120
|
+
}
|
|
121
|
+
catch {
|
|
122
|
+
return {
|
|
123
|
+
status: 'unreadable',
|
|
124
|
+
text: null,
|
|
125
|
+
finding: makeFinding('warning', 'host_instruction_unreadable', relativePath, 'Host instruction file could not be read.', false),
|
|
126
|
+
};
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
function collectCursorRuleDefinitions(projectRoot) {
|
|
130
|
+
const cursorRulesPath = resolveProjectPath(projectRoot, '.cursor/rules');
|
|
131
|
+
if (!existsSync(cursorRulesPath)) {
|
|
132
|
+
return [];
|
|
133
|
+
}
|
|
134
|
+
try {
|
|
135
|
+
const stat = lstatSync(cursorRulesPath);
|
|
136
|
+
if (!stat.isDirectory() || stat.isSymbolicLink()) {
|
|
137
|
+
return [{ host: 'cursor', path: '.cursor/rules/' }];
|
|
138
|
+
}
|
|
139
|
+
return readdirSync(cursorRulesPath, { withFileTypes: true })
|
|
140
|
+
.filter((entry) => entry.isFile() && (entry.name.endsWith('.md') || entry.name.endsWith('.mdc')))
|
|
141
|
+
.map((entry) => ({ host: 'cursor', path: `.cursor/rules/${entry.name}` }))
|
|
142
|
+
.sort((left, right) => left.path.localeCompare(right.path))
|
|
143
|
+
.slice(0, MAX_CURSOR_RULE_FILES);
|
|
144
|
+
}
|
|
145
|
+
catch {
|
|
146
|
+
return [{ host: 'cursor', path: '.cursor/rules/' }];
|
|
147
|
+
}
|
|
148
|
+
}
|
|
149
|
+
function inspectHostInstruction(definition, text) {
|
|
150
|
+
if (!text) {
|
|
151
|
+
return [];
|
|
152
|
+
}
|
|
153
|
+
const findings = [
|
|
154
|
+
makeFinding('info', 'host_instruction_present', definition.path, 'Host-specific instruction file is present. It may guide that host, but it is not mustflow command authority.', false),
|
|
155
|
+
];
|
|
156
|
+
if (HOST_AGENT_CONFLICT_PATTERNS.some((pattern) => pattern.test(text))) {
|
|
157
|
+
findings.push(makeFinding('warning', 'host_instruction_conflicts_with_agents', definition.path, 'Host instruction appears to tell agents to ignore or override AGENTS.md. Resolve the instruction conflict before relying on the host adapter.', true));
|
|
158
|
+
}
|
|
159
|
+
if (DIRECT_COMMAND_PATTERNS.some((pattern) => pattern.test(text))) {
|
|
160
|
+
findings.push(makeFinding('warning', 'host_instruction_direct_command_hint', definition.path, 'Host instruction mentions direct tool commands. Agents must still use configured mustflow command intents for project verification.', false));
|
|
161
|
+
}
|
|
162
|
+
return findings;
|
|
163
|
+
}
|
|
164
|
+
function buildAdapterSurfaces(projectRoot) {
|
|
165
|
+
return ADAPTER_SURFACE_DEFINITIONS.map((definition) => ({
|
|
166
|
+
host: definition.host,
|
|
167
|
+
path: definition.path,
|
|
168
|
+
kind: definition.kind,
|
|
169
|
+
present: surfaceExists(projectRoot, definition.path),
|
|
170
|
+
generated_by_mustflow: false,
|
|
171
|
+
generation_policy: 'explicit_user_request_only',
|
|
172
|
+
mustflow_command_authority: false,
|
|
173
|
+
}));
|
|
174
|
+
}
|
|
175
|
+
export function inspectAdapterCompatibility(projectRoot) {
|
|
176
|
+
const hostDefinitions = [...HOST_INSTRUCTION_FILES, ...collectCursorRuleDefinitions(projectRoot)];
|
|
177
|
+
const hostFiles = [];
|
|
178
|
+
const findings = [
|
|
179
|
+
makeFinding('info', 'command_authority_boundary', '.mustflow/config/commands.toml', 'Project command authority remains .mustflow/config/commands.toml; host-specific files cannot authorize command execution.', false),
|
|
180
|
+
makeFinding('info', 'adapter_generation_not_default', null, 'mustflow does not generate host adapters, editor settings, CI files, Makefile, justfile, Taskfile.yml, or package-manager scripts by default.', false),
|
|
181
|
+
makeFinding('info', 'runtime_policy_not_repo_visible', null, 'Host approval and sandbox policies are runtime settings, so this report can only inspect repository-visible compatibility hints.', false),
|
|
182
|
+
];
|
|
183
|
+
for (const definition of hostDefinitions) {
|
|
184
|
+
const read = readHostInstruction(projectRoot, definition.path);
|
|
185
|
+
hostFiles.push(makeHostFile(definition, read.status));
|
|
186
|
+
if (read.finding) {
|
|
187
|
+
findings.push(read.finding);
|
|
188
|
+
}
|
|
189
|
+
findings.push(...inspectHostInstruction(definition, read.text));
|
|
190
|
+
}
|
|
191
|
+
const adapterSurfaces = buildAdapterSurfaces(projectRoot);
|
|
192
|
+
const compatibilityNotes = findings.filter((finding) => !finding.required_change);
|
|
193
|
+
const requiredChanges = findings.filter((finding) => finding.required_change);
|
|
194
|
+
const doesNotGenerate = ADAPTER_SURFACE_DEFINITIONS.map((definition) => definition.path);
|
|
195
|
+
return {
|
|
196
|
+
schema_version: ADAPTER_SCHEMA_VERSION,
|
|
197
|
+
command: 'adapters_status',
|
|
198
|
+
ok: true,
|
|
199
|
+
mustflow_root: projectRoot,
|
|
200
|
+
agents_file: {
|
|
201
|
+
path: 'AGENTS.md',
|
|
202
|
+
present: fileExists(projectRoot, 'AGENTS.md'),
|
|
203
|
+
authority: 'binding',
|
|
204
|
+
lifecycle: 'user_editable',
|
|
205
|
+
generated_by_mustflow: fileExists(projectRoot, '.mustflow/config/manifest.lock.toml'),
|
|
206
|
+
},
|
|
207
|
+
summary: {
|
|
208
|
+
host_instruction_files: hostFiles.filter((file) => file.status === 'present').length,
|
|
209
|
+
adapter_surfaces_present: adapterSurfaces.filter((surface) => surface.present).length,
|
|
210
|
+
compatibility_notes: compatibilityNotes.length,
|
|
211
|
+
conflicts: requiredChanges.filter((finding) => finding.code === 'host_instruction_conflicts_with_agents').length,
|
|
212
|
+
required_changes: requiredChanges.length,
|
|
213
|
+
},
|
|
214
|
+
host_files: hostFiles,
|
|
215
|
+
adapter_surfaces: adapterSurfaces,
|
|
216
|
+
findings,
|
|
217
|
+
compatibility_notes: compatibilityNotes,
|
|
218
|
+
required_changes: requiredChanges,
|
|
219
|
+
runtime_policy: {
|
|
220
|
+
approval_policy: 'not_repo_visible',
|
|
221
|
+
sandbox_policy: 'not_repo_visible',
|
|
222
|
+
stricter_than_mustflow: 'unknown',
|
|
223
|
+
note: 'Repository files cannot prove host runtime approval or sandbox strictness.',
|
|
224
|
+
},
|
|
225
|
+
boundaries: {
|
|
226
|
+
command_authority: '.mustflow/config/commands.toml',
|
|
227
|
+
host_files_are_command_authority: false,
|
|
228
|
+
adapter_generation: 'explicit_user_request_only',
|
|
229
|
+
does_not_generate: doesNotGenerate,
|
|
230
|
+
},
|
|
231
|
+
};
|
|
232
|
+
}
|
|
233
|
+
export function formatAdapterPath(relativePath) {
|
|
234
|
+
return toPosixPath(relativePath);
|
|
235
|
+
}
|
|
@@ -1,3 +1,8 @@
|
|
|
1
|
+
export const PUBLIC_SURFACE_UPDATE_POLICIES = [
|
|
2
|
+
'update',
|
|
3
|
+
'update_or_mark_stale',
|
|
4
|
+
'not_applicable',
|
|
5
|
+
];
|
|
1
6
|
function surface(kind, category, isPublicSurface, validationReasons, affectedContracts, updatePolicy, driftChecks) {
|
|
2
7
|
return {
|
|
3
8
|
kind,
|
|
@@ -28,6 +33,7 @@ const CHANGE_CLASSIFICATION_RULES = [
|
|
|
28
33
|
rule('installed_template_translation', /^templates\/[^/]+\/locales\/[^/]+\//u, ['installed_template', 'translation'], surface('installed_template_translation', 'installed-template', true, ['i18n_change', 'template_version_change'], ['installed template files', 'localized workflow documents', 'template i18n metadata'], 'update_or_mark_stale', ['template i18n metadata', 'localized frontmatter', 'source revision'])),
|
|
29
34
|
rule('installed_template', /^templates\/[^/]+\//u, ['installed_template'], surface('installed_template', 'installed-template', true, ['template_version_change', 'packaging_change'], ['installed template files', 'package contents', 'template manifest'], 'update', ['template manifest', 'package inventory', 'localized copies'])),
|
|
30
35
|
rule('workflow_root', /^(AGENTS\.md|\.mustflow\/(?:docs|context|skills|config)\/)/u, ['workflow'], surface('workflow_root', 'workflow', true, ['mustflow_docs_change', 'mustflow_config_change'], ['agent workflow contract', 'command contract', 'installed workflow files'], 'update', ['strict workflow validation', 'installed template parity', 'skill route alignment'])),
|
|
36
|
+
rule('host_instruction', /^(CLAUDE\.md|GEMINI\.md|\.github\/copilot-instructions\.md|\.cursor\/rules\/[^/]+\.(?:md|mdc))$/u, ['workflow', 'host_instruction'], surface('host_instruction', 'workflow', true, ['mustflow_docs_change'], ['host instruction compatibility', 'agent workflow contract', 'command contract boundary'], 'update_or_mark_stale', ['host instruction conflicts', 'command contract boundary'])),
|
|
31
37
|
rule('example', /^examples\//u, ['example'], surface('example', 'example', true, ['docs_change', 'public_api_change'], ['generated examples', 'human-readable examples'], 'update', ['example commands', 'linked docs', 'public behavior claims'])),
|
|
32
38
|
rule('schema_contract', /^schemas\//u, ['schema'], surface('schema_contract', 'contract', true, ['public_api_change', 'release_risk'], ['JSON schema', 'machine-readable output contract'], 'update', ['schema tests', 'documented JSON fields', 'package inventory'])),
|
|
33
39
|
rule('package_metadata', /^package\.json$/u, ['package_metadata'], surface('package_metadata', 'release', true, ['package_metadata_change', 'release_risk'], ['npm package metadata', 'published package contents'], 'update', ['package metadata tests', 'version source discovery', 'published file inventory'])),
|
|
@@ -73,6 +79,9 @@ export function listChangeClassificationRuleDescriptors() {
|
|
|
73
79
|
surface: classificationRule.surface,
|
|
74
80
|
}));
|
|
75
81
|
}
|
|
82
|
+
export function listChangeClassificationValidationReasons() {
|
|
83
|
+
return uniqueSorted(CHANGE_CLASSIFICATION_RULES.flatMap((classificationRule) => classificationRule.surface.validationReasons));
|
|
84
|
+
}
|
|
76
85
|
export function createChangeClassificationReport(source, relativePaths) {
|
|
77
86
|
const files = uniqueSorted(relativePaths.map(normalizeStatusPath).filter((filePath) => filePath.length > 0));
|
|
78
87
|
const classifications = files.map(classifyChangePath);
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { CHANGE_CLASSIFICATION_SURFACE_AUTHORITY, createPathTarget, } from './surface-decision-model.js';
|
|
2
2
|
import { createVerificationPlan, } from './verification-plan.js';
|
|
3
|
+
import { createVerificationDecisionGraph, } from './verification-decision-graph.js';
|
|
3
4
|
import { createVerificationSchedule, } from './verification-scheduler.js';
|
|
4
5
|
export const CHANGE_VERIFICATION_SCHEMA_VERSION = '1';
|
|
5
6
|
function uniqueSorted(values) {
|
|
@@ -62,11 +63,16 @@ function gapForRequirement(requirement, candidates) {
|
|
|
62
63
|
}
|
|
63
64
|
export function createChangeVerificationReport(classificationReport, commandContract, projectRoot) {
|
|
64
65
|
const requirements = classificationReport.summary.validationReasons.map((reason) => createVerificationRequirement(classificationReport, reason));
|
|
65
|
-
const
|
|
66
|
-
|
|
66
|
+
const plans = requirements.map((requirement) => ({
|
|
67
|
+
requirement,
|
|
68
|
+
candidates: createVerificationPlan(commandContract, requirement.reason).candidates,
|
|
69
|
+
}));
|
|
70
|
+
const candidatePlans = plans.flatMap((plan) => plan.candidates);
|
|
71
|
+
const candidates = plans.flatMap((plan) => plan.candidates.map((candidate) => toChangeVerificationCandidate(plan.requirement.reason, candidate)));
|
|
67
72
|
const gaps = requirements
|
|
68
73
|
.map((requirement) => gapForRequirement(requirement, candidates))
|
|
69
74
|
.filter((gap) => gap !== null);
|
|
75
|
+
const schedule = createVerificationSchedule(projectRoot, commandContract, candidatePlans);
|
|
70
76
|
return {
|
|
71
77
|
schema_version: CHANGE_VERIFICATION_SCHEMA_VERSION,
|
|
72
78
|
source: classificationReport.source,
|
|
@@ -75,6 +81,7 @@ export function createChangeVerificationReport(classificationReport, commandCont
|
|
|
75
81
|
requirements,
|
|
76
82
|
candidates,
|
|
77
83
|
gaps,
|
|
78
|
-
schedule
|
|
84
|
+
schedule,
|
|
85
|
+
decision_graph: createVerificationDecisionGraph(commandContract, requirements, candidates, gaps, schedule),
|
|
79
86
|
};
|
|
80
87
|
}
|
|
@@ -20,6 +20,10 @@ const CHECK_ISSUE_ID_RULES = [
|
|
|
20
20
|
['mustflow.release.template_version_intentionally_unchanged', /^Strict warning: templates\/default\/manifest\.toml version "[^"]+" is older than package\.json version "[^"]+"; this is allowed only when the installed template surface is unchanged$/u],
|
|
21
21
|
['mustflow.preferences.release_versioning_contract_authority', /^Strict: \[preferences\.release\.versioning\]\.[a-z_]+ cannot define version sources or release authority; use \.mustflow\/config\/versioning\.toml or \.mustflow\/config\/commands\.toml$/u],
|
|
22
22
|
['mustflow.preferences.verification_selection_command_authority', /^Strict: \[preferences\.verification\.selection\]\.[a-z_]+ cannot define command authority; use \.mustflow\/config\/commands\.toml$/u],
|
|
23
|
+
['mustflow.contract_model.deferred_policy', /^Strict: \.mustflow\/config\/policy\.toml is deferred; use narrow candidate contract files instead$/u],
|
|
24
|
+
['mustflow.contract_model.command_authority_field', /^Strict: \.mustflow\/config\/(?:changes|surfaces)\.toml .+ cannot define command authority; use \.mustflow\/config\/commands\.toml$/u],
|
|
25
|
+
['mustflow.contract_model.invalid_match_kind', /^Strict: \.mustflow\/config\/(?:changes|surfaces)\.toml rules\[\d+\]\.match\.kind must be "exact", "prefix", or "glob"; regular expressions are deferred$/u],
|
|
26
|
+
['mustflow.contract_model.invalid_shape', /^Strict: \.mustflow\/config\/(?:changes|surfaces)\.toml .+(?:must be|must define|is not allowed)/u],
|
|
23
27
|
['mustflow.skill.procedure_only', /^Strict: \.mustflow\/skills\/[^/]+\/SKILL\.md metadata\.mustflow_kind must be "procedure"$/u],
|
|
24
28
|
['mustflow.skill.raw_command_block', /^Strict: \.mustflow\/skills\/[^/]+\/SKILL\.md contains a raw shell command block; reference command intents instead$/u],
|
|
25
29
|
['mustflow.skill.command_permission_claim', /^Strict: \.mustflow\/skills\/[^/]+\/SKILL\.md claims command execution permission; keep permissions in \.mustflow\/config\/commands\.toml$/u],
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { COMMAND_LIFECYCLES, COMMAND_RUN_POLICIES, LONG_RUNNING_LIFECYCLES, isRecord, } from './config-loading.js';
|
|
2
|
+
import { COMMAND_ENV_POLICIES } from './command-env.js';
|
|
2
3
|
import { COMMAND_EFFECT_CONCURRENCY, COMMAND_EFFECT_MODES, COMMAND_EFFECT_TYPES, validateCommandEffectLockWarnings, validateCommandEffects, } from './command-effects.js';
|
|
3
4
|
import { commandIntentHasBlockedShellBackgroundPattern, commandIntentHasCommandSource, commandIntentNameIsSafe, } from './command-contract-rules.js';
|
|
4
5
|
function commandContractIssue(message) {
|
|
@@ -31,6 +32,15 @@ function validateStringField(table, key, label, issues) {
|
|
|
31
32
|
issues.push(commandContractIssue(`${label} must be a string`));
|
|
32
33
|
}
|
|
33
34
|
}
|
|
35
|
+
function validateStringArrayField(table, key, label, issues) {
|
|
36
|
+
if (!hasOwn(table, key)) {
|
|
37
|
+
return;
|
|
38
|
+
}
|
|
39
|
+
const value = table[key];
|
|
40
|
+
if (!Array.isArray(value) || value.some((entry) => typeof entry !== 'string' || entry.trim().length === 0)) {
|
|
41
|
+
issues.push(commandContractIssue(`${label} must be a string array`));
|
|
42
|
+
}
|
|
43
|
+
}
|
|
34
44
|
function validatePositiveIntegerField(table, key, label, issues) {
|
|
35
45
|
if (hasOwn(table, key) && !isPositiveInteger(table[key])) {
|
|
36
46
|
issues.push(commandContractIssue(`${label} must be a positive integer`));
|
|
@@ -57,6 +67,8 @@ function validateCommandDefaults(commandsToml, issues) {
|
|
|
57
67
|
validateStringField(defaults, 'default_cwd', '[commands.defaults].default_cwd', issues);
|
|
58
68
|
validateStringField(defaults, 'stdin', '[commands.defaults].stdin', issues);
|
|
59
69
|
validateStringField(defaults, 'on_timeout', '[commands.defaults].on_timeout', issues);
|
|
70
|
+
validateAllowedStringField(defaults, 'env_policy', '[commands.defaults].env_policy', COMMAND_ENV_POLICIES, issues);
|
|
71
|
+
validateStringArrayField(defaults, 'env_allowlist', '[commands.defaults].env_allowlist', issues);
|
|
60
72
|
validatePositiveIntegerField(defaults, 'default_timeout_seconds', '[commands.defaults].default_timeout_seconds', issues);
|
|
61
73
|
validatePositiveIntegerField(defaults, 'max_output_bytes', '[commands.defaults].max_output_bytes', issues);
|
|
62
74
|
validatePositiveIntegerField(defaults, 'kill_after_seconds', '[commands.defaults].kill_after_seconds', issues);
|
|
@@ -115,6 +127,8 @@ function validateCommandIntent(intentName, intent, issues) {
|
|
|
115
127
|
validateStringField(intent, 'status', `[commands.intents.${intentName}].status`, issues);
|
|
116
128
|
validateAllowedStringField(intent, 'lifecycle', `[commands.intents.${intentName}].lifecycle`, COMMAND_LIFECYCLES, issues);
|
|
117
129
|
validateAllowedStringField(intent, 'run_policy', `[commands.intents.${intentName}].run_policy`, COMMAND_RUN_POLICIES, issues);
|
|
130
|
+
validateAllowedStringField(intent, 'env_policy', `[commands.intents.${intentName}].env_policy`, COMMAND_ENV_POLICIES, issues);
|
|
131
|
+
validateStringArrayField(intent, 'env_allowlist', `[commands.intents.${intentName}].env_allowlist`, issues);
|
|
118
132
|
if (intent.status !== 'configured') {
|
|
119
133
|
return;
|
|
120
134
|
}
|
package/dist/core/command-cwd.js
CHANGED
|
@@ -1,12 +1,24 @@
|
|
|
1
|
+
import { existsSync, realpathSync, statSync } from 'node:fs';
|
|
1
2
|
import path from 'node:path';
|
|
3
|
+
function normalizeForContainment(value) {
|
|
4
|
+
const normalized = path.resolve(value);
|
|
5
|
+
return process.platform === 'win32' ? normalized.toLowerCase() : normalized;
|
|
6
|
+
}
|
|
7
|
+
function isInsideOrEqual(parent, child) {
|
|
8
|
+
const normalizedParent = normalizeForContainment(parent);
|
|
9
|
+
const normalizedChild = normalizeForContainment(child);
|
|
10
|
+
return normalizedChild === normalizedParent || normalizedChild.startsWith(`${normalizedParent}${path.sep}`);
|
|
11
|
+
}
|
|
2
12
|
export function resolveSafeProjectCwd(projectRoot, rawCwd) {
|
|
3
13
|
const cwd = rawCwd ?? '.';
|
|
4
14
|
const resolved = path.resolve(projectRoot, cwd);
|
|
5
|
-
const
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
15
|
+
const rootRealPath = realpathSync.native(projectRoot);
|
|
16
|
+
if (!existsSync(resolved) || !statSync(resolved).isDirectory()) {
|
|
17
|
+
throw new Error(`Intent cwd must stay inside the current root and resolve to an existing directory: ${cwd}`);
|
|
18
|
+
}
|
|
19
|
+
const cwdRealPath = realpathSync.native(resolved);
|
|
20
|
+
if (!isInsideOrEqual(rootRealPath, cwdRealPath)) {
|
|
21
|
+
throw new Error(`Intent cwd must stay inside the current root and resolve to an existing directory: ${cwd}`);
|
|
10
22
|
}
|
|
11
|
-
return
|
|
23
|
+
return cwdRealPath;
|
|
12
24
|
}
|
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
import path from 'node:path';
|
|
2
|
+
import { readString, readStringArray } from './config-loading.js';
|
|
3
|
+
export const COMMAND_ENV_POLICIES = new Set(['inherit', 'minimal', 'allowlist']);
|
|
4
|
+
export const DEFAULT_COMMAND_ENV_POLICY = 'inherit';
|
|
5
|
+
const BASE_MINIMAL_ENV_KEYS = [
|
|
6
|
+
'CI',
|
|
7
|
+
'COLORTERM',
|
|
8
|
+
'COMSPEC',
|
|
9
|
+
'ComSpec',
|
|
10
|
+
'FORCE_COLOR',
|
|
11
|
+
'HOME',
|
|
12
|
+
'HOMEDRIVE',
|
|
13
|
+
'HOMEPATH',
|
|
14
|
+
'LANG',
|
|
15
|
+
'LC_ALL',
|
|
16
|
+
'NO_COLOR',
|
|
17
|
+
'PATHEXT',
|
|
18
|
+
'Path',
|
|
19
|
+
'SystemRoot',
|
|
20
|
+
'TEMP',
|
|
21
|
+
'TERM',
|
|
22
|
+
'TMP',
|
|
23
|
+
'TMPDIR',
|
|
24
|
+
'USERPROFILE',
|
|
25
|
+
'WINDIR',
|
|
26
|
+
'windir',
|
|
27
|
+
];
|
|
28
|
+
function getPathEnvKey(env) {
|
|
29
|
+
return Object.keys(env).find((key) => key.toLowerCase() === 'path') ?? 'PATH';
|
|
30
|
+
}
|
|
31
|
+
function sameResolvedPath(left, right) {
|
|
32
|
+
const resolvedLeft = path.resolve(left);
|
|
33
|
+
const resolvedRight = path.resolve(right);
|
|
34
|
+
return process.platform === 'win32'
|
|
35
|
+
? resolvedLeft.toLowerCase() === resolvedRight.toLowerCase()
|
|
36
|
+
: resolvedLeft === resolvedRight;
|
|
37
|
+
}
|
|
38
|
+
function uniqueEnvNames(values) {
|
|
39
|
+
return [...new Set(values.map((value) => value.trim()).filter((value) => value.length > 0))].sort((left, right) => left.localeCompare(right));
|
|
40
|
+
}
|
|
41
|
+
function readEnvPolicy(table) {
|
|
42
|
+
if (!table) {
|
|
43
|
+
return undefined;
|
|
44
|
+
}
|
|
45
|
+
const value = readString(table, 'env_policy');
|
|
46
|
+
return value && COMMAND_ENV_POLICIES.has(value) ? value : undefined;
|
|
47
|
+
}
|
|
48
|
+
function readEnvAllowlist(table) {
|
|
49
|
+
return table ? (readStringArray(table, 'env_allowlist') ?? []) : [];
|
|
50
|
+
}
|
|
51
|
+
function pickEnv(source, names) {
|
|
52
|
+
const output = {};
|
|
53
|
+
for (const name of names) {
|
|
54
|
+
const value = source[name];
|
|
55
|
+
if (value !== undefined) {
|
|
56
|
+
output[name] = value;
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
return output;
|
|
60
|
+
}
|
|
61
|
+
function removeProjectLocalBinFromPath(env, projectRoot) {
|
|
62
|
+
const pathKey = getPathEnvKey(env);
|
|
63
|
+
const currentPath = env[pathKey];
|
|
64
|
+
if (!currentPath) {
|
|
65
|
+
return env;
|
|
66
|
+
}
|
|
67
|
+
const localBinPath = path.join(projectRoot, 'node_modules', '.bin');
|
|
68
|
+
env[pathKey] = currentPath
|
|
69
|
+
.split(path.delimiter)
|
|
70
|
+
.filter((entry) => entry.length > 0 && !sameResolvedPath(entry, localBinPath))
|
|
71
|
+
.join(path.delimiter);
|
|
72
|
+
return env;
|
|
73
|
+
}
|
|
74
|
+
export function resolveCommandEnv(contract, intent) {
|
|
75
|
+
const policy = readEnvPolicy(intent) ?? readEnvPolicy(contract.defaults) ?? DEFAULT_COMMAND_ENV_POLICY;
|
|
76
|
+
const allowlist = policy === 'allowlist'
|
|
77
|
+
? uniqueEnvNames([...readEnvAllowlist(contract.defaults), ...readEnvAllowlist(intent)])
|
|
78
|
+
: [];
|
|
79
|
+
return {
|
|
80
|
+
policy,
|
|
81
|
+
allowlist,
|
|
82
|
+
};
|
|
83
|
+
}
|
|
84
|
+
export function createCommandEnv(projectRoot, resolution, sourceEnv = process.env) {
|
|
85
|
+
const pathKey = getPathEnvKey(sourceEnv);
|
|
86
|
+
const minimalKeys = uniqueEnvNames([...BASE_MINIMAL_ENV_KEYS, pathKey]);
|
|
87
|
+
const env = resolution.policy === 'inherit'
|
|
88
|
+
? { ...sourceEnv }
|
|
89
|
+
: pickEnv(sourceEnv, resolution.policy === 'allowlist' ? [...minimalKeys, ...resolution.allowlist] : minimalKeys);
|
|
90
|
+
return removeProjectLocalBinFromPath(env, projectRoot);
|
|
91
|
+
}
|