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,213 @@
|
|
|
1
|
+
import { explainCommandIntent } from '../../core/command-explanation.js';
|
|
2
|
+
import { readCommandContract } from '../../core/config-loading.js';
|
|
3
|
+
import { createVerificationDecisionGraph, } from '../../core/verification-decision-graph.js';
|
|
4
|
+
import { createVerificationPlan, } from '../../core/verification-plan.js';
|
|
5
|
+
import { createVerificationSchedule } from '../../core/verification-scheduler.js';
|
|
6
|
+
import { t } from '../lib/i18n.js';
|
|
7
|
+
import { readLocalCommandEffectGraphs, } from '../lib/local-index.js';
|
|
8
|
+
import { planErrorMessageKey, readInputFromPlan } from './verify.js';
|
|
9
|
+
export function parseExplainVerifyArgs(args) {
|
|
10
|
+
let reason;
|
|
11
|
+
let fromPlan;
|
|
12
|
+
for (let index = 0; index < args.length; index += 1) {
|
|
13
|
+
const arg = args[index];
|
|
14
|
+
if (arg === '--reason') {
|
|
15
|
+
const value = args[index + 1];
|
|
16
|
+
if (!value || value.startsWith('-')) {
|
|
17
|
+
return { reason, fromPlan, error: 'missing_reason_value' };
|
|
18
|
+
}
|
|
19
|
+
reason = value;
|
|
20
|
+
index += 1;
|
|
21
|
+
continue;
|
|
22
|
+
}
|
|
23
|
+
if (arg === '--from-plan') {
|
|
24
|
+
const value = args[index + 1];
|
|
25
|
+
if (!value || value.startsWith('-')) {
|
|
26
|
+
return { reason, fromPlan, error: 'missing_from_plan_value' };
|
|
27
|
+
}
|
|
28
|
+
fromPlan = value;
|
|
29
|
+
index += 1;
|
|
30
|
+
continue;
|
|
31
|
+
}
|
|
32
|
+
if (arg.startsWith('--reason=')) {
|
|
33
|
+
const value = arg.slice('--reason='.length);
|
|
34
|
+
if (value.length === 0) {
|
|
35
|
+
return { reason, fromPlan, error: 'missing_reason_value' };
|
|
36
|
+
}
|
|
37
|
+
reason = value;
|
|
38
|
+
continue;
|
|
39
|
+
}
|
|
40
|
+
if (arg.startsWith('--from-plan=')) {
|
|
41
|
+
const value = arg.slice('--from-plan='.length);
|
|
42
|
+
if (value.length === 0) {
|
|
43
|
+
return { reason, fromPlan, error: 'missing_from_plan_value' };
|
|
44
|
+
}
|
|
45
|
+
fromPlan = value;
|
|
46
|
+
continue;
|
|
47
|
+
}
|
|
48
|
+
if (arg.startsWith('-')) {
|
|
49
|
+
return { reason, fromPlan, error: arg };
|
|
50
|
+
}
|
|
51
|
+
return { reason, fromPlan, error: `unexpected:${arg}` };
|
|
52
|
+
}
|
|
53
|
+
return { reason, fromPlan };
|
|
54
|
+
}
|
|
55
|
+
export function explainVerifyArgErrorMessage(error, lang) {
|
|
56
|
+
if (error === 'missing_reason_value') {
|
|
57
|
+
return t(lang, 'cli.error.missingValue', { option: '--reason' });
|
|
58
|
+
}
|
|
59
|
+
if (error === 'missing_from_plan_value') {
|
|
60
|
+
return t(lang, 'cli.error.missingValue', { option: '--from-plan' });
|
|
61
|
+
}
|
|
62
|
+
if (error.startsWith('unexpected:')) {
|
|
63
|
+
return t(lang, 'cli.error.unexpectedArgument', { argument: error.slice('unexpected:'.length) });
|
|
64
|
+
}
|
|
65
|
+
return t(lang, 'cli.error.unknownOption', { option: error });
|
|
66
|
+
}
|
|
67
|
+
export function explainVerifyPlanErrorMessage(error, lang) {
|
|
68
|
+
const code = error instanceof Error ? error.message : 'invalid_plan_file';
|
|
69
|
+
return t(lang, planErrorMessageKey(code));
|
|
70
|
+
}
|
|
71
|
+
export function readExplainVerifyPlanReasons(projectRoot, planPath) {
|
|
72
|
+
return readInputFromPlan(projectRoot, planPath).reasons;
|
|
73
|
+
}
|
|
74
|
+
export async function getVerifyExplainOutput(schemaVersion, projectRoot, reasons, inputReason, planSource) {
|
|
75
|
+
const contract = readCommandContract(projectRoot);
|
|
76
|
+
const plans = reasons.map((reason) => createVerificationPlan(contract, reason));
|
|
77
|
+
const graphRequirements = reasons.map((reason) => ({
|
|
78
|
+
reason,
|
|
79
|
+
files: [],
|
|
80
|
+
surfaces: [],
|
|
81
|
+
affectedContracts: [],
|
|
82
|
+
driftChecks: [],
|
|
83
|
+
updatePolicies: [],
|
|
84
|
+
source: 'change_classification',
|
|
85
|
+
}));
|
|
86
|
+
const graphCandidates = plans.flatMap((plan) => plan.candidates.map((candidate) => ({
|
|
87
|
+
reason: plan.reason,
|
|
88
|
+
intent: candidate.intent.length > 0 ? candidate.intent : null,
|
|
89
|
+
status: candidate.status,
|
|
90
|
+
skipReason: candidate.reason,
|
|
91
|
+
detail: candidate.detail,
|
|
92
|
+
})));
|
|
93
|
+
const graphGaps = graphRequirements
|
|
94
|
+
.filter((requirement) => graphCandidates.every((candidate) => candidate.reason !== requirement.reason || candidate.status !== 'runnable'))
|
|
95
|
+
.map((requirement) => ({
|
|
96
|
+
reason: requirement.reason,
|
|
97
|
+
files: requirement.files,
|
|
98
|
+
surfaces: requirement.surfaces,
|
|
99
|
+
detail: `No runnable command intents cover required_after = "${requirement.reason}".`,
|
|
100
|
+
}));
|
|
101
|
+
const schedule = createVerificationSchedule(projectRoot, contract, plans.flatMap((plan) => plan.candidates));
|
|
102
|
+
const decisionGraph = createVerificationDecisionGraph(contract, graphRequirements, graphCandidates, graphGaps, schedule);
|
|
103
|
+
const intentNames = [
|
|
104
|
+
...new Set(plans.flatMap((plan) => plan.candidates.map((candidate) => candidate.intent).filter((intent) => intent.length > 0))),
|
|
105
|
+
];
|
|
106
|
+
const graphsByIntent = intentNames.length > 0 ? await readLocalCommandEffectGraphs(projectRoot, intentNames) : new Map();
|
|
107
|
+
const requirements = plans.map((plan) => {
|
|
108
|
+
const candidates = plan.candidates.map((candidate) => {
|
|
109
|
+
const command = candidate.intent ? explainCommandIntent(contract, candidate.intent).intent : null;
|
|
110
|
+
return {
|
|
111
|
+
intent: candidate.intent.length > 0 ? candidate.intent : null,
|
|
112
|
+
status: candidate.status,
|
|
113
|
+
skipReason: candidate.reason,
|
|
114
|
+
detail: candidate.detail,
|
|
115
|
+
requiredAfter: command?.requiredAfter ?? [],
|
|
116
|
+
command,
|
|
117
|
+
effectGraph: candidate.intent ? graphsByIntent.get(candidate.intent) ?? null : null,
|
|
118
|
+
};
|
|
119
|
+
});
|
|
120
|
+
const matchingIntents = candidates
|
|
121
|
+
.map((candidate) => candidate.intent)
|
|
122
|
+
.filter((intent) => intent !== null)
|
|
123
|
+
.sort((left, right) => left.localeCompare(right));
|
|
124
|
+
const hasRunnableCandidate = candidates.some((candidate) => candidate.status === 'runnable');
|
|
125
|
+
return {
|
|
126
|
+
reason: plan.reason,
|
|
127
|
+
matchingIntents,
|
|
128
|
+
candidates,
|
|
129
|
+
gap: hasRunnableCandidate ? null : `No runnable command intents cover required_after = "${plan.reason}".`,
|
|
130
|
+
};
|
|
131
|
+
});
|
|
132
|
+
const allCandidates = requirements.flatMap((requirement) => requirement.candidates);
|
|
133
|
+
const runnableCount = allCandidates.filter((candidate) => candidate.status === 'runnable').length;
|
|
134
|
+
const skippedCount = allCandidates.filter((candidate) => candidate.status === 'skipped').length;
|
|
135
|
+
const reasonLabel = reasons.join(', ');
|
|
136
|
+
return {
|
|
137
|
+
schema_version: schemaVersion,
|
|
138
|
+
command: 'explain',
|
|
139
|
+
topic: 'verify',
|
|
140
|
+
mustflow_root: projectRoot,
|
|
141
|
+
decision: {
|
|
142
|
+
kind: 'verify',
|
|
143
|
+
input: {
|
|
144
|
+
reason: inputReason,
|
|
145
|
+
planSource,
|
|
146
|
+
},
|
|
147
|
+
decision: runnableCount > 0
|
|
148
|
+
? `verification reason "${reasonLabel}" has ${runnableCount} runnable candidate(s)`
|
|
149
|
+
: `verification reason "${reasonLabel}" has no runnable candidates`,
|
|
150
|
+
reason: 'verify explanations reuse required_after matching and the same command eligibility rules used by mf run and mf verify.',
|
|
151
|
+
effectiveAction: runnableCount > 0
|
|
152
|
+
? 'Use mf verify when you need execution receipts; this explanation only shows the selected verification candidates.'
|
|
153
|
+
: 'Do not guess a command; report the skipped candidate reasons or add a configured command intent.',
|
|
154
|
+
countsAsMustflowVerification: false,
|
|
155
|
+
sourceFiles: [
|
|
156
|
+
'.mustflow/config/commands.toml',
|
|
157
|
+
'.mustflow/docs/agent-workflow.md',
|
|
158
|
+
'src/core/verification-plan.ts',
|
|
159
|
+
'src/core/command-intent-eligibility.ts',
|
|
160
|
+
],
|
|
161
|
+
verification: {
|
|
162
|
+
planSource,
|
|
163
|
+
reasons,
|
|
164
|
+
candidateCount: allCandidates.length,
|
|
165
|
+
runnableCount,
|
|
166
|
+
skippedCount,
|
|
167
|
+
requirements,
|
|
168
|
+
decisionGraph,
|
|
169
|
+
},
|
|
170
|
+
},
|
|
171
|
+
};
|
|
172
|
+
}
|
|
173
|
+
export function renderVerifyExplainDecision(decision, lang) {
|
|
174
|
+
const verification = decision.verification;
|
|
175
|
+
const lines = [
|
|
176
|
+
'',
|
|
177
|
+
'Verification explanation',
|
|
178
|
+
`- plan_source: ${verification.planSource ?? t(lang, 'value.none')}`,
|
|
179
|
+
`- reasons: ${verification.reasons.join(', ') || t(lang, 'value.none')}`,
|
|
180
|
+
`- candidates: ${verification.candidateCount}`,
|
|
181
|
+
`- runnable: ${verification.runnableCount}`,
|
|
182
|
+
`- skipped: ${verification.skippedCount}`,
|
|
183
|
+
`- decision_graph_nodes: ${verification.decisionGraph.summary.nodeCount}`,
|
|
184
|
+
`- decision_graph_gaps: ${verification.decisionGraph.summary.gapCount}`,
|
|
185
|
+
];
|
|
186
|
+
for (const requirement of verification.requirements) {
|
|
187
|
+
lines.push(`- required_after: ${requirement.reason}`);
|
|
188
|
+
if (requirement.matchingIntents.length > 0) {
|
|
189
|
+
lines.push(` matching_intents: ${requirement.matchingIntents.join(', ')}`);
|
|
190
|
+
}
|
|
191
|
+
if (requirement.gap) {
|
|
192
|
+
lines.push(` gap: ${requirement.gap}`);
|
|
193
|
+
}
|
|
194
|
+
for (const candidate of requirement.candidates) {
|
|
195
|
+
const intent = candidate.intent ?? t(lang, 'value.none');
|
|
196
|
+
const reason = candidate.skipReason ? ` (${candidate.skipReason})` : '';
|
|
197
|
+
lines.push(` - ${intent}: ${candidate.status}${reason}`);
|
|
198
|
+
if (candidate.detail) {
|
|
199
|
+
lines.push(` detail: ${candidate.detail}`);
|
|
200
|
+
}
|
|
201
|
+
if (candidate.requiredAfter.length > 0) {
|
|
202
|
+
lines.push(` required_after: ${candidate.requiredAfter.join(', ')}`);
|
|
203
|
+
}
|
|
204
|
+
if (candidate.effectGraph) {
|
|
205
|
+
lines.push(` effect_graph: ${candidate.effectGraph.status}`, ` index_fresh: ${candidate.effectGraph.indexFresh ? t(lang, 'value.yes') : t(lang, 'value.no')}`);
|
|
206
|
+
if (candidate.effectGraph.refreshHint) {
|
|
207
|
+
lines.push(` refresh_hint: ${candidate.effectGraph.refreshHint}`);
|
|
208
|
+
}
|
|
209
|
+
}
|
|
210
|
+
}
|
|
211
|
+
}
|
|
212
|
+
return lines;
|
|
213
|
+
}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { printUsageError, renderHelp } from '../lib/cli-output.js';
|
|
2
2
|
import { t } from '../lib/i18n.js';
|
|
3
3
|
import { resolveMustflowRoot } from '../lib/project-root.js';
|
|
4
|
-
import { explainAssetOptimization, explainCommandIntent } from '../../core/command-explanation.js';
|
|
4
|
+
import { explainAssetOptimization, explainCommandIntent, } from '../../core/command-explanation.js';
|
|
5
5
|
import { readCommandContract, readMustflowConfigIfExists } from '../../core/config-loading.js';
|
|
6
6
|
import { explainManagedMarkdownAuthority, } from '../../core/authority-resolution.js';
|
|
7
7
|
import { explainRetentionPolicy } from '../../core/retention-explanation.js';
|
|
@@ -11,10 +11,11 @@ import { explainPublicSurface } from '../../core/public-surface-explanation.js';
|
|
|
11
11
|
import { explainSourceAnchor } from '../../core/source-anchor-explanation.js';
|
|
12
12
|
import { checkMustflowProject } from '../lib/validation.js';
|
|
13
13
|
import { readLocalCommandEffectGraph, readLocalPathSurface, } from '../lib/local-index.js';
|
|
14
|
+
import { explainVerifyArgErrorMessage, explainVerifyPlanErrorMessage, getVerifyExplainOutput, parseExplainVerifyArgs, readExplainVerifyPlanReasons, renderVerifyExplainDecision, } from './explain-verify.js';
|
|
14
15
|
const EXPLAIN_SCHEMA_VERSION = '1';
|
|
15
16
|
export function getExplainHelp(lang = 'en') {
|
|
16
17
|
return renderHelp({
|
|
17
|
-
usage: 'mf explain <topic> [target] [options]',
|
|
18
|
+
usage: 'mf explain <topic> [target] [options] | mf explain verify --reason <event> [options] | mf explain verify --from-plan <path> [options]',
|
|
18
19
|
summary: t(lang, 'explain.help.summary'),
|
|
19
20
|
options: [
|
|
20
21
|
{ label: '--json', description: t(lang, 'cli.option.json') },
|
|
@@ -31,6 +32,8 @@ export function getExplainHelp(lang = 'en') {
|
|
|
31
32
|
'mf explain command lint --json',
|
|
32
33
|
'mf explain retention',
|
|
33
34
|
'mf explain retention --json',
|
|
35
|
+
'mf explain verify --reason code_change',
|
|
36
|
+
'mf explain verify --from-plan verify-plan.json --json',
|
|
34
37
|
'mf explain skill code-review',
|
|
35
38
|
'mf explain skill mustflow.core.code-review --json',
|
|
36
39
|
'mf explain skills',
|
|
@@ -146,6 +149,9 @@ function renderExplainDecision(output, lang) {
|
|
|
146
149
|
if ('expectation' in output.decision && output.decision.expectation) {
|
|
147
150
|
lines.push('', t(lang, 'explain.label.expectedFrontmatter'), `- mustflow_doc: ${output.decision.expectation.docId}`, `- authority: ${output.decision.expectation.authority}`, `- lifecycle: ${output.decision.expectation.lifecycle}`);
|
|
148
151
|
}
|
|
152
|
+
if ('verification' in output.decision) {
|
|
153
|
+
lines.push(...renderVerifyExplainDecision(output.decision, lang));
|
|
154
|
+
}
|
|
149
155
|
if ('boundary' in output.decision) {
|
|
150
156
|
lines.push('', t(lang, 'explain.label.authorityBoundary'), `- role: ${output.decision.boundary.role}`);
|
|
151
157
|
if (output.decision.boundary.canDefine.length > 0) {
|
|
@@ -246,13 +252,51 @@ export async function runExplain(args, reporter, lang = 'en') {
|
|
|
246
252
|
return 0;
|
|
247
253
|
}
|
|
248
254
|
const json = args.includes('--json');
|
|
255
|
+
const positional = args.filter((arg) => arg !== '--json');
|
|
256
|
+
const [topic, targetArg, ...rest] = positional;
|
|
257
|
+
if (topic === 'verify') {
|
|
258
|
+
const verifyArgs = targetArg === undefined ? rest : [targetArg, ...rest];
|
|
259
|
+
const parsed = parseExplainVerifyArgs(verifyArgs);
|
|
260
|
+
if (parsed.error) {
|
|
261
|
+
printUsageError(reporter, explainVerifyArgErrorMessage(parsed.error, lang), 'mf explain --help', getExplainHelp(lang), lang);
|
|
262
|
+
return 1;
|
|
263
|
+
}
|
|
264
|
+
const selectedInputCount = [parsed.reason, parsed.fromPlan].filter(Boolean).length;
|
|
265
|
+
if (selectedInputCount > 1) {
|
|
266
|
+
printUsageError(reporter, t(lang, 'verify.error.conflictingInputs'), 'mf explain --help', getExplainHelp(lang), lang);
|
|
267
|
+
return 1;
|
|
268
|
+
}
|
|
269
|
+
if (selectedInputCount === 0) {
|
|
270
|
+
printUsageError(reporter, t(lang, 'verify.error.missingReason'), 'mf explain --help', getExplainHelp(lang), lang);
|
|
271
|
+
return 1;
|
|
272
|
+
}
|
|
273
|
+
const projectRoot = resolveMustflowRoot();
|
|
274
|
+
let output;
|
|
275
|
+
try {
|
|
276
|
+
if (parsed.fromPlan) {
|
|
277
|
+
const reasons = readExplainVerifyPlanReasons(projectRoot, parsed.fromPlan);
|
|
278
|
+
output = await getVerifyExplainOutput(EXPLAIN_SCHEMA_VERSION, projectRoot, reasons, null, parsed.fromPlan);
|
|
279
|
+
}
|
|
280
|
+
else {
|
|
281
|
+
output = await getVerifyExplainOutput(EXPLAIN_SCHEMA_VERSION, projectRoot, [parsed.reason], parsed.reason, null);
|
|
282
|
+
}
|
|
283
|
+
}
|
|
284
|
+
catch (error) {
|
|
285
|
+
printUsageError(reporter, explainVerifyPlanErrorMessage(error, lang), 'mf explain --help', getExplainHelp(lang), lang);
|
|
286
|
+
return 1;
|
|
287
|
+
}
|
|
288
|
+
if (json) {
|
|
289
|
+
reporter.stdout(JSON.stringify(output, null, 2));
|
|
290
|
+
return 0;
|
|
291
|
+
}
|
|
292
|
+
reporter.stdout(renderExplainDecision(output, lang));
|
|
293
|
+
return 0;
|
|
294
|
+
}
|
|
249
295
|
const unsupported = args.filter((arg) => arg.startsWith('-') && arg !== '--json');
|
|
250
296
|
if (unsupported.length > 0) {
|
|
251
297
|
printUsageError(reporter, t(lang, 'cli.error.unknownOption', { option: unsupported[0] }), 'mf explain --help', getExplainHelp(lang), lang);
|
|
252
298
|
return 1;
|
|
253
299
|
}
|
|
254
|
-
const positional = args.filter((arg) => arg !== '--json');
|
|
255
|
-
const [topic, targetArg, ...rest] = positional;
|
|
256
300
|
if (topic !== 'asset-optimization' &&
|
|
257
301
|
topic !== 'anchor' &&
|
|
258
302
|
topic !== 'authority' &&
|
|
@@ -0,0 +1,136 @@
|
|
|
1
|
+
import { lstatSync } from 'node:fs';
|
|
2
|
+
import path from 'node:path';
|
|
3
|
+
import { MAX_HANDOFF_RECORD_BYTES, validateHandoffRecordJson, } from '../../core/handoff-record.js';
|
|
4
|
+
import { printUsageError, renderHelp } from '../lib/cli-output.js';
|
|
5
|
+
import { ensureInsideWithoutSymlinks, readUtf8FileInsideWithoutSymlinks } from '../lib/filesystem.js';
|
|
6
|
+
import { t } from '../lib/i18n.js';
|
|
7
|
+
import { resolveMustflowRoot } from '../lib/project-root.js';
|
|
8
|
+
export function getHandoffHelp(lang = 'en') {
|
|
9
|
+
return renderHelp({
|
|
10
|
+
usage: 'mf handoff validate <path> [options]',
|
|
11
|
+
summary: t(lang, 'handoff.help.summary'),
|
|
12
|
+
options: [
|
|
13
|
+
{ label: '--json', description: t(lang, 'cli.option.json') },
|
|
14
|
+
{ label: '-h, --help', description: t(lang, 'cli.option.help') },
|
|
15
|
+
],
|
|
16
|
+
examples: [
|
|
17
|
+
'mf handoff validate .mustflow/work-items/MF-0001.json',
|
|
18
|
+
'mf handoff validate .mustflow/work-items/MF-0001.json --json',
|
|
19
|
+
],
|
|
20
|
+
exitCodes: [
|
|
21
|
+
{ label: '0', description: t(lang, 'handoff.help.exit.ok') },
|
|
22
|
+
{ label: '1', description: t(lang, 'handoff.help.exit.fail') },
|
|
23
|
+
],
|
|
24
|
+
}, lang);
|
|
25
|
+
}
|
|
26
|
+
function parseHandoffArgs(args, lang) {
|
|
27
|
+
const [action, ...rest] = args;
|
|
28
|
+
let json = false;
|
|
29
|
+
let recordPath;
|
|
30
|
+
if (!action) {
|
|
31
|
+
return { action: 'validate', json, error: t(lang, 'handoff.error.missingAction') };
|
|
32
|
+
}
|
|
33
|
+
if (action !== 'validate') {
|
|
34
|
+
return { action: 'validate', json, error: t(lang, 'handoff.error.unknownAction', { action }) };
|
|
35
|
+
}
|
|
36
|
+
for (const arg of rest) {
|
|
37
|
+
if (arg === '--json') {
|
|
38
|
+
json = true;
|
|
39
|
+
continue;
|
|
40
|
+
}
|
|
41
|
+
if (arg.startsWith('-')) {
|
|
42
|
+
return { action, path: recordPath, json, error: t(lang, 'cli.error.unknownOption', { option: arg }) };
|
|
43
|
+
}
|
|
44
|
+
if (recordPath) {
|
|
45
|
+
return { action, path: recordPath, json, error: t(lang, 'cli.error.unexpectedArgument', { argument: arg }) };
|
|
46
|
+
}
|
|
47
|
+
recordPath = arg;
|
|
48
|
+
}
|
|
49
|
+
if (!recordPath) {
|
|
50
|
+
return { action, json, error: t(lang, 'handoff.error.missingPath') };
|
|
51
|
+
}
|
|
52
|
+
return { action, path: recordPath, json };
|
|
53
|
+
}
|
|
54
|
+
function createReadFailureReport(mustflowRoot, recordPath, code, message) {
|
|
55
|
+
return {
|
|
56
|
+
schema_version: '1',
|
|
57
|
+
command: 'handoff_validate',
|
|
58
|
+
ok: false,
|
|
59
|
+
mustflow_root: mustflowRoot,
|
|
60
|
+
path: recordPath,
|
|
61
|
+
record_kind: null,
|
|
62
|
+
task_id: null,
|
|
63
|
+
summary: {
|
|
64
|
+
scope_count: 0,
|
|
65
|
+
acceptance_criteria_count: 0,
|
|
66
|
+
source_ref_count: 0,
|
|
67
|
+
verification_plan_count: 0,
|
|
68
|
+
coverage_count: 0,
|
|
69
|
+
remaining_risk_count: 0,
|
|
70
|
+
},
|
|
71
|
+
issues: [{ severity: 'error', code, path: '$', message }],
|
|
72
|
+
};
|
|
73
|
+
}
|
|
74
|
+
function toRelativePosixPath(rootPath, targetPath) {
|
|
75
|
+
return path.relative(rootPath, targetPath).split(path.sep).join('/');
|
|
76
|
+
}
|
|
77
|
+
function renderHandoffReport(report, lang) {
|
|
78
|
+
const lines = [
|
|
79
|
+
t(lang, 'handoff.title'),
|
|
80
|
+
`${t(lang, 'label.mustflowRoot')}: ${report.mustflow_root}`,
|
|
81
|
+
`${t(lang, 'handoff.label.path')}: ${report.path}`,
|
|
82
|
+
`${t(lang, 'handoff.label.status')}: ${report.ok ? t(lang, 'handoff.value.valid') : t(lang, 'handoff.value.invalid')}`,
|
|
83
|
+
`${t(lang, 'handoff.label.kind')}: ${report.record_kind ?? t(lang, 'value.none')}`,
|
|
84
|
+
`${t(lang, 'handoff.label.task')}: ${report.task_id ?? t(lang, 'value.none')}`,
|
|
85
|
+
`${t(lang, 'handoff.label.issues')}: ${report.issues.length}`,
|
|
86
|
+
];
|
|
87
|
+
if (report.issues.length > 0) {
|
|
88
|
+
lines.push('', t(lang, 'handoff.label.issues'));
|
|
89
|
+
for (const issue of report.issues) {
|
|
90
|
+
lines.push(`- [${issue.severity}] ${issue.code} ${issue.path}: ${issue.message}`);
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
return lines.join('\n');
|
|
94
|
+
}
|
|
95
|
+
export function runHandoff(args, reporter, lang = 'en') {
|
|
96
|
+
const helpText = getHandoffHelp(lang);
|
|
97
|
+
if (args.includes('--help') || args.includes('-h')) {
|
|
98
|
+
reporter.stdout(helpText);
|
|
99
|
+
return 0;
|
|
100
|
+
}
|
|
101
|
+
const options = parseHandoffArgs(args, lang);
|
|
102
|
+
if (options.error || !options.path) {
|
|
103
|
+
printUsageError(reporter, options.error ?? t(lang, 'handoff.error.missingPath'), 'mf handoff --help', helpText, lang);
|
|
104
|
+
return 1;
|
|
105
|
+
}
|
|
106
|
+
const mustflowRoot = resolveMustflowRoot();
|
|
107
|
+
const recordPath = path.resolve(mustflowRoot, options.path);
|
|
108
|
+
let report;
|
|
109
|
+
try {
|
|
110
|
+
ensureInsideWithoutSymlinks(mustflowRoot, recordPath);
|
|
111
|
+
const stats = lstatSync(recordPath);
|
|
112
|
+
if (!stats.isFile()) {
|
|
113
|
+
report = createReadFailureReport(mustflowRoot, toRelativePosixPath(mustflowRoot, recordPath), 'record_not_regular_file', t(lang, 'handoff.error.notFile'));
|
|
114
|
+
}
|
|
115
|
+
else if (stats.size > MAX_HANDOFF_RECORD_BYTES) {
|
|
116
|
+
report = createReadFailureReport(mustflowRoot, toRelativePosixPath(mustflowRoot, recordPath), 'record_too_large', t(lang, 'handoff.error.tooLarge'));
|
|
117
|
+
}
|
|
118
|
+
else {
|
|
119
|
+
const content = readUtf8FileInsideWithoutSymlinks(mustflowRoot, recordPath);
|
|
120
|
+
report = validateHandoffRecordJson(content, {
|
|
121
|
+
mustflowRoot,
|
|
122
|
+
path: toRelativePosixPath(mustflowRoot, recordPath),
|
|
123
|
+
});
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
catch (error) {
|
|
127
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
128
|
+
report = createReadFailureReport(mustflowRoot, options.path, 'record_unreadable', t(lang, 'handoff.error.unreadable', { message }));
|
|
129
|
+
}
|
|
130
|
+
if (options.json) {
|
|
131
|
+
reporter.stdout(JSON.stringify(report, null, 2));
|
|
132
|
+
return report.ok ? 0 : 1;
|
|
133
|
+
}
|
|
134
|
+
reporter.stdout(renderHandoffReport(report, lang));
|
|
135
|
+
return report.ok ? 0 : 1;
|
|
136
|
+
}
|