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
|
@@ -14,6 +14,10 @@ const DEFAULT_DATABASE_RELATIVE_PATH = '.mustflow/cache/mustflow.sqlite';
|
|
|
14
14
|
const LOCAL_INDEX_CONTENT_MODE = 'metadata_and_snippets';
|
|
15
15
|
const LOCAL_INDEX_STORE_FULL_CONTENT = false;
|
|
16
16
|
const MAX_SNIPPET_BYTES_PER_DOCUMENT = 2048;
|
|
17
|
+
const MAX_SEARCH_MATCH_SNIPPET_CHARS = 240;
|
|
18
|
+
const SEARCH_MATCH_CONTEXT_BEFORE_CHARS = 48;
|
|
19
|
+
const SEARCH_MATCH_CONTEXT_AFTER_CHARS = 96;
|
|
20
|
+
const SEARCH_MATCH_TRUNCATION_MARKER = '...';
|
|
17
21
|
const SEARCH_NGRAM_MIN_LENGTH = 2;
|
|
18
22
|
const SEARCH_NGRAM_MAX_LENGTH = 3;
|
|
19
23
|
const SEARCH_BACKEND_FTS5 = 'fts5';
|
|
@@ -447,6 +451,9 @@ function splitIndexedList(value) {
|
|
|
447
451
|
function createCommandEffectGraphStatus(databasePath, status, stalePaths = []) {
|
|
448
452
|
return {
|
|
449
453
|
source: 'local_index',
|
|
454
|
+
authority: 'explanation_only',
|
|
455
|
+
commandAuthority: '.mustflow/config/commands.toml',
|
|
456
|
+
grantsCommandAuthority: false,
|
|
450
457
|
status,
|
|
451
458
|
databasePath,
|
|
452
459
|
indexFresh: status === 'fresh',
|
|
@@ -628,16 +635,22 @@ function getMatchSnippet(fields, query) {
|
|
|
628
635
|
if (start === -1) {
|
|
629
636
|
const [firstGram] = buildSearchNgrams([query]).filter((gram) => lower.includes(gram));
|
|
630
637
|
if (!firstGram) {
|
|
631
|
-
return normalized
|
|
638
|
+
return truncateSearchMatchSnippet(normalized);
|
|
632
639
|
}
|
|
633
640
|
start = lower.indexOf(firstGram);
|
|
634
641
|
matchLength = firstGram.length;
|
|
635
642
|
}
|
|
636
|
-
const from = Math.max(0, start -
|
|
637
|
-
const to = Math.min(normalized.length, start + matchLength +
|
|
638
|
-
const prefix = from > 0 ?
|
|
639
|
-
const suffix = to < normalized.length ?
|
|
640
|
-
return `${prefix}${normalized.slice(from, to)}${suffix}
|
|
643
|
+
const from = Math.max(0, start - SEARCH_MATCH_CONTEXT_BEFORE_CHARS);
|
|
644
|
+
const to = Math.min(normalized.length, start + matchLength + SEARCH_MATCH_CONTEXT_AFTER_CHARS);
|
|
645
|
+
const prefix = from > 0 ? SEARCH_MATCH_TRUNCATION_MARKER : '';
|
|
646
|
+
const suffix = to < normalized.length ? SEARCH_MATCH_TRUNCATION_MARKER : '';
|
|
647
|
+
return truncateSearchMatchSnippet(`${prefix}${normalized.slice(from, to)}${suffix}`);
|
|
648
|
+
}
|
|
649
|
+
function truncateSearchMatchSnippet(value) {
|
|
650
|
+
if (value.length <= MAX_SEARCH_MATCH_SNIPPET_CHARS) {
|
|
651
|
+
return value;
|
|
652
|
+
}
|
|
653
|
+
return `${value.slice(0, MAX_SEARCH_MATCH_SNIPPET_CHARS - SEARCH_MATCH_TRUNCATION_MARKER.length)}${SEARCH_MATCH_TRUNCATION_MARKER}`;
|
|
641
654
|
}
|
|
642
655
|
function scoreMatch(primaryFields, secondaryFields, query) {
|
|
643
656
|
const lowerQuery = query.toLowerCase();
|
|
@@ -1397,6 +1410,9 @@ ORDER BY lock, left_intent, right_intent
|
|
|
1397
1410
|
`, [intent, intent]).map((row) => mapCommandLockConflict(row, intent));
|
|
1398
1411
|
return {
|
|
1399
1412
|
source: 'local_index',
|
|
1413
|
+
authority: 'explanation_only',
|
|
1414
|
+
commandAuthority: '.mustflow/config/commands.toml',
|
|
1415
|
+
grantsCommandAuthority: false,
|
|
1400
1416
|
status: 'fresh',
|
|
1401
1417
|
databasePath,
|
|
1402
1418
|
indexFresh: true,
|
|
@@ -0,0 +1,222 @@
|
|
|
1
|
+
import path from 'node:path';
|
|
2
|
+
import { isMustflowBinName } from '../../core/command-classification.js';
|
|
3
|
+
import { resolveSafeProjectCwd } from '../../core/command-cwd.js';
|
|
4
|
+
import { resolveCommandEnv } from '../../core/command-env.js';
|
|
5
|
+
import { evaluateCommandIntentEligibility, } from '../../core/command-intent-eligibility.js';
|
|
6
|
+
import { isRecord, readPositiveInteger, readString, readStringArray, } from '../../core/config-loading.js';
|
|
7
|
+
function getSuccessExitCodes(intent) {
|
|
8
|
+
const value = intent.success_exit_codes;
|
|
9
|
+
if (!Array.isArray(value) || value.length === 0 || value.some((entry) => !Number.isInteger(entry))) {
|
|
10
|
+
return [0];
|
|
11
|
+
}
|
|
12
|
+
return value.map(Number);
|
|
13
|
+
}
|
|
14
|
+
function readBoolean(intent, key) {
|
|
15
|
+
const value = intent[key];
|
|
16
|
+
return typeof value === 'boolean' ? value : undefined;
|
|
17
|
+
}
|
|
18
|
+
function readArray(intent, key) {
|
|
19
|
+
const value = intent[key];
|
|
20
|
+
return Array.isArray(value) ? value : undefined;
|
|
21
|
+
}
|
|
22
|
+
function toPosixPath(value) {
|
|
23
|
+
return value.split(path.sep).join('/');
|
|
24
|
+
}
|
|
25
|
+
function getRelativeProjectPath(projectRoot, targetPath) {
|
|
26
|
+
const relativePath = path.relative(projectRoot, targetPath);
|
|
27
|
+
return relativePath.length > 0 ? toPosixPath(relativePath) : '.';
|
|
28
|
+
}
|
|
29
|
+
function shouldUseShellForArgvExecutable(executablePath) {
|
|
30
|
+
return process.platform === 'win32' && executablePath.toLowerCase().endsWith('.cmd');
|
|
31
|
+
}
|
|
32
|
+
export function isMustflowBuiltinIntent(intent) {
|
|
33
|
+
return readString(intent, 'kind') === 'mustflow_builtin';
|
|
34
|
+
}
|
|
35
|
+
function resolveCurrentCliEntrypoint() {
|
|
36
|
+
const entrypoint = process.argv[1];
|
|
37
|
+
return entrypoint ? path.resolve(entrypoint) : undefined;
|
|
38
|
+
}
|
|
39
|
+
function resolveArgvCommand(intent, commandArgv) {
|
|
40
|
+
const [command = '', ...args] = commandArgv;
|
|
41
|
+
if (isMustflowBuiltinIntent(intent) && isMustflowBinName(command)) {
|
|
42
|
+
const entrypoint = resolveCurrentCliEntrypoint();
|
|
43
|
+
if (entrypoint) {
|
|
44
|
+
return {
|
|
45
|
+
executable: process.execPath,
|
|
46
|
+
args: [entrypoint, ...args],
|
|
47
|
+
shell: false,
|
|
48
|
+
};
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
return {
|
|
52
|
+
executable: command,
|
|
53
|
+
args,
|
|
54
|
+
shell: shouldUseShellForArgvExecutable(command),
|
|
55
|
+
};
|
|
56
|
+
}
|
|
57
|
+
function getRunPlanMode(commandArgv, intent) {
|
|
58
|
+
if (commandArgv) {
|
|
59
|
+
return 'argv';
|
|
60
|
+
}
|
|
61
|
+
return intent.mode === 'shell' ? 'shell' : null;
|
|
62
|
+
}
|
|
63
|
+
function readRunIntentMetadata(contract, intent) {
|
|
64
|
+
const configuredCwd = readString(intent, 'cwd') ?? readString(contract.defaults, 'default_cwd') ?? '.';
|
|
65
|
+
const commandArgv = readStringArray(intent, 'argv');
|
|
66
|
+
const shellCommand = intent.mode === 'shell' ? readString(intent, 'cmd') : undefined;
|
|
67
|
+
const env = resolveCommandEnv(contract, intent);
|
|
68
|
+
return {
|
|
69
|
+
intentStatus: readString(intent, 'status') ?? 'unknown',
|
|
70
|
+
lifecycle: readString(intent, 'lifecycle') ?? null,
|
|
71
|
+
runPolicy: readString(intent, 'run_policy') ?? null,
|
|
72
|
+
kind: readString(intent, 'kind') ?? null,
|
|
73
|
+
configuredCwd,
|
|
74
|
+
timeoutSeconds: readPositiveInteger(intent, 'timeout_seconds') ?? null,
|
|
75
|
+
maxOutputBytes: readPositiveInteger(intent, 'max_output_bytes') ?? readPositiveInteger(contract.defaults, 'max_output_bytes') ?? 1_048_576,
|
|
76
|
+
successExitCodes: getSuccessExitCodes(intent),
|
|
77
|
+
commandArgv,
|
|
78
|
+
shellCommand,
|
|
79
|
+
mode: getRunPlanMode(commandArgv, intent),
|
|
80
|
+
writes: readStringArray(intent, 'writes'),
|
|
81
|
+
effects: readArray(intent, 'effects'),
|
|
82
|
+
network: readBoolean(intent, 'network'),
|
|
83
|
+
destructive: readBoolean(intent, 'destructive'),
|
|
84
|
+
envPolicy: env.policy,
|
|
85
|
+
envAllowlist: env.allowlist,
|
|
86
|
+
};
|
|
87
|
+
}
|
|
88
|
+
function createBlockedRunPlan(contract, intentName, intent, eligibility, reasonCode, detail) {
|
|
89
|
+
const metadata = intent ? readRunIntentMetadata(contract, intent) : null;
|
|
90
|
+
return {
|
|
91
|
+
intentName,
|
|
92
|
+
intent,
|
|
93
|
+
ok: false,
|
|
94
|
+
eligibility,
|
|
95
|
+
reasonCode,
|
|
96
|
+
detail,
|
|
97
|
+
intentStatus: metadata?.intentStatus ?? null,
|
|
98
|
+
lifecycle: metadata?.lifecycle ?? null,
|
|
99
|
+
runPolicy: metadata?.runPolicy ?? null,
|
|
100
|
+
kind: metadata?.kind ?? null,
|
|
101
|
+
configuredCwd: metadata?.configuredCwd ?? null,
|
|
102
|
+
cwd: null,
|
|
103
|
+
relativeCwd: null,
|
|
104
|
+
timeoutSeconds: metadata?.timeoutSeconds ?? null,
|
|
105
|
+
maxOutputBytes: metadata?.maxOutputBytes ?? null,
|
|
106
|
+
successExitCodes: metadata?.successExitCodes ?? null,
|
|
107
|
+
commandArgv: metadata?.commandArgv,
|
|
108
|
+
shellCommand: metadata?.shellCommand,
|
|
109
|
+
mode: metadata?.mode ?? null,
|
|
110
|
+
argvCommand: undefined,
|
|
111
|
+
writes: metadata?.writes,
|
|
112
|
+
effects: metadata?.effects,
|
|
113
|
+
network: metadata?.network,
|
|
114
|
+
destructive: metadata?.destructive,
|
|
115
|
+
envPolicy: metadata?.envPolicy ?? null,
|
|
116
|
+
envAllowlist: metadata?.envAllowlist ?? [],
|
|
117
|
+
};
|
|
118
|
+
}
|
|
119
|
+
export function createRunPlan(projectRoot, contract, intentName) {
|
|
120
|
+
const rawIntent = contract.intents[intentName];
|
|
121
|
+
const eligibility = evaluateCommandIntentEligibility(intentName, rawIntent);
|
|
122
|
+
if (!isRecord(rawIntent)) {
|
|
123
|
+
return createBlockedRunPlan(contract, intentName, undefined, eligibility, 'intent_not_table', eligibility.detail);
|
|
124
|
+
}
|
|
125
|
+
if (!eligibility.ok) {
|
|
126
|
+
return createBlockedRunPlan(contract, intentName, rawIntent, eligibility, eligibility.code, eligibility.detail);
|
|
127
|
+
}
|
|
128
|
+
const metadata = readRunIntentMetadata(contract, rawIntent);
|
|
129
|
+
let cwd;
|
|
130
|
+
try {
|
|
131
|
+
cwd = resolveSafeProjectCwd(projectRoot, metadata.configuredCwd);
|
|
132
|
+
}
|
|
133
|
+
catch (error) {
|
|
134
|
+
return createBlockedRunPlan(contract, intentName, rawIntent, eligibility, 'cwd_outside_project', error instanceof Error ? error.message : String(error));
|
|
135
|
+
}
|
|
136
|
+
if (!metadata.timeoutSeconds || !metadata.mode) {
|
|
137
|
+
return createBlockedRunPlan(contract, intentName, rawIntent, eligibility, !metadata.timeoutSeconds ? 'missing_timeout' : 'missing_command_source', !metadata.timeoutSeconds ? 'Intent timeout_seconds is missing or invalid.' : 'Intent does not define argv or shell cmd.');
|
|
138
|
+
}
|
|
139
|
+
return {
|
|
140
|
+
intentName,
|
|
141
|
+
intent: rawIntent,
|
|
142
|
+
ok: true,
|
|
143
|
+
eligibility,
|
|
144
|
+
reasonCode: null,
|
|
145
|
+
detail: null,
|
|
146
|
+
intentStatus: metadata.intentStatus,
|
|
147
|
+
lifecycle: metadata.lifecycle,
|
|
148
|
+
runPolicy: metadata.runPolicy,
|
|
149
|
+
kind: metadata.kind,
|
|
150
|
+
configuredCwd: metadata.configuredCwd,
|
|
151
|
+
cwd,
|
|
152
|
+
relativeCwd: getRelativeProjectPath(projectRoot, cwd),
|
|
153
|
+
timeoutSeconds: metadata.timeoutSeconds,
|
|
154
|
+
maxOutputBytes: metadata.maxOutputBytes,
|
|
155
|
+
successExitCodes: metadata.successExitCodes,
|
|
156
|
+
commandArgv: metadata.commandArgv,
|
|
157
|
+
shellCommand: metadata.shellCommand,
|
|
158
|
+
mode: metadata.mode,
|
|
159
|
+
argvCommand: metadata.commandArgv ? resolveArgvCommand(rawIntent, metadata.commandArgv) : undefined,
|
|
160
|
+
writes: metadata.writes,
|
|
161
|
+
effects: metadata.effects,
|
|
162
|
+
network: metadata.network,
|
|
163
|
+
destructive: metadata.destructive,
|
|
164
|
+
envPolicy: metadata.envPolicy,
|
|
165
|
+
envAllowlist: metadata.envAllowlist,
|
|
166
|
+
};
|
|
167
|
+
}
|
|
168
|
+
export function createRunPreview(plan, previewMode) {
|
|
169
|
+
return {
|
|
170
|
+
schema_version: '1',
|
|
171
|
+
command: 'run',
|
|
172
|
+
preview: true,
|
|
173
|
+
preview_mode: previewMode,
|
|
174
|
+
intent: plan.intentName,
|
|
175
|
+
runnable: plan.ok,
|
|
176
|
+
eligibility: plan.eligibility,
|
|
177
|
+
reason_code: plan.reasonCode,
|
|
178
|
+
detail: plan.detail,
|
|
179
|
+
status: plan.intentStatus,
|
|
180
|
+
lifecycle: plan.lifecycle,
|
|
181
|
+
run_policy: plan.runPolicy,
|
|
182
|
+
kind: plan.kind,
|
|
183
|
+
configured_cwd: plan.configuredCwd,
|
|
184
|
+
cwd: plan.relativeCwd,
|
|
185
|
+
resolved_cwd: plan.cwd,
|
|
186
|
+
timeout_seconds: plan.timeoutSeconds,
|
|
187
|
+
max_output_bytes: plan.maxOutputBytes,
|
|
188
|
+
mode: plan.mode,
|
|
189
|
+
argv: plan.commandArgv,
|
|
190
|
+
resolved_argv: plan.argvCommand,
|
|
191
|
+
cmd: plan.shellCommand,
|
|
192
|
+
writes: plan.writes,
|
|
193
|
+
effects: plan.effects,
|
|
194
|
+
network: plan.network,
|
|
195
|
+
destructive: plan.destructive,
|
|
196
|
+
env_policy: plan.envPolicy,
|
|
197
|
+
env_allowlist: plan.envAllowlist,
|
|
198
|
+
success_exit_codes: plan.successExitCodes,
|
|
199
|
+
};
|
|
200
|
+
}
|
|
201
|
+
export function renderRunPreviewText(plan, previewMode) {
|
|
202
|
+
const lines = [
|
|
203
|
+
`mf run ${previewMode}`,
|
|
204
|
+
`Intent: ${plan.intentName}`,
|
|
205
|
+
`Runnable: ${plan.ok ? 'yes' : 'no'}`,
|
|
206
|
+
];
|
|
207
|
+
if (!plan.ok) {
|
|
208
|
+
lines.push(`Reason: ${plan.reasonCode}${plan.detail ? ` (${plan.detail})` : ''}`);
|
|
209
|
+
return lines.join('\n');
|
|
210
|
+
}
|
|
211
|
+
lines.push(`Mode: ${plan.mode}`);
|
|
212
|
+
lines.push(`Cwd: ${plan.relativeCwd}`);
|
|
213
|
+
lines.push(`Timeout: ${plan.timeoutSeconds}s`);
|
|
214
|
+
lines.push(`Environment: ${plan.envPolicy}${plan.envAllowlist.length > 0 ? ` (${plan.envAllowlist.join(', ')})` : ''}`);
|
|
215
|
+
if (plan.commandArgv) {
|
|
216
|
+
lines.push(`Argv: ${plan.commandArgv.join(' ')}`);
|
|
217
|
+
}
|
|
218
|
+
else if (plan.shellCommand) {
|
|
219
|
+
lines.push(`Shell: ${plan.shellCommand}`);
|
|
220
|
+
}
|
|
221
|
+
return lines.join('\n');
|
|
222
|
+
}
|
|
@@ -163,17 +163,32 @@ export function getDefaultTemplate() {
|
|
|
163
163
|
export function getTemplateFiles(template, locale = template.manifest.defaultLocale, profile = template.manifest.defaultProfile, options = {}) {
|
|
164
164
|
const commonRoot = path.join(template.templateRoot, template.manifest.commonRoot);
|
|
165
165
|
const localeRoot = template.manifest.localesRoot ? path.join(template.templateRoot, template.manifest.localesRoot, locale) : undefined;
|
|
166
|
+
const sourceLocaleRoot = template.manifest.localesRoot && locale !== template.manifest.defaultLocale
|
|
167
|
+
? path.join(template.templateRoot, template.manifest.localesRoot, template.manifest.defaultLocale)
|
|
168
|
+
: undefined;
|
|
166
169
|
const selectedSkills = selectedSkillNames(template.manifest, profile, options);
|
|
167
170
|
return template.manifest.creates.filter((relativePath) => shouldIncludeTemplatePath(relativePath, selectedSkills)).map((relativePath) => {
|
|
168
171
|
const localePath = localeRoot ? path.join(localeRoot, ...relativePath.split('/')) : undefined;
|
|
172
|
+
const sourceLocalePath = sourceLocaleRoot ? path.join(sourceLocaleRoot, ...relativePath.split('/')) : undefined;
|
|
169
173
|
const commonPath = path.join(commonRoot, ...relativePath.split('/'));
|
|
174
|
+
const localizedPath = localePath && existsSync(localePath) ? localePath : undefined;
|
|
175
|
+
const fallbackLocalePath = sourceLocalePath && existsSync(sourceLocalePath) ? sourceLocalePath : undefined;
|
|
176
|
+
const indexSourcePath = localizedPath ?? fallbackLocalePath ?? commonPath;
|
|
170
177
|
const content = relativePath === '.mustflow/skills/INDEX.md'
|
|
171
|
-
? filterSkillIndexContent(readFileSync(
|
|
178
|
+
? filterSkillIndexContent(readFileSync(indexSourcePath, 'utf8'), selectedSkills)
|
|
172
179
|
: undefined;
|
|
173
|
-
if (
|
|
180
|
+
if (localizedPath) {
|
|
174
181
|
return {
|
|
175
182
|
relativePath,
|
|
176
|
-
sourcePath:
|
|
183
|
+
sourcePath: localizedPath,
|
|
184
|
+
sourceKind: 'locale',
|
|
185
|
+
content,
|
|
186
|
+
};
|
|
187
|
+
}
|
|
188
|
+
if (fallbackLocalePath) {
|
|
189
|
+
return {
|
|
190
|
+
relativePath,
|
|
191
|
+
sourcePath: fallbackLocalePath,
|
|
177
192
|
sourceKind: 'locale',
|
|
178
193
|
content,
|
|
179
194
|
};
|
|
@@ -0,0 +1,163 @@
|
|
|
1
|
+
import { existsSync, readFileSync } from 'node:fs';
|
|
2
|
+
import path from 'node:path';
|
|
3
|
+
import { ensureFileTargetInsideWithoutSymlinks, readUtf8FileInsideWithoutSymlinks } from './filesystem.js';
|
|
4
|
+
const DIFF_PREVIEW_MAX_LINES = 120;
|
|
5
|
+
const DIFF_PREVIEW_MAX_LINE_BYTES = 240;
|
|
6
|
+
const DIFF_PREVIEW_CONTEXT_LINES = 3;
|
|
7
|
+
const DIFF_PREVIEW_TRUNCATION_MARKER = '[... diff preview truncated ...]';
|
|
8
|
+
const DIFF_PREVIEW_LINE_TRUNCATION_MARKER = ' [... line truncated]';
|
|
9
|
+
export function shouldPreviewUpdateDiff(action) {
|
|
10
|
+
return action === 'create' || action === 'update' || action === 'blocked-local-change' || action === 'manual-review';
|
|
11
|
+
}
|
|
12
|
+
function templateFileContent(source) {
|
|
13
|
+
return source.content === undefined ? readFileSync(source.sourcePath, 'utf8') : source.content;
|
|
14
|
+
}
|
|
15
|
+
function shouldOmitDiffPreview(relativePath) {
|
|
16
|
+
const normalizedPath = relativePath.replaceAll('\\', '/');
|
|
17
|
+
const lowerPath = normalizedPath.toLowerCase();
|
|
18
|
+
return (normalizedPath.startsWith('.mustflow/state/') ||
|
|
19
|
+
normalizedPath.startsWith('.mustflow/cache/') ||
|
|
20
|
+
normalizedPath.startsWith('.mustflow/backups/') ||
|
|
21
|
+
lowerPath === '.env' ||
|
|
22
|
+
lowerPath.startsWith('.env.') ||
|
|
23
|
+
lowerPath.endsWith('.pem') ||
|
|
24
|
+
lowerPath.endsWith('.key'));
|
|
25
|
+
}
|
|
26
|
+
function unavailableDiffPreview(reason) {
|
|
27
|
+
return {
|
|
28
|
+
format: 'unified',
|
|
29
|
+
available: false,
|
|
30
|
+
from: 'unavailable',
|
|
31
|
+
to: 'bundled_template',
|
|
32
|
+
bounded: true,
|
|
33
|
+
truncated: false,
|
|
34
|
+
max_lines: DIFF_PREVIEW_MAX_LINES,
|
|
35
|
+
max_line_bytes: DIFF_PREVIEW_MAX_LINE_BYTES,
|
|
36
|
+
lines: [],
|
|
37
|
+
reason,
|
|
38
|
+
};
|
|
39
|
+
}
|
|
40
|
+
function splitDiffLines(content) {
|
|
41
|
+
const normalized = content.replace(/\r\n/g, '\n').replace(/\r/g, '\n');
|
|
42
|
+
if (normalized.length === 0) {
|
|
43
|
+
return [];
|
|
44
|
+
}
|
|
45
|
+
return normalized.endsWith('\n') ? normalized.slice(0, -1).split('\n') : normalized.split('\n');
|
|
46
|
+
}
|
|
47
|
+
function unifiedRange(startIndex, count) {
|
|
48
|
+
if (count === 0) {
|
|
49
|
+
return `${startIndex},0`;
|
|
50
|
+
}
|
|
51
|
+
return `${startIndex + 1},${count}`;
|
|
52
|
+
}
|
|
53
|
+
function truncateDiffLine(line) {
|
|
54
|
+
if (Buffer.byteLength(line, 'utf8') <= DIFF_PREVIEW_MAX_LINE_BYTES) {
|
|
55
|
+
return { line, truncated: false };
|
|
56
|
+
}
|
|
57
|
+
let result = '';
|
|
58
|
+
for (const character of line) {
|
|
59
|
+
const candidate = `${result}${character}${DIFF_PREVIEW_LINE_TRUNCATION_MARKER}`;
|
|
60
|
+
if (Buffer.byteLength(candidate, 'utf8') > DIFF_PREVIEW_MAX_LINE_BYTES) {
|
|
61
|
+
break;
|
|
62
|
+
}
|
|
63
|
+
result += character;
|
|
64
|
+
}
|
|
65
|
+
return {
|
|
66
|
+
line: `${result}${DIFF_PREVIEW_LINE_TRUNCATION_MARKER}`,
|
|
67
|
+
truncated: true,
|
|
68
|
+
};
|
|
69
|
+
}
|
|
70
|
+
function boundDiffLines(lines) {
|
|
71
|
+
const bounded = [];
|
|
72
|
+
let truncated = false;
|
|
73
|
+
for (const line of lines) {
|
|
74
|
+
if (bounded.length >= DIFF_PREVIEW_MAX_LINES) {
|
|
75
|
+
truncated = true;
|
|
76
|
+
break;
|
|
77
|
+
}
|
|
78
|
+
const boundedLine = truncateDiffLine(line);
|
|
79
|
+
truncated = truncated || boundedLine.truncated;
|
|
80
|
+
bounded.push(boundedLine.line);
|
|
81
|
+
}
|
|
82
|
+
if (truncated) {
|
|
83
|
+
if (bounded.length >= DIFF_PREVIEW_MAX_LINES) {
|
|
84
|
+
bounded[bounded.length - 1] = DIFF_PREVIEW_TRUNCATION_MARKER;
|
|
85
|
+
}
|
|
86
|
+
else {
|
|
87
|
+
bounded.push(DIFF_PREVIEW_TRUNCATION_MARKER);
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
return { lines: bounded, truncated };
|
|
91
|
+
}
|
|
92
|
+
function createUnifiedDiffLines(relativePath, currentContent, templateContent, targetExists) {
|
|
93
|
+
const currentLines = splitDiffLines(currentContent);
|
|
94
|
+
const templateLines = splitDiffLines(templateContent);
|
|
95
|
+
let prefixLength = 0;
|
|
96
|
+
while (prefixLength < currentLines.length &&
|
|
97
|
+
prefixLength < templateLines.length &&
|
|
98
|
+
currentLines[prefixLength] === templateLines[prefixLength]) {
|
|
99
|
+
prefixLength += 1;
|
|
100
|
+
}
|
|
101
|
+
let suffixLength = 0;
|
|
102
|
+
while (suffixLength < currentLines.length - prefixLength &&
|
|
103
|
+
suffixLength < templateLines.length - prefixLength &&
|
|
104
|
+
currentLines[currentLines.length - 1 - suffixLength] === templateLines[templateLines.length - 1 - suffixLength]) {
|
|
105
|
+
suffixLength += 1;
|
|
106
|
+
}
|
|
107
|
+
const currentChangeEnd = currentLines.length - suffixLength;
|
|
108
|
+
const templateChangeEnd = templateLines.length - suffixLength;
|
|
109
|
+
const currentStart = Math.max(0, prefixLength - DIFF_PREVIEW_CONTEXT_LINES);
|
|
110
|
+
const templateStart = Math.max(0, prefixLength - DIFF_PREVIEW_CONTEXT_LINES);
|
|
111
|
+
const currentEnd = Math.min(currentLines.length, currentChangeEnd + DIFF_PREVIEW_CONTEXT_LINES);
|
|
112
|
+
const templateEnd = Math.min(templateLines.length, templateChangeEnd + DIFF_PREVIEW_CONTEXT_LINES);
|
|
113
|
+
const lines = [
|
|
114
|
+
targetExists ? `--- ${relativePath} (current)` : '--- /dev/null',
|
|
115
|
+
`+++ ${relativePath} (template)`,
|
|
116
|
+
`@@ -${unifiedRange(currentStart, currentEnd - currentStart)} +${unifiedRange(templateStart, templateEnd - templateStart)} @@`,
|
|
117
|
+
];
|
|
118
|
+
for (let index = currentStart; index < prefixLength; index += 1) {
|
|
119
|
+
lines.push(` ${currentLines[index]}`);
|
|
120
|
+
}
|
|
121
|
+
for (let index = prefixLength; index < currentChangeEnd; index += 1) {
|
|
122
|
+
lines.push(`-${currentLines[index]}`);
|
|
123
|
+
}
|
|
124
|
+
for (let index = prefixLength; index < templateChangeEnd; index += 1) {
|
|
125
|
+
lines.push(`+${templateLines[index]}`);
|
|
126
|
+
}
|
|
127
|
+
for (let index = currentChangeEnd; index < currentEnd; index += 1) {
|
|
128
|
+
lines.push(` ${currentLines[index]}`);
|
|
129
|
+
}
|
|
130
|
+
return lines;
|
|
131
|
+
}
|
|
132
|
+
export function createUpdateDiffPreview(projectRoot, input) {
|
|
133
|
+
if (shouldOmitDiffPreview(input.relativePath)) {
|
|
134
|
+
return unavailableDiffPreview('diff preview omitted for generated state, cache, backup, or sensitive-looking path');
|
|
135
|
+
}
|
|
136
|
+
const targetPath = path.join(projectRoot, input.relativePath);
|
|
137
|
+
const targetExists = existsSync(targetPath);
|
|
138
|
+
try {
|
|
139
|
+
if (targetExists) {
|
|
140
|
+
ensureFileTargetInsideWithoutSymlinks(projectRoot, targetPath);
|
|
141
|
+
}
|
|
142
|
+
else {
|
|
143
|
+
ensureFileTargetInsideWithoutSymlinks(projectRoot, targetPath, { allowMissingLeaf: true });
|
|
144
|
+
}
|
|
145
|
+
const currentContent = targetExists ? readUtf8FileInsideWithoutSymlinks(projectRoot, targetPath) : '';
|
|
146
|
+
const templateContent = templateFileContent(input.source);
|
|
147
|
+
const boundedLines = boundDiffLines(createUnifiedDiffLines(input.relativePath, currentContent, templateContent, targetExists));
|
|
148
|
+
return {
|
|
149
|
+
format: 'unified',
|
|
150
|
+
available: true,
|
|
151
|
+
from: targetExists ? 'current_target' : 'missing_target',
|
|
152
|
+
to: 'bundled_template',
|
|
153
|
+
bounded: true,
|
|
154
|
+
truncated: boundedLines.truncated,
|
|
155
|
+
max_lines: DIFF_PREVIEW_MAX_LINES,
|
|
156
|
+
max_line_bytes: DIFF_PREVIEW_MAX_LINE_BYTES,
|
|
157
|
+
lines: boundedLines.lines,
|
|
158
|
+
};
|
|
159
|
+
}
|
|
160
|
+
catch (error) {
|
|
161
|
+
return unavailableDiffPreview(error instanceof Error ? error.message : String(error));
|
|
162
|
+
}
|
|
163
|
+
}
|
|
@@ -13,6 +13,7 @@ import { inspectManifestLock } from './manifest-lock.js';
|
|
|
13
13
|
import { COMMIT_MESSAGE_STYLES, TEST_AUTHORING_POLICIES } from './preferences-options.js';
|
|
14
14
|
import { generateRepoMap } from './repo-map.js';
|
|
15
15
|
import { readTomlFile } from './toml.js';
|
|
16
|
+
import { getContractModelDefinitions, validateCandidateContractModelConfig, } from '../../core/contract-models.js';
|
|
16
17
|
import { VERSIONING_CONFIG_PATH, VERSION_SOURCE_AUTHORITIES, VERSION_SOURCE_KINDS, detectVersionSourcePaths, readDeclaredVersionSources, releaseVersioningIsEnabled, } from '../../core/version-sources.js';
|
|
17
18
|
export { describeCheckIssues, getCheckIssueId, } from '../../core/check-issues.js';
|
|
18
19
|
const REQUIRED_SKILL_SECTION_IDS = [
|
|
@@ -1222,6 +1223,26 @@ function validateStrictVerificationSelectionAuthority(preferencesToml, issues) {
|
|
|
1222
1223
|
}
|
|
1223
1224
|
}
|
|
1224
1225
|
}
|
|
1226
|
+
function validateStrictCandidateContractModelConfigs(projectRoot, issues) {
|
|
1227
|
+
for (const model of getContractModelDefinitions()) {
|
|
1228
|
+
const configPath = path.join(projectRoot, ...model.filePath.split('/'));
|
|
1229
|
+
if (!existsSync(configPath)) {
|
|
1230
|
+
continue;
|
|
1231
|
+
}
|
|
1232
|
+
let parsed;
|
|
1233
|
+
try {
|
|
1234
|
+
parsed = readTomlFile(configPath);
|
|
1235
|
+
}
|
|
1236
|
+
catch (error) {
|
|
1237
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
1238
|
+
pushStrictIssue(issues, `Invalid TOML in ${model.filePath}: ${message}`);
|
|
1239
|
+
continue;
|
|
1240
|
+
}
|
|
1241
|
+
for (const issue of validateCandidateContractModelConfig(model, parsed)) {
|
|
1242
|
+
pushStrictIssue(issues, issue.message);
|
|
1243
|
+
}
|
|
1244
|
+
}
|
|
1245
|
+
}
|
|
1225
1246
|
function validateStrictReleaseVersioningAuthority(preferencesToml, issues) {
|
|
1226
1247
|
if (!preferencesToml || !isRecord(preferencesToml.release)) {
|
|
1227
1248
|
return;
|
|
@@ -1597,6 +1618,7 @@ function validateStrict(projectRoot, parsed, issues) {
|
|
|
1597
1618
|
validateStrictCommandDefaults(projectRoot, parsed.commandsToml, issues);
|
|
1598
1619
|
validateStrictReleaseVersioningAuthority(parsed.preferencesToml, issues);
|
|
1599
1620
|
validateStrictVerificationSelectionAuthority(parsed.preferencesToml, issues);
|
|
1621
|
+
validateStrictCandidateContractModelConfigs(projectRoot, issues);
|
|
1600
1622
|
validateStrictVersionSources(projectRoot, parsed.preferencesToml, parsed.versioningToml, issues);
|
|
1601
1623
|
validateStrictTemplateVersionSync(projectRoot, parsed.preferencesToml, issues);
|
|
1602
1624
|
validateStrictManagedMarkdownIdentities(projectRoot, issues);
|