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.
Files changed (439) hide show
  1. package/README.md +2 -2
  2. package/package.json +3 -2
  3. package/src/command-runner.mjs +107 -0
  4. package/src/self-update.js +7 -4
  5. package/src/template/instance-runtime.js +1 -1
  6. package/template/.agents/skills/.strategic-design-skills-manifest.json +2 -2
  7. package/template/.agents/skills/code-review/SKILL.md +4 -0
  8. package/template/.agents/skills/code-review/agents/openai.yaml +1 -1
  9. package/template/.agents/skills/code-review/references/yss-review-standards.md +9 -2
  10. package/template/.agents/skills/competitive-intelligence/SKILL.md +4 -4
  11. package/template/.agents/skills/domain-modeling/CONTEXT-FORMAT.md +1 -1
  12. package/template/.agents/skills/grill-with-docs/SKILL.md +1 -1
  13. package/template/.agents/skills/setup-matt-pocock-skills/issue-tracker-local.md +1 -1
  14. package/template/.agents/skills/yss-ddd-scaffold-generator/SKILL.md +1 -1
  15. package/template/.agents/skills/yss-ddd-scaffold-generator/scripts/generate_scaffold.mjs +7 -3
  16. package/template/.agents/skills/yss-ddd-scaffold-generator/scripts/run_scaffold_verification.mjs +8 -8
  17. package/template/.agents/skills/yss-ddd-scaffold-generator/scripts/scaffold-generator.test.mjs +9 -0
  18. package/template/.agents/skills/yss-frontend-scaffold-generator/SKILL.md +10 -7
  19. package/template/.agents/skills/yss-frontend-scaffold-generator/scripts/generate_and_verify_scaffold.mjs +10 -0
  20. package/template/.agents/skills/yss-frontend-scaffold-generator/scripts/generate_scaffold.mjs +121 -0
  21. package/template/.agents/skills/yss-frontend-scaffold-generator/scripts/run_scaffold_verification.mjs +40 -0
  22. package/template/.agents/skills/yss-frontend-scaffold-generator/scripts/scaffold-generator.test.mjs +55 -0
  23. package/template/.agents/skills/yss-implementation-contract-compiler/SKILL.md +1 -1
  24. package/template/.agents/skills/yss-implementation-contract-compiler/references/boundaries.md +4 -0
  25. package/template/.agents/skills/yss-implementation-contract-compiler/references/compiler-contract.yaml +25 -0
  26. package/template/.agents/skills/yss-layered-mvc-scaffold-generator/SKILL.md +2 -2
  27. package/template/.agents/skills/yss-layered-mvc-scaffold-generator/scripts/generate_scaffold.mjs +8 -5
  28. package/template/.agents/skills/yss-layered-mvc-scaffold-generator/scripts/scaffold-generator.test.mjs +17 -2
  29. package/template/.agents/skills/yss-mybatis/SKILL.md +34 -58
  30. package/template/.agents/skills/yss-mybatis/agents/openai.yaml +2 -2
  31. package/template/.agents/skills/yss-mybatis/references/source-index.md +88 -68
  32. package/template/.agents/skills/yss-product-lifecycle/SKILL.md +50 -42
  33. package/template/.agents/skills/yss-product-lifecycle/references/artifact-dependencies.md +5 -3
  34. package/template/.agents/skills/yss-product-lifecycle/references/matt-yss-adapter.md +3 -3
  35. package/template/.agents/skills/yss-product-lifecycle/references/orchestration-contract.yaml +124 -16
  36. package/template/.agents/skills/yss-product-lifecycle/references/orchestration.md +16 -2
  37. package/template/.agents/skills/yss-product-lifecycle/references/state-model.md +5 -2
  38. package/template/.agents/skills/yss-repository/SKILL.md +28 -70
  39. package/template/.agents/skills/yss-repository/agents/openai.yaml +2 -2
  40. package/template/.agents/skills/yss-repository/references/profiles/layered-mvc-service.md +19 -1
  41. package/template/.agents/skills/yss-repository/references/profiles/mvc-data-analysis-v1.md +19 -1
  42. package/template/.agents/skills/yss-repository/references/profiles/target-domain-model.md +21 -1
  43. package/template/.agents/skills/yss-repository/tests/profile-routing.test.mjs +59 -0
  44. package/template/.agents/skills/yss-research/SKILL.md +1 -1
  45. package/template/.agents/skills/yss-skill-source-index-refresh/SKILL.md +8 -5
  46. package/template/.agents/skills/yss-skill-source-index-refresh/references/source-location.md +2 -1
  47. package/template/.agents/skills/yss-skill-source-index-refresh/scripts/refresh-yss-skill-index.mjs +388 -18
  48. package/template/.agents/skills/yss-skill-source-index-refresh/scripts/refresh-yss-skill-index.test.mjs +79 -1
  49. package/template/.agents/skills/yss-stage-decision/SKILL.md +5 -3
  50. package/template/.agents/skills/yss-stage-decision/references/stage-decision-package-contract.md +1 -1
  51. package/template/.claude/skills/code-review/SKILL.md +4 -0
  52. package/template/.claude/skills/code-review/agents/openai.yaml +1 -1
  53. package/template/.claude/skills/code-review/references/yss-review-standards.md +9 -2
  54. package/template/.claude/skills/competitive-intelligence/SKILL.md +4 -4
  55. package/template/.claude/skills/domain-modeling/CONTEXT-FORMAT.md +1 -1
  56. package/template/.claude/skills/grill-with-docs/SKILL.md +1 -1
  57. package/template/.claude/skills/setup-matt-pocock-skills/issue-tracker-local.md +1 -1
  58. package/template/.claude/skills/yss-ddd-scaffold-generator/SKILL.md +1 -1
  59. package/template/.claude/skills/yss-ddd-scaffold-generator/scripts/generate_scaffold.mjs +7 -3
  60. package/template/.claude/skills/yss-ddd-scaffold-generator/scripts/run_scaffold_verification.mjs +8 -8
  61. package/template/.claude/skills/yss-ddd-scaffold-generator/scripts/scaffold-generator.test.mjs +9 -0
  62. package/template/.claude/skills/yss-frontend-scaffold-generator/SKILL.md +10 -7
  63. package/template/.claude/skills/yss-frontend-scaffold-generator/scripts/generate_and_verify_scaffold.mjs +10 -0
  64. package/template/.claude/skills/yss-frontend-scaffold-generator/scripts/generate_scaffold.mjs +121 -0
  65. package/template/.claude/skills/yss-frontend-scaffold-generator/scripts/run_scaffold_verification.mjs +40 -0
  66. package/template/.claude/skills/yss-frontend-scaffold-generator/scripts/scaffold-generator.test.mjs +55 -0
  67. package/template/.claude/skills/yss-implementation-contract-compiler/SKILL.md +1 -1
  68. package/template/.claude/skills/yss-implementation-contract-compiler/references/boundaries.md +4 -0
  69. package/template/.claude/skills/yss-implementation-contract-compiler/references/compiler-contract.yaml +25 -0
  70. package/template/.claude/skills/yss-layered-mvc-scaffold-generator/SKILL.md +2 -2
  71. package/template/.claude/skills/yss-layered-mvc-scaffold-generator/scripts/generate_scaffold.mjs +8 -5
  72. package/template/.claude/skills/yss-layered-mvc-scaffold-generator/scripts/scaffold-generator.test.mjs +17 -2
  73. package/template/.claude/skills/yss-mybatis/SKILL.md +34 -58
  74. package/template/.claude/skills/yss-mybatis/agents/openai.yaml +2 -2
  75. package/template/.claude/skills/yss-mybatis/references/source-index.md +88 -68
  76. package/template/.claude/skills/yss-product-lifecycle/SKILL.md +50 -42
  77. package/template/.claude/skills/yss-product-lifecycle/references/artifact-dependencies.md +5 -3
  78. package/template/.claude/skills/yss-product-lifecycle/references/matt-yss-adapter.md +3 -3
  79. package/template/.claude/skills/yss-product-lifecycle/references/orchestration-contract.yaml +124 -16
  80. package/template/.claude/skills/yss-product-lifecycle/references/orchestration.md +16 -2
  81. package/template/.claude/skills/yss-product-lifecycle/references/state-model.md +5 -2
  82. package/template/.claude/skills/yss-repository/SKILL.md +28 -70
  83. package/template/.claude/skills/yss-repository/agents/openai.yaml +2 -2
  84. package/template/.claude/skills/yss-repository/references/profiles/layered-mvc-service.md +19 -1
  85. package/template/.claude/skills/yss-repository/references/profiles/mvc-data-analysis-v1.md +19 -1
  86. package/template/.claude/skills/yss-repository/references/profiles/target-domain-model.md +21 -1
  87. package/template/.claude/skills/yss-repository/tests/profile-routing.test.mjs +59 -0
  88. package/template/.claude/skills/yss-research/SKILL.md +1 -1
  89. package/template/.claude/skills/yss-skill-source-index-refresh/SKILL.md +8 -5
  90. package/template/.claude/skills/yss-skill-source-index-refresh/references/source-location.md +2 -1
  91. package/template/.claude/skills/yss-skill-source-index-refresh/scripts/refresh-yss-skill-index.mjs +388 -18
  92. package/template/.claude/skills/yss-skill-source-index-refresh/scripts/refresh-yss-skill-index.test.mjs +79 -1
  93. package/template/.claude/skills/yss-stage-decision/SKILL.md +5 -3
  94. package/template/.claude/skills/yss-stage-decision/references/stage-decision-package-contract.md +1 -1
  95. package/template/.codex/skills/code-review/SKILL.md +4 -0
  96. package/template/.codex/skills/code-review/agents/openai.yaml +1 -1
  97. package/template/.codex/skills/code-review/references/yss-review-standards.md +9 -2
  98. package/template/.codex/skills/competitive-intelligence/SKILL.md +4 -4
  99. package/template/.codex/skills/domain-modeling/CONTEXT-FORMAT.md +1 -1
  100. package/template/.codex/skills/grill-with-docs/SKILL.md +1 -1
  101. package/template/.codex/skills/setup-matt-pocock-skills/issue-tracker-local.md +1 -1
  102. package/template/.codex/skills/yss-ddd-scaffold-generator/SKILL.md +1 -1
  103. package/template/.codex/skills/yss-ddd-scaffold-generator/scripts/generate_scaffold.mjs +7 -3
  104. package/template/.codex/skills/yss-ddd-scaffold-generator/scripts/run_scaffold_verification.mjs +8 -8
  105. package/template/.codex/skills/yss-ddd-scaffold-generator/scripts/scaffold-generator.test.mjs +9 -0
  106. package/template/.codex/skills/yss-frontend-scaffold-generator/SKILL.md +10 -7
  107. package/template/.codex/skills/yss-frontend-scaffold-generator/scripts/generate_and_verify_scaffold.mjs +10 -0
  108. package/template/.codex/skills/yss-frontend-scaffold-generator/scripts/generate_scaffold.mjs +121 -0
  109. package/template/.codex/skills/yss-frontend-scaffold-generator/scripts/run_scaffold_verification.mjs +40 -0
  110. package/template/.codex/skills/yss-frontend-scaffold-generator/scripts/scaffold-generator.test.mjs +55 -0
  111. package/template/.codex/skills/yss-implementation-contract-compiler/SKILL.md +1 -1
  112. package/template/.codex/skills/yss-implementation-contract-compiler/references/boundaries.md +4 -0
  113. package/template/.codex/skills/yss-implementation-contract-compiler/references/compiler-contract.yaml +25 -0
  114. package/template/.codex/skills/yss-layered-mvc-scaffold-generator/SKILL.md +2 -2
  115. package/template/.codex/skills/yss-layered-mvc-scaffold-generator/scripts/generate_scaffold.mjs +8 -5
  116. package/template/.codex/skills/yss-layered-mvc-scaffold-generator/scripts/scaffold-generator.test.mjs +17 -2
  117. package/template/.codex/skills/yss-mybatis/SKILL.md +34 -58
  118. package/template/.codex/skills/yss-mybatis/agents/openai.yaml +2 -2
  119. package/template/.codex/skills/yss-mybatis/references/source-index.md +88 -68
  120. package/template/.codex/skills/yss-product-lifecycle/SKILL.md +50 -42
  121. package/template/.codex/skills/yss-product-lifecycle/references/artifact-dependencies.md +5 -3
  122. package/template/.codex/skills/yss-product-lifecycle/references/matt-yss-adapter.md +3 -3
  123. package/template/.codex/skills/yss-product-lifecycle/references/orchestration-contract.yaml +124 -16
  124. package/template/.codex/skills/yss-product-lifecycle/references/orchestration.md +16 -2
  125. package/template/.codex/skills/yss-product-lifecycle/references/state-model.md +5 -2
  126. package/template/.codex/skills/yss-repository/SKILL.md +28 -70
  127. package/template/.codex/skills/yss-repository/agents/openai.yaml +2 -2
  128. package/template/.codex/skills/yss-repository/references/profiles/layered-mvc-service.md +19 -1
  129. package/template/.codex/skills/yss-repository/references/profiles/mvc-data-analysis-v1.md +19 -1
  130. package/template/.codex/skills/yss-repository/references/profiles/target-domain-model.md +21 -1
  131. package/template/.codex/skills/yss-repository/tests/profile-routing.test.mjs +59 -0
  132. package/template/.codex/skills/yss-research/SKILL.md +1 -1
  133. package/template/.codex/skills/yss-skill-source-index-refresh/SKILL.md +8 -5
  134. package/template/.codex/skills/yss-skill-source-index-refresh/references/source-location.md +2 -1
  135. package/template/.codex/skills/yss-skill-source-index-refresh/scripts/refresh-yss-skill-index.mjs +388 -18
  136. package/template/.codex/skills/yss-skill-source-index-refresh/scripts/refresh-yss-skill-index.test.mjs +79 -1
  137. package/template/.codex/skills/yss-stage-decision/SKILL.md +5 -3
  138. package/template/.codex/skills/yss-stage-decision/references/stage-decision-package-contract.md +1 -1
  139. package/template/.cursor/skills/code-review/SKILL.md +4 -0
  140. package/template/.cursor/skills/code-review/agents/openai.yaml +1 -1
  141. package/template/.cursor/skills/code-review/references/yss-review-standards.md +9 -2
  142. package/template/.cursor/skills/competitive-intelligence/SKILL.md +4 -4
  143. package/template/.cursor/skills/domain-modeling/CONTEXT-FORMAT.md +1 -1
  144. package/template/.cursor/skills/grill-with-docs/SKILL.md +1 -1
  145. package/template/.cursor/skills/setup-matt-pocock-skills/issue-tracker-local.md +1 -1
  146. package/template/.cursor/skills/yss-ddd-scaffold-generator/SKILL.md +1 -1
  147. package/template/.cursor/skills/yss-ddd-scaffold-generator/scripts/generate_scaffold.mjs +7 -3
  148. package/template/.cursor/skills/yss-ddd-scaffold-generator/scripts/run_scaffold_verification.mjs +8 -8
  149. package/template/.cursor/skills/yss-ddd-scaffold-generator/scripts/scaffold-generator.test.mjs +9 -0
  150. package/template/.cursor/skills/yss-frontend-scaffold-generator/SKILL.md +10 -7
  151. package/template/.cursor/skills/yss-frontend-scaffold-generator/scripts/generate_and_verify_scaffold.mjs +10 -0
  152. package/template/.cursor/skills/yss-frontend-scaffold-generator/scripts/generate_scaffold.mjs +121 -0
  153. package/template/.cursor/skills/yss-frontend-scaffold-generator/scripts/run_scaffold_verification.mjs +40 -0
  154. package/template/.cursor/skills/yss-frontend-scaffold-generator/scripts/scaffold-generator.test.mjs +55 -0
  155. package/template/.cursor/skills/yss-implementation-contract-compiler/SKILL.md +1 -1
  156. package/template/.cursor/skills/yss-implementation-contract-compiler/references/boundaries.md +4 -0
  157. package/template/.cursor/skills/yss-implementation-contract-compiler/references/compiler-contract.yaml +25 -0
  158. package/template/.cursor/skills/yss-layered-mvc-scaffold-generator/SKILL.md +2 -2
  159. package/template/.cursor/skills/yss-layered-mvc-scaffold-generator/scripts/generate_scaffold.mjs +8 -5
  160. package/template/.cursor/skills/yss-layered-mvc-scaffold-generator/scripts/scaffold-generator.test.mjs +17 -2
  161. package/template/.cursor/skills/yss-mybatis/SKILL.md +34 -58
  162. package/template/.cursor/skills/yss-mybatis/agents/openai.yaml +2 -2
  163. package/template/.cursor/skills/yss-mybatis/references/source-index.md +88 -68
  164. package/template/.cursor/skills/yss-product-lifecycle/SKILL.md +50 -42
  165. package/template/.cursor/skills/yss-product-lifecycle/references/artifact-dependencies.md +5 -3
  166. package/template/.cursor/skills/yss-product-lifecycle/references/matt-yss-adapter.md +3 -3
  167. package/template/.cursor/skills/yss-product-lifecycle/references/orchestration-contract.yaml +124 -16
  168. package/template/.cursor/skills/yss-product-lifecycle/references/orchestration.md +16 -2
  169. package/template/.cursor/skills/yss-product-lifecycle/references/state-model.md +5 -2
  170. package/template/.cursor/skills/yss-repository/SKILL.md +28 -70
  171. package/template/.cursor/skills/yss-repository/agents/openai.yaml +2 -2
  172. package/template/.cursor/skills/yss-repository/references/profiles/layered-mvc-service.md +19 -1
  173. package/template/.cursor/skills/yss-repository/references/profiles/mvc-data-analysis-v1.md +19 -1
  174. package/template/.cursor/skills/yss-repository/references/profiles/target-domain-model.md +21 -1
  175. package/template/.cursor/skills/yss-repository/tests/profile-routing.test.mjs +59 -0
  176. package/template/.cursor/skills/yss-research/SKILL.md +1 -1
  177. package/template/.cursor/skills/yss-skill-source-index-refresh/SKILL.md +8 -5
  178. package/template/.cursor/skills/yss-skill-source-index-refresh/references/source-location.md +2 -1
  179. package/template/.cursor/skills/yss-skill-source-index-refresh/scripts/refresh-yss-skill-index.mjs +388 -18
  180. package/template/.cursor/skills/yss-skill-source-index-refresh/scripts/refresh-yss-skill-index.test.mjs +79 -1
  181. package/template/.cursor/skills/yss-stage-decision/SKILL.md +5 -3
  182. package/template/.cursor/skills/yss-stage-decision/references/stage-decision-package-contract.md +1 -1
  183. package/template/.pi/skills/code-review/SKILL.md +4 -0
  184. package/template/.pi/skills/code-review/agents/openai.yaml +1 -1
  185. package/template/.pi/skills/code-review/references/yss-review-standards.md +9 -2
  186. package/template/.pi/skills/competitive-intelligence/SKILL.md +4 -4
  187. package/template/.pi/skills/domain-modeling/CONTEXT-FORMAT.md +1 -1
  188. package/template/.pi/skills/grill-with-docs/SKILL.md +1 -1
  189. package/template/.pi/skills/setup-matt-pocock-skills/issue-tracker-local.md +1 -1
  190. package/template/.pi/skills/yss-ddd-scaffold-generator/SKILL.md +1 -1
  191. package/template/.pi/skills/yss-ddd-scaffold-generator/scripts/generate_scaffold.mjs +7 -3
  192. package/template/.pi/skills/yss-ddd-scaffold-generator/scripts/run_scaffold_verification.mjs +8 -8
  193. package/template/.pi/skills/yss-ddd-scaffold-generator/scripts/scaffold-generator.test.mjs +9 -0
  194. package/template/.pi/skills/yss-frontend-scaffold-generator/SKILL.md +10 -7
  195. package/template/.pi/skills/yss-frontend-scaffold-generator/scripts/generate_and_verify_scaffold.mjs +10 -0
  196. package/template/.pi/skills/yss-frontend-scaffold-generator/scripts/generate_scaffold.mjs +121 -0
  197. package/template/.pi/skills/yss-frontend-scaffold-generator/scripts/run_scaffold_verification.mjs +40 -0
  198. package/template/.pi/skills/yss-frontend-scaffold-generator/scripts/scaffold-generator.test.mjs +55 -0
  199. package/template/.pi/skills/yss-implementation-contract-compiler/SKILL.md +1 -1
  200. package/template/.pi/skills/yss-implementation-contract-compiler/references/boundaries.md +4 -0
  201. package/template/.pi/skills/yss-implementation-contract-compiler/references/compiler-contract.yaml +25 -0
  202. package/template/.pi/skills/yss-layered-mvc-scaffold-generator/SKILL.md +2 -2
  203. package/template/.pi/skills/yss-layered-mvc-scaffold-generator/scripts/generate_scaffold.mjs +8 -5
  204. package/template/.pi/skills/yss-layered-mvc-scaffold-generator/scripts/scaffold-generator.test.mjs +17 -2
  205. package/template/.pi/skills/yss-mybatis/SKILL.md +34 -58
  206. package/template/.pi/skills/yss-mybatis/agents/openai.yaml +2 -2
  207. package/template/.pi/skills/yss-mybatis/references/source-index.md +88 -68
  208. package/template/.pi/skills/yss-product-lifecycle/SKILL.md +50 -42
  209. package/template/.pi/skills/yss-product-lifecycle/references/artifact-dependencies.md +5 -3
  210. package/template/.pi/skills/yss-product-lifecycle/references/matt-yss-adapter.md +3 -3
  211. package/template/.pi/skills/yss-product-lifecycle/references/orchestration-contract.yaml +124 -16
  212. package/template/.pi/skills/yss-product-lifecycle/references/orchestration.md +16 -2
  213. package/template/.pi/skills/yss-product-lifecycle/references/state-model.md +5 -2
  214. package/template/.pi/skills/yss-repository/SKILL.md +28 -70
  215. package/template/.pi/skills/yss-repository/agents/openai.yaml +2 -2
  216. package/template/.pi/skills/yss-repository/references/profiles/layered-mvc-service.md +19 -1
  217. package/template/.pi/skills/yss-repository/references/profiles/mvc-data-analysis-v1.md +19 -1
  218. package/template/.pi/skills/yss-repository/references/profiles/target-domain-model.md +21 -1
  219. package/template/.pi/skills/yss-repository/tests/profile-routing.test.mjs +59 -0
  220. package/template/.pi/skills/yss-research/SKILL.md +1 -1
  221. package/template/.pi/skills/yss-skill-source-index-refresh/SKILL.md +8 -5
  222. package/template/.pi/skills/yss-skill-source-index-refresh/references/source-location.md +2 -1
  223. package/template/.pi/skills/yss-skill-source-index-refresh/scripts/refresh-yss-skill-index.mjs +388 -18
  224. package/template/.pi/skills/yss-skill-source-index-refresh/scripts/refresh-yss-skill-index.test.mjs +79 -1
  225. package/template/.pi/skills/yss-stage-decision/SKILL.md +5 -3
  226. package/template/.pi/skills/yss-stage-decision/references/stage-decision-package-contract.md +1 -1
  227. package/template/.qoder/skills/code-review/SKILL.md +4 -0
  228. package/template/.qoder/skills/code-review/agents/openai.yaml +1 -1
  229. package/template/.qoder/skills/code-review/references/yss-review-standards.md +9 -2
  230. package/template/.qoder/skills/competitive-intelligence/SKILL.md +4 -4
  231. package/template/.qoder/skills/domain-modeling/CONTEXT-FORMAT.md +1 -1
  232. package/template/.qoder/skills/grill-with-docs/SKILL.md +1 -1
  233. package/template/.qoder/skills/setup-matt-pocock-skills/issue-tracker-local.md +1 -1
  234. package/template/.qoder/skills/yss-ddd-scaffold-generator/SKILL.md +1 -1
  235. package/template/.qoder/skills/yss-ddd-scaffold-generator/scripts/generate_scaffold.mjs +7 -3
  236. package/template/.qoder/skills/yss-ddd-scaffold-generator/scripts/run_scaffold_verification.mjs +8 -8
  237. package/template/.qoder/skills/yss-ddd-scaffold-generator/scripts/scaffold-generator.test.mjs +9 -0
  238. package/template/.qoder/skills/yss-frontend-scaffold-generator/SKILL.md +10 -7
  239. package/template/.qoder/skills/yss-frontend-scaffold-generator/scripts/generate_and_verify_scaffold.mjs +10 -0
  240. package/template/.qoder/skills/yss-frontend-scaffold-generator/scripts/generate_scaffold.mjs +121 -0
  241. package/template/.qoder/skills/yss-frontend-scaffold-generator/scripts/run_scaffold_verification.mjs +40 -0
  242. package/template/.qoder/skills/yss-frontend-scaffold-generator/scripts/scaffold-generator.test.mjs +55 -0
  243. package/template/.qoder/skills/yss-implementation-contract-compiler/SKILL.md +1 -1
  244. package/template/.qoder/skills/yss-implementation-contract-compiler/references/boundaries.md +4 -0
  245. package/template/.qoder/skills/yss-implementation-contract-compiler/references/compiler-contract.yaml +25 -0
  246. package/template/.qoder/skills/yss-layered-mvc-scaffold-generator/SKILL.md +2 -2
  247. package/template/.qoder/skills/yss-layered-mvc-scaffold-generator/scripts/generate_scaffold.mjs +8 -5
  248. package/template/.qoder/skills/yss-layered-mvc-scaffold-generator/scripts/scaffold-generator.test.mjs +17 -2
  249. package/template/.qoder/skills/yss-mybatis/SKILL.md +34 -58
  250. package/template/.qoder/skills/yss-mybatis/agents/openai.yaml +2 -2
  251. package/template/.qoder/skills/yss-mybatis/references/source-index.md +88 -68
  252. package/template/.qoder/skills/yss-product-lifecycle/SKILL.md +50 -42
  253. package/template/.qoder/skills/yss-product-lifecycle/references/artifact-dependencies.md +5 -3
  254. package/template/.qoder/skills/yss-product-lifecycle/references/matt-yss-adapter.md +3 -3
  255. package/template/.qoder/skills/yss-product-lifecycle/references/orchestration-contract.yaml +124 -16
  256. package/template/.qoder/skills/yss-product-lifecycle/references/orchestration.md +16 -2
  257. package/template/.qoder/skills/yss-product-lifecycle/references/state-model.md +5 -2
  258. package/template/.qoder/skills/yss-repository/SKILL.md +28 -70
  259. package/template/.qoder/skills/yss-repository/agents/openai.yaml +2 -2
  260. package/template/.qoder/skills/yss-repository/references/profiles/layered-mvc-service.md +19 -1
  261. package/template/.qoder/skills/yss-repository/references/profiles/mvc-data-analysis-v1.md +19 -1
  262. package/template/.qoder/skills/yss-repository/references/profiles/target-domain-model.md +21 -1
  263. package/template/.qoder/skills/yss-repository/tests/profile-routing.test.mjs +59 -0
  264. package/template/.qoder/skills/yss-research/SKILL.md +1 -1
  265. package/template/.qoder/skills/yss-skill-source-index-refresh/SKILL.md +8 -5
  266. package/template/.qoder/skills/yss-skill-source-index-refresh/references/source-location.md +2 -1
  267. package/template/.qoder/skills/yss-skill-source-index-refresh/scripts/refresh-yss-skill-index.mjs +388 -18
  268. package/template/.qoder/skills/yss-skill-source-index-refresh/scripts/refresh-yss-skill-index.test.mjs +79 -1
  269. package/template/.qoder/skills/yss-stage-decision/SKILL.md +5 -3
  270. package/template/.qoder/skills/yss-stage-decision/references/stage-decision-package-contract.md +1 -1
  271. package/template/.trae/skills/code-review/SKILL.md +4 -0
  272. package/template/.trae/skills/code-review/agents/openai.yaml +1 -1
  273. package/template/.trae/skills/code-review/references/yss-review-standards.md +9 -2
  274. package/template/.trae/skills/competitive-intelligence/SKILL.md +4 -4
  275. package/template/.trae/skills/domain-modeling/CONTEXT-FORMAT.md +1 -1
  276. package/template/.trae/skills/grill-with-docs/SKILL.md +1 -1
  277. package/template/.trae/skills/setup-matt-pocock-skills/issue-tracker-local.md +1 -1
  278. package/template/.trae/skills/yss-ddd-scaffold-generator/SKILL.md +1 -1
  279. package/template/.trae/skills/yss-ddd-scaffold-generator/scripts/generate_scaffold.mjs +7 -3
  280. package/template/.trae/skills/yss-ddd-scaffold-generator/scripts/run_scaffold_verification.mjs +8 -8
  281. package/template/.trae/skills/yss-ddd-scaffold-generator/scripts/scaffold-generator.test.mjs +9 -0
  282. package/template/.trae/skills/yss-frontend-scaffold-generator/SKILL.md +10 -7
  283. package/template/.trae/skills/yss-frontend-scaffold-generator/scripts/generate_and_verify_scaffold.mjs +10 -0
  284. package/template/.trae/skills/yss-frontend-scaffold-generator/scripts/generate_scaffold.mjs +121 -0
  285. package/template/.trae/skills/yss-frontend-scaffold-generator/scripts/run_scaffold_verification.mjs +40 -0
  286. package/template/.trae/skills/yss-frontend-scaffold-generator/scripts/scaffold-generator.test.mjs +55 -0
  287. package/template/.trae/skills/yss-implementation-contract-compiler/SKILL.md +1 -1
  288. package/template/.trae/skills/yss-implementation-contract-compiler/references/boundaries.md +4 -0
  289. package/template/.trae/skills/yss-implementation-contract-compiler/references/compiler-contract.yaml +25 -0
  290. package/template/.trae/skills/yss-layered-mvc-scaffold-generator/SKILL.md +2 -2
  291. package/template/.trae/skills/yss-layered-mvc-scaffold-generator/scripts/generate_scaffold.mjs +8 -5
  292. package/template/.trae/skills/yss-layered-mvc-scaffold-generator/scripts/scaffold-generator.test.mjs +17 -2
  293. package/template/.trae/skills/yss-mybatis/SKILL.md +34 -58
  294. package/template/.trae/skills/yss-mybatis/agents/openai.yaml +2 -2
  295. package/template/.trae/skills/yss-mybatis/references/source-index.md +88 -68
  296. package/template/.trae/skills/yss-product-lifecycle/SKILL.md +50 -42
  297. package/template/.trae/skills/yss-product-lifecycle/references/artifact-dependencies.md +5 -3
  298. package/template/.trae/skills/yss-product-lifecycle/references/matt-yss-adapter.md +3 -3
  299. package/template/.trae/skills/yss-product-lifecycle/references/orchestration-contract.yaml +124 -16
  300. package/template/.trae/skills/yss-product-lifecycle/references/orchestration.md +16 -2
  301. package/template/.trae/skills/yss-product-lifecycle/references/state-model.md +5 -2
  302. package/template/.trae/skills/yss-repository/SKILL.md +28 -70
  303. package/template/.trae/skills/yss-repository/agents/openai.yaml +2 -2
  304. package/template/.trae/skills/yss-repository/references/profiles/layered-mvc-service.md +19 -1
  305. package/template/.trae/skills/yss-repository/references/profiles/mvc-data-analysis-v1.md +19 -1
  306. package/template/.trae/skills/yss-repository/references/profiles/target-domain-model.md +21 -1
  307. package/template/.trae/skills/yss-repository/tests/profile-routing.test.mjs +59 -0
  308. package/template/.trae/skills/yss-research/SKILL.md +1 -1
  309. package/template/.trae/skills/yss-skill-source-index-refresh/SKILL.md +8 -5
  310. package/template/.trae/skills/yss-skill-source-index-refresh/references/source-location.md +2 -1
  311. package/template/.trae/skills/yss-skill-source-index-refresh/scripts/refresh-yss-skill-index.mjs +388 -18
  312. package/template/.trae/skills/yss-skill-source-index-refresh/scripts/refresh-yss-skill-index.test.mjs +79 -1
  313. package/template/.trae/skills/yss-stage-decision/SKILL.md +5 -3
  314. package/template/.trae/skills/yss-stage-decision/references/stage-decision-package-contract.md +1 -1
  315. package/template/AGENTS.md +2 -2
  316. package/template/CONTEXT.md +3 -2
  317. package/template/README.md +3 -3
  318. package/template/docs/agents/digital-human-roles.md +1 -1
  319. package/template/docs/agents/digital-human-roles.yaml +13 -11
  320. package/template/docs/agents/issue-tracker.md +1 -1
  321. package/template/docs/agents/strategic-design-skills-integration.md +2 -0
  322. package/template/docs/agents/yss-skill-registry.yaml +5 -0
  323. package/template/docs/architecture/README.md +1 -1
  324. package/template/docs/architecture/templates/business-architecture-template.md +1 -1
  325. package/template/docs/architecture/templates/functional-architecture-template.md +1 -1
  326. package/template/docs/design/README.md +1 -1
  327. package/template/docs/design/templates/interaction-spec-template.md +1 -1
  328. package/template/docs/design/templates/product-overview-design-template.md +1 -1
  329. package/template/docs/{discovery → plan}/IDEATION.md +5 -5
  330. package/template/docs/plan/README.md +9 -0
  331. package/template/docs/plan/entry-review.md +23 -0
  332. package/template/docs/plan/templates/plan-template.md +58 -0
  333. package/template/docs/process/harness-process-tailoring.md +1 -1
  334. package/template/docs/process/lifecycle-artifact-map.md +10 -6
  335. package/template/docs/process/lifecycle-registry-baseline.json +10 -1
  336. package/template/docs/process/lifecycle-registry.yaml +48 -20
  337. package/template/docs/process/plan-migration.md +13 -0
  338. package/template/docs/process/schemas/digital-human-task-package.schema.json +2 -0
  339. package/template/docs/process/schemas/implementation-repository-preparation-result.schema.json +38 -0
  340. package/template/docs/process/schemas/lifecycle-checkpoint.schema.json +3 -0
  341. package/template/docs/process/schemas/lifecycle-registry.schema.json +1 -1
  342. package/template/docs/process/schemas/project-scaffold-contract.schema.json +113 -0
  343. package/template/docs/process/template-engineering-overview.md +2 -2
  344. package/template/docs/process/template-verification-profiles.yaml +25 -0
  345. package/template/docs/process/templates/context-reconciliation-template.yaml +2 -2
  346. package/template/docs/process/templates/lifecycle-checkpoint-template.yaml +1 -1
  347. package/template/docs/requirements/README.md +2 -2
  348. package/template/docs/templates/implementation-repo-registry-template.md +8 -0
  349. package/template/docs/templates/local-parent-ticket-template.md +1 -1
  350. package/template/docs/templates/review-report-template.md +7 -3
  351. package/template/docs/templates/subagent-task-package-template.md +1 -1
  352. package/template/docs/user-guide//347/224/250/346/210/267/346/211/213/345/206/214.md +1 -1
  353. package/template/scripts/cache-template-commit +2 -2
  354. package/template/scripts/fixtures/strategic-handoff/source-roles.json +7 -7
  355. package/template/scripts/fixtures/user-decision/plan-fixture.mjs +30 -0
  356. package/template/scripts/lib/backend-delivery.mjs +5 -2
  357. package/template/scripts/lib/command-runner.mjs +107 -0
  358. package/template/scripts/lib/context-reconciliation.mjs +34 -0
  359. package/template/scripts/lib/json-schema.mjs +42 -13
  360. package/template/scripts/lib/lifecycle-context-query.mjs +141 -0
  361. package/template/scripts/lib/lifecycle-transition.mjs +118 -6
  362. package/template/scripts/lib/plan-spec-entry.mjs +87 -0
  363. package/template/scripts/lib/scenario-checks.mjs +44 -38
  364. package/template/scripts/lib/skill-registry.mjs +9 -0
  365. package/template/scripts/lib/skill-supply-chain.mjs +18 -2
  366. package/template/scripts/lib/strategic-handoff-io.mjs +5 -4
  367. package/template/scripts/lib/strategic-handoff.mjs +10 -9
  368. package/template/scripts/lib/task-package.mjs +2 -0
  369. package/template/scripts/lib/template-commit-cache.mjs +7 -5
  370. package/template/scripts/query-lifecycle-context +25 -0
  371. package/template/scripts/run-template-verification +9 -3
  372. package/template/scripts/sync-strategic-handoff-tools +9 -0
  373. package/template/scripts/verify-business-language-scenarios +0 -7
  374. package/template/scripts/verify-context-reconciliation +2 -48
  375. package/template/scripts/verify-context-reconciliation-scenarios +1 -1
  376. package/template/scripts/verify-frontend-scaffold-generator-scenarios +2 -0
  377. package/template/scripts/verify-lifecycle-checkpoint +2 -0
  378. package/template/scripts/verify-lifecycle-context-query-scenarios +88 -0
  379. package/template/scripts/verify-lifecycle-transition-scenarios +44 -4
  380. package/template/scripts/verify-plan-spec-entry +11 -0
  381. package/template/scripts/verify-plan-spec-entry-scenarios +79 -0
  382. package/template/scripts/verify-script-performance-scenarios +56 -0
  383. package/template/scripts/verify-subagent-task-package-scenarios +9 -8
  384. package/template/scripts/verify-template-cache-scenarios +11 -1
  385. package/template/scripts/verify-user-decision-scenarios +4 -4
  386. package/template/skills-lock.json +23 -23
  387. package/template.manifest.json +2 -1
  388. package/template.snapshot.json +5 -5
  389. package/template/.agents/skills/yss-mybatis/assets/BaseRepository.java +0 -112
  390. package/template/.agents/skills/yss-mybatis/assets/EntityQueryAspect.java +0 -37
  391. package/template/.agents/skills/yss-mybatis/assets/MybatisBaseConfiguration.java +0 -18
  392. package/template/.agents/skills/yss-mybatis/assets/PageQueryEntityConfigration.java +0 -18
  393. package/template/.agents/skills/yss-mybatis/references/README.md +0 -57
  394. package/template/.agents/skills/yss-repository/references/infrastructure-layer-guide.md +0 -107
  395. package/template/.claude/skills/yss-mybatis/assets/BaseRepository.java +0 -112
  396. package/template/.claude/skills/yss-mybatis/assets/EntityQueryAspect.java +0 -37
  397. package/template/.claude/skills/yss-mybatis/assets/MybatisBaseConfiguration.java +0 -18
  398. package/template/.claude/skills/yss-mybatis/assets/PageQueryEntityConfigration.java +0 -18
  399. package/template/.claude/skills/yss-mybatis/references/README.md +0 -57
  400. package/template/.claude/skills/yss-repository/references/infrastructure-layer-guide.md +0 -107
  401. package/template/.codex/skills/yss-mybatis/assets/BaseRepository.java +0 -112
  402. package/template/.codex/skills/yss-mybatis/assets/EntityQueryAspect.java +0 -37
  403. package/template/.codex/skills/yss-mybatis/assets/MybatisBaseConfiguration.java +0 -18
  404. package/template/.codex/skills/yss-mybatis/assets/PageQueryEntityConfigration.java +0 -18
  405. package/template/.codex/skills/yss-mybatis/references/README.md +0 -57
  406. package/template/.codex/skills/yss-repository/references/infrastructure-layer-guide.md +0 -107
  407. package/template/.cursor/skills/yss-mybatis/assets/BaseRepository.java +0 -112
  408. package/template/.cursor/skills/yss-mybatis/assets/EntityQueryAspect.java +0 -37
  409. package/template/.cursor/skills/yss-mybatis/assets/MybatisBaseConfiguration.java +0 -18
  410. package/template/.cursor/skills/yss-mybatis/assets/PageQueryEntityConfigration.java +0 -18
  411. package/template/.cursor/skills/yss-mybatis/references/README.md +0 -57
  412. package/template/.cursor/skills/yss-repository/references/infrastructure-layer-guide.md +0 -107
  413. package/template/.pi/skills/yss-mybatis/assets/BaseRepository.java +0 -112
  414. package/template/.pi/skills/yss-mybatis/assets/EntityQueryAspect.java +0 -37
  415. package/template/.pi/skills/yss-mybatis/assets/MybatisBaseConfiguration.java +0 -18
  416. package/template/.pi/skills/yss-mybatis/assets/PageQueryEntityConfigration.java +0 -18
  417. package/template/.pi/skills/yss-mybatis/references/README.md +0 -57
  418. package/template/.pi/skills/yss-repository/references/infrastructure-layer-guide.md +0 -107
  419. package/template/.qoder/skills/yss-mybatis/assets/BaseRepository.java +0 -112
  420. package/template/.qoder/skills/yss-mybatis/assets/EntityQueryAspect.java +0 -37
  421. package/template/.qoder/skills/yss-mybatis/assets/MybatisBaseConfiguration.java +0 -18
  422. package/template/.qoder/skills/yss-mybatis/assets/PageQueryEntityConfigration.java +0 -18
  423. package/template/.qoder/skills/yss-mybatis/references/README.md +0 -57
  424. package/template/.qoder/skills/yss-repository/references/infrastructure-layer-guide.md +0 -107
  425. package/template/.trae/skills/yss-mybatis/assets/BaseRepository.java +0 -112
  426. package/template/.trae/skills/yss-mybatis/assets/EntityQueryAspect.java +0 -37
  427. package/template/.trae/skills/yss-mybatis/assets/MybatisBaseConfiguration.java +0 -18
  428. package/template/.trae/skills/yss-mybatis/assets/PageQueryEntityConfigration.java +0 -18
  429. package/template/.trae/skills/yss-mybatis/references/README.md +0 -57
  430. package/template/.trae/skills/yss-repository/references/infrastructure-layer-guide.md +0 -107
  431. package/template/docs/discovery/README.md +0 -87
  432. package/template/docs/discovery/reports/.gitkeep +0 -0
  433. package/template/docs/discovery/reports/agent-governance-options.md +0 -71
  434. package/template/docs/discovery/reports/competitor-deep-dive/.gitkeep +0 -0
  435. package/template/docs/discovery/templates/discovery-template.md +0 -94
  436. /package/template/docs/{discovery → plan}/templates/competitive-analysis-template.md +0 -0
  437. /package/template/docs/{discovery → plan}/templates/competitive-matrix-template.md +0 -0
  438. /package/template/docs/{discovery → plan}/templates/market-analysis-template.md +0 -0
  439. /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
