create-yss-spec 3.2.0 → 3.3.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +2 -2
- package/package.json +3 -2
- package/src/command-runner.mjs +107 -0
- package/src/self-update.js +7 -4
- package/src/template/instance-runtime.js +1 -1
- package/template/.agents/skills/.strategic-design-skills-manifest.json +2 -2
- package/template/.agents/skills/code-review/SKILL.md +4 -0
- package/template/.agents/skills/code-review/agents/openai.yaml +1 -1
- package/template/.agents/skills/code-review/references/yss-review-standards.md +9 -2
- package/template/.agents/skills/competitive-intelligence/SKILL.md +4 -4
- package/template/.agents/skills/domain-modeling/CONTEXT-FORMAT.md +1 -1
- package/template/.agents/skills/grill-with-docs/SKILL.md +1 -1
- package/template/.agents/skills/setup-matt-pocock-skills/issue-tracker-local.md +1 -1
- package/template/.agents/skills/yss-ddd-scaffold-generator/SKILL.md +1 -1
- package/template/.agents/skills/yss-ddd-scaffold-generator/scripts/generate_scaffold.mjs +7 -3
- package/template/.agents/skills/yss-ddd-scaffold-generator/scripts/run_scaffold_verification.mjs +8 -8
- package/template/.agents/skills/yss-ddd-scaffold-generator/scripts/scaffold-generator.test.mjs +9 -0
- package/template/.agents/skills/yss-frontend-scaffold-generator/SKILL.md +10 -7
- package/template/.agents/skills/yss-frontend-scaffold-generator/scripts/generate_and_verify_scaffold.mjs +10 -0
- package/template/.agents/skills/yss-frontend-scaffold-generator/scripts/generate_scaffold.mjs +121 -0
- package/template/.agents/skills/yss-frontend-scaffold-generator/scripts/run_scaffold_verification.mjs +40 -0
- package/template/.agents/skills/yss-frontend-scaffold-generator/scripts/scaffold-generator.test.mjs +55 -0
- package/template/.agents/skills/yss-implementation-contract-compiler/SKILL.md +1 -1
- package/template/.agents/skills/yss-implementation-contract-compiler/references/boundaries.md +4 -0
- package/template/.agents/skills/yss-implementation-contract-compiler/references/compiler-contract.yaml +25 -0
- package/template/.agents/skills/yss-layered-mvc-scaffold-generator/SKILL.md +2 -2
- package/template/.agents/skills/yss-layered-mvc-scaffold-generator/scripts/generate_scaffold.mjs +8 -5
- package/template/.agents/skills/yss-layered-mvc-scaffold-generator/scripts/scaffold-generator.test.mjs +17 -2
- package/template/.agents/skills/yss-mybatis/SKILL.md +34 -58
- package/template/.agents/skills/yss-mybatis/agents/openai.yaml +2 -2
- package/template/.agents/skills/yss-mybatis/references/source-index.md +88 -68
- package/template/.agents/skills/yss-product-lifecycle/SKILL.md +50 -42
- package/template/.agents/skills/yss-product-lifecycle/references/artifact-dependencies.md +5 -3
- package/template/.agents/skills/yss-product-lifecycle/references/matt-yss-adapter.md +3 -3
- package/template/.agents/skills/yss-product-lifecycle/references/orchestration-contract.yaml +124 -16
- package/template/.agents/skills/yss-product-lifecycle/references/orchestration.md +16 -2
- package/template/.agents/skills/yss-product-lifecycle/references/state-model.md +5 -2
- package/template/.agents/skills/yss-repository/SKILL.md +28 -70
- package/template/.agents/skills/yss-repository/agents/openai.yaml +2 -2
- package/template/.agents/skills/yss-repository/references/profiles/layered-mvc-service.md +19 -1
- package/template/.agents/skills/yss-repository/references/profiles/mvc-data-analysis-v1.md +19 -1
- package/template/.agents/skills/yss-repository/references/profiles/target-domain-model.md +21 -1
- package/template/.agents/skills/yss-repository/tests/profile-routing.test.mjs +59 -0
- package/template/.agents/skills/yss-research/SKILL.md +1 -1
- package/template/.agents/skills/yss-skill-source-index-refresh/SKILL.md +8 -5
- package/template/.agents/skills/yss-skill-source-index-refresh/references/source-location.md +2 -1
- package/template/.agents/skills/yss-skill-source-index-refresh/scripts/refresh-yss-skill-index.mjs +388 -18
- package/template/.agents/skills/yss-skill-source-index-refresh/scripts/refresh-yss-skill-index.test.mjs +79 -1
- package/template/.agents/skills/yss-stage-decision/SKILL.md +5 -3
- package/template/.agents/skills/yss-stage-decision/references/stage-decision-package-contract.md +1 -1
- package/template/.claude/skills/code-review/SKILL.md +4 -0
- package/template/.claude/skills/code-review/agents/openai.yaml +1 -1
- package/template/.claude/skills/code-review/references/yss-review-standards.md +9 -2
- package/template/.claude/skills/competitive-intelligence/SKILL.md +4 -4
- package/template/.claude/skills/domain-modeling/CONTEXT-FORMAT.md +1 -1
- package/template/.claude/skills/grill-with-docs/SKILL.md +1 -1
- package/template/.claude/skills/setup-matt-pocock-skills/issue-tracker-local.md +1 -1
- package/template/.claude/skills/yss-ddd-scaffold-generator/SKILL.md +1 -1
- package/template/.claude/skills/yss-ddd-scaffold-generator/scripts/generate_scaffold.mjs +7 -3
- package/template/.claude/skills/yss-ddd-scaffold-generator/scripts/run_scaffold_verification.mjs +8 -8
- package/template/.claude/skills/yss-ddd-scaffold-generator/scripts/scaffold-generator.test.mjs +9 -0
- package/template/.claude/skills/yss-frontend-scaffold-generator/SKILL.md +10 -7
- package/template/.claude/skills/yss-frontend-scaffold-generator/scripts/generate_and_verify_scaffold.mjs +10 -0
- package/template/.claude/skills/yss-frontend-scaffold-generator/scripts/generate_scaffold.mjs +121 -0
- package/template/.claude/skills/yss-frontend-scaffold-generator/scripts/run_scaffold_verification.mjs +40 -0
- package/template/.claude/skills/yss-frontend-scaffold-generator/scripts/scaffold-generator.test.mjs +55 -0
- package/template/.claude/skills/yss-implementation-contract-compiler/SKILL.md +1 -1
- package/template/.claude/skills/yss-implementation-contract-compiler/references/boundaries.md +4 -0
- package/template/.claude/skills/yss-implementation-contract-compiler/references/compiler-contract.yaml +25 -0
- package/template/.claude/skills/yss-layered-mvc-scaffold-generator/SKILL.md +2 -2
- package/template/.claude/skills/yss-layered-mvc-scaffold-generator/scripts/generate_scaffold.mjs +8 -5
- package/template/.claude/skills/yss-layered-mvc-scaffold-generator/scripts/scaffold-generator.test.mjs +17 -2
- package/template/.claude/skills/yss-mybatis/SKILL.md +34 -58
- package/template/.claude/skills/yss-mybatis/agents/openai.yaml +2 -2
- package/template/.claude/skills/yss-mybatis/references/source-index.md +88 -68
- package/template/.claude/skills/yss-product-lifecycle/SKILL.md +50 -42
- package/template/.claude/skills/yss-product-lifecycle/references/artifact-dependencies.md +5 -3
- package/template/.claude/skills/yss-product-lifecycle/references/matt-yss-adapter.md +3 -3
- package/template/.claude/skills/yss-product-lifecycle/references/orchestration-contract.yaml +124 -16
- package/template/.claude/skills/yss-product-lifecycle/references/orchestration.md +16 -2
- package/template/.claude/skills/yss-product-lifecycle/references/state-model.md +5 -2
- package/template/.claude/skills/yss-repository/SKILL.md +28 -70
- package/template/.claude/skills/yss-repository/agents/openai.yaml +2 -2
- package/template/.claude/skills/yss-repository/references/profiles/layered-mvc-service.md +19 -1
- package/template/.claude/skills/yss-repository/references/profiles/mvc-data-analysis-v1.md +19 -1
- package/template/.claude/skills/yss-repository/references/profiles/target-domain-model.md +21 -1
- package/template/.claude/skills/yss-repository/tests/profile-routing.test.mjs +59 -0
- package/template/.claude/skills/yss-research/SKILL.md +1 -1
- package/template/.claude/skills/yss-skill-source-index-refresh/SKILL.md +8 -5
- package/template/.claude/skills/yss-skill-source-index-refresh/references/source-location.md +2 -1
- package/template/.claude/skills/yss-skill-source-index-refresh/scripts/refresh-yss-skill-index.mjs +388 -18
- package/template/.claude/skills/yss-skill-source-index-refresh/scripts/refresh-yss-skill-index.test.mjs +79 -1
- package/template/.claude/skills/yss-stage-decision/SKILL.md +5 -3
- package/template/.claude/skills/yss-stage-decision/references/stage-decision-package-contract.md +1 -1
- package/template/.codex/skills/code-review/SKILL.md +4 -0
- package/template/.codex/skills/code-review/agents/openai.yaml +1 -1
- package/template/.codex/skills/code-review/references/yss-review-standards.md +9 -2
- package/template/.codex/skills/competitive-intelligence/SKILL.md +4 -4
- package/template/.codex/skills/domain-modeling/CONTEXT-FORMAT.md +1 -1
- package/template/.codex/skills/grill-with-docs/SKILL.md +1 -1
- package/template/.codex/skills/setup-matt-pocock-skills/issue-tracker-local.md +1 -1
- package/template/.codex/skills/yss-ddd-scaffold-generator/SKILL.md +1 -1
- package/template/.codex/skills/yss-ddd-scaffold-generator/scripts/generate_scaffold.mjs +7 -3
- package/template/.codex/skills/yss-ddd-scaffold-generator/scripts/run_scaffold_verification.mjs +8 -8
- package/template/.codex/skills/yss-ddd-scaffold-generator/scripts/scaffold-generator.test.mjs +9 -0
- package/template/.codex/skills/yss-frontend-scaffold-generator/SKILL.md +10 -7
- package/template/.codex/skills/yss-frontend-scaffold-generator/scripts/generate_and_verify_scaffold.mjs +10 -0
- package/template/.codex/skills/yss-frontend-scaffold-generator/scripts/generate_scaffold.mjs +121 -0
- package/template/.codex/skills/yss-frontend-scaffold-generator/scripts/run_scaffold_verification.mjs +40 -0
- package/template/.codex/skills/yss-frontend-scaffold-generator/scripts/scaffold-generator.test.mjs +55 -0
- package/template/.codex/skills/yss-implementation-contract-compiler/SKILL.md +1 -1
- package/template/.codex/skills/yss-implementation-contract-compiler/references/boundaries.md +4 -0
- package/template/.codex/skills/yss-implementation-contract-compiler/references/compiler-contract.yaml +25 -0
- package/template/.codex/skills/yss-layered-mvc-scaffold-generator/SKILL.md +2 -2
- package/template/.codex/skills/yss-layered-mvc-scaffold-generator/scripts/generate_scaffold.mjs +8 -5
- package/template/.codex/skills/yss-layered-mvc-scaffold-generator/scripts/scaffold-generator.test.mjs +17 -2
- package/template/.codex/skills/yss-mybatis/SKILL.md +34 -58
- package/template/.codex/skills/yss-mybatis/agents/openai.yaml +2 -2
- package/template/.codex/skills/yss-mybatis/references/source-index.md +88 -68
- package/template/.codex/skills/yss-product-lifecycle/SKILL.md +50 -42
- package/template/.codex/skills/yss-product-lifecycle/references/artifact-dependencies.md +5 -3
- package/template/.codex/skills/yss-product-lifecycle/references/matt-yss-adapter.md +3 -3
- package/template/.codex/skills/yss-product-lifecycle/references/orchestration-contract.yaml +124 -16
- package/template/.codex/skills/yss-product-lifecycle/references/orchestration.md +16 -2
- package/template/.codex/skills/yss-product-lifecycle/references/state-model.md +5 -2
- package/template/.codex/skills/yss-repository/SKILL.md +28 -70
- package/template/.codex/skills/yss-repository/agents/openai.yaml +2 -2
- package/template/.codex/skills/yss-repository/references/profiles/layered-mvc-service.md +19 -1
- package/template/.codex/skills/yss-repository/references/profiles/mvc-data-analysis-v1.md +19 -1
- package/template/.codex/skills/yss-repository/references/profiles/target-domain-model.md +21 -1
- package/template/.codex/skills/yss-repository/tests/profile-routing.test.mjs +59 -0
- package/template/.codex/skills/yss-research/SKILL.md +1 -1
- package/template/.codex/skills/yss-skill-source-index-refresh/SKILL.md +8 -5
- package/template/.codex/skills/yss-skill-source-index-refresh/references/source-location.md +2 -1
- package/template/.codex/skills/yss-skill-source-index-refresh/scripts/refresh-yss-skill-index.mjs +388 -18
- package/template/.codex/skills/yss-skill-source-index-refresh/scripts/refresh-yss-skill-index.test.mjs +79 -1
- package/template/.codex/skills/yss-stage-decision/SKILL.md +5 -3
- package/template/.codex/skills/yss-stage-decision/references/stage-decision-package-contract.md +1 -1
- package/template/.cursor/skills/code-review/SKILL.md +4 -0
- package/template/.cursor/skills/code-review/agents/openai.yaml +1 -1
- package/template/.cursor/skills/code-review/references/yss-review-standards.md +9 -2
- package/template/.cursor/skills/competitive-intelligence/SKILL.md +4 -4
- package/template/.cursor/skills/domain-modeling/CONTEXT-FORMAT.md +1 -1
- package/template/.cursor/skills/grill-with-docs/SKILL.md +1 -1
- package/template/.cursor/skills/setup-matt-pocock-skills/issue-tracker-local.md +1 -1
- package/template/.cursor/skills/yss-ddd-scaffold-generator/SKILL.md +1 -1
- package/template/.cursor/skills/yss-ddd-scaffold-generator/scripts/generate_scaffold.mjs +7 -3
- package/template/.cursor/skills/yss-ddd-scaffold-generator/scripts/run_scaffold_verification.mjs +8 -8
- package/template/.cursor/skills/yss-ddd-scaffold-generator/scripts/scaffold-generator.test.mjs +9 -0
- package/template/.cursor/skills/yss-frontend-scaffold-generator/SKILL.md +10 -7
- package/template/.cursor/skills/yss-frontend-scaffold-generator/scripts/generate_and_verify_scaffold.mjs +10 -0
- package/template/.cursor/skills/yss-frontend-scaffold-generator/scripts/generate_scaffold.mjs +121 -0
- package/template/.cursor/skills/yss-frontend-scaffold-generator/scripts/run_scaffold_verification.mjs +40 -0
- package/template/.cursor/skills/yss-frontend-scaffold-generator/scripts/scaffold-generator.test.mjs +55 -0
- package/template/.cursor/skills/yss-implementation-contract-compiler/SKILL.md +1 -1
- package/template/.cursor/skills/yss-implementation-contract-compiler/references/boundaries.md +4 -0
- package/template/.cursor/skills/yss-implementation-contract-compiler/references/compiler-contract.yaml +25 -0
- package/template/.cursor/skills/yss-layered-mvc-scaffold-generator/SKILL.md +2 -2
- package/template/.cursor/skills/yss-layered-mvc-scaffold-generator/scripts/generate_scaffold.mjs +8 -5
- package/template/.cursor/skills/yss-layered-mvc-scaffold-generator/scripts/scaffold-generator.test.mjs +17 -2
- package/template/.cursor/skills/yss-mybatis/SKILL.md +34 -58
- package/template/.cursor/skills/yss-mybatis/agents/openai.yaml +2 -2
- package/template/.cursor/skills/yss-mybatis/references/source-index.md +88 -68
- package/template/.cursor/skills/yss-product-lifecycle/SKILL.md +50 -42
- package/template/.cursor/skills/yss-product-lifecycle/references/artifact-dependencies.md +5 -3
- package/template/.cursor/skills/yss-product-lifecycle/references/matt-yss-adapter.md +3 -3
- package/template/.cursor/skills/yss-product-lifecycle/references/orchestration-contract.yaml +124 -16
- package/template/.cursor/skills/yss-product-lifecycle/references/orchestration.md +16 -2
- package/template/.cursor/skills/yss-product-lifecycle/references/state-model.md +5 -2
- package/template/.cursor/skills/yss-repository/SKILL.md +28 -70
- package/template/.cursor/skills/yss-repository/agents/openai.yaml +2 -2
- package/template/.cursor/skills/yss-repository/references/profiles/layered-mvc-service.md +19 -1
- package/template/.cursor/skills/yss-repository/references/profiles/mvc-data-analysis-v1.md +19 -1
- package/template/.cursor/skills/yss-repository/references/profiles/target-domain-model.md +21 -1
- package/template/.cursor/skills/yss-repository/tests/profile-routing.test.mjs +59 -0
- package/template/.cursor/skills/yss-research/SKILL.md +1 -1
- package/template/.cursor/skills/yss-skill-source-index-refresh/SKILL.md +8 -5
- package/template/.cursor/skills/yss-skill-source-index-refresh/references/source-location.md +2 -1
- package/template/.cursor/skills/yss-skill-source-index-refresh/scripts/refresh-yss-skill-index.mjs +388 -18
- package/template/.cursor/skills/yss-skill-source-index-refresh/scripts/refresh-yss-skill-index.test.mjs +79 -1
- package/template/.cursor/skills/yss-stage-decision/SKILL.md +5 -3
- package/template/.cursor/skills/yss-stage-decision/references/stage-decision-package-contract.md +1 -1
- package/template/.pi/skills/code-review/SKILL.md +4 -0
- package/template/.pi/skills/code-review/agents/openai.yaml +1 -1
- package/template/.pi/skills/code-review/references/yss-review-standards.md +9 -2
- package/template/.pi/skills/competitive-intelligence/SKILL.md +4 -4
- package/template/.pi/skills/domain-modeling/CONTEXT-FORMAT.md +1 -1
- package/template/.pi/skills/grill-with-docs/SKILL.md +1 -1
- package/template/.pi/skills/setup-matt-pocock-skills/issue-tracker-local.md +1 -1
- package/template/.pi/skills/yss-ddd-scaffold-generator/SKILL.md +1 -1
- package/template/.pi/skills/yss-ddd-scaffold-generator/scripts/generate_scaffold.mjs +7 -3
- package/template/.pi/skills/yss-ddd-scaffold-generator/scripts/run_scaffold_verification.mjs +8 -8
- package/template/.pi/skills/yss-ddd-scaffold-generator/scripts/scaffold-generator.test.mjs +9 -0
- package/template/.pi/skills/yss-frontend-scaffold-generator/SKILL.md +10 -7
- package/template/.pi/skills/yss-frontend-scaffold-generator/scripts/generate_and_verify_scaffold.mjs +10 -0
- package/template/.pi/skills/yss-frontend-scaffold-generator/scripts/generate_scaffold.mjs +121 -0
- package/template/.pi/skills/yss-frontend-scaffold-generator/scripts/run_scaffold_verification.mjs +40 -0
- package/template/.pi/skills/yss-frontend-scaffold-generator/scripts/scaffold-generator.test.mjs +55 -0
- package/template/.pi/skills/yss-implementation-contract-compiler/SKILL.md +1 -1
- package/template/.pi/skills/yss-implementation-contract-compiler/references/boundaries.md +4 -0
- package/template/.pi/skills/yss-implementation-contract-compiler/references/compiler-contract.yaml +25 -0
- package/template/.pi/skills/yss-layered-mvc-scaffold-generator/SKILL.md +2 -2
- package/template/.pi/skills/yss-layered-mvc-scaffold-generator/scripts/generate_scaffold.mjs +8 -5
- package/template/.pi/skills/yss-layered-mvc-scaffold-generator/scripts/scaffold-generator.test.mjs +17 -2
- package/template/.pi/skills/yss-mybatis/SKILL.md +34 -58
- package/template/.pi/skills/yss-mybatis/agents/openai.yaml +2 -2
- package/template/.pi/skills/yss-mybatis/references/source-index.md +88 -68
- package/template/.pi/skills/yss-product-lifecycle/SKILL.md +50 -42
- package/template/.pi/skills/yss-product-lifecycle/references/artifact-dependencies.md +5 -3
- package/template/.pi/skills/yss-product-lifecycle/references/matt-yss-adapter.md +3 -3
- package/template/.pi/skills/yss-product-lifecycle/references/orchestration-contract.yaml +124 -16
- package/template/.pi/skills/yss-product-lifecycle/references/orchestration.md +16 -2
- package/template/.pi/skills/yss-product-lifecycle/references/state-model.md +5 -2
- package/template/.pi/skills/yss-repository/SKILL.md +28 -70
- package/template/.pi/skills/yss-repository/agents/openai.yaml +2 -2
- package/template/.pi/skills/yss-repository/references/profiles/layered-mvc-service.md +19 -1
- package/template/.pi/skills/yss-repository/references/profiles/mvc-data-analysis-v1.md +19 -1
- package/template/.pi/skills/yss-repository/references/profiles/target-domain-model.md +21 -1
- package/template/.pi/skills/yss-repository/tests/profile-routing.test.mjs +59 -0
- package/template/.pi/skills/yss-research/SKILL.md +1 -1
- package/template/.pi/skills/yss-skill-source-index-refresh/SKILL.md +8 -5
- package/template/.pi/skills/yss-skill-source-index-refresh/references/source-location.md +2 -1
- package/template/.pi/skills/yss-skill-source-index-refresh/scripts/refresh-yss-skill-index.mjs +388 -18
- package/template/.pi/skills/yss-skill-source-index-refresh/scripts/refresh-yss-skill-index.test.mjs +79 -1
- package/template/.pi/skills/yss-stage-decision/SKILL.md +5 -3
- package/template/.pi/skills/yss-stage-decision/references/stage-decision-package-contract.md +1 -1
- package/template/.qoder/skills/code-review/SKILL.md +4 -0
- package/template/.qoder/skills/code-review/agents/openai.yaml +1 -1
- package/template/.qoder/skills/code-review/references/yss-review-standards.md +9 -2
- package/template/.qoder/skills/competitive-intelligence/SKILL.md +4 -4
- package/template/.qoder/skills/domain-modeling/CONTEXT-FORMAT.md +1 -1
- package/template/.qoder/skills/grill-with-docs/SKILL.md +1 -1
- package/template/.qoder/skills/setup-matt-pocock-skills/issue-tracker-local.md +1 -1
- package/template/.qoder/skills/yss-ddd-scaffold-generator/SKILL.md +1 -1
- package/template/.qoder/skills/yss-ddd-scaffold-generator/scripts/generate_scaffold.mjs +7 -3
- package/template/.qoder/skills/yss-ddd-scaffold-generator/scripts/run_scaffold_verification.mjs +8 -8
- package/template/.qoder/skills/yss-ddd-scaffold-generator/scripts/scaffold-generator.test.mjs +9 -0
- package/template/.qoder/skills/yss-frontend-scaffold-generator/SKILL.md +10 -7
- package/template/.qoder/skills/yss-frontend-scaffold-generator/scripts/generate_and_verify_scaffold.mjs +10 -0
- package/template/.qoder/skills/yss-frontend-scaffold-generator/scripts/generate_scaffold.mjs +121 -0
- package/template/.qoder/skills/yss-frontend-scaffold-generator/scripts/run_scaffold_verification.mjs +40 -0
- package/template/.qoder/skills/yss-frontend-scaffold-generator/scripts/scaffold-generator.test.mjs +55 -0
- package/template/.qoder/skills/yss-implementation-contract-compiler/SKILL.md +1 -1
- package/template/.qoder/skills/yss-implementation-contract-compiler/references/boundaries.md +4 -0
- package/template/.qoder/skills/yss-implementation-contract-compiler/references/compiler-contract.yaml +25 -0
- package/template/.qoder/skills/yss-layered-mvc-scaffold-generator/SKILL.md +2 -2
- package/template/.qoder/skills/yss-layered-mvc-scaffold-generator/scripts/generate_scaffold.mjs +8 -5
- package/template/.qoder/skills/yss-layered-mvc-scaffold-generator/scripts/scaffold-generator.test.mjs +17 -2
- package/template/.qoder/skills/yss-mybatis/SKILL.md +34 -58
- package/template/.qoder/skills/yss-mybatis/agents/openai.yaml +2 -2
- package/template/.qoder/skills/yss-mybatis/references/source-index.md +88 -68
- package/template/.qoder/skills/yss-product-lifecycle/SKILL.md +50 -42
- package/template/.qoder/skills/yss-product-lifecycle/references/artifact-dependencies.md +5 -3
- package/template/.qoder/skills/yss-product-lifecycle/references/matt-yss-adapter.md +3 -3
- package/template/.qoder/skills/yss-product-lifecycle/references/orchestration-contract.yaml +124 -16
- package/template/.qoder/skills/yss-product-lifecycle/references/orchestration.md +16 -2
- package/template/.qoder/skills/yss-product-lifecycle/references/state-model.md +5 -2
- package/template/.qoder/skills/yss-repository/SKILL.md +28 -70
- package/template/.qoder/skills/yss-repository/agents/openai.yaml +2 -2
- package/template/.qoder/skills/yss-repository/references/profiles/layered-mvc-service.md +19 -1
- package/template/.qoder/skills/yss-repository/references/profiles/mvc-data-analysis-v1.md +19 -1
- package/template/.qoder/skills/yss-repository/references/profiles/target-domain-model.md +21 -1
- package/template/.qoder/skills/yss-repository/tests/profile-routing.test.mjs +59 -0
- package/template/.qoder/skills/yss-research/SKILL.md +1 -1
- package/template/.qoder/skills/yss-skill-source-index-refresh/SKILL.md +8 -5
- package/template/.qoder/skills/yss-skill-source-index-refresh/references/source-location.md +2 -1
- package/template/.qoder/skills/yss-skill-source-index-refresh/scripts/refresh-yss-skill-index.mjs +388 -18
- package/template/.qoder/skills/yss-skill-source-index-refresh/scripts/refresh-yss-skill-index.test.mjs +79 -1
- package/template/.qoder/skills/yss-stage-decision/SKILL.md +5 -3
- package/template/.qoder/skills/yss-stage-decision/references/stage-decision-package-contract.md +1 -1
- package/template/.trae/skills/code-review/SKILL.md +4 -0
- package/template/.trae/skills/code-review/agents/openai.yaml +1 -1
- package/template/.trae/skills/code-review/references/yss-review-standards.md +9 -2
- package/template/.trae/skills/competitive-intelligence/SKILL.md +4 -4
- package/template/.trae/skills/domain-modeling/CONTEXT-FORMAT.md +1 -1
- package/template/.trae/skills/grill-with-docs/SKILL.md +1 -1
- package/template/.trae/skills/setup-matt-pocock-skills/issue-tracker-local.md +1 -1
- package/template/.trae/skills/yss-ddd-scaffold-generator/SKILL.md +1 -1
- package/template/.trae/skills/yss-ddd-scaffold-generator/scripts/generate_scaffold.mjs +7 -3
- package/template/.trae/skills/yss-ddd-scaffold-generator/scripts/run_scaffold_verification.mjs +8 -8
- package/template/.trae/skills/yss-ddd-scaffold-generator/scripts/scaffold-generator.test.mjs +9 -0
- package/template/.trae/skills/yss-frontend-scaffold-generator/SKILL.md +10 -7
- package/template/.trae/skills/yss-frontend-scaffold-generator/scripts/generate_and_verify_scaffold.mjs +10 -0
- package/template/.trae/skills/yss-frontend-scaffold-generator/scripts/generate_scaffold.mjs +121 -0
- package/template/.trae/skills/yss-frontend-scaffold-generator/scripts/run_scaffold_verification.mjs +40 -0
- package/template/.trae/skills/yss-frontend-scaffold-generator/scripts/scaffold-generator.test.mjs +55 -0
- package/template/.trae/skills/yss-implementation-contract-compiler/SKILL.md +1 -1
- package/template/.trae/skills/yss-implementation-contract-compiler/references/boundaries.md +4 -0
- package/template/.trae/skills/yss-implementation-contract-compiler/references/compiler-contract.yaml +25 -0
- package/template/.trae/skills/yss-layered-mvc-scaffold-generator/SKILL.md +2 -2
- package/template/.trae/skills/yss-layered-mvc-scaffold-generator/scripts/generate_scaffold.mjs +8 -5
- package/template/.trae/skills/yss-layered-mvc-scaffold-generator/scripts/scaffold-generator.test.mjs +17 -2
- package/template/.trae/skills/yss-mybatis/SKILL.md +34 -58
- package/template/.trae/skills/yss-mybatis/agents/openai.yaml +2 -2
- package/template/.trae/skills/yss-mybatis/references/source-index.md +88 -68
- package/template/.trae/skills/yss-product-lifecycle/SKILL.md +50 -42
- package/template/.trae/skills/yss-product-lifecycle/references/artifact-dependencies.md +5 -3
- package/template/.trae/skills/yss-product-lifecycle/references/matt-yss-adapter.md +3 -3
- package/template/.trae/skills/yss-product-lifecycle/references/orchestration-contract.yaml +124 -16
- package/template/.trae/skills/yss-product-lifecycle/references/orchestration.md +16 -2
- package/template/.trae/skills/yss-product-lifecycle/references/state-model.md +5 -2
- package/template/.trae/skills/yss-repository/SKILL.md +28 -70
- package/template/.trae/skills/yss-repository/agents/openai.yaml +2 -2
- package/template/.trae/skills/yss-repository/references/profiles/layered-mvc-service.md +19 -1
- package/template/.trae/skills/yss-repository/references/profiles/mvc-data-analysis-v1.md +19 -1
- package/template/.trae/skills/yss-repository/references/profiles/target-domain-model.md +21 -1
- package/template/.trae/skills/yss-repository/tests/profile-routing.test.mjs +59 -0
- package/template/.trae/skills/yss-research/SKILL.md +1 -1
- package/template/.trae/skills/yss-skill-source-index-refresh/SKILL.md +8 -5
- package/template/.trae/skills/yss-skill-source-index-refresh/references/source-location.md +2 -1
- package/template/.trae/skills/yss-skill-source-index-refresh/scripts/refresh-yss-skill-index.mjs +388 -18
- package/template/.trae/skills/yss-skill-source-index-refresh/scripts/refresh-yss-skill-index.test.mjs +79 -1
- package/template/.trae/skills/yss-stage-decision/SKILL.md +5 -3
- package/template/.trae/skills/yss-stage-decision/references/stage-decision-package-contract.md +1 -1
- package/template/AGENTS.md +2 -2
- package/template/CONTEXT.md +3 -2
- package/template/README.md +3 -3
- package/template/docs/agents/digital-human-roles.md +1 -1
- package/template/docs/agents/digital-human-roles.yaml +13 -11
- package/template/docs/agents/issue-tracker.md +1 -1
- package/template/docs/agents/strategic-design-skills-integration.md +2 -0
- package/template/docs/agents/yss-skill-registry.yaml +5 -0
- package/template/docs/architecture/README.md +1 -1
- package/template/docs/architecture/templates/business-architecture-template.md +1 -1
- package/template/docs/architecture/templates/functional-architecture-template.md +1 -1
- package/template/docs/design/README.md +1 -1
- package/template/docs/design/templates/interaction-spec-template.md +1 -1
- package/template/docs/design/templates/product-overview-design-template.md +1 -1
- package/template/docs/{discovery → plan}/IDEATION.md +5 -5
- package/template/docs/plan/README.md +9 -0
- package/template/docs/plan/entry-review.md +23 -0
- package/template/docs/plan/templates/plan-template.md +58 -0
- package/template/docs/process/harness-process-tailoring.md +1 -1
- package/template/docs/process/lifecycle-artifact-map.md +10 -6
- package/template/docs/process/lifecycle-registry-baseline.json +10 -1
- package/template/docs/process/lifecycle-registry.yaml +48 -20
- package/template/docs/process/plan-migration.md +13 -0
- package/template/docs/process/schemas/digital-human-task-package.schema.json +2 -0
- package/template/docs/process/schemas/implementation-repository-preparation-result.schema.json +38 -0
- package/template/docs/process/schemas/lifecycle-checkpoint.schema.json +3 -0
- package/template/docs/process/schemas/lifecycle-registry.schema.json +1 -1
- package/template/docs/process/schemas/project-scaffold-contract.schema.json +113 -0
- package/template/docs/process/template-engineering-overview.md +2 -2
- package/template/docs/process/template-verification-profiles.yaml +25 -0
- package/template/docs/process/templates/context-reconciliation-template.yaml +2 -2
- package/template/docs/process/templates/lifecycle-checkpoint-template.yaml +1 -1
- package/template/docs/requirements/README.md +2 -2
- package/template/docs/templates/implementation-repo-registry-template.md +8 -0
- package/template/docs/templates/local-parent-ticket-template.md +1 -1
- package/template/docs/templates/review-report-template.md +7 -3
- package/template/docs/templates/subagent-task-package-template.md +1 -1
- package/template/docs/user-guide//347/224/250/346/210/267/346/211/213/345/206/214.md +1 -1
- package/template/scripts/cache-template-commit +2 -2
- package/template/scripts/fixtures/strategic-handoff/source-roles.json +7 -7
- package/template/scripts/fixtures/user-decision/plan-fixture.mjs +30 -0
- package/template/scripts/lib/backend-delivery.mjs +5 -2
- package/template/scripts/lib/command-runner.mjs +107 -0
- package/template/scripts/lib/context-reconciliation.mjs +34 -0
- package/template/scripts/lib/json-schema.mjs +42 -13
- package/template/scripts/lib/lifecycle-context-query.mjs +141 -0
- package/template/scripts/lib/lifecycle-transition.mjs +118 -6
- package/template/scripts/lib/plan-spec-entry.mjs +87 -0
- package/template/scripts/lib/scenario-checks.mjs +44 -38
- package/template/scripts/lib/skill-registry.mjs +9 -0
- package/template/scripts/lib/skill-supply-chain.mjs +18 -2
- package/template/scripts/lib/strategic-handoff-io.mjs +5 -4
- package/template/scripts/lib/strategic-handoff.mjs +10 -9
- package/template/scripts/lib/task-package.mjs +2 -0
- package/template/scripts/lib/template-commit-cache.mjs +7 -5
- package/template/scripts/query-lifecycle-context +25 -0
- package/template/scripts/run-template-verification +9 -3
- package/template/scripts/sync-strategic-handoff-tools +9 -0
- package/template/scripts/verify-business-language-scenarios +0 -7
- package/template/scripts/verify-context-reconciliation +2 -48
- package/template/scripts/verify-context-reconciliation-scenarios +1 -1
- package/template/scripts/verify-frontend-scaffold-generator-scenarios +2 -0
- package/template/scripts/verify-lifecycle-checkpoint +2 -0
- package/template/scripts/verify-lifecycle-context-query-scenarios +88 -0
- package/template/scripts/verify-lifecycle-transition-scenarios +44 -4
- package/template/scripts/verify-plan-spec-entry +11 -0
- package/template/scripts/verify-plan-spec-entry-scenarios +79 -0
- package/template/scripts/verify-script-performance-scenarios +56 -0
- package/template/scripts/verify-subagent-task-package-scenarios +9 -8
- package/template/scripts/verify-template-cache-scenarios +11 -1
- package/template/scripts/verify-user-decision-scenarios +4 -4
- package/template/skills-lock.json +23 -23
- package/template.manifest.json +2 -1
- package/template.snapshot.json +5 -5
- package/template/.agents/skills/yss-mybatis/assets/BaseRepository.java +0 -112
- package/template/.agents/skills/yss-mybatis/assets/EntityQueryAspect.java +0 -37
- package/template/.agents/skills/yss-mybatis/assets/MybatisBaseConfiguration.java +0 -18
- package/template/.agents/skills/yss-mybatis/assets/PageQueryEntityConfigration.java +0 -18
- package/template/.agents/skills/yss-mybatis/references/README.md +0 -57
- package/template/.agents/skills/yss-repository/references/infrastructure-layer-guide.md +0 -107
- package/template/.claude/skills/yss-mybatis/assets/BaseRepository.java +0 -112
- package/template/.claude/skills/yss-mybatis/assets/EntityQueryAspect.java +0 -37
- package/template/.claude/skills/yss-mybatis/assets/MybatisBaseConfiguration.java +0 -18
- package/template/.claude/skills/yss-mybatis/assets/PageQueryEntityConfigration.java +0 -18
- package/template/.claude/skills/yss-mybatis/references/README.md +0 -57
- package/template/.claude/skills/yss-repository/references/infrastructure-layer-guide.md +0 -107
- package/template/.codex/skills/yss-mybatis/assets/BaseRepository.java +0 -112
- package/template/.codex/skills/yss-mybatis/assets/EntityQueryAspect.java +0 -37
- package/template/.codex/skills/yss-mybatis/assets/MybatisBaseConfiguration.java +0 -18
- package/template/.codex/skills/yss-mybatis/assets/PageQueryEntityConfigration.java +0 -18
- package/template/.codex/skills/yss-mybatis/references/README.md +0 -57
- package/template/.codex/skills/yss-repository/references/infrastructure-layer-guide.md +0 -107
- package/template/.cursor/skills/yss-mybatis/assets/BaseRepository.java +0 -112
- package/template/.cursor/skills/yss-mybatis/assets/EntityQueryAspect.java +0 -37
- package/template/.cursor/skills/yss-mybatis/assets/MybatisBaseConfiguration.java +0 -18
- package/template/.cursor/skills/yss-mybatis/assets/PageQueryEntityConfigration.java +0 -18
- package/template/.cursor/skills/yss-mybatis/references/README.md +0 -57
- package/template/.cursor/skills/yss-repository/references/infrastructure-layer-guide.md +0 -107
- package/template/.pi/skills/yss-mybatis/assets/BaseRepository.java +0 -112
- package/template/.pi/skills/yss-mybatis/assets/EntityQueryAspect.java +0 -37
- package/template/.pi/skills/yss-mybatis/assets/MybatisBaseConfiguration.java +0 -18
- package/template/.pi/skills/yss-mybatis/assets/PageQueryEntityConfigration.java +0 -18
- package/template/.pi/skills/yss-mybatis/references/README.md +0 -57
- package/template/.pi/skills/yss-repository/references/infrastructure-layer-guide.md +0 -107
- package/template/.qoder/skills/yss-mybatis/assets/BaseRepository.java +0 -112
- package/template/.qoder/skills/yss-mybatis/assets/EntityQueryAspect.java +0 -37
- package/template/.qoder/skills/yss-mybatis/assets/MybatisBaseConfiguration.java +0 -18
- package/template/.qoder/skills/yss-mybatis/assets/PageQueryEntityConfigration.java +0 -18
- package/template/.qoder/skills/yss-mybatis/references/README.md +0 -57
- package/template/.qoder/skills/yss-repository/references/infrastructure-layer-guide.md +0 -107
- package/template/.trae/skills/yss-mybatis/assets/BaseRepository.java +0 -112
- package/template/.trae/skills/yss-mybatis/assets/EntityQueryAspect.java +0 -37
- package/template/.trae/skills/yss-mybatis/assets/MybatisBaseConfiguration.java +0 -18
- package/template/.trae/skills/yss-mybatis/assets/PageQueryEntityConfigration.java +0 -18
- package/template/.trae/skills/yss-mybatis/references/README.md +0 -57
- package/template/.trae/skills/yss-repository/references/infrastructure-layer-guide.md +0 -107
- package/template/docs/discovery/README.md +0 -87
- package/template/docs/discovery/reports/.gitkeep +0 -0
- package/template/docs/discovery/reports/agent-governance-options.md +0 -71
- package/template/docs/discovery/reports/competitor-deep-dive/.gitkeep +0 -0
- package/template/docs/discovery/templates/discovery-template.md +0 -94
- /package/template/docs/{discovery → plan}/templates/competitive-analysis-template.md +0 -0
- /package/template/docs/{discovery → plan}/templates/competitive-matrix-template.md +0 -0
- /package/template/docs/{discovery → plan}/templates/market-analysis-template.md +0 -0
- /package/template/docs/{discovery → plan}/templates/user-pain-points-template.md +0 -0
|
@@ -0,0 +1,121 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import { createHash } from "node:crypto";
|
|
3
|
+
import { cpSync, existsSync, lstatSync, mkdirSync, mkdtempSync, readFileSync, readdirSync, rmSync, writeFileSync } from "node:fs";
|
|
4
|
+
import path from "node:path";
|
|
5
|
+
import { tmpdir } from "node:os";
|
|
6
|
+
import { spawnSync } from "node:child_process";
|
|
7
|
+
import { fileURLToPath } from "node:url";
|
|
8
|
+
import { validateJsonSchema } from "../../../../scripts/lib/json-schema.mjs";
|
|
9
|
+
|
|
10
|
+
const fail = (message) => { throw new TypeError(message); };
|
|
11
|
+
const REPOSITORY_ROOT = path.resolve(path.dirname(fileURLToPath(import.meta.url)), "../../../..");
|
|
12
|
+
const sha256 = (value) => `sha256:${createHash("sha256").update(value).digest("hex")}`;
|
|
13
|
+
function argsOf(argv) {
|
|
14
|
+
const args = {};
|
|
15
|
+
for (let i = 0; i < argv.length; i += 2) args[argv[i].replace(/^--/, "")] = argv[i + 1];
|
|
16
|
+
return args;
|
|
17
|
+
}
|
|
18
|
+
function git(cwd, ...args) {
|
|
19
|
+
const result = spawnSync("git", args, { cwd, encoding: "utf8" });
|
|
20
|
+
if (result.status !== 0) fail(result.stderr || `git ${args.join(" ")} failed`);
|
|
21
|
+
return result.stdout.trim();
|
|
22
|
+
}
|
|
23
|
+
function walk(root) {
|
|
24
|
+
return readdirSync(root, { withFileTypes: true }).flatMap((entry) => {
|
|
25
|
+
const item = path.join(root, entry.name);
|
|
26
|
+
return entry.isDirectory() ? walk(item) : entry.isFile() || entry.isSymbolicLink() ? [item] : [];
|
|
27
|
+
});
|
|
28
|
+
}
|
|
29
|
+
function validate(contract, outputDir) {
|
|
30
|
+
validateJsonSchema(contract, path.join(REPOSITORY_ROOT, "docs/process/schemas/project-scaffold-contract.schema.json"), { label: "Project Scaffold Contract v4" });
|
|
31
|
+
if (contract.schema_version !== 4 || contract.kind !== "project-scaffold-contract") fail("frontend scaffold requires Project Scaffold Contract schema v4");
|
|
32
|
+
if (contract.status !== "approved" || contract.current_version !== true || !contract.persisted_ref) fail("scaffold contract must be approved, persisted and current");
|
|
33
|
+
if (contract.delivery_role !== "frontend" || contract.scaffold_kind !== "frontend-yss-vue3" || contract.generator_skill !== "yss-frontend-scaffold-generator") fail("contract is not for the YSS frontend generator");
|
|
34
|
+
if (path.resolve(contract.target_output_dir) !== outputDir) fail("output directory differs from approved contract");
|
|
35
|
+
if (contract.generation_policy?.mode !== "initialize-only" || contract.generation_policy?.existing_target !== "unsupported") fail("unsupported generation policy");
|
|
36
|
+
if (!contract.frontend?.template?.repository || !/^[a-f0-9]{40}$/.test(contract.frontend.template.commit || "")) fail("template repository and exact 40-character commit are required");
|
|
37
|
+
if (contract.frontend.openapi_impact === "frozen" && (!contract.frontend.openapi_json_ref || !contract.frontend.openapi_json_digest)) fail("frozen OpenAPI JSON and digest are required");
|
|
38
|
+
if (contract.frontend.openapi_impact === "not-applicable" && !contract.frontend.openapi_not_applicable_reason) fail("no-API scaffold requires a reason");
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
export function generate({ contractFile, templateCheckout, outputDir }) {
|
|
42
|
+
const contract = JSON.parse(readFileSync(contractFile, "utf8"));
|
|
43
|
+
outputDir = path.resolve(outputDir);
|
|
44
|
+
templateCheckout = path.resolve(templateCheckout);
|
|
45
|
+
validate(contract, outputDir);
|
|
46
|
+
if (!existsSync(path.join(templateCheckout, ".git"))) fail("template checkout must be a Git worktree");
|
|
47
|
+
if (git(templateCheckout, "rev-parse", "HEAD") !== contract.frontend.template.commit) fail("template checkout does not match approved commit");
|
|
48
|
+
if (git(templateCheckout, "config", "--get", "remote.origin.url") !== contract.frontend.template.repository) fail("template repository differs from approved source");
|
|
49
|
+
if (existsSync(outputDir) && readdirSync(outputDir).length > 0) fail("target directory must not exist or must be empty");
|
|
50
|
+
mkdirSync(outputDir, { recursive: true });
|
|
51
|
+
const scratch = mkdtempSync(path.join(tmpdir(), "yss-frontend-source-"));
|
|
52
|
+
try {
|
|
53
|
+
// Read the approved Git tree, never dependency caches or edits in the checkout.
|
|
54
|
+
const archive = spawnSync("git", ["archive", contract.frontend.template.commit], { cwd: templateCheckout, maxBuffer: 256 * 1024 * 1024 });
|
|
55
|
+
if (archive.error || archive.status !== 0) fail(archive.error?.message || String(archive.stderr));
|
|
56
|
+
const unpack = spawnSync("tar", ["-xf", "-", "-C", scratch], { input: archive.stdout });
|
|
57
|
+
if (unpack.error || unpack.status !== 0) fail(unpack.error?.message || String(unpack.stderr));
|
|
58
|
+
cpSync(scratch, outputDir, { recursive: true, verbatimSymlinks: true });
|
|
59
|
+
} finally { rmSync(scratch, { recursive: true, force: true }); }
|
|
60
|
+
|
|
61
|
+
const replacements = {
|
|
62
|
+
"__APP_NAME__": contract.frontend.app_name,
|
|
63
|
+
"__MICROAPP_NAME__": contract.frontend.microapp_name,
|
|
64
|
+
"__BASE_ROUTE__": contract.frontend.base_route,
|
|
65
|
+
...(contract.frontend.replacements || {}),
|
|
66
|
+
};
|
|
67
|
+
const generatedFiles = walk(outputDir).map(file => path.relative(outputDir, file));
|
|
68
|
+
for (const ref of generatedFiles) {
|
|
69
|
+
const file = path.join(outputDir, ref);
|
|
70
|
+
const info = lstatSync(file);
|
|
71
|
+
if (info.isSymbolicLink() || info.size > 2_000_000) continue;
|
|
72
|
+
const bytes = readFileSync(file);
|
|
73
|
+
if (bytes.includes(0) || !Buffer.from(bytes.toString("utf8")).equals(bytes)) continue;
|
|
74
|
+
const text = bytes.toString("utf8");
|
|
75
|
+
const replaced = Object.entries(replacements).reduce((value, [from, to]) => value.split(from).join(to), text);
|
|
76
|
+
if (replaced !== text) writeFileSync(file, replaced);
|
|
77
|
+
}
|
|
78
|
+
if (contract.frontend.openapi_impact === "frozen") {
|
|
79
|
+
const bytes = readFileSync(contract.frontend.openapi_json_ref);
|
|
80
|
+
if (sha256(bytes) !== contract.frontend.openapi_json_digest) fail("OpenAPI JSON digest mismatch");
|
|
81
|
+
mkdirSync(path.join(outputDir, "openapi"), { recursive: true });
|
|
82
|
+
writeFileSync(path.join(outputDir, "openapi", "openapi.json"), bytes);
|
|
83
|
+
if (!generatedFiles.includes("openapi/openapi.json")) generatedFiles.push("openapi/openapi.json");
|
|
84
|
+
}
|
|
85
|
+
if (contract.init_git === true) git(outputDir, "init");
|
|
86
|
+
generatedFiles.sort();
|
|
87
|
+
const manifest = {
|
|
88
|
+
schema_version: 4,
|
|
89
|
+
kind: "frontend-scaffold",
|
|
90
|
+
delivery_role: "frontend",
|
|
91
|
+
generator_skill: "yss-frontend-scaffold-generator",
|
|
92
|
+
contract_id: contract.contract_id,
|
|
93
|
+
contract_version: contract.contract_version,
|
|
94
|
+
contract_digest: sha256(readFileSync(contractFile)),
|
|
95
|
+
contract_file_ref: path.resolve(contractFile),
|
|
96
|
+
persisted_ref: contract.persisted_ref,
|
|
97
|
+
approval_ref: contract.approval.approval_ref,
|
|
98
|
+
template: { ...contract.frontend.template, checkout: templateCheckout },
|
|
99
|
+
repository_scope: contract.repository_scope,
|
|
100
|
+
target_output_dir: outputDir,
|
|
101
|
+
init_git: contract.init_git,
|
|
102
|
+
openapi_impact: contract.frontend.openapi_impact,
|
|
103
|
+
generation_mode: "controlled-generation",
|
|
104
|
+
generation_policy: contract.generation_policy,
|
|
105
|
+
verification_commands: contract.verification_commands,
|
|
106
|
+
generated_files: generatedFiles,
|
|
107
|
+
completion_level: "generated",
|
|
108
|
+
generated_at: new Date().toISOString(),
|
|
109
|
+
};
|
|
110
|
+
mkdirSync(path.join(outputDir, ".yss"), { recursive: true });
|
|
111
|
+
writeFileSync(path.join(outputDir, ".yss", "scaffold-generation.json"), `${JSON.stringify(manifest, null, 2)}\n`);
|
|
112
|
+
return manifest;
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
if (import.meta.url === `file://${process.argv[1]}`) {
|
|
116
|
+
try {
|
|
117
|
+
const args = argsOf(process.argv.slice(2));
|
|
118
|
+
generate({ contractFile: args["contract-file"], templateCheckout: args["template-checkout"], outputDir: args["output-dir"] });
|
|
119
|
+
process.stdout.write("frontend scaffold generated\n");
|
|
120
|
+
} catch (error) { process.stderr.write(`${error.message}\n`); process.exitCode = 1; }
|
|
121
|
+
}
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import { mkdirSync, readFileSync, writeFileSync } from "node:fs";
|
|
3
|
+
import path from "node:path";
|
|
4
|
+
import { runCommandSync } from "../../../../scripts/lib/command-runner.mjs";
|
|
5
|
+
|
|
6
|
+
const ALLOWED = new Map([
|
|
7
|
+
["pnpm install --frozen-lockfile", ["install", "--frozen-lockfile"]],
|
|
8
|
+
["pnpm lint", ["lint"]],
|
|
9
|
+
["pnpm type-check", ["type-check"]],
|
|
10
|
+
["pnpm build", ["build"]],
|
|
11
|
+
]);
|
|
12
|
+
function argsOf(argv) { const args = {}; for (let i = 0; i < argv.length; i += 2) args[argv[i].replace(/^--/, "")] = argv[i + 1]; return args; }
|
|
13
|
+
export function verify(projectRoot, evidenceDir, { timeoutMs = 0 } = {}) {
|
|
14
|
+
projectRoot = path.resolve(projectRoot); evidenceDir = path.resolve(evidenceDir);
|
|
15
|
+
const manifestPath = path.join(projectRoot, ".yss", "scaffold-generation.json");
|
|
16
|
+
const manifest = JSON.parse(readFileSync(manifestPath, "utf8"));
|
|
17
|
+
if (manifest.schema_version !== 4 || manifest.kind !== "frontend-scaffold" || manifest.generation_mode !== "controlled-generation") throw new TypeError("invalid frontend scaffold manifest");
|
|
18
|
+
if (!manifest.generated_files.includes("pnpm-lock.yaml")) throw new TypeError("frontend template must contain pnpm-lock.yaml");
|
|
19
|
+
const commands = manifest.verification_commands;
|
|
20
|
+
for (const required of ALLOWED.keys()) if (!commands.includes(required)) throw new TypeError(`missing required verification command: ${required}`);
|
|
21
|
+
mkdirSync(evidenceDir, { recursive: true });
|
|
22
|
+
const results = commands.map((command, index) => {
|
|
23
|
+
const argv = ALLOWED.get(command);
|
|
24
|
+
if (!argv) throw new TypeError(`unsupported verification command: ${command}`);
|
|
25
|
+
const started = Date.now();
|
|
26
|
+
const stdoutRef = path.join(evidenceDir, `${index + 1}-stdout.log`), stderrRef = path.join(evidenceDir, `${index + 1}-stderr.log`);
|
|
27
|
+
const result = runCommandSync("pnpm", argv, { cwd: projectRoot, timeoutMs, stdoutFile: stdoutRef, stderrFile: stderrRef, progress: true });
|
|
28
|
+
return { command, exit_code: result.status ?? 1, duration_ms: Date.now() - started, ...(result.termination ? { termination: result.termination } : {}), stdout_ref: stdoutRef, stderr_ref: stderrRef, executed_at: new Date().toISOString() };
|
|
29
|
+
});
|
|
30
|
+
const passed = results.every((item) => item.exit_code === 0);
|
|
31
|
+
const report = { schema_version: 1, kind: "frontend-scaffold-verification", status: passed ? "passed" : "failed", project_root: projectRoot, scaffold_manifest_ref: manifestPath, commands: results };
|
|
32
|
+
const reportPath = path.join(evidenceDir, "scaffold-verification.json");
|
|
33
|
+
writeFileSync(reportPath, `${JSON.stringify(report, null, 2)}\n`);
|
|
34
|
+
if (passed) { manifest.completion_level = "empty-scaffold-verified"; manifest.scaffold_verification_ref = reportPath; writeFileSync(manifestPath, `${JSON.stringify(manifest, null, 2)}\n`); }
|
|
35
|
+
return report;
|
|
36
|
+
}
|
|
37
|
+
if (import.meta.url === `file://${process.argv[1]}`) {
|
|
38
|
+
try { const args = argsOf(process.argv.slice(2)); const report = verify(args["project-root"], args["evidence-dir"], { timeoutMs: Number(args["timeout-ms"] || 0) }); process.stdout.write(`${report.status}\n`); if (report.status !== "passed") process.exitCode = 1; }
|
|
39
|
+
catch (error) { process.stderr.write(`${error.message}\n`); process.exitCode = 1; }
|
|
40
|
+
}
|
package/template/.agents/skills/yss-frontend-scaffold-generator/scripts/scaffold-generator.test.mjs
ADDED
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import assert from "node:assert/strict";
|
|
3
|
+
import { chmodSync, existsSync, mkdirSync, mkdtempSync, readFileSync, readlinkSync, rmSync, statSync, symlinkSync, writeFileSync } from "node:fs";
|
|
4
|
+
import os from "node:os";
|
|
5
|
+
import path from "node:path";
|
|
6
|
+
import { spawnSync } from "node:child_process";
|
|
7
|
+
|
|
8
|
+
const root = mkdtempSync(path.join(os.tmpdir(), "yss-frontend-scaffold-"));
|
|
9
|
+
process.on("exit", () => rmSync(root, { recursive: true, force: true }));
|
|
10
|
+
const template = path.join(root, "template"), output = path.join(root, "output"), evidence = path.join(root, "evidence"), bin = path.join(root, "bin");
|
|
11
|
+
mkdirSync(template); mkdirSync(bin);
|
|
12
|
+
writeFileSync(path.join(template, "package.json"), JSON.stringify({ name: "__APP_NAME__", scripts: { lint: "noop", "type-check": "noop", build: "noop" } }));
|
|
13
|
+
writeFileSync(path.join(template, "pnpm-lock.yaml"), "lockfileVersion: '9.0'\n");
|
|
14
|
+
writeFileSync(path.join(template, "micro-config.json"), JSON.stringify({ name: "__MICROAPP_NAME__", route: "__BASE_ROUTE__" }));
|
|
15
|
+
mkdirSync(path.join(template, "assets"));
|
|
16
|
+
writeFileSync(path.join(template, "assets/binary.bin"), Buffer.from([0, 255, 95, 95, 65, 80, 80, 95, 78, 65, 77, 69, 95, 95]));
|
|
17
|
+
writeFileSync(path.join(template, "assets/large.txt"), "__APP_NAME__".repeat(200_000));
|
|
18
|
+
writeFileSync(path.join(template, "assets/run.sh"), "#!/bin/sh\necho __APP_NAME__\n");
|
|
19
|
+
chmodSync(path.join(template, "assets/run.sh"), 0o755);
|
|
20
|
+
symlinkSync("run.sh", path.join(template, "assets/current"));
|
|
21
|
+
for (const args of [["init"], ["config", "user.email", "test@example.com"], ["config", "user.name", "test"], ["remote", "add", "origin", template], ["add", "."], ["commit", "-m", "fixture"]]) {
|
|
22
|
+
const result = spawnSync("git", args, { cwd: template, encoding: "utf8" }); assert.equal(result.status, 0, result.stderr);
|
|
23
|
+
}
|
|
24
|
+
const commit = spawnSync("git", ["rev-parse", "HEAD"], { cwd: template, encoding: "utf8" }).stdout.trim();
|
|
25
|
+
mkdirSync(path.join(template, "node_modules"));
|
|
26
|
+
writeFileSync(path.join(template, "node_modules/cache.txt"), "not approved");
|
|
27
|
+
writeFileSync(path.join(template, "micro-config.json"), "uncommitted edit");
|
|
28
|
+
const contract = {
|
|
29
|
+
schema_version: 4, kind: "project-scaffold-contract", contract_id: "frontend.demo.v1", contract_version: "1", status: "approved", persisted_ref: "docs/.scratch/demo/scaffold-contract.json", current_version: true,
|
|
30
|
+
delivery_role: "frontend", scaffold_kind: "frontend-yss-vue3", generator_skill: "yss-frontend-scaffold-generator", implementation_repository: output, target_output_dir: output, repository_scope: "external-repository", init_git: false,
|
|
31
|
+
frontend: { app_name: "demo-app", microapp_name: "demo", base_route: "/demo", package_manager: "pnpm", template: { repository: template, commit }, openapi_impact: "not-applicable", openapi_not_applicable_reason: "static-only" },
|
|
32
|
+
allowed_write_paths: [output], expected_evidence_files: [".yss/scaffold-generation.json"], verification_commands: ["pnpm install --frozen-lockfile", "pnpm lint", "pnpm type-check", "pnpm build"], approval: { approval_ref: "decision://frontend", approver: "user" }, generation_policy: { mode: "initialize-only", existing_target: "unsupported", old_project_migration: "unsupported", template_upgrade: "unsupported" }
|
|
33
|
+
};
|
|
34
|
+
const contractFile = path.join(root, "contract.json"); writeFileSync(contractFile, JSON.stringify(contract));
|
|
35
|
+
const mockPnpm = path.join(bin, "pnpm"); writeFileSync(mockPnpm, "#!/bin/sh\nexit 0\n"); chmodSync(mockPnpm, 0o755);
|
|
36
|
+
const runner = path.resolve(".agents/skills/yss-frontend-scaffold-generator/scripts/generate_and_verify_scaffold.mjs");
|
|
37
|
+
const result = spawnSync(process.execPath, [runner, "--contract-file", contractFile, "--template-checkout", template, "--output-dir", output, "--evidence-dir", evidence], { encoding: "utf8", env: { ...process.env, PATH: `${bin}:${process.env.PATH}` } });
|
|
38
|
+
assert.equal(result.status, 0, result.stderr);
|
|
39
|
+
assert.equal(existsSync(path.join(output, ".git")), false);
|
|
40
|
+
assert.equal(JSON.parse(readFileSync(path.join(output, "package.json"))).name, "demo-app");
|
|
41
|
+
assert.equal(JSON.parse(readFileSync(path.join(output, ".yss", "scaffold-generation.json"))).completion_level, "empty-scaffold-verified");
|
|
42
|
+
assert.equal(JSON.parse(readFileSync(path.join(evidence, "scaffold-verification.json"))).commands.length, 4);
|
|
43
|
+
assert.equal(existsSync(path.join(output, "node_modules")), false);
|
|
44
|
+
assert.equal(JSON.parse(readFileSync(path.join(output, "micro-config.json"))).name, "demo");
|
|
45
|
+
assert.deepEqual(readFileSync(path.join(output, "assets/binary.bin")), readFileSync(path.join(template, "assets/binary.bin")));
|
|
46
|
+
assert.deepEqual(readFileSync(path.join(output, "assets/large.txt")), readFileSync(path.join(template, "assets/large.txt")));
|
|
47
|
+
assert.equal(readlinkSync(path.join(output, "assets/current")), "run.sh");
|
|
48
|
+
assert.equal(statSync(path.join(output, "assets/run.sh")).mode & 0o777, 0o755);
|
|
49
|
+
assert.match(readFileSync(path.join(output, "assets/current"), "utf8"), /echo demo-app/);
|
|
50
|
+
const generated = JSON.parse(readFileSync(path.join(output, ".yss/scaffold-generation.json"))).generated_files;
|
|
51
|
+
assert.deepEqual(generated, ["assets/binary.bin", "assets/current", "assets/large.txt", "assets/run.sh", "micro-config.json", "package.json", "pnpm-lock.yaml"]);
|
|
52
|
+
const second = spawnSync(process.execPath, [runner, "--contract-file", contractFile, "--template-checkout", template, "--output-dir", output, "--evidence-dir", evidence], { encoding: "utf8", env: { ...process.env, PATH: `${bin}:${process.env.PATH}` } });
|
|
53
|
+
assert.notEqual(second.status, 0);
|
|
54
|
+
assert.match(second.stderr, /must not exist or must be empty/);
|
|
55
|
+
process.stdout.write("前端脚手架受控生成场景验证通过\n");
|
|
@@ -39,7 +39,7 @@ description: Use when a YSS vertical slice is entering implementation, spans mul
|
|
|
39
39
|
- Harness 内实现路径必须落在 `apps/backend/<project>/` 或 `apps/frontend/<project>/` 的具体项目目录;`apps/backend/`、`apps/frontend/` 只能作为容器,`app/backend/`、`app/frontend/` 及其子路径一律阻断。外部实现仓库使用其登记的真实项目根路径。`git-submodule` 使用 `implementation_path_policy: git-submodule-harness-apps`,空 gitlink、detached HEAD 或 `--force` 覆盖挂载点不得脚手架;`inspectWorkingTreeScope.writable` 必须为显式布尔值。
|
|
40
40
|
- 当前用户、缓存、审计、Excel、分布式 ID、请求校验、错误映射、加解密或网关韧性命中时,必须按 `compiler-contract.yaml` 的 `impact_to_capabilities` 补齐入口 capability;不能只在 `boundaries.md` 中提及。仅复用已经验证的平台认证 / 授权能力不算 component impact,不自动增加权限专项 skill。
|
|
41
41
|
- 业务行为使用 `behavior-tdd`;只有机械脚手架/生成物可用 `controlled-generation`,并记录例外和验证。
|
|
42
|
-
-
|
|
42
|
+
- 阶段 5 若命中交付面且无已有工程,按 Project Scaffold Contract schema v4 编译 `controlled-generation` 合同 draft。后端先读取 `scaffold-architecture-decisions.yaml`,只接受已达到 `lifecycle-approved` 且 digest 当前的 DDD / Layered MVC 选择;前端绑定标准模板精确 commit、应用标识、路由、OpenAPI 影响、目标路径和 `init_git` 决定。合同经生命周期批准并持久化后才能运行生成器。历史后端 schema v3 只读兼容并可完成已批准生成;前端只接受 v4。生成与验证完成、仓库登记并通过 `gate.implementation-repositories-ready` 后,才编译 Ticket 与业务 Slice Contract。
|
|
43
43
|
- 脚手架合同在编译阶段只能是 `draft` / `ready-for-lifecycle-review` / `blocked`;只有生命周期编排器可以把已持久化脚手架合同标记为 `approved`。脚手架合同只覆盖业务代码前的工程骨架工作单元;生成、基线校验和合同重编译完成后,它不能替代脚手架后的 Slice Implementation Contract。
|
|
44
44
|
- 脚手架输出消费批准的脚手架合同;脚手架后的所有生成后端代码都必须绑定当前批准且版本当前的 Slice Implementation Contract、主 YSS skill、依赖闭包、允许写路径、预期证据和 YSS Skill Execution Result。打印命令、`./mvnw validate` 单项通过或脚手架成功不能替代合同批准;生成范围从机械内容变成业务行为时触发完整重路由。
|
|
45
45
|
- 专项结果中的越界路径、缺失证据、`drift`、`violation` 或 `new_impacts` 必须阻断或重路由。
|
package/template/.agents/skills/yss-implementation-contract-compiler/references/boundaries.md
CHANGED
|
@@ -46,6 +46,7 @@
|
|
|
46
46
|
| `component.gateway-resilience` | `yss-resilience4j` | `guidance`, `integration`, `slice-implementation`, `troubleshooting`, `component-maintenance`, `review-input` |
|
|
47
47
|
| `scaffold.ddd` | `yss-ddd-scaffold-generator` | `integration`, `component-maintenance` |
|
|
48
48
|
| `scaffold.layered-mvc` | `yss-layered-mvc-scaffold-generator` | `integration`, `component-maintenance` |
|
|
49
|
+
| `scaffold.frontend-vue3` | `yss-frontend-scaffold-generator` | `integration`, `component-maintenance` |
|
|
49
50
|
| `project-init.mvc-data-analysis` | `yss-mvc-data-analysis-project-initializer` | `component-maintenance` |
|
|
50
51
|
| `migration.springboot3` | `yss-up-springboot3` | `guidance`, `integration`, `troubleshooting`, `component-maintenance`, `review-input` |
|
|
51
52
|
|
|
@@ -73,6 +74,7 @@
|
|
|
73
74
|
| `backend.distributed-id` | `component.distributed-id` |
|
|
74
75
|
| `backend.ddd-scaffold` | `scaffold.ddd`, `quality.java-code-style` |
|
|
75
76
|
| `backend.mvc-scaffold` | `scaffold.layered-mvc`, `quality.java-code-style` |
|
|
77
|
+
| `frontend.vue3-scaffold` | `scaffold.frontend-vue3` |
|
|
76
78
|
| `backend.springboot3-migration` | `migration.springboot3`, `quality.java-code-style` |
|
|
77
79
|
|
|
78
80
|
## Impact Entry Mapping
|
|
@@ -103,6 +105,8 @@
|
|
|
103
105
|
|
|
104
106
|
| Skill | Dependency | Type | Condition |
|
|
105
107
|
| --- | --- | --- | --- |
|
|
108
|
+
| `code-review` | `yss-repository` | `context-conditional` | `backend-persistence-impact` |
|
|
109
|
+
| `code-review` | `yss-mybatis` | `context-conditional` | `backend-persistence-impact` |
|
|
106
110
|
| `yss-prototype-stage` | `prototype-review` | `review-only` | — |
|
|
107
111
|
| `yss-prototype-stage` | `yss-design-system` | `coordination-only` | — |
|
|
108
112
|
| `yss-prototype-stage` | `yss-antdv-next-design` | `context-conditional` | `h2-vue-antdv-next-default` |
|
|
@@ -138,8 +138,33 @@ context_plan:
|
|
|
138
138
|
context_stop_rule: minimal-sufficient-evidence
|
|
139
139
|
missing_context_action: [blocked, reroute]
|
|
140
140
|
|
|
141
|
+
project_scaffold_contract_schema:
|
|
142
|
+
schema_version: 4
|
|
143
|
+
schema_ref: docs/process/schemas/project-scaffold-contract.schema.json
|
|
144
|
+
identity: project-engineering-baseline
|
|
145
|
+
discriminant: delivery_role
|
|
146
|
+
delivery_roles:
|
|
147
|
+
backend:
|
|
148
|
+
scaffold_kinds: [backend-ddd, backend-layered-mvc]
|
|
149
|
+
generators: [yss-ddd-scaffold-generator, yss-layered-mvc-scaffold-generator]
|
|
150
|
+
requires: [scaffold_request_id, architecture_family, decision_ref, decision_id, decision_digest, project_name, base_package, maven_coordinates, profiles, module_profile]
|
|
151
|
+
frontend:
|
|
152
|
+
scaffold_kinds: [frontend-yss-vue3]
|
|
153
|
+
generators: [yss-frontend-scaffold-generator]
|
|
154
|
+
requires: [frontend, repository_scope, init_git]
|
|
155
|
+
openapi_modes: [frozen, not-applicable]
|
|
156
|
+
common_required: [contract_id, contract_version, status, persisted_ref, current_version, delivery_role, scaffold_kind, generator_skill, implementation_repository, target_output_dir, repository_scope, init_git, allowed_write_paths, expected_evidence_files, verification_commands, approval, generation_policy]
|
|
157
|
+
approved_by: yss-product-lifecycle
|
|
158
|
+
generation_mode: controlled-generation
|
|
159
|
+
target_policy: nonexistent-or-empty
|
|
160
|
+
force_overwrite: forbidden
|
|
161
|
+
compatibility:
|
|
162
|
+
backend_schema_v3: read-only-and-complete-approved-generation
|
|
163
|
+
frontend_before_v4: unsupported
|
|
164
|
+
|
|
141
165
|
scaffold_contract_schema:
|
|
142
166
|
schema_version: 3
|
|
167
|
+
compatibility_status: legacy-backend-read-only
|
|
143
168
|
identity: service-engineering-baseline
|
|
144
169
|
compiled_by: yss-implementation-contract-compiler
|
|
145
170
|
approved_by: yss-product-lifecycle
|
|
@@ -11,7 +11,7 @@ description: 用于在生命周期已批准的脚手架合同下生成通用 YSS
|
|
|
11
11
|
|
|
12
12
|
- backend `scaffold_status=required`,目标目录已确认且不存在。
|
|
13
13
|
- `scaffold-architecture-decisions.yaml` 中对应项目已达到 `lifecycle-approved`,确认架构为 `layered-mvc`。
|
|
14
|
-
- `yss-implementation-contract-compiler`
|
|
14
|
+
- `yss-implementation-contract-compiler` 已编译统一 Project Scaffold Contract schema v4;已批准且当前的后端 schema v3 可完成兼容生成。合同须由生命周期批准并持久化。
|
|
15
15
|
- 合同中的 `decision_id`、文件 digest、Profile、能力闭包、写路径和验证命令仍为当前版本。
|
|
16
16
|
|
|
17
17
|
任一条件缺失时返回 `blocked`。本生成器无交互、无默认回退;用户选择由 `yss-product-lifecycle` 在 `work-unit.technical-analysis` 的工程基线内完成。
|
|
@@ -55,7 +55,7 @@ node scripts/generate_and_verify_scaffold.mjs \
|
|
|
55
55
|
|
|
56
56
|
## 硬约束
|
|
57
57
|
|
|
58
|
-
-
|
|
58
|
+
- 接受统一 schema v4,兼容已批准后端 schema v3;验证器接受对应 Manifest v3/v4。历史 v2 只读兼容,不用于新生成。
|
|
59
59
|
- `architecture_family` 必须为 `layered-mvc`,`generator_skill` 必须为本 skill。
|
|
60
60
|
- 目标存在、`--force`、旧项目迁移、模板升级均为 `unsupported`。
|
|
61
61
|
- Harness 内只允许以 `apps/backend/` 为输出父容器;外部实现仓库使用已登记真实路径。
|
package/template/.agents/skills/yss-layered-mvc-scaffold-generator/scripts/generate_scaffold.mjs
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
/**
|
|
2
|
+
/** 依据生命周期批准的兼容 schema v3 或统一 schema v4 合同生成纯机械 YSS 分层 MVC 后端骨架。 */
|
|
3
3
|
import { assertScaffoldUserDecision } from "../../../../scripts/lib/user-decision.mjs";
|
|
4
4
|
import { createHash } from "node:crypto";
|
|
5
5
|
import { chmod, cp, lstat, mkdir, mkdtemp, readFile, readdir, rename, rm, writeFile } from "node:fs/promises";
|
|
@@ -10,6 +10,7 @@ import { parseDocument } from "../../../../scripts/vendor/yaml.mjs";
|
|
|
10
10
|
import { findGitRoot, gitSubmoduleScaffoldViolation, overlayMountViolation } from "../../../../scripts/lib/repository-scope-policy.mjs";
|
|
11
11
|
import { assertLocalDatabaseProfile, localDatabaseConfiguration, scaffoldArchitectureIdentity } from "../../../../scripts/lib/scaffold-local-database.mjs";
|
|
12
12
|
import { validateArchitectureIdentity } from "../../../../scripts/lib/backend-architecture.mjs";
|
|
13
|
+
import { validateJsonSchema } from "../../../../scripts/lib/json-schema.mjs";
|
|
13
14
|
|
|
14
15
|
const SCRIPT_DIR = path.dirname(fileURLToPath(import.meta.url));
|
|
15
16
|
const SKILL_ROOT = path.resolve(SCRIPT_DIR, "..");
|
|
@@ -151,11 +152,13 @@ async function validateContract(options, skillId, architectureProfile) {
|
|
|
151
152
|
const contractText = await readFile(contractFile, "utf8").catch(() => fail(`脚手架合同不可读取: ${contractFile}`));
|
|
152
153
|
let contract;
|
|
153
154
|
try { contract = JSON.parse(contractText); } catch { fail("脚手架合同必须是 JSON 对象"); }
|
|
154
|
-
if (contract.schema_version
|
|
155
|
+
if (![3, 4].includes(contract.schema_version)) fail(`unsupported: 只接受兼容 scaffold contract v3 或统一 v4,收到 v${contract.schema_version}`);
|
|
156
|
+
if (contract.schema_version === 4 && (contract.kind !== "project-scaffold-contract" || contract.delivery_role !== "backend" || contract.scaffold_kind !== "backend-layered-mvc")) fail("schema v4 合同必须绑定 backend/backend-layered-mvc");
|
|
157
|
+
if (contract.schema_version === 4) validateJsonSchema(contract, path.join(REPOSITORY_ROOT, "docs/process/schemas/project-scaffold-contract.schema.json"), { label: "Project Scaffold Contract v4" });
|
|
155
158
|
const required = ["contract_id", "contract_version", "scaffold_request_id", "status", "compiler_draft_ref", "lifecycle_approval_ref", "persisted_ref", "current_version", "implementation_repository", "backend_repository", "scaffold_status", "project_name", "target_output_dir", "base_package", "architecture_family", "generator_skill", "decision_ref", "decision_id", "decision_digest", "maven_coordinates", "profiles", "module_profile", "allowed_write_paths", "expected_evidence_files", "verification_commands", "approval", "work_unit", "generation_policy"];
|
|
156
159
|
const missing = required.filter((field) => !isPresent(contract[field]));
|
|
157
160
|
if (missing.length) fail(`脚手架合同缺少字段: ${missing.join(", ")}`);
|
|
158
|
-
if (contract.status !== "approved" || contract.current_version !== contract.contract_version) fail("脚手架合同必须已批准且为当前版本");
|
|
161
|
+
if (contract.status !== "approved" || (contract.current_version !== contract.contract_version && !(contract.schema_version === 4 && contract.current_version === true))) fail("脚手架合同必须已批准且为当前版本");
|
|
159
162
|
if (contract.contract_id !== options.contractId || contract.contract_version !== options.contractVersion || contract.compiler_draft_ref !== options.compilerDraftRef || contract.lifecycle_approval_ref !== options.approvalRef || contract.persisted_ref !== options.persistedRef) fail("命令行合同元数据与批准合同不一致");
|
|
160
163
|
if (contract.scaffold_status !== "required" || contract.architecture_family !== "layered-mvc" || contract.generator_skill !== skillId) fail("合同必须绑定 layered-mvc 与本生成器");
|
|
161
164
|
if (contract.project_name !== options.projectName || contract.base_package !== options.basePackage || path.resolve(contract.target_output_dir) !== path.resolve(options.outputDir)) fail("项目身份或输出目录与合同不一致");
|
|
@@ -244,14 +247,14 @@ export async function generate(options, { skillId = SKILL_ID, architectureProfil
|
|
|
244
247
|
await cp(wrapper, projectRoot, { recursive: true });
|
|
245
248
|
await chmod(path.join(projectRoot, "mvnw"), 0o755);
|
|
246
249
|
if (finalize) await finalize({ projectRoot, contract, architectureIdentity: scaffoldArchitectureIdentity(contract, sha256(contractText)) });
|
|
247
|
-
await put(projectRoot, "README.md", `# ${options.projectName}\n\n该工程由 ${skillId} 根据批准的 schema
|
|
250
|
+
await put(projectRoot, "README.md", `# ${options.projectName}\n\n该工程由 ${skillId} 根据批准的 schema v${contract.schema_version} 合同生成。模块:${modules.join("、")}。不包含业务 API、SQL 或生产数据库绑定。\n\n本地运行需同时显式启用 Maven -Pscaffold-local 和 Spring scaffold-local Profile;测试独立使用 H2。生产数据库须由后续已批准存储工作单元接入。`);
|
|
248
251
|
const generatedFiles = [];
|
|
249
252
|
for (const entry of await fileEntries(projectRoot, new Set([".yss/scaffold-generation.json"]))) generatedFiles.push({ path: entry.relative, owner: "generator", sha256: rawSha256(await readFile(entry.target)) });
|
|
250
253
|
const architectureRuleset = `${serverRoot}/src/test/java/${packagePath}/architecture/LayeredMvcArchitectureTest.java`;
|
|
251
254
|
const downstream = {};
|
|
252
255
|
for (const skill of ["yss-application", "yss-repository", "yss-mybatis", "yss-web-controller", "yss-dto", "yss-exception", "yss-validation", "mapstruct", "lombok", "alibaba-java-code-style"]) downstream[skill] = (await treeDigest(path.join(REPOSITORY_ROOT, ".agents/skills", skill))).replace(/^sha256:/, "");
|
|
253
256
|
const manifest = {
|
|
254
|
-
schema_version:
|
|
257
|
+
schema_version: contract.schema_version,
|
|
255
258
|
kind: architectureProfile === "mvc-data-analysis-v1" ? "service-project-initialization" : "backend-scaffold",
|
|
256
259
|
architecture_profile: contract.architecture_profile,
|
|
257
260
|
architecture_identity: scaffoldArchitectureIdentity(contract, sha256(contractText)),
|
|
@@ -18,7 +18,7 @@ const capabilityModules = {
|
|
|
18
18
|
combined: { capabilities: ["external-integration", "feign-client"], modules: ["server", "service", "repository", "adapter", "client", "feign-client"] }
|
|
19
19
|
};
|
|
20
20
|
|
|
21
|
-
async function fixture(t, { profile = capabilityModules.basic, architectureProfile = "layered-mvc-service", skillId = "yss-layered-mvc-scaffold-generator" } = {}) {
|
|
21
|
+
async function fixture(t, { profile = capabilityModules.basic, architectureProfile = "layered-mvc-service", skillId = "yss-layered-mvc-scaffold-generator", schemaVersion = 3 } = {}) {
|
|
22
22
|
const root = await mkdtemp(path.join(os.tmpdir(), "yss-layered-mvc-"));
|
|
23
23
|
t.after(() => rm(root, { recursive: true, force: true }));
|
|
24
24
|
const output = path.join(root, "backend");
|
|
@@ -30,7 +30,12 @@ async function fixture(t, { profile = capabilityModules.basic, architectureProfi
|
|
|
30
30
|
const decisionFile = path.join(root, "scaffold-architecture-decisions.yaml");
|
|
31
31
|
await writeFile(decisionFile, decisionText);
|
|
32
32
|
const contract = {
|
|
33
|
-
schema_version:
|
|
33
|
+
schema_version: schemaVersion,
|
|
34
|
+
kind: "project-scaffold-contract",
|
|
35
|
+
delivery_role: "backend",
|
|
36
|
+
scaffold_kind: "backend-layered-mvc",
|
|
37
|
+
repository_scope: "external-repository",
|
|
38
|
+
init_git: false,
|
|
34
39
|
contract_id: "scaffold.demo-service.v1",
|
|
35
40
|
contract_version: 1,
|
|
36
41
|
scaffold_request_id: "request.demo-service",
|
|
@@ -97,6 +102,16 @@ test("旧数据库和 Mock 参数在写入前被拒绝", async (t) => {
|
|
|
97
102
|
}
|
|
98
103
|
});
|
|
99
104
|
|
|
105
|
+
test("统一 Project Scaffold Contract v4 可生成 Layered MVC 后端并保留 v4 Manifest", async (t) => {
|
|
106
|
+
const data = await fixture(t, { schemaVersion: 4 });
|
|
107
|
+
data.contract.current_version = true;
|
|
108
|
+
await writeFile(data.contractFile, JSON.stringify(data.contract));
|
|
109
|
+
const result = spawnSync(process.execPath, [script, ...data.args], { encoding: "utf8" });
|
|
110
|
+
assert.equal(result.status, 0, result.stderr);
|
|
111
|
+
const manifest = JSON.parse(await readFile(path.join(data.project, ".yss/scaffold-generation.json"), "utf8"));
|
|
112
|
+
assert.equal(manifest.schema_version, 4);
|
|
113
|
+
});
|
|
114
|
+
|
|
100
115
|
test("可选离线 Maven 可行性检查(不替代受控仓库验收)", { skip: process.env.YSS_BACKEND_OFFLINE_PROBE !== "1" }, async (t) => {
|
|
101
116
|
const data = await fixture(t);
|
|
102
117
|
const generated = spawnSync(process.execPath, [script, ...data.args], { encoding: "utf8" });
|
|
@@ -1,77 +1,53 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: yss-mybatis
|
|
3
|
-
description: 用于 YSS MyBatis
|
|
3
|
+
description: 用于 YSS MyBatis / MyBatis-Plus 组件能力核验、接入决策和排障;涉及 Mapper/Repository 基类、分页、批量 SQL、扫描配置或数据源能力时使用,不负责生成持久层结构。
|
|
4
4
|
---
|
|
5
5
|
|
|
6
6
|
# yss-mybatis
|
|
7
7
|
|
|
8
|
-
|
|
8
|
+
本 Skill 只维护 `yss-component-persistence` 的组件能力、选择条件和排障顺序。PO、Repository、Convertor、Gateway/Query Adapter 的结构与生成边界由 `yss-repository` 负责。
|
|
9
9
|
|
|
10
|
-
##
|
|
10
|
+
## 入口与前置
|
|
11
11
|
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
-
|
|
12
|
+
1. 读取批准且当前的 `architecture_identity`、`persistence_profile`、实现仓登记和 Slice Implementation Contract。没有合同的故障诊断可以继续,但不得据此生成或改变架构。
|
|
13
|
+
2. 精确类名、方法签名、配置 key、默认值或启用条件必须先读 [source-index.md](references/source-index.md),并按 `yss-skill-source-index-refresh/references/source-location.md` 核验组件 tree 与组件子树 clean 状态。
|
|
14
|
+
3. 组件 tree 不匹配或 persistence 子树为 dirty 时,路径提示只能用于定位;精确实现或审查结论返回 `stale` / `missing_evidence`,刷新索引后再继续。
|
|
15
|
+
4. 新 DDD / MVC scaffold 只支持批准的 `mybatis-plus` Profile。普通 MyBatis 仅用于既有工程维护、兼容与排障;新增支持必须有独立 Profile 和 fixture,不自动猜测或混用。
|
|
16
16
|
|
|
17
|
-
##
|
|
17
|
+
## 稳定决策规则
|
|
18
18
|
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
19
|
+
- 基类、Mapper 注解、XML 位置和扫描范围以批准 Profile、当前工程基线及当前组件源码共同决定;不得在既有体系外再造 Mapper 抽象。
|
|
20
|
+
- 一条查询 seam 只能有一个分页责任模型。核对实际插件/切面开关、拦截范围、参数绑定条件和返回 total 的责任,不以“依赖已引入”代替行为验证。
|
|
21
|
+
- 批量写入必须证明是组件当前支持的 SQL 级批量能力,并验证分批大小、字段填充、主键和数据库方言;循环单条写入不能冒充批量 SQL。
|
|
22
|
+
- 多数据源实例创建不等于动态路由、线程上下文切换或事务传播。先做 capability check;组件未提供的路由能力必须由批准的上层适配承担。
|
|
23
|
+
- Mapper/XML、逻辑删除、审计字段、主键策略、动态排序/分组白名单和参数绑定必须与数据合同一致;任何 SQL/DDL/索引新影响返回 `new_impacts`。
|
|
24
|
+
- 事务边界归批准的 Application 用例或 MVC service/core;Repository 不临时声明新的业务事务。
|
|
23
25
|
|
|
24
|
-
##
|
|
26
|
+
## 任务分流
|
|
25
27
|
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
## 实施建议
|
|
33
|
-
|
|
34
|
-
- 通用模式优先继承 `BaseRepository`
|
|
35
|
-
- MP 模式优先继承项目既有的 `BasePlusRepository`
|
|
36
|
-
- 批量导入优先使用真正的 SQL 级批量方法,不要默认循环单条插入
|
|
37
|
-
- 多数据源问题优先先看配置和扫描范围,再怀疑业务代码
|
|
38
|
-
- DDD 分页经 Application Query Port 进入 Infrastructure;MVC 经 service/core 进入 Repository。不把 `PageQuery` 带入 Domain Gateway,也不得在 Repository 内临时发明分页参数。
|
|
39
|
-
- 生成或重构持久层时,先看当前模块已有 Repository/Mapper 命名、包路径、XML 位置。
|
|
40
|
-
|
|
41
|
-
## 检查清单
|
|
42
|
-
|
|
43
|
-
- Mapper 扫描路径是否正确。
|
|
44
|
-
- XML 路径和接口是否对齐。
|
|
45
|
-
- `PageQuery` 是否真的出现在被拦截的方法参数里。
|
|
46
|
-
- 批量方法是否用了项目推荐实现。
|
|
47
|
-
- 多数据源名称和主从配置是否一致。
|
|
48
|
-
- MyBatis 与 MyBatis-Plus 的基类、分页插件和扫描配置是否混用。
|
|
49
|
-
- 数据源切换是否在事务边界之前完成。
|
|
28
|
+
| 请求 | 本 Skill 动作 | 后续路由 |
|
|
29
|
+
|---|---|---|
|
|
30
|
+
| 组件接入、基类选择、配置核验 | 读取当前 Profile 和源码能力矩阵,给出来源可追踪的选择 | 需要结构实现时转 `yss-repository` |
|
|
31
|
+
| 分页、批量、扫描、XML、数据源故障 | 按下列顺序定位并保留实际证据 | 发现合同或数据影响时返回编译器 |
|
|
32
|
+
| 生成 PO / Repository / Convertor / GatewayImpl | 不生成 | `yss-repository` |
|
|
33
|
+
| 普通 MyBatis 新工程生成 | `unsupported` | 新 Profile / fixture 获批后再进入 |
|
|
50
34
|
|
|
51
35
|
## 排障顺序
|
|
52
36
|
|
|
53
|
-
1.
|
|
54
|
-
2.
|
|
55
|
-
3.
|
|
56
|
-
4.
|
|
57
|
-
5.
|
|
58
|
-
6.
|
|
59
|
-
|
|
60
|
-
## 修改约束
|
|
61
|
-
|
|
62
|
-
- 不要同时引入两套分页机制而不说明谁生效。
|
|
63
|
-
- 不要在已有 Repository 基类体系之外再造一套 Mapper 抽象。
|
|
64
|
-
- 若用户只是要生成持久层骨架,优先衔接 `yss-repository`。
|
|
37
|
+
1. 依赖与 Profile:starter、组件版本、MyBatis/MyBatis-Plus 模式是否与合同一致。
|
|
38
|
+
2. 装配与开关:自动配置、条件属性、Mapper 扫描和 XML location 是否真实生效。
|
|
39
|
+
3. 调用 seam:代理是否命中、分页参数位置/类型、分页插件链和 total 回填责任。
|
|
40
|
+
4. 映射:接口签名、XML namespace、resultMap、字段、逻辑删除和主键策略。
|
|
41
|
+
5. 批量:是否调用当前公开批量入口、分批与方言是否匹配、是否退化为循环单条。
|
|
42
|
+
6. 数据源:先确认组件只提供了什么,再检查上层路由与事务进入顺序;不得假设存在当前线程数据源上下文。
|
|
43
|
+
7. 最后检查 SQL、绑定参数、数据库方言与执行计划。
|
|
65
44
|
|
|
66
|
-
##
|
|
45
|
+
## Review 输入
|
|
67
46
|
|
|
68
|
-
-
|
|
69
|
-
- 基础 Repository:`assets/BaseRepository.java`
|
|
70
|
-
- 分页切面:`assets/EntityQueryAspect.java`
|
|
71
|
-
- MyBatis 基础配置:`assets/MybatisBaseConfiguration.java`
|
|
47
|
+
仅审查本体项目和合同/实现仓登记的后端研发项目。命中 Mapper、Repository、SQL、分页、批量、扫描配置或数据源能力时,`code-review` Standards 轴必须读取本 Skill 和当前 source index;无持久化影响时显式记录带原因的 `not-applicable`。
|
|
72
48
|
|
|
73
|
-
##
|
|
49
|
+
## 结果与验证
|
|
74
50
|
|
|
75
|
-
-
|
|
76
|
-
-
|
|
77
|
-
-
|
|
51
|
+
- 行为变更使用 `behavior-tdd`;纯 Mapper/XML 骨架仅在批准合同明确为 `controlled-generation` 时允许。
|
|
52
|
+
- 使用项目根 `./mvnw ...` 记录实际命令、退出码和时间;H2 只证明本地/测试行为,不证明生产方言。
|
|
53
|
+
- 按 [YSS Skill Execution Result v2](../yss-implementation-contract-compiler/references/yss-skill-execution-result.md) 返回证据、`seam_deferred`、`deviations`、`new_impacts`、`drift` 和 `violation`。
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
version: 1
|
|
2
2
|
interface:
|
|
3
3
|
display_name: "YSS MyBatis"
|
|
4
|
-
short_description: "MyBatis
|
|
5
|
-
default_prompt: "Use $yss-mybatis to
|
|
4
|
+
short_description: "MyBatis 组件能力、配置、分页、批量与数据源排障"
|
|
5
|
+
default_prompt: "Use $yss-mybatis to verify or troubleshoot current YSS MyBatis capabilities and configuration; route persistence structure work to $yss-repository."
|