create-yss-spec 3.2.0 → 3.3.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 +2 -2
- package/package.json +1 -1
- 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/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 +1 -1
- 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 +107 -0
- package/template/.agents/skills/yss-frontend-scaffold-generator/scripts/run_scaffold_verification.mjs +41 -0
- package/template/.agents/skills/yss-frontend-scaffold-generator/scripts/scaffold-generator.test.mjs +37 -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 +48 -43
- package/template/.agents/skills/yss-product-lifecycle/references/artifact-dependencies.md +4 -2
- package/template/.agents/skills/yss-product-lifecycle/references/orchestration-contract.yaml +67 -10
- package/template/.agents/skills/yss-product-lifecycle/references/orchestration.md +5 -1
- 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-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/.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/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 +1 -1
- 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 +107 -0
- package/template/.claude/skills/yss-frontend-scaffold-generator/scripts/run_scaffold_verification.mjs +41 -0
- package/template/.claude/skills/yss-frontend-scaffold-generator/scripts/scaffold-generator.test.mjs +37 -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 +48 -43
- package/template/.claude/skills/yss-product-lifecycle/references/artifact-dependencies.md +4 -2
- package/template/.claude/skills/yss-product-lifecycle/references/orchestration-contract.yaml +67 -10
- package/template/.claude/skills/yss-product-lifecycle/references/orchestration.md +5 -1
- 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-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/.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/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 +1 -1
- 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 +107 -0
- package/template/.codex/skills/yss-frontend-scaffold-generator/scripts/run_scaffold_verification.mjs +41 -0
- package/template/.codex/skills/yss-frontend-scaffold-generator/scripts/scaffold-generator.test.mjs +37 -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 +48 -43
- package/template/.codex/skills/yss-product-lifecycle/references/artifact-dependencies.md +4 -2
- package/template/.codex/skills/yss-product-lifecycle/references/orchestration-contract.yaml +67 -10
- package/template/.codex/skills/yss-product-lifecycle/references/orchestration.md +5 -1
- 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-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/.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/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 +1 -1
- 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 +107 -0
- package/template/.cursor/skills/yss-frontend-scaffold-generator/scripts/run_scaffold_verification.mjs +41 -0
- package/template/.cursor/skills/yss-frontend-scaffold-generator/scripts/scaffold-generator.test.mjs +37 -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 +48 -43
- package/template/.cursor/skills/yss-product-lifecycle/references/artifact-dependencies.md +4 -2
- package/template/.cursor/skills/yss-product-lifecycle/references/orchestration-contract.yaml +67 -10
- package/template/.cursor/skills/yss-product-lifecycle/references/orchestration.md +5 -1
- 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-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/.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/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 +1 -1
- 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 +107 -0
- package/template/.pi/skills/yss-frontend-scaffold-generator/scripts/run_scaffold_verification.mjs +41 -0
- package/template/.pi/skills/yss-frontend-scaffold-generator/scripts/scaffold-generator.test.mjs +37 -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 +48 -43
- package/template/.pi/skills/yss-product-lifecycle/references/artifact-dependencies.md +4 -2
- package/template/.pi/skills/yss-product-lifecycle/references/orchestration-contract.yaml +67 -10
- package/template/.pi/skills/yss-product-lifecycle/references/orchestration.md +5 -1
- 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-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/.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/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 +1 -1
- 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 +107 -0
- package/template/.qoder/skills/yss-frontend-scaffold-generator/scripts/run_scaffold_verification.mjs +41 -0
- package/template/.qoder/skills/yss-frontend-scaffold-generator/scripts/scaffold-generator.test.mjs +37 -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 +48 -43
- package/template/.qoder/skills/yss-product-lifecycle/references/artifact-dependencies.md +4 -2
- package/template/.qoder/skills/yss-product-lifecycle/references/orchestration-contract.yaml +67 -10
- package/template/.qoder/skills/yss-product-lifecycle/references/orchestration.md +5 -1
- 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-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/.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/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 +1 -1
- 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 +107 -0
- package/template/.trae/skills/yss-frontend-scaffold-generator/scripts/run_scaffold_verification.mjs +41 -0
- package/template/.trae/skills/yss-frontend-scaffold-generator/scripts/scaffold-generator.test.mjs +37 -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 +48 -43
- package/template/.trae/skills/yss-product-lifecycle/references/artifact-dependencies.md +4 -2
- package/template/.trae/skills/yss-product-lifecycle/references/orchestration-contract.yaml +67 -10
- package/template/.trae/skills/yss-product-lifecycle/references/orchestration.md +5 -1
- 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-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/docs/agents/digital-human-roles.yaml +2 -0
- package/template/docs/agents/yss-skill-registry.yaml +5 -0
- package/template/docs/process/lifecycle-artifact-map.md +4 -0
- package/template/docs/process/lifecycle-registry-baseline.json +6 -1
- package/template/docs/process/lifecycle-registry.yaml +23 -0
- package/template/docs/process/schemas/implementation-repository-preparation-result.schema.json +38 -0
- package/template/docs/process/schemas/project-scaffold-contract.schema.json +113 -0
- package/template/docs/process/template-verification-profiles.yaml +23 -0
- package/template/docs/templates/implementation-repo-registry-template.md +8 -0
- package/template/docs/templates/review-report-template.md +7 -3
- package/template/scripts/lib/lifecycle-context-query.mjs +137 -0
- package/template/scripts/lib/lifecycle-transition.mjs +109 -3
- package/template/scripts/lib/scenario-checks.mjs +29 -26
- package/template/scripts/lib/skill-registry.mjs +9 -0
- package/template/scripts/query-lifecycle-context +25 -0
- package/template/scripts/verify-business-language-scenarios +0 -7
- package/template/scripts/verify-frontend-scaffold-generator-scenarios +2 -0
- package/template/scripts/verify-lifecycle-context-query-scenarios +68 -0
- package/template/scripts/verify-lifecycle-transition-scenarios +44 -4
- package/template/skills-lock.json +9 -9
- package/template.snapshot.json +4 -4
- 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/.pi/skills/yss-skill-source-index-refresh/scripts/refresh-yss-skill-index.mjs
CHANGED
|
@@ -1,24 +1,394 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
+
import { createHash } from "node:crypto";
|
|
2
3
|
import { execFileSync } from "node:child_process";
|
|
3
|
-
import { access, mkdir, readdir, writeFile } from "node:fs/promises";
|
|
4
|
+
import { access, mkdir, readFile, readdir, writeFile } from "node:fs/promises";
|
|
4
5
|
import os from "node:os";
|
|
5
6
|
import path from "node:path";
|
|
6
7
|
import { fileURLToPath } from "node:url";
|
|
7
8
|
|
|
8
|
-
const BACKEND = {
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
9
|
+
const BACKEND = {
|
|
10
|
+
"yss-cache": ["yss-microservice-components/yss-component-cache-parent"],
|
|
11
|
+
"yss-mybatis": ["yss-microservice-components/yss-component-persistence"],
|
|
12
|
+
"yss-dto": ["yss-microservice-components/yss-component-dto"],
|
|
13
|
+
"yss-audit-log": ["yss-microservice-components/yss-component-audit-log"],
|
|
14
|
+
"yss-excel-mvc": [
|
|
15
|
+
"yss-microservice-components/yss-component-excel-mvc",
|
|
16
|
+
"yss-microservice-components/yss-component-excel-starter",
|
|
17
|
+
],
|
|
18
|
+
"yss-distributed-id": [
|
|
19
|
+
"yss-microservice-components/yss-component-distributed-id",
|
|
20
|
+
"yss-microservice-components/yss-component-leaf",
|
|
21
|
+
],
|
|
22
|
+
"yss-resilience4j": ["yss-microservice-components/yss-component-resilience4j-starter"],
|
|
23
|
+
"yss-validation": [
|
|
24
|
+
"yss-microservice-components/yss-component-validation-engine-parent",
|
|
25
|
+
"yss-microservice-components/yss-component-validation-jsr303",
|
|
26
|
+
],
|
|
27
|
+
"yss-security-algorithm": ["yss-microservice-components/yss-component-security-algorithm"],
|
|
28
|
+
"yss-userinfo": ["yss-microservice-components/yss-component-userinfo-starter"],
|
|
29
|
+
"yss-exception": ["yss-microservice-components/yss-component-exception"],
|
|
30
|
+
};
|
|
31
|
+
|
|
32
|
+
const FRONTEND = {
|
|
33
|
+
"yss-ui": ["components", "hooks", "skills"],
|
|
34
|
+
"yss-components": ["components"],
|
|
35
|
+
"yss-hook": ["hooks"],
|
|
36
|
+
"yss-ui-business-page-generation": ["components", "hooks", "skills"],
|
|
37
|
+
"yss-use-table-height": ["hooks"],
|
|
38
|
+
"yss-use-tree-height": ["hooks"],
|
|
39
|
+
};
|
|
40
|
+
|
|
41
|
+
const URLS = {
|
|
42
|
+
components: "http://192.168.164.27:3200/components",
|
|
43
|
+
hooks: "http://192.168.164.27:3200/hooks",
|
|
44
|
+
skills: "http://192.168.164.27:3200/skills",
|
|
45
|
+
};
|
|
46
|
+
|
|
47
|
+
const KEYS = [
|
|
48
|
+
"Audit", "Cache", "Clear", "Command", "Configuration", "Controller", "DTO", "Data", "Enable", "Excel",
|
|
49
|
+
"Handler", "Interceptor", "Jdbc", "Mapper", "Mybatis", "Page", "Properties", "Query", "Repository", "Request",
|
|
50
|
+
"Response", "Result", "Update", "Aspect", "Leaf", "Id", "Dir", "Dic", "Dictionary", "File", "Upload", "Log",
|
|
51
|
+
"Message", "Mail", "Liquibase", "Circuit", "Breaker", "Sql", "Tpl", "Tag", "Task", "Flow", "Report",
|
|
52
|
+
"Validation", "Validator", "Security", "Crypto", "User", "Variable", "Quality", "Search", "Similarity",
|
|
53
|
+
"Scheduler", "Runner", "Duck", "Dynamic", "Factory", "Client", "Feign", "Gateway", "Convertor", "Adapter",
|
|
54
|
+
"Advice", "Bridge", "Route", "Uploader", "Sftp", "Minio", "Parser", "Express", "Rule", "Template", "Generator",
|
|
55
|
+
"Importer", "Engine", "Event", "Submitter", "Executor", "Context", "Status", "Type", "State",
|
|
56
|
+
];
|
|
57
|
+
|
|
58
|
+
const DOCS = new Set(["README.md", "readme.md", "HELP.md", "TECHNICAL_DESIGN.md"]);
|
|
59
|
+
const SKIPPED_DIRECTORIES = new Set([".git", "node_modules", "target", "build", "out", "${project.build.directory}"]);
|
|
60
|
+
|
|
61
|
+
const MYBATIS_CAPABILITIES = [
|
|
62
|
+
{
|
|
63
|
+
title: "Repository abstractions",
|
|
64
|
+
sources: [
|
|
65
|
+
{
|
|
66
|
+
suffix: "/support/BaseRepository.java",
|
|
67
|
+
patterns: [/public interface BaseRepository/, /int (insert|insertSelective|insertList|updateList|updateListSelective)\(/],
|
|
68
|
+
},
|
|
69
|
+
{
|
|
70
|
+
suffix: "/support/BasePlusRepository.java",
|
|
71
|
+
patterns: [/public interface BasePlusRepository/, /insertBatchSomeColumn/],
|
|
72
|
+
},
|
|
73
|
+
],
|
|
74
|
+
},
|
|
75
|
+
{
|
|
76
|
+
title: "Pagination and activation",
|
|
77
|
+
sources: [
|
|
78
|
+
{ suffix: "/aop/EntityQueryAspect.java", patterns: [/@Around\(/, /PageHelper\.offsetPage/] },
|
|
79
|
+
{ suffix: "/config/PageQueryEntityConfigration.java", patterns: [/@ConditionalOnProperty/] },
|
|
80
|
+
{
|
|
81
|
+
suffix: "/YssMybatisMapperProperties.java",
|
|
82
|
+
patterns: [
|
|
83
|
+
/@ConfigurationProperties/,
|
|
84
|
+
/private (String mapperLocation|String mapperScan|Integer batchSize|String dbType|PageHelper pageHelper|MybatisPlusPagination mybatisPlusPagination)/,
|
|
85
|
+
/public static class (PageHelper|MybatisPlusPagination)/,
|
|
86
|
+
/private Boolean enabled/,
|
|
87
|
+
],
|
|
88
|
+
},
|
|
89
|
+
{
|
|
90
|
+
suffix: "/config/MapperConfiguration.java",
|
|
91
|
+
patterns: [/new PageInterceptor\(/, /new PaginationInnerInterceptor\(/, /setBatchSize\(/, /setDbType\(/],
|
|
92
|
+
},
|
|
93
|
+
],
|
|
94
|
+
},
|
|
95
|
+
{
|
|
96
|
+
title: "SQL-level batch insertion",
|
|
97
|
+
sources: [
|
|
98
|
+
{ suffix: "/config/BatchInsertSettings.java", patterns: [/DEFAULT_BATCH_SIZE/, /configuredBatchSize/] },
|
|
99
|
+
{ suffix: "/config/BatchSqlInjector.java", patterns: [/public class BatchSqlInjector/, /insertBatchSomeColumnInternal/, /FieldFill\.UPDATE/] },
|
|
100
|
+
{ suffix: "/config/DialectInsertBatchSomeColumn.java", patterns: [/public class DialectInsertBatchSomeColumn/, /DbType\.(ORACLE|ORACLE_12C|DM)/] },
|
|
101
|
+
],
|
|
102
|
+
},
|
|
103
|
+
{
|
|
104
|
+
title: "Multi-data-source capability boundary",
|
|
105
|
+
sources: [
|
|
106
|
+
{
|
|
107
|
+
suffix: "/MultiDataSourceHolder.java",
|
|
108
|
+
patterns: [/public class MultiDataSourceHolder/, /Map<String, DataSource>/, /getMultiDataSource\(/],
|
|
109
|
+
},
|
|
110
|
+
],
|
|
111
|
+
},
|
|
112
|
+
];
|
|
113
|
+
|
|
114
|
+
const exists = async (target) => {
|
|
115
|
+
try {
|
|
116
|
+
await access(target);
|
|
117
|
+
return true;
|
|
118
|
+
} catch {
|
|
119
|
+
return false;
|
|
120
|
+
}
|
|
121
|
+
};
|
|
122
|
+
|
|
123
|
+
async function walk(root) {
|
|
124
|
+
if (!await exists(root)) return [];
|
|
125
|
+
const output = [];
|
|
126
|
+
for (const item of await readdir(root, { withFileTypes: true })) {
|
|
127
|
+
const target = path.join(root, item.name);
|
|
128
|
+
if (item.isDirectory() && !SKIPPED_DIRECTORIES.has(item.name)) output.push(...await walk(target));
|
|
129
|
+
else if (item.isFile()) output.push(target);
|
|
130
|
+
}
|
|
131
|
+
return output;
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
function relative(root, target) {
|
|
135
|
+
const value = path.relative(root, target).replaceAll(path.sep, "/");
|
|
136
|
+
return value && !value.startsWith("..") ? value : target;
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
function runGit(root, args) {
|
|
140
|
+
return execFileSync("git", ["-C", root, ...args], {
|
|
141
|
+
encoding: "utf8",
|
|
142
|
+
stdio: ["ignore", "pipe", "ignore"],
|
|
143
|
+
}).trim();
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
export function sourceState(root, componentPaths) {
|
|
147
|
+
try {
|
|
148
|
+
const commit = runGit(root, ["rev-parse", "HEAD"]);
|
|
149
|
+
const componentWorktree = runGit(root, ["status", "--porcelain", "--", ...componentPaths]) ? "dirty" : "clean";
|
|
150
|
+
const componentTrees = componentPaths.map((componentPath) => {
|
|
151
|
+
let tree = "missing";
|
|
152
|
+
try {
|
|
153
|
+
tree = runGit(root, ["rev-parse", `HEAD:${componentPath}`]);
|
|
154
|
+
} catch {
|
|
155
|
+
// The path can be newly added or absent in the indexed commit.
|
|
156
|
+
}
|
|
157
|
+
return { path: componentPath, tree };
|
|
158
|
+
});
|
|
159
|
+
return { commit, componentWorktree, componentTrees };
|
|
160
|
+
} catch {
|
|
161
|
+
return {
|
|
162
|
+
commit: "unavailable",
|
|
163
|
+
componentWorktree: "unknown",
|
|
164
|
+
componentTrees: componentPaths.map((componentPath) => ({ path: componentPath, tree: "unavailable" })),
|
|
165
|
+
};
|
|
166
|
+
}
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
async function sourceRoot() {
|
|
170
|
+
if (process.env.YSS_SOURCE_ROOT) {
|
|
171
|
+
const root = path.resolve(process.env.YSS_SOURCE_ROOT);
|
|
172
|
+
if (await exists(path.join(root, "yss-microservice-components"))) return root;
|
|
173
|
+
throw new Error(`YSS_SOURCE_ROOT must point to the repository root containing \`yss-microservice-components\`: ${root}`);
|
|
174
|
+
}
|
|
175
|
+
|
|
176
|
+
const home = os.homedir();
|
|
177
|
+
const candidates = [
|
|
178
|
+
process.cwd(),
|
|
179
|
+
...ancestors(process.cwd()),
|
|
180
|
+
path.join(home, "Documents/yss-project/yss-cloud-microservice"),
|
|
181
|
+
path.join(home, "Documents/yss-project"),
|
|
182
|
+
path.join(home, "Projects/yss-cloud-microservice"),
|
|
183
|
+
path.join(home, "Projects"),
|
|
184
|
+
];
|
|
185
|
+
for (const base of [path.join(home, "Projects"), path.join(home, "Documents"), path.join(home, "Documents/yss-project")]) {
|
|
186
|
+
if (!await exists(base)) continue;
|
|
187
|
+
for (const entry of await readdir(base, { withFileTypes: true })) {
|
|
188
|
+
if (entry.isDirectory()) candidates.push(path.join(base, entry.name));
|
|
189
|
+
}
|
|
190
|
+
}
|
|
191
|
+
for (const root of candidates) {
|
|
192
|
+
if (await exists(path.join(root, "yss-microservice-components"))) return path.resolve(root);
|
|
193
|
+
}
|
|
194
|
+
throw new Error("Could not find a YSS source repository containing `yss-microservice-components`. Export YSS_SOURCE_ROOT=/absolute/path/to/yss-cloud-microservice and rerun.");
|
|
195
|
+
}
|
|
196
|
+
|
|
197
|
+
function ancestors(start) {
|
|
198
|
+
const output = [];
|
|
199
|
+
let current = path.resolve(start);
|
|
200
|
+
while (path.dirname(current) !== current) {
|
|
201
|
+
current = path.dirname(current);
|
|
202
|
+
output.push(current);
|
|
203
|
+
}
|
|
204
|
+
return output;
|
|
205
|
+
}
|
|
206
|
+
|
|
207
|
+
async function files(bases) {
|
|
208
|
+
const output = { docs: [], poms: [], java: [], metadata: [] };
|
|
209
|
+
for (const base of bases) {
|
|
210
|
+
for (const target of await walk(base)) {
|
|
211
|
+
if (DOCS.has(path.basename(target))) output.docs.push(target);
|
|
212
|
+
else if (path.basename(target) === "pom.xml") output.poms.push(target);
|
|
213
|
+
else if (target.endsWith(".java") && target.includes(`${path.sep}src${path.sep}main${path.sep}java${path.sep}`)) output.java.push(target);
|
|
214
|
+
else if (path.basename(target) === "spring.factories") output.metadata.push(target);
|
|
215
|
+
}
|
|
216
|
+
}
|
|
217
|
+
for (const items of Object.values(output)) items.sort();
|
|
218
|
+
return output;
|
|
219
|
+
}
|
|
220
|
+
|
|
221
|
+
async function sha256(target) {
|
|
222
|
+
return createHash("sha256").update(await readFile(target)).digest("hex");
|
|
223
|
+
}
|
|
224
|
+
|
|
225
|
+
function list(items, render, empty) {
|
|
226
|
+
return items.length ? items.map(render) : [empty];
|
|
227
|
+
}
|
|
228
|
+
|
|
229
|
+
async function genericJavaEntries(source, javaFiles) {
|
|
230
|
+
const selected = javaFiles
|
|
231
|
+
.filter((target) => KEYS.some((key) => path.basename(target, ".java").includes(key)))
|
|
232
|
+
.slice(0, 120);
|
|
233
|
+
const output = [];
|
|
234
|
+
for (const target of selected) {
|
|
235
|
+
output.push(`- \`${relative(source, target)}\` — \`sha256:${await sha256(target)}\``);
|
|
236
|
+
}
|
|
237
|
+
return output.length ? output : ["- No key Java entry points matched the configured name patterns."];
|
|
238
|
+
}
|
|
239
|
+
|
|
240
|
+
function matchingLines(contents, patterns) {
|
|
241
|
+
return contents
|
|
242
|
+
.split(/\r?\n/)
|
|
243
|
+
.map((line, index) => ({ line: index + 1, text: line.trim().replace(/\s+/g, " ") }))
|
|
244
|
+
.filter(({ text }) => text && patterns.some((pattern) => pattern.test(text)))
|
|
245
|
+
.slice(0, 14);
|
|
246
|
+
}
|
|
247
|
+
|
|
248
|
+
async function mybatisCapabilityMatrix(source, javaFiles, metadataFiles) {
|
|
249
|
+
const output = ["## Capability Matrix", ""];
|
|
250
|
+
for (const capability of MYBATIS_CAPABILITIES) {
|
|
251
|
+
output.push(`### ${capability.title}`, "");
|
|
252
|
+
for (const expected of capability.sources) {
|
|
253
|
+
const target = javaFiles.find((candidate) => relative(source, candidate).endsWith(expected.suffix));
|
|
254
|
+
if (!target) {
|
|
255
|
+
output.push(`- \`${path.basename(expected.suffix)}\` — source not found.`);
|
|
256
|
+
continue;
|
|
257
|
+
}
|
|
258
|
+
const sourcePath = relative(source, target);
|
|
259
|
+
output.push(`- \`${sourcePath}\` — \`sha256:${await sha256(target)}\``);
|
|
260
|
+
const lines = matchingLines(await readFile(target, "utf8"), expected.patterns);
|
|
261
|
+
if (!lines.length) output.push(" - No configured public fact matched; refresh rules may need maintenance.");
|
|
262
|
+
else for (const fact of lines) output.push(` - \`${sourcePath}:${fact.line}\` — \`${fact.text.replaceAll("`", "'")}\``);
|
|
263
|
+
}
|
|
264
|
+
output.push("");
|
|
265
|
+
}
|
|
266
|
+
|
|
267
|
+
output.push("### Auto-configuration registration", "");
|
|
268
|
+
for (const target of metadataFiles) {
|
|
269
|
+
const sourcePath = relative(source, target);
|
|
270
|
+
output.push(`- \`${sourcePath}\` — \`sha256:${await sha256(target)}\``);
|
|
271
|
+
const registrations = (await readFile(target, "utf8"))
|
|
272
|
+
.split(/\r?\n/)
|
|
273
|
+
.map((line) => line.trim())
|
|
274
|
+
.filter((line) => line && !line.startsWith("#"));
|
|
275
|
+
for (const registration of registrations.slice(0, 12)) output.push(` - \`${registration.replaceAll("`", "'")}\``);
|
|
276
|
+
}
|
|
277
|
+
if (!metadataFiles.length) output.push("- No `spring.factories` registration found.");
|
|
278
|
+
output.push("");
|
|
279
|
+
return output;
|
|
280
|
+
}
|
|
281
|
+
|
|
282
|
+
async function backendIndex({ skill, parts, source, found, now, stateResolver }) {
|
|
283
|
+
const currentState = stateResolver(source, parts);
|
|
284
|
+
const bases = parts.map((item) => path.join(source, item));
|
|
285
|
+
const baseHints = await Promise.all(bases.map(async (target) =>
|
|
286
|
+
`- \`${relative(source, target)}\` (${await exists(target) ? "existed" : "missing"} when indexed)`,
|
|
287
|
+
));
|
|
288
|
+
const treeLines = currentState.componentTrees.map(({ path: componentPath, tree }) =>
|
|
289
|
+
`Component tree \`${componentPath}\`: \`${tree}\``,
|
|
290
|
+
);
|
|
291
|
+
const lines = [
|
|
292
|
+
`# ${skill} Source Index`,
|
|
293
|
+
"",
|
|
294
|
+
`Generated: ${now}`,
|
|
295
|
+
`Source commit: \`${currentState.commit}\``,
|
|
296
|
+
`Component worktree: \`${currentState.componentWorktree}\``,
|
|
297
|
+
...treeLines,
|
|
298
|
+
"Indexed source root: resolved at refresh time; set `YSS_SOURCE_ROOT` to reproduce or refresh.",
|
|
299
|
+
"",
|
|
300
|
+
"This file is generated by `yss-skill-source-index-refresh/scripts/refresh-yss-skill-index.mjs`. Do not hand-edit generated sections.",
|
|
301
|
+
"",
|
|
302
|
+
"Paths are relocatable source hints. Exact guidance requires a matching component tree and a clean indexed component subtree; the repository commit is trace metadata and may differ when unrelated components change.",
|
|
303
|
+
"",
|
|
304
|
+
"## Component Path Hints",
|
|
305
|
+
"",
|
|
306
|
+
...baseHints,
|
|
307
|
+
"",
|
|
308
|
+
"## Documentation Files",
|
|
309
|
+
"",
|
|
310
|
+
...list(found.docs, (target) => `- \`${relative(source, target)}\``, "- No component documentation files found."),
|
|
311
|
+
"",
|
|
312
|
+
"Component documentation is a discovery aid. For API signatures, conditions and defaults, prefer the indexed source facts below when documentation differs.",
|
|
313
|
+
"",
|
|
314
|
+
"## Maven Modules",
|
|
315
|
+
"",
|
|
316
|
+
...list(found.poms, (target) => `- \`${relative(source, path.dirname(target))}\``, "- No Maven modules found."),
|
|
317
|
+
"",
|
|
318
|
+
];
|
|
319
|
+
|
|
320
|
+
if (skill === "yss-mybatis") lines.push(...await mybatisCapabilityMatrix(source, found.java, found.metadata));
|
|
321
|
+
else lines.push("## Key Java Entry Points", "", ...await genericJavaEntries(source, found.java), "");
|
|
322
|
+
|
|
323
|
+
lines.push(
|
|
324
|
+
"## Freshness and Use",
|
|
325
|
+
"",
|
|
326
|
+
"- Locate the current source root using `YSS_SOURCE_ROOT`, CodeGraph, Maven artifact names or repository search.",
|
|
327
|
+
"- Compare each indexed `Component tree` with `git rev-parse HEAD:<component-path>` and require the current component subtree to be clean before exact guidance.",
|
|
328
|
+
"- A repository commit difference alone is not stale when the component tree is unchanged; a component tree mismatch or component-local dirty state is stale.",
|
|
329
|
+
"- Read only the source entries needed for the current decision or troubleshooting path.",
|
|
330
|
+
"",
|
|
331
|
+
);
|
|
332
|
+
return lines.join("\n");
|
|
333
|
+
}
|
|
334
|
+
|
|
335
|
+
export async function refresh({
|
|
336
|
+
skillsRoot,
|
|
337
|
+
source,
|
|
338
|
+
now = new Date().toISOString(),
|
|
339
|
+
frontend = true,
|
|
340
|
+
backendSkills = Object.keys(BACKEND),
|
|
341
|
+
stateResolver = sourceState,
|
|
342
|
+
}) {
|
|
343
|
+
const unknownSkills = backendSkills.filter((skill) => !(skill in BACKEND));
|
|
344
|
+
if (unknownSkills.length) throw new Error(`Unknown backend source-index skill: ${unknownSkills.join(", ")}`);
|
|
345
|
+
for (const skill of backendSkills) {
|
|
346
|
+
const parts = BACKEND[skill];
|
|
347
|
+
const bases = parts.map((item) => path.join(source, item));
|
|
348
|
+
const found = await files(bases);
|
|
349
|
+
const target = path.join(skillsRoot, skill, "references", "source-index.md");
|
|
350
|
+
await mkdir(path.dirname(target), { recursive: true });
|
|
351
|
+
await writeFile(target, await backendIndex({ skill, parts, source, found, now, stateResolver }), "utf8");
|
|
352
|
+
}
|
|
353
|
+
|
|
354
|
+
if (frontend) {
|
|
355
|
+
for (const [skill, keys] of Object.entries(FRONTEND)) {
|
|
356
|
+
if (!await exists(path.join(skillsRoot, skill))) continue;
|
|
357
|
+
const target = path.join(skillsRoot, skill, "references", "frontend-docs.md");
|
|
358
|
+
await mkdir(path.dirname(target), { recursive: true });
|
|
359
|
+
await writeFile(target, [
|
|
360
|
+
`# ${skill} Frontend Documentation`,
|
|
361
|
+
"",
|
|
362
|
+
`Generated: ${now}`,
|
|
363
|
+
"",
|
|
364
|
+
"Use these YSS UI documentation entry points as authoritative references when local repo examples are insufficient.",
|
|
365
|
+
"",
|
|
366
|
+
...keys.map((key) => `- ${key}: ${URLS[key]}`),
|
|
367
|
+
"",
|
|
368
|
+
"When documentation and local code differ, inspect the current project code before editing and prefer established local usage.",
|
|
369
|
+
"",
|
|
370
|
+
].join("\n"), "utf8");
|
|
371
|
+
}
|
|
372
|
+
}
|
|
373
|
+
return { backend: backendSkills.length, frontend: frontend ? Object.keys(FRONTEND).length : 0 };
|
|
374
|
+
}
|
|
375
|
+
|
|
376
|
+
async function main() {
|
|
377
|
+
try {
|
|
378
|
+
const script = path.dirname(fileURLToPath(import.meta.url));
|
|
379
|
+
const result = await refresh({
|
|
380
|
+
skillsRoot: path.resolve(process.env.YSS_SKILLS_ROOT || path.join(script, "../..")),
|
|
381
|
+
source: await sourceRoot(),
|
|
382
|
+
frontend: !["0", "false", "no"].includes((process.env.YSS_REFRESH_FRONTEND || "true").toLowerCase()),
|
|
383
|
+
backendSkills: process.env.YSS_REFRESH_BACKEND_SKILLS
|
|
384
|
+
? process.env.YSS_REFRESH_BACKEND_SKILLS.split(",").map((skill) => skill.trim()).filter(Boolean)
|
|
385
|
+
: Object.keys(BACKEND),
|
|
386
|
+
});
|
|
387
|
+
console.log(`Updated ${result.backend} backend indexes and ${result.frontend} frontend doc references.`);
|
|
388
|
+
} catch (error) {
|
|
389
|
+
console.error(error.message);
|
|
390
|
+
process.exitCode = 1;
|
|
391
|
+
}
|
|
392
|
+
}
|
|
393
|
+
|
|
394
|
+
if (process.argv[1] === fileURLToPath(import.meta.url)) await main();
|
package/template/.pi/skills/yss-skill-source-index-refresh/scripts/refresh-yss-skill-index.test.mjs
CHANGED
|
@@ -1,9 +1,10 @@
|
|
|
1
1
|
import assert from "node:assert/strict";
|
|
2
|
+
import { execFileSync } from "node:child_process";
|
|
2
3
|
import { mkdir, mkdtemp, readFile, writeFile } from "node:fs/promises";
|
|
3
4
|
import { tmpdir } from "node:os";
|
|
4
5
|
import path from "node:path";
|
|
5
6
|
import test from "node:test";
|
|
6
|
-
import { refresh } from "./refresh-yss-skill-index.mjs";
|
|
7
|
+
import { refresh, sourceState } from "./refresh-yss-skill-index.mjs";
|
|
7
8
|
|
|
8
9
|
test("writes Node-labelled generated indexes", async () => {
|
|
9
10
|
const root=await mkdtemp(path.join(tmpdir(),"yss-index-")); const source=path.join(root,"source"); const skills=path.join(root,"skills");
|
|
@@ -13,3 +14,80 @@ test("writes Node-labelled generated indexes", async () => {
|
|
|
13
14
|
assert.match(await readFile(path.join(skills,"yss-cache/references/source-index.md"),"utf8"),/refresh-yss-skill-index\.mjs/);
|
|
14
15
|
assert.match(await readFile(path.join(skills,"yss-ui/references/frontend-docs.md"),"utf8"),/components/);
|
|
15
16
|
});
|
|
17
|
+
|
|
18
|
+
test("writes a source-backed MyBatis capability matrix without absolute paths", async () => {
|
|
19
|
+
const root = await mkdtemp(path.join(tmpdir(), "yss-mybatis-index-"));
|
|
20
|
+
const source = path.join(root, "source");
|
|
21
|
+
const skills = path.join(root, "skills");
|
|
22
|
+
const component = "yss-microservice-components/yss-component-persistence";
|
|
23
|
+
const plusJava = path.join(source, component, "yss-component-mybatis-plus-starter/src/main/java/com/yss/cloud/mybatis");
|
|
24
|
+
const baseJava = path.join(source, component, "yss-component-mybatis-starter/src/main/java/com/yss/cloud/mybatis");
|
|
25
|
+
const commonJava = path.join(source, component, "yss-component-persistence-common/src/main/java/com/yss/cloud/mybatis");
|
|
26
|
+
|
|
27
|
+
await mkdir(path.join(plusJava, "support"), { recursive: true });
|
|
28
|
+
await mkdir(path.join(baseJava, "config"), { recursive: true });
|
|
29
|
+
await mkdir(commonJava, { recursive: true });
|
|
30
|
+
await mkdir(path.join(skills, "yss-mybatis"), { recursive: true });
|
|
31
|
+
await writeFile(path.join(source, component, "pom.xml"), "<project/>");
|
|
32
|
+
await writeFile(path.join(plusJava, "support/BasePlusRepository.java"), [
|
|
33
|
+
"public interface BasePlusRepository<T> extends BaseMapper<T> {",
|
|
34
|
+
" default Integer insertBatchSomeColumn(List<T> entities) { return 0; }",
|
|
35
|
+
" Integer insertBatchSomeColumnInternal(List<T> entities);",
|
|
36
|
+
"}",
|
|
37
|
+
].join("\n"));
|
|
38
|
+
await writeFile(path.join(baseJava, "config/PageQueryEntityConfigration.java"), [
|
|
39
|
+
"public class PageQueryEntityConfigration {",
|
|
40
|
+
" @ConditionalOnProperty(name = \"yss.mybatis.page-helper.enabled\", havingValue = \"true\", matchIfMissing = true)",
|
|
41
|
+
"}",
|
|
42
|
+
].join("\n"));
|
|
43
|
+
await writeFile(path.join(commonJava, "MultiDataSourceHolder.java"), [
|
|
44
|
+
"public class MultiDataSourceHolder {",
|
|
45
|
+
" private Map<String, DataSource> multiDataSource;",
|
|
46
|
+
"}",
|
|
47
|
+
].join("\n"));
|
|
48
|
+
|
|
49
|
+
await refresh({
|
|
50
|
+
skillsRoot: skills,
|
|
51
|
+
source,
|
|
52
|
+
now: "2026-01-01T00:00:00Z",
|
|
53
|
+
frontend: false,
|
|
54
|
+
backendSkills: ["yss-mybatis"],
|
|
55
|
+
stateResolver: () => ({
|
|
56
|
+
commit: "a".repeat(40),
|
|
57
|
+
componentWorktree: "clean",
|
|
58
|
+
componentTrees: [{ path: component, tree: "b".repeat(40) }],
|
|
59
|
+
}),
|
|
60
|
+
});
|
|
61
|
+
|
|
62
|
+
const index = await readFile(path.join(skills, "yss-mybatis/references/source-index.md"), "utf8");
|
|
63
|
+
assert.match(index, /## Capability Matrix/);
|
|
64
|
+
assert.match(index, /BasePlusRepository<T>/);
|
|
65
|
+
assert.match(index, /yss\.mybatis\.page-helper\.enabled/);
|
|
66
|
+
assert.match(index, /Map<String, DataSource>/);
|
|
67
|
+
assert.match(index, /Component worktree: `clean`/);
|
|
68
|
+
assert.match(index, /Component tree.*b{40}/);
|
|
69
|
+
assert.doesNotMatch(index, new RegExp(root.replaceAll("/", "\\/")));
|
|
70
|
+
assert.doesNotMatch(index, /## Key Java Entry Points/);
|
|
71
|
+
});
|
|
72
|
+
|
|
73
|
+
test("source freshness is scoped to the indexed component subtree", async () => {
|
|
74
|
+
const root = await mkdtemp(path.join(tmpdir(), "yss-component-state-"));
|
|
75
|
+
const component = "yss-microservice-components/yss-component-persistence";
|
|
76
|
+
const componentFile = path.join(root, component, "pom.xml");
|
|
77
|
+
const unrelatedFile = path.join(root, "yss-microservice-components/other/README.md");
|
|
78
|
+
await mkdir(path.dirname(componentFile), { recursive: true });
|
|
79
|
+
await mkdir(path.dirname(unrelatedFile), { recursive: true });
|
|
80
|
+
await writeFile(componentFile, "<project/>\n");
|
|
81
|
+
await writeFile(unrelatedFile, "clean\n");
|
|
82
|
+
execFileSync("git", ["init", "-q"], { cwd: root });
|
|
83
|
+
execFileSync("git", ["config", "user.email", "test@example.com"], { cwd: root });
|
|
84
|
+
execFileSync("git", ["config", "user.name", "Test"], { cwd: root });
|
|
85
|
+
execFileSync("git", ["add", "."], { cwd: root });
|
|
86
|
+
execFileSync("git", ["commit", "-qm", "fixture"], { cwd: root });
|
|
87
|
+
|
|
88
|
+
await writeFile(unrelatedFile, "dirty elsewhere\n");
|
|
89
|
+
assert.equal(sourceState(root, [component]).componentWorktree, "clean");
|
|
90
|
+
|
|
91
|
+
await writeFile(componentFile, "<project><dirty/></project>\n");
|
|
92
|
+
assert.equal(sourceState(root, [component]).componentWorktree, "dirty");
|
|
93
|
+
});
|
|
@@ -62,6 +62,10 @@ Look for the originating spec, in this order:
|
|
|
62
62
|
|
|
63
63
|
Compile sources **before** spawning reviewers. For YSS implementation candidates follow [yss-review-standards.md](references/yss-review-standards.md): run machine checks that exist in the implementation repo; then collect repo docs (`CODING_STANDARDS.md` / `CONTRIBUTING.md` if present), every Slice `required_skills` skill file, the impact-conditioned specialist inputs (`alibaba-java-code-style`, `yss-ui`, `yss-domain`, …), and `docs/templates/review-report-template.md`. Missing applicable coverage is `missing_evidence`, not a pass.
|
|
64
64
|
|
|
65
|
+
For YSS backend review, derive the review roots from the candidate project root, implementation-repository registry, Slice `project_roots` and `allowed_write_paths`. Review only the project itself and registered backend development projects; exclude frontend roots, unrelated submodules/vendor trees and unregistered directories. Never replace this resolution with a fixed `apps/backend` assumption.
|
|
66
|
+
|
|
67
|
+
Every backend candidate must explicitly assess `yss-repository` and `yss-mybatis`. When the candidate changes persistence structure, Mapper/XML, SQL, pagination, batch operations, scanning/configuration or data-source behavior, read both skills and the selected Repository Profile; exact component claims also require a current `yss-mybatis` source index. When no persistence impact exists, record a concrete `not-applicable` reason for both instead of silently skipping them.
|
|
68
|
+
|
|
65
69
|
Anything in the repo that documents how code should be written, such as `CODING_STANDARDS.md` or `CONTRIBUTING.md`, remains a source. It does **not** replace YSS or Alibaba specialist inputs.
|
|
66
70
|
|
|
67
71
|
On top of whatever the repo documents, the Standards axis always carries the **smell baseline** below — a fixed set of Fowler code smells (_Refactoring_, ch.3) that applies even when a repo documents nothing. Two rules bind it:
|
|
@@ -11,7 +11,7 @@
|
|
|
11
11
|
1. 仓库文档:`CODING_STANDARDS.md`、`CONTRIBUTING.md` 或实现仓等价文件(若存在)。
|
|
12
12
|
2. Slice Implementation Contract 的 `required_skills`:对每个技能读取 `.agents/skills/<id>/SKILL.md` 及该 skill 指明的 references。
|
|
13
13
|
3. 影响面专项检查输入(与合同并集,不得互相替代):
|
|
14
|
-
- 后端:`alibaba-java-code-style`、`yss-domain`、`yss-application`、`yss-repository`、`yss-web-controller`、`yss-dto`、`mapstruct`、`lombok`
|
|
14
|
+
- 后端:`alibaba-java-code-style`、`yss-domain`、`yss-application`、`yss-repository`、`yss-mybatis`、`yss-web-controller`、`yss-dto`、`mapstruct`、`lombok`
|
|
15
15
|
- UI:`yss-ui`、`yss-design-system`、`yss-ui-business-page-generation`
|
|
16
16
|
4. 报告模板中的后端 / 前端门禁表。空着的适用行视为 `missing_evidence`。
|
|
17
17
|
|
|
@@ -19,11 +19,18 @@ YSS 页面模块约定(YTable、YFormily、页面骨架等)走 Standards,
|
|
|
19
19
|
|
|
20
20
|
审查者只读这些 skill,不得用它们写实现路径。`role.test-engineer` 任务包禁止 `implement` 与脚手架生成器。
|
|
21
21
|
|
|
22
|
+
### 后端范围与持久化适用性
|
|
23
|
+
|
|
24
|
+
- Review roots 从候选本体项目、实现仓登记、Slice `project_roots` 和 `allowed_write_paths` 解析;只包含本体项目和已登记后端研发项目,不固定为 `apps/backend`,不扫描前端、无关 submodule/vendor 或未登记目录。
|
|
25
|
+
- 每个后端候选都必须分别评估 `yss-repository` 与 `yss-mybatis`。命中 PO、Repository、Mapper/XML、SQL、分页、批量、扫描/配置或数据源行为时,两者均为 applicable,并加载所选 Repository Profile 与当前 MyBatis source index。
|
|
26
|
+
- 精确组件 API/配置结论要求 source index 的组件 tree 与当前源码一致且组件子树 clean;不满足时为 `missing_evidence` / `stale`,不能判 pass。
|
|
27
|
+
- 无持久化影响时,两项 Skill 分别记录具体 `not-applicable` 原因;仅写“未命中”或留空不构成证据。
|
|
28
|
+
|
|
22
29
|
## 2. 机器检查
|
|
23
30
|
|
|
24
31
|
在派发 Standards / Spec 子审查之前,对实现仓**已登记且当前可执行**的命令实际跑一遍:
|
|
25
32
|
|
|
26
|
-
-
|
|
33
|
+
- 后端优先:对本体项目和每个已登记后端研发项目分别执行其切片合同里的 `./mvnw` 验证;若工程已配置 Checkstyle / P3C / Spotless / `validate`,一并执行。
|
|
27
34
|
- 前端优先:切片合同里的 `pnpm` 验证;若存在 `pnpm lint` / `pnpm type-check`,一并执行。
|
|
28
35
|
|
|
29
36
|
记录命令、退出码、时间和证据引用。退出码非 0 记为 Standards **hard violation**。
|
|
@@ -88,7 +88,7 @@ node scripts/run_first_slice_verification.mjs \
|
|
|
88
88
|
- 生成后的后端工程必须使用项目根目录 `./mvnw ...` 执行构建、测试、运行和 CI 验证;不得在 README、实施记录、Ticket、Review 或 Release 中默认写裸 `mvn ...`。既有仓库确实无法使用 wrapper 时,必须记录受控例外。
|
|
89
89
|
- 原型确认后,`scaffold_status=required` 才能进入本 skill;本 skill 的生成边界是工程结构、POM、配置、Wrapper 和机械模板,不是业务实现。
|
|
90
90
|
- 脚手架合同必须携带 `contract_id`、`contract_version`、实现合同编译器 draft 引用、生命周期批准引用、持久化引用、当前版本、允许写路径、预期证据文件和验证命令;字段缺失或版本过期时阻断。
|
|
91
|
-
-
|
|
91
|
+
- 新脚手架优先接受统一 Project Scaffold Contract schema v4;已批准且当前的后端 schema v3 可完成兼容生成。两者都必须携带 `architecture_family=domain-driven`、`generator_skill`、`decision_ref/id/digest`、固定模块闭包,以及 `project_name`、`base_package` 和 `maven_coordinates`。历史 schema v2 仅只读兼容,不用于新生成;schema v1/v2 均不自动升级。
|
|
92
92
|
- 合同 `profiles` 只支持 `target-domain-model`、`mybatis-plus`、`mysql`、`spring-boot-2.7-jdk8`、`javax`、`web`、`yss-internal`。普通 MyBatis、Boot 3、独立 client module、client-in-domain 和其他旧架构均为 `unsupported`,不提供回退分支。
|
|
93
93
|
- 运行生成器必须传入 `--contract-file`;生成器会校验合同 `status=approved`、`current_version`、`primary_skill`、`controlled-generation`、实际输出路径和固定三条验证命令,不接受仅凭任意字符串引用的放行。
|
|
94
94
|
- 生成项目必须写入 Manifest v3 `.yss/scaffold-generation.json`,记录架构选择及 digest、生成器、合同 digest、Target Profile、模块闭包、模板 digest、下游完整 skill tree digest、脚手架父合同与 实现合同编译器 合同 digest、generator-owned 文件 hash、严格 `generation_policy` 和完成等级;清单缺失或不一致时不得交给后续 实现合同编译器。
|
|
@@ -9,6 +9,7 @@ import { fileURLToPath } from "node:url";
|
|
|
9
9
|
import { parseDocument } from "../../../../scripts/vendor/yaml.mjs";
|
|
10
10
|
import { assertLocalDatabaseProfile, localDatabaseConfiguration, scaffoldArchitectureIdentity } from "../../../../scripts/lib/scaffold-local-database.mjs";
|
|
11
11
|
import { validateArchitectureIdentity } from "../../../../scripts/lib/backend-architecture.mjs";
|
|
12
|
+
import { validateJsonSchema } from "../../../../scripts/lib/json-schema.mjs";
|
|
12
13
|
|
|
13
14
|
import {
|
|
14
15
|
findGitRoot,
|
|
@@ -204,7 +205,9 @@ class ScaffoldGenerator {
|
|
|
204
205
|
const contractText = await readFile(this.contractFile, "utf8");
|
|
205
206
|
let contract; try { contract = JSON.parse(contractText); } catch { fail(`脚手架合同文件无法读取或不是合法 JSON: ${this.contractFile}`); }
|
|
206
207
|
if (!contract || Array.isArray(contract) || typeof contract !== "object") fail("脚手架合同必须是 JSON 对象");
|
|
207
|
-
if (contract.schema_version
|
|
208
|
+
if (![3, 4].includes(contract.schema_version)) fail(`unsupported: scaffold contract schema_version=${contract.schema_version};只接受兼容 v3 或统一 v4`);
|
|
209
|
+
if (contract.schema_version === 4 && (contract.kind !== "project-scaffold-contract" || contract.delivery_role !== "backend" || contract.scaffold_kind !== "backend-ddd")) fail("schema v4 合同必须绑定 backend/backend-ddd");
|
|
210
|
+
if (contract.schema_version === 4) validateJsonSchema(contract, path.join(REPOSITORY_ROOT, "docs/process/schemas/project-scaffold-contract.schema.json"), { label: "Project Scaffold Contract v4" });
|
|
208
211
|
const requiredMetadata = [["--contract-id", this.options.contractId], ["--contract-version", this.options.contractVersion], ["--approval-ref", this.options.approvalRef], ["--compiler-draft-ref", this.options.compilerDraftRef], ["--persisted-ref", this.options.persistedRef]];
|
|
209
212
|
const missing = requiredMetadata.filter(([, value]) => !isPresent(value)).map(([flag]) => flag);
|
|
210
213
|
if (missing.length) fail(`生成项目必须提供当前已批准脚手架合同的完整元数据: ${missing.join(", ")}`);
|
|
@@ -214,7 +217,7 @@ class ScaffoldGenerator {
|
|
|
214
217
|
if (contract.status !== "approved") fail("脚手架合同必须已由生命周期批准");
|
|
215
218
|
if (contract.contract_id !== this.options.contractId) fail("--contract-id 与脚手架合同不一致");
|
|
216
219
|
if (contract.contract_version !== this.options.contractVersion) fail("--contract-version 与脚手架合同不一致");
|
|
217
|
-
if (contract.current_version !== contract.contract_version) fail("脚手架合同版本不是当前版本");
|
|
220
|
+
if (contract.current_version !== contract.contract_version && !(contract.schema_version === 4 && contract.current_version === true)) fail("脚手架合同版本不是当前版本");
|
|
218
221
|
if (contract.compiler_draft_ref !== this.options.compilerDraftRef) fail("--compiler-draft-ref 与脚手架合同不一致");
|
|
219
222
|
if (contract.persisted_ref !== this.options.persistedRef) fail("--persisted-ref 与脚手架合同不一致");
|
|
220
223
|
if (contract.lifecycle_approval_ref !== this.options.approvalRef) fail("--approval-ref 与脚手架合同不一致");
|
|
@@ -364,6 +367,7 @@ class ScaffoldGenerator {
|
|
|
364
367
|
const scaffoldParent = path.join(SKILL_ROOT, "references", "yss-backend-scaffold-parent", "SKILL.md");
|
|
365
368
|
const compilerContract = path.join(REPOSITORY_ROOT, ".agents", "skills", "yss-implementation-contract-compiler", "references", "compiler-contract.yaml");
|
|
366
369
|
const manifest = { schema_version: 3, kind: "backend-scaffold", architecture_profile: contract.architecture_profile, architecture_identity: scaffoldArchitectureIdentity(contract, this.contractDigest), contract_id: this.options.contractId, contract_version: this.options.contractVersion, scaffold_request_id: contract.scaffold_request_id, architecture_family: contract.architecture_family, generator_skill: contract.generator_skill, decision_id: contract.decision_id, decision_digest: contract.decision_digest, module_profile: contract.module_profile, approval_ref: this.options.approvalRef, compiler_draft_ref: this.options.compilerDraftRef, persisted_ref: this.options.persistedRef, contract_file_ref: this.contractFile, contract_digest: this.contractDigest, lifecycle_approval_ref: contract.lifecycle_approval_ref, current_version: contract.current_version, approver: contract.approval.approver, allowed_write_paths: contract.allowed_write_paths, expected_evidence_files: contract.expected_evidence_files, project_name: this.projectName, base_package: this.basePackage, bootstrap_main_class: `${this.basePackage}.${this.applicationClassName}`, bootstrap_main_source: this.bootstrapMainSource, maven_coordinates: this.mavenCoordinates, maven_coordinates_source: this.mavenCoordinatesSource, profiles: this.profiles, generation_mode: "controlled-generation", completion_level: "generated", generator: { id: "yss-ddd-scaffold-generator", template_digest: await treeDigest(path.join(SKILL_ROOT, "assets")) }, ownership: { generated_files: generatedFiles, user_owned_globs: ["**/src/main/java/**", "**/src/test/java/**", "db/**"] }, readiness: { downstream_skills: downstream, contracts: { scaffold_parent: sha256(await readFile(scaffoldParent)), compiler_contract: sha256(await readFile(compilerContract)) }, architecture_ruleset: sha256(await readFile(path.join(this.javaTemplateDir, "architecture-rules-test.java.template"))) }, generation_policy: { mode: "initialize-only", existing_target: "unsupported", old_project_migration: "unsupported", template_upgrade: "unsupported" }, verification_commands: COMMANDS, generated_at: isoNow() };
|
|
370
|
+
manifest.schema_version = contract.schema_version;
|
|
367
371
|
await writeText(path.join(this.projectRoot, ".yss", "scaffold-generation.json"), `${JSON.stringify(manifest, null, 2)}\n`); console.log(" ✓ .yss/scaffold-generation.json");
|
|
368
372
|
}
|
|
369
373
|
async copyWrapperFiles() {
|
|
@@ -375,7 +379,7 @@ class ScaffoldGenerator {
|
|
|
375
379
|
const required = [path.join(this.projectRoot, "pom.xml"), path.join(this.projectRoot, `${this.projectName}-bootstrap`, "pom.xml"), path.join(this.projectRoot, this.bootstrapMainSource), path.join(this.projectRoot, "mvnw"), path.join(this.projectRoot, ".yss", "scaffold-generation.json")];
|
|
376
380
|
const missing = []; for (const target of required) if (!await isFile(target)) missing.push(target); if (missing.length) fail(`生成产物缺失: ${missing.join(", ")}`);
|
|
377
381
|
const manifest = await readJson(required[4], "脚手架生成元数据清单无法读取");
|
|
378
|
-
if (manifest.schema_version
|
|
382
|
+
if (![3, 4].includes(manifest.schema_version) || manifest.contract_id !== this.options.contractId || manifest.contract_version !== this.options.contractVersion || (manifest.current_version !== this.options.contractVersion && manifest.current_version !== true) || manifest.generation_mode !== "controlled-generation" || manifest.architecture_family !== "domain-driven" || manifest.generator_skill !== "yss-ddd-scaffold-generator" || manifest.decision_id !== this.scaffoldContract.decision_id || manifest.decision_digest !== this.scaffoldContract.decision_digest || JSON.stringify(manifest.module_profile) !== JSON.stringify(this.scaffoldContract.module_profile) || manifest.bootstrap_main_class !== `${this.basePackage}.${this.applicationClassName}` || manifest.bootstrap_main_source !== this.bootstrapMainSource || manifest.profiles.architecture !== SUPPORTED_PROFILES.architecture || manifest.generation_policy.mode !== "initialize-only" || manifest.generation_policy.existing_target !== "unsupported" || JSON.stringify(manifest.verification_commands) !== JSON.stringify(COMMANDS)) fail("脚手架生成元数据清单与当前批准架构决策、合同、Target Profile、initialize-only 边界、机械启动入口或固定验证命令不一致");
|
|
379
383
|
const stack = [this.projectRoot], binary = new Set([".class", ".db", ".jar", ".png", ".jpg", ".jpeg", ".gif"]);
|
|
380
384
|
while (stack.length) { const dir = stack.pop(); for (const entry of await readdir(dir, { withFileTypes: true })) { const target = path.join(dir, entry.name); if (entry.isDirectory()) { stack.push(target); continue; } if (!entry.isFile() || binary.has(path.extname(entry.name))) continue; const content = await readFile(target, "utf8"); if (content.includes("{{") || content.includes("root/root")) fail(`生成文件包含未替换占位符或明文凭据: ${target}`); } }
|
|
381
385
|
}
|