+ }
@@ -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
- - 原型确认后若 backend `scaffold_status=required`,必须先读取工程基线中的 `scaffold-architecture-decisions.yaml`。编译器按已达到 `lifecycle-approved` 且 digest 当前的选择,把 `domain-driven` 解析为 `backend.ddd-scaffold` / `yss-ddd-scaffold-generator`,把 `layered-mvc` 解析为 `backend.mvc-scaffold` / `yss-layered-mvc-scaffold-generator`;处于 `undecided`、`recommended`、`awaiting-user-decision` 或 `stale` 时返回 `blocked`,不得默认 DDD。随后按 `scaffold_contract_schema` v3 编译 `controlled-generation` 工作单元合同 draft;合同必须带选择引用与 digest、`generator_skill`、Profile、能力模块闭包、批准/持久化引用、允许写路径、预期证据和验证命令。经生命周期批准并持久化后才能运行对应生成器,再由受控工作单元实际执行固定的 `./mvnw validate`、`./mvnw test`、`./mvnw package` 并记录逐条结果,随后重新编译业务合同;脚手架不承载业务行为。
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` 必须阻断或重路由。
@@ -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` 已编译 scaffold contract schema v3,生命周期已批准并持久化。
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
- - 只接受 scaffold contract schema v3 和 Manifest schema v3;历史 v2 只读兼容,不用于新生成。
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/` 为输出父容器;外部实现仓库使用已登记真实路径。
@@ -1,5 +1,5 @@
1
1
  #!/usr/bin/env node
2
- /** 依据生命周期批准的 schema v3 合同生成纯机械 YSS 分层 MVC 后端骨架。 */
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 !== 3) fail(`unsupported: 新生成只接受 scaffold contract schema v3,收到 v${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 v3 合同生成。模块:${modules.join("、")}。不包含业务 API、SQL 或生产数据库绑定。\n\n本地运行需同时显式启用 Maven -Pscaffold-local 和 Spring scaffold-local Profile;测试独立使用 H2。生产数据库须由后续已批准存储工作单元接入。`);
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: 3,
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: 3,
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 与 MyBatis-Plus 持久层规范、配置和排障。当用户提到 BaseRepository、BasePlusRepository、PageQuery 自动分页、多数据源、批量插入或 MyBatis 配置异常时调用。
3
+ description: 用于 YSS MyBatis / MyBatis-Plus 组件能力核验、接入决策和排障;涉及 Mapper/Repository 基类、分页、批量 SQL、扫描配置或数据源能力时使用,不负责生成持久层结构。
4
4
  ---
5
5
 
6
6
  # yss-mybatis
7
7
 
8
- 用于处理 `yss-component-persistence` 相关的持久层规范、接入和问题定位。
8
+ 本 Skill 只维护 `yss-component-persistence` 的组件能力、选择条件和排障顺序。PO、Repository、Convertor、Gateway/Query Adapter 的结构与生成边界由 `yss-repository` 负责。
9
9
 
10
- ## 何时使用
10
+ ## 入口与前置
11
11
 
12
- - 用户要定义新的 Repository。
13
- - 用户在 MyBatis 与 MyBatis-Plus 两种模式间排查问题。
14
- - 用户提到自动分页、`PageQuery`、批量插入、多数据源。
15
- - 用户反馈 Mapper 扫描、分页不生效、批量性能差。
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
- 1. 先读取批准的 `persistence_profile` 和 `architecture_identity`。新 DDD / MVC scaffold 都使用 `mybatis-plus`;普通 MyBatis 必须有独立 fixture 和批准 Profile,禁止自动猜测或混用。模块所有权按 `docs/agents/backend-architecture-profiles.md`;H2 仅用于本地/测试,生产数据库另行批准接入。
20
- 2. 涉及真实类名、配置项、模块依赖或排障时,先读 `references/source-index.md`,再定位源码或文档。
21
- 3. 先复用现有基类与配置,不手搓新的基础设施。
22
- 4. 涉及分页时,先验证 `PageQuery` 传递链路和拦截器是否生效。
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
- - 源码位置不要假设固定目录;先按 `yss-skill-source-index-refresh/references/source-location.md` 定位。
27
- - 当前技能索引:`references/source-index.md`
28
- - 重点源码入口通常包括 `BaseRepository`、`BasePlusRepository`、`EntityQueryAspect`、`PageQueryEntityConfigration`、`MybatisBaseConfiguration`、`MybatisPlusConfiguration`、`MultiDataSourceConfiguration`、`MultiDataSourceHolder`。
29
-
30
- 当组件源码变化后,用 `yss-skill-source-index-refresh` 刷新索引;刷新或读取前先按源码定位策略确认真实位置。
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. 确认依赖模块:starter、mapper、plus starter、persistence common。
54
- 2. 确认 Mapper/Repository 扫描范围。
55
- 3. 确认分页参数、分页切面或插件是否参与调用。
56
- 4. 确认 XML、方法签名、resultMap/字段映射是否一致。
57
- 5. 确认多数据源配置和当前线程数据源上下文。
58
- 6. 最后再排查 SQL 本身和数据库执行计划。
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
- - 源码索引:`references/source-index.md`
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
- ## 阶段 7 合同
49
+ ## 结果与验证
74
50
 
75
- - 仅在数据架构、Repository 策略和批准合同明确时使用。
76
- - Mapper/XML 骨架可受控生成;查询语义、分页、数据源切换和事务行为使用 `behavior-tdd`。
77
- - 按统一 `YSS Skill Execution Result` 返回 Mapper/XML/配置、集成测试、实际 `./mvnw ...` 结果和新增 SQL/DDL/索引影响。
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 implement or debug YSS MyBatis repositories, pagination, and multi-datasource access."
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."