create-yss-spec 3.1.0 → 3.2.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.
Files changed (302) hide show
  1. package/README.md +119 -89
  2. package/bin/create-yss-spec.js +11 -3
  3. package/package.json +9 -2
  4. package/src/api/_sync-service.js +191 -0
  5. package/src/api/index.js +22 -0
  6. package/src/api/project-diff.js +9 -0
  7. package/src/api/project-doctor.js +10 -0
  8. package/src/api/template-apply.js +10 -0
  9. package/src/api/template-plan.js +9 -0
  10. package/src/cli/args.js +60 -0
  11. package/src/cli/error-output.js +52 -0
  12. package/src/cli/flags.js +9 -0
  13. package/src/cli/help.js +95 -0
  14. package/src/cli/index.js +82 -0
  15. package/src/cli/plan-output.js +61 -0
  16. package/src/cli/prompts.js +91 -0
  17. package/src/cli/router.js +41 -0
  18. package/src/cli.js +5 -2253
  19. package/src/commands/attach.js +280 -0
  20. package/src/commands/diff.js +23 -0
  21. package/src/commands/doctor.js +417 -0
  22. package/src/commands/init.js +193 -0
  23. package/src/commands/sync.js +146 -0
  24. package/src/commands/update.js +14 -0
  25. package/src/contracts/apply-result-v1.json +45 -0
  26. package/src/contracts/customization-policy-v1.json +28 -0
  27. package/src/contracts/doctor-report-v1.json +29 -0
  28. package/src/contracts/error-envelope-v1.json +24 -0
  29. package/src/contracts/generator-policy-v1.json +24 -0
  30. package/src/contracts/ownership-policy-v1.json +40 -0
  31. package/src/contracts/plan-schema-v1.json +115 -0
  32. package/src/family-identity.js +365 -0
  33. package/src/family-runtime.js +23 -0
  34. package/src/filesystem/apply-plan.js +44 -0
  35. package/src/filesystem/copy-path.js +28 -0
  36. package/src/filesystem/path-utils.js +67 -0
  37. package/src/filesystem/transaction-runner.js +41 -0
  38. package/src/filesystem/transaction.js +153 -0
  39. package/src/git/submodule.js +115 -0
  40. package/src/git/worktree.js +69 -0
  41. package/src/template/attach-planner-runtime.js +51 -0
  42. package/src/template/attach-planner.js +160 -0
  43. package/src/template/instance-runtime.js +463 -0
  44. package/src/template/lifecycle-metadata.js +99 -0
  45. package/src/template/lifecycle-policy.js +129 -0
  46. package/src/template/lifecycle-runtime.js +90 -0
  47. package/src/template/migration-planner.js +95 -0
  48. package/src/template/migration-runtime.js +247 -0
  49. package/src/template/ownership-metadata.js +79 -0
  50. package/src/template/ownership-policy.js +149 -0
  51. package/src/template/ownership-runtime.js +109 -0
  52. package/src/template/plan-schema.js +36 -0
  53. package/src/template/sync-planner-runtime.js +57 -0
  54. package/src/template/sync-planner.js +206 -0
  55. package/src/template/verification-runtime.js +154 -0
  56. package/src/validation/identity.js +41 -0
  57. package/src/validation/metadata.js +105 -0
  58. package/src/validation/security.js +67 -0
  59. package/src/validation/snapshot.js +47 -0
  60. package/template/.agents/skills/.strategic-design-skills-manifest.json +1 -1
  61. package/template/.agents/skills/yss-domain/SKILL.md +3 -3
  62. package/template/.agents/skills/yss-frontend-scaffold-generator/SKILL.md +2 -0
  63. package/template/.agents/skills/yss-implementation-contract-compiler/SKILL.md +4 -2
  64. package/template/.agents/skills/yss-implementation-contract-compiler/references/boundaries.md +5 -0
  65. package/template/.agents/skills/yss-implementation-contract-compiler/references/compiler-contract.yaml +16 -2
  66. package/template/.agents/skills/yss-implementation-contract-compiler/references/slice-implementation-contract.md +10 -1
  67. package/template/.agents/skills/yss-mvc-design/SKILL.md +16 -0
  68. package/template/.agents/skills/yss-mvc-design/agents/openai.yaml +4 -0
  69. package/template/.agents/skills/yss-mvc-design/references/mvc-design.schema.json +315 -0
  70. package/template/.agents/skills/yss-product-lifecycle/SKILL.md +4 -2
  71. package/template/.agents/skills/yss-product-lifecycle/references/artifact-dependencies.md +2 -2
  72. package/template/.agents/skills/yss-product-lifecycle/references/orchestration-contract.yaml +14 -9
  73. package/template/.agents/skills/yss-product-lifecycle/references/orchestration.md +1 -1
  74. package/template/.agents/skills/yss-product-lifecycle/references/state-model.md +1 -1
  75. package/template/.agents/skills/yss-tactical-design/SKILL.md +2 -2
  76. package/template/.agents/skills/yss-tactical-design/references/output-template.md +2 -0
  77. package/template/.agents/skills/yss-tactical-design/references/tactical-design-contract.md +3 -1
  78. package/template/.agents/skills/yss-tactical-design/scripts/validate-tactical-design.mjs +3 -2
  79. package/template/.agents/skills/yss-technical-design/SKILL.md +31 -0
  80. package/template/.agents/skills/yss-technical-design/agents/openai.yaml +4 -0
  81. package/template/.agents/skills/yss-technical-design/references/technical-design-common.schema.json +290 -0
  82. package/template/.agents/skills/yss-technical-design/references/technical-design-contract.md +31 -0
  83. package/template/.agents/skills/yss-technical-design/references/technical-design.schema.json +759 -0
  84. package/template/.agents/skills/yss-technical-design/scripts/generate-schema.mjs +20 -0
  85. package/template/.agents/skills/yss-technical-design/scripts/validate-technical-design.mjs +134 -0
  86. package/template/.agents/skills/yss-technical-design/tests/fixtures.mjs +32 -0
  87. package/template/.agents/skills/yss-technical-design/tests/run-scenarios.mjs +82 -0
  88. package/template/.agents/skills/yss-ui/SKILL.md +2 -0
  89. package/template/.claude/skills/yss-domain/SKILL.md +3 -3
  90. package/template/.claude/skills/yss-frontend-scaffold-generator/SKILL.md +2 -0
  91. package/template/.claude/skills/yss-implementation-contract-compiler/SKILL.md +4 -2
  92. package/template/.claude/skills/yss-implementation-contract-compiler/references/boundaries.md +5 -0
  93. package/template/.claude/skills/yss-implementation-contract-compiler/references/compiler-contract.yaml +16 -2
  94. package/template/.claude/skills/yss-implementation-contract-compiler/references/slice-implementation-contract.md +10 -1
  95. package/template/.claude/skills/yss-mvc-design/SKILL.md +16 -0
  96. package/template/.claude/skills/yss-mvc-design/agents/openai.yaml +4 -0
  97. package/template/.claude/skills/yss-mvc-design/references/mvc-design.schema.json +315 -0
  98. package/template/.claude/skills/yss-product-lifecycle/SKILL.md +4 -2
  99. package/template/.claude/skills/yss-product-lifecycle/references/artifact-dependencies.md +2 -2
  100. package/template/.claude/skills/yss-product-lifecycle/references/orchestration-contract.yaml +14 -9
  101. package/template/.claude/skills/yss-product-lifecycle/references/orchestration.md +1 -1
  102. package/template/.claude/skills/yss-product-lifecycle/references/state-model.md +1 -1
  103. package/template/.claude/skills/yss-tactical-design/SKILL.md +2 -2
  104. package/template/.claude/skills/yss-tactical-design/references/output-template.md +2 -0
  105. package/template/.claude/skills/yss-tactical-design/references/tactical-design-contract.md +3 -1
  106. package/template/.claude/skills/yss-tactical-design/scripts/validate-tactical-design.mjs +3 -2
  107. package/template/.claude/skills/yss-technical-design/SKILL.md +31 -0
  108. package/template/.claude/skills/yss-technical-design/agents/openai.yaml +4 -0
  109. package/template/.claude/skills/yss-technical-design/references/technical-design-common.schema.json +290 -0
  110. package/template/.claude/skills/yss-technical-design/references/technical-design-contract.md +31 -0
  111. package/template/.claude/skills/yss-technical-design/references/technical-design.schema.json +759 -0
  112. package/template/.claude/skills/yss-technical-design/scripts/generate-schema.mjs +20 -0
  113. package/template/.claude/skills/yss-technical-design/scripts/validate-technical-design.mjs +134 -0
  114. package/template/.claude/skills/yss-technical-design/tests/fixtures.mjs +32 -0
  115. package/template/.claude/skills/yss-technical-design/tests/run-scenarios.mjs +82 -0
  116. package/template/.claude/skills/yss-ui/SKILL.md +2 -0
  117. package/template/.codex/skills/yss-domain/SKILL.md +3 -3
  118. package/template/.codex/skills/yss-frontend-scaffold-generator/SKILL.md +2 -0
  119. package/template/.codex/skills/yss-implementation-contract-compiler/SKILL.md +4 -2
  120. package/template/.codex/skills/yss-implementation-contract-compiler/references/boundaries.md +5 -0
  121. package/template/.codex/skills/yss-implementation-contract-compiler/references/compiler-contract.yaml +16 -2
  122. package/template/.codex/skills/yss-implementation-contract-compiler/references/slice-implementation-contract.md +10 -1
  123. package/template/.codex/skills/yss-mvc-design/SKILL.md +16 -0
  124. package/template/.codex/skills/yss-mvc-design/agents/openai.yaml +4 -0
  125. package/template/.codex/skills/yss-mvc-design/references/mvc-design.schema.json +315 -0
  126. package/template/.codex/skills/yss-product-lifecycle/SKILL.md +4 -2
  127. package/template/.codex/skills/yss-product-lifecycle/references/artifact-dependencies.md +2 -2
  128. package/template/.codex/skills/yss-product-lifecycle/references/orchestration-contract.yaml +14 -9
  129. package/template/.codex/skills/yss-product-lifecycle/references/orchestration.md +1 -1
  130. package/template/.codex/skills/yss-product-lifecycle/references/state-model.md +1 -1
  131. package/template/.codex/skills/yss-tactical-design/SKILL.md +2 -2
  132. package/template/.codex/skills/yss-tactical-design/references/output-template.md +2 -0
  133. package/template/.codex/skills/yss-tactical-design/references/tactical-design-contract.md +3 -1
  134. package/template/.codex/skills/yss-tactical-design/scripts/validate-tactical-design.mjs +3 -2
  135. package/template/.codex/skills/yss-technical-design/SKILL.md +31 -0
  136. package/template/.codex/skills/yss-technical-design/agents/openai.yaml +4 -0
  137. package/template/.codex/skills/yss-technical-design/references/technical-design-common.schema.json +290 -0
  138. package/template/.codex/skills/yss-technical-design/references/technical-design-contract.md +31 -0
  139. package/template/.codex/skills/yss-technical-design/references/technical-design.schema.json +759 -0
  140. package/template/.codex/skills/yss-technical-design/scripts/generate-schema.mjs +20 -0
  141. package/template/.codex/skills/yss-technical-design/scripts/validate-technical-design.mjs +134 -0
  142. package/template/.codex/skills/yss-technical-design/tests/fixtures.mjs +32 -0
  143. package/template/.codex/skills/yss-technical-design/tests/run-scenarios.mjs +82 -0
  144. package/template/.codex/skills/yss-ui/SKILL.md +2 -0
  145. package/template/.cursor/skills/yss-domain/SKILL.md +3 -3
  146. package/template/.cursor/skills/yss-frontend-scaffold-generator/SKILL.md +2 -0
  147. package/template/.cursor/skills/yss-implementation-contract-compiler/SKILL.md +4 -2
  148. package/template/.cursor/skills/yss-implementation-contract-compiler/references/boundaries.md +5 -0
  149. package/template/.cursor/skills/yss-implementation-contract-compiler/references/compiler-contract.yaml +16 -2
  150. package/template/.cursor/skills/yss-implementation-contract-compiler/references/slice-implementation-contract.md +10 -1
  151. package/template/.cursor/skills/yss-mvc-design/SKILL.md +16 -0
  152. package/template/.cursor/skills/yss-mvc-design/agents/openai.yaml +4 -0
  153. package/template/.cursor/skills/yss-mvc-design/references/mvc-design.schema.json +315 -0
  154. package/template/.cursor/skills/yss-product-lifecycle/SKILL.md +4 -2
  155. package/template/.cursor/skills/yss-product-lifecycle/references/artifact-dependencies.md +2 -2
  156. package/template/.cursor/skills/yss-product-lifecycle/references/orchestration-contract.yaml +14 -9
  157. package/template/.cursor/skills/yss-product-lifecycle/references/orchestration.md +1 -1
  158. package/template/.cursor/skills/yss-product-lifecycle/references/state-model.md +1 -1
  159. package/template/.cursor/skills/yss-tactical-design/SKILL.md +2 -2
  160. package/template/.cursor/skills/yss-tactical-design/references/output-template.md +2 -0
  161. package/template/.cursor/skills/yss-tactical-design/references/tactical-design-contract.md +3 -1
  162. package/template/.cursor/skills/yss-tactical-design/scripts/validate-tactical-design.mjs +3 -2
  163. package/template/.cursor/skills/yss-technical-design/SKILL.md +31 -0
  164. package/template/.cursor/skills/yss-technical-design/agents/openai.yaml +4 -0
  165. package/template/.cursor/skills/yss-technical-design/references/technical-design-common.schema.json +290 -0
  166. package/template/.cursor/skills/yss-technical-design/references/technical-design-contract.md +31 -0
  167. package/template/.cursor/skills/yss-technical-design/references/technical-design.schema.json +759 -0
  168. package/template/.cursor/skills/yss-technical-design/scripts/generate-schema.mjs +20 -0
  169. package/template/.cursor/skills/yss-technical-design/scripts/validate-technical-design.mjs +134 -0
  170. package/template/.cursor/skills/yss-technical-design/tests/fixtures.mjs +32 -0
  171. package/template/.cursor/skills/yss-technical-design/tests/run-scenarios.mjs +82 -0
  172. package/template/.cursor/skills/yss-ui/SKILL.md +2 -0
  173. package/template/.pi/skills/yss-domain/SKILL.md +3 -3
  174. package/template/.pi/skills/yss-frontend-scaffold-generator/SKILL.md +2 -0
  175. package/template/.pi/skills/yss-implementation-contract-compiler/SKILL.md +4 -2
  176. package/template/.pi/skills/yss-implementation-contract-compiler/references/boundaries.md +5 -0
  177. package/template/.pi/skills/yss-implementation-contract-compiler/references/compiler-contract.yaml +16 -2
  178. package/template/.pi/skills/yss-implementation-contract-compiler/references/slice-implementation-contract.md +10 -1
  179. package/template/.pi/skills/yss-mvc-design/SKILL.md +16 -0
  180. package/template/.pi/skills/yss-mvc-design/agents/openai.yaml +4 -0
  181. package/template/.pi/skills/yss-mvc-design/references/mvc-design.schema.json +315 -0
  182. package/template/.pi/skills/yss-product-lifecycle/SKILL.md +4 -2
  183. package/template/.pi/skills/yss-product-lifecycle/references/artifact-dependencies.md +2 -2
  184. package/template/.pi/skills/yss-product-lifecycle/references/orchestration-contract.yaml +14 -9
  185. package/template/.pi/skills/yss-product-lifecycle/references/orchestration.md +1 -1
  186. package/template/.pi/skills/yss-product-lifecycle/references/state-model.md +1 -1
  187. package/template/.pi/skills/yss-tactical-design/SKILL.md +2 -2
  188. package/template/.pi/skills/yss-tactical-design/references/output-template.md +2 -0
  189. package/template/.pi/skills/yss-tactical-design/references/tactical-design-contract.md +3 -1
  190. package/template/.pi/skills/yss-tactical-design/scripts/validate-tactical-design.mjs +3 -2
  191. package/template/.pi/skills/yss-technical-design/SKILL.md +31 -0
  192. package/template/.pi/skills/yss-technical-design/agents/openai.yaml +4 -0
  193. package/template/.pi/skills/yss-technical-design/references/technical-design-common.schema.json +290 -0
  194. package/template/.pi/skills/yss-technical-design/references/technical-design-contract.md +31 -0
  195. package/template/.pi/skills/yss-technical-design/references/technical-design.schema.json +759 -0
  196. package/template/.pi/skills/yss-technical-design/scripts/generate-schema.mjs +20 -0
  197. package/template/.pi/skills/yss-technical-design/scripts/validate-technical-design.mjs +134 -0
  198. package/template/.pi/skills/yss-technical-design/tests/fixtures.mjs +32 -0
  199. package/template/.pi/skills/yss-technical-design/tests/run-scenarios.mjs +82 -0
  200. package/template/.pi/skills/yss-ui/SKILL.md +2 -0
  201. package/template/.qoder/skills/yss-domain/SKILL.md +3 -3
  202. package/template/.qoder/skills/yss-frontend-scaffold-generator/SKILL.md +2 -0
  203. package/template/.qoder/skills/yss-implementation-contract-compiler/SKILL.md +4 -2
  204. package/template/.qoder/skills/yss-implementation-contract-compiler/references/boundaries.md +5 -0
  205. package/template/.qoder/skills/yss-implementation-contract-compiler/references/compiler-contract.yaml +16 -2
  206. package/template/.qoder/skills/yss-implementation-contract-compiler/references/slice-implementation-contract.md +10 -1
  207. package/template/.qoder/skills/yss-mvc-design/SKILL.md +16 -0
  208. package/template/.qoder/skills/yss-mvc-design/agents/openai.yaml +4 -0
  209. package/template/.qoder/skills/yss-mvc-design/references/mvc-design.schema.json +315 -0
  210. package/template/.qoder/skills/yss-product-lifecycle/SKILL.md +4 -2
  211. package/template/.qoder/skills/yss-product-lifecycle/references/artifact-dependencies.md +2 -2
  212. package/template/.qoder/skills/yss-product-lifecycle/references/orchestration-contract.yaml +14 -9
  213. package/template/.qoder/skills/yss-product-lifecycle/references/orchestration.md +1 -1
  214. package/template/.qoder/skills/yss-product-lifecycle/references/state-model.md +1 -1
  215. package/template/.qoder/skills/yss-tactical-design/SKILL.md +2 -2
  216. package/template/.qoder/skills/yss-tactical-design/references/output-template.md +2 -0
  217. package/template/.qoder/skills/yss-tactical-design/references/tactical-design-contract.md +3 -1
  218. package/template/.qoder/skills/yss-tactical-design/scripts/validate-tactical-design.mjs +3 -2
  219. package/template/.qoder/skills/yss-technical-design/SKILL.md +31 -0
  220. package/template/.qoder/skills/yss-technical-design/agents/openai.yaml +4 -0
  221. package/template/.qoder/skills/yss-technical-design/references/technical-design-common.schema.json +290 -0
  222. package/template/.qoder/skills/yss-technical-design/references/technical-design-contract.md +31 -0
  223. package/template/.qoder/skills/yss-technical-design/references/technical-design.schema.json +759 -0
  224. package/template/.qoder/skills/yss-technical-design/scripts/generate-schema.mjs +20 -0
  225. package/template/.qoder/skills/yss-technical-design/scripts/validate-technical-design.mjs +134 -0
  226. package/template/.qoder/skills/yss-technical-design/tests/fixtures.mjs +32 -0
  227. package/template/.qoder/skills/yss-technical-design/tests/run-scenarios.mjs +82 -0
  228. package/template/.qoder/skills/yss-ui/SKILL.md +2 -0
  229. package/template/.trae/skills/yss-domain/SKILL.md +3 -3
  230. package/template/.trae/skills/yss-frontend-scaffold-generator/SKILL.md +2 -0
  231. package/template/.trae/skills/yss-implementation-contract-compiler/SKILL.md +4 -2
  232. package/template/.trae/skills/yss-implementation-contract-compiler/references/boundaries.md +5 -0
  233. package/template/.trae/skills/yss-implementation-contract-compiler/references/compiler-contract.yaml +16 -2
  234. package/template/.trae/skills/yss-implementation-contract-compiler/references/slice-implementation-contract.md +10 -1
  235. package/template/.trae/skills/yss-mvc-design/SKILL.md +16 -0
  236. package/template/.trae/skills/yss-mvc-design/agents/openai.yaml +4 -0
  237. package/template/.trae/skills/yss-mvc-design/references/mvc-design.schema.json +315 -0
  238. package/template/.trae/skills/yss-product-lifecycle/SKILL.md +4 -2
  239. package/template/.trae/skills/yss-product-lifecycle/references/artifact-dependencies.md +2 -2
  240. package/template/.trae/skills/yss-product-lifecycle/references/orchestration-contract.yaml +14 -9
  241. package/template/.trae/skills/yss-product-lifecycle/references/orchestration.md +1 -1
  242. package/template/.trae/skills/yss-product-lifecycle/references/state-model.md +1 -1
  243. package/template/.trae/skills/yss-tactical-design/SKILL.md +2 -2
  244. package/template/.trae/skills/yss-tactical-design/references/output-template.md +2 -0
  245. package/template/.trae/skills/yss-tactical-design/references/tactical-design-contract.md +3 -1
  246. package/template/.trae/skills/yss-tactical-design/scripts/validate-tactical-design.mjs +3 -2
  247. package/template/.trae/skills/yss-technical-design/SKILL.md +31 -0
  248. package/template/.trae/skills/yss-technical-design/agents/openai.yaml +4 -0
  249. package/template/.trae/skills/yss-technical-design/references/technical-design-common.schema.json +290 -0
  250. package/template/.trae/skills/yss-technical-design/references/technical-design-contract.md +31 -0
  251. package/template/.trae/skills/yss-technical-design/references/technical-design.schema.json +759 -0
  252. package/template/.trae/skills/yss-technical-design/scripts/generate-schema.mjs +20 -0
  253. package/template/.trae/skills/yss-technical-design/scripts/validate-technical-design.mjs +134 -0
  254. package/template/.trae/skills/yss-technical-design/tests/fixtures.mjs +32 -0
  255. package/template/.trae/skills/yss-technical-design/tests/run-scenarios.mjs +82 -0
  256. package/template/.trae/skills/yss-ui/SKILL.md +2 -0
  257. package/template/CONTEXT.md +4 -1
  258. package/template/README.md +4 -0
  259. package/template/docs/agents/digital-human-roles.yaml +3 -2
  260. package/template/docs/agents/yss-skill-registry.yaml +20 -1
  261. package/template/docs/architecture/templates/architecture-review-checklist.md +1 -1
  262. package/template/docs/architecture/templates/system-overview-design-template.md +15 -4
  263. package/template/docs/process/frontend-backend-delivery.md +72 -0
  264. package/template/docs/process/implementation-repo-integration.md +2 -0
  265. package/template/docs/process/lifecycle-artifact-map.md +3 -0
  266. package/template/docs/process/lifecycle-registry-baseline.json +4 -1
  267. package/template/docs/process/lifecycle-registry.yaml +14 -2
  268. package/template/docs/process/schemas/backend-delivery-verification.schema.json +113 -0
  269. package/template/docs/process/schemas/backend-delivery.schema.json +301 -0
  270. package/template/docs/process/schemas/digital-human-task-package.schema.json +8 -0
  271. package/template/docs/process/schemas/frontend-delivery-acceptance.schema.json +200 -0
  272. package/template/docs/process/schemas/frontend-implementation-evidence.schema.json +3 -0
  273. package/template/docs/process/schemas/strategic-design-handoff.schema.json +77 -4
  274. package/template/docs/process/strategic-handoff-package.md +4 -2
  275. package/template/docs/process/template-verification-profiles.yaml +20 -0
  276. package/template/docs/user-guide//346/210/230/346/234/257/350/256/276/350/256/241/345/255/220/351/241/271/347/233/256/347/224/250/346/210/267/346/211/213/345/206/214.md +21 -206
  277. package/template/docs/user-guide//347/224/250/346/210/267/346/211/213/345/206/214.md +63 -963
  278. package/template/docs/user-guide//347/224/250/346/210/267/346/211/213/345/206/214/347/264/242/345/274/225.md +11 -14
  279. package/template/docs/user-guide//350/256/276/345/244/207/345/200/237/347/224/250/350/264/257/347/251/277/346/241/210/344/276/213.md +127 -0
  280. package/template/scripts/backend-delivery +14 -0
  281. package/template/scripts/fixtures/backend-delivery/revision-server.mjs +11 -0
  282. package/template/scripts/fixtures/strategic-handoff/fixture.mjs +3 -2
  283. package/template/scripts/instantiate-harness +69 -0
  284. package/template/scripts/lib/backend-delivery.mjs +164 -0
  285. package/template/scripts/lib/frontend-delivery-boundary.mjs +49 -0
  286. package/template/scripts/lib/frontend-delivery.mjs +73 -0
  287. package/template/scripts/lib/harness-execution-scope.mjs +52 -0
  288. package/template/scripts/lib/implementation-contract-compiler.mjs +19 -2
  289. package/template/scripts/lib/lifecycle-transition.mjs +7 -0
  290. package/template/scripts/lib/strategic-handoff-consumption.mjs +17 -10
  291. package/template/scripts/lib/strategic-handoff-design-targets.mjs +15 -0
  292. package/template/scripts/lib/strategic-handoff.mjs +1 -1
  293. package/template/scripts/lib/task-package.mjs +7 -0
  294. package/template/scripts/lib/technical-design-boundary.mjs +23 -0
  295. package/template/scripts/sync-strategic-handoff-tools +5 -2
  296. package/template/scripts/verify-frontend-delivery +9 -0
  297. package/template/scripts/verify-frontend-delivery-scenarios +131 -0
  298. package/template/scripts/verify-frontend-implementation-evidence +2 -0
  299. package/template/scripts/verify-strategic-handoff-package-scenarios +7 -1
  300. package/template/skills-lock.json +43 -13
  301. package/template.manifest.json +43 -1
  302. package/template.snapshot.json +5 -5
@@ -0,0 +1,153 @@
1
+ "use strict";
2
+
3
+ const fs = require("node:fs");
4
+ const os = require("node:os");
5
+ const path = require("node:path");
6
+ const { copyPath } = require("./copy-path");
7
+ const {
8
+ normalizeRelativePath,
9
+ targetPath,
10
+ pathKind,
11
+ } = require("./path-utils");
12
+
13
+ class FileTransaction {
14
+ constructor(targetDir, deps = {}) {
15
+ this.targetDir = path.resolve(targetDir);
16
+ this.fs = deps.fs || fs;
17
+ this.path = deps.path || path;
18
+ this.copyPath = deps.copyPath || copyPath;
19
+ this.pathKind = deps.pathKind || pathKind;
20
+ this.backupRoot = deps.backupRoot || this.fs.mkdtempSync(
21
+ this.path.join((deps.os || os).tmpdir(), "create-yss-spec-backup-"),
22
+ );
23
+ this.backups = [];
24
+ this.mutated = [];
25
+ this.createdDirectories = [];
26
+ }
27
+
28
+ relative(absolutePath) {
29
+ return normalizeRelativePath(this.path.relative(this.targetDir, absolutePath));
30
+ }
31
+
32
+ backupPath(relativePath) {
33
+ return this.path.join(this.backupRoot, ...normalizeRelativePath(relativePath).split("/"));
34
+ }
35
+
36
+ prepare(relativePaths) {
37
+ const candidates = [...new Set(relativePaths)]
38
+ .map((relativePath) => normalizeRelativePath(relativePath))
39
+ .filter(
40
+ (relativePath) =>
41
+ relativePath &&
42
+ this.pathKind(targetPath(this.targetDir, relativePath)) !== "missing",
43
+ )
44
+ .sort((left, right) => left.split("/").length - right.split("/").length);
45
+
46
+ for (const relativePath of candidates) {
47
+ if (
48
+ this.backups.some(
49
+ (backup) =>
50
+ relativePath === backup.relativePath ||
51
+ relativePath.startsWith(`${backup.relativePath}/`),
52
+ )
53
+ ) {
54
+ continue;
55
+ }
56
+
57
+ const source = targetPath(this.targetDir, relativePath);
58
+ const destination = this.backupPath(relativePath);
59
+ this.copyPath(source, destination);
60
+ this.backups.push({ relativePath, destination });
61
+ }
62
+ }
63
+
64
+ ensureParent(absolutePath) {
65
+ const missing = [];
66
+ let current = this.path.dirname(absolutePath);
67
+
68
+ while (current !== this.targetDir && !this.fs.existsSync(current)) {
69
+ missing.push(current);
70
+ current = this.path.dirname(current);
71
+ }
72
+
73
+ if (current !== this.targetDir && this.pathKind(current) !== "directory") {
74
+ throw new Error(`目标父路径不是目录:${this.relative(current)}`);
75
+ }
76
+
77
+ for (const directory of missing.reverse()) {
78
+ this.fs.mkdirSync(directory);
79
+ this.createdDirectories.push(this.relative(directory));
80
+ }
81
+ }
82
+
83
+ mark(absolutePath) {
84
+ this.mutated.push(this.relative(absolutePath));
85
+ }
86
+
87
+ writeFile(absolutePath, content, options = "utf8") {
88
+ this.ensureParent(absolutePath);
89
+ this.fs.writeFileSync(absolutePath, content, options);
90
+ this.mark(absolutePath);
91
+ }
92
+
93
+ copyFile(sourcePath, destinationPath) {
94
+ this.ensureParent(destinationPath);
95
+ this.copyPath(sourcePath, destinationPath);
96
+ this.mark(destinationPath);
97
+ }
98
+
99
+ remove(absolutePath) {
100
+ if (!this.fs.existsSync(absolutePath)) return;
101
+ this.fs.rmSync(absolutePath, { recursive: true, force: true });
102
+ this.mark(absolutePath);
103
+ }
104
+
105
+ move(sourcePath, destinationPath) {
106
+ this.ensureParent(destinationPath);
107
+ this.copyPath(sourcePath, destinationPath);
108
+ this.mark(destinationPath);
109
+ this.remove(sourcePath);
110
+ }
111
+
112
+ rollback() {
113
+ for (const relativePath of [...new Set(this.mutated)].sort(
114
+ (left, right) => right.split("/").length - left.split("/").length,
115
+ )) {
116
+ this.fs.rmSync(targetPath(this.targetDir, relativePath), {
117
+ recursive: true,
118
+ force: true,
119
+ });
120
+ }
121
+
122
+ for (const relativePath of [...new Set(this.createdDirectories)].sort(
123
+ (left, right) => right.split("/").length - left.split("/").length,
124
+ )) {
125
+ const directory = targetPath(this.targetDir, relativePath);
126
+ if (this.fs.existsSync(directory) && this.fs.readdirSync(directory).length === 0) {
127
+ this.fs.rmdirSync(directory);
128
+ }
129
+ }
130
+
131
+ for (const backup of [...this.backups].sort(
132
+ (left, right) =>
133
+ left.relativePath.split("/").length - right.relativePath.split("/").length,
134
+ )) {
135
+ this.copyPath(
136
+ backup.destination,
137
+ targetPath(this.targetDir, backup.relativePath),
138
+ );
139
+ }
140
+ }
141
+
142
+ finish() {
143
+ if (this.backups.length === 0) {
144
+ this.fs.rmSync(this.backupRoot, { recursive: true, force: true });
145
+ return null;
146
+ }
147
+ return this.backupRoot;
148
+ }
149
+ }
150
+
151
+ module.exports = {
152
+ FileTransaction,
153
+ };
@@ -0,0 +1,115 @@
1
+ "use strict";
2
+
3
+ const fs = require("node:fs");
4
+ const path = require("node:path");
5
+ const { spawnSync } = require("node:child_process");
6
+
7
+ const GITLINK_MODE = "160000";
8
+ const GITLINK_PATH_CACHE = new Map();
9
+
10
+ function posixRelative(from, to) {
11
+ return path.relative(from, to).split(path.sep).join("/");
12
+ }
13
+
14
+ function parseGitmodules(content) {
15
+ const modules = [];
16
+ if (typeof content !== "string" || content.length === 0) return modules;
17
+ let current = null;
18
+ for (const rawLine of content.split(/\r?\n/)) {
19
+ const line = rawLine.trim();
20
+ const name = line.match(/^\[submodule "(.+)"\]$/);
21
+ if (name) {
22
+ current = { name: name[1], path: "", url: "" };
23
+ modules.push(current);
24
+ continue;
25
+ }
26
+ if (!current) continue;
27
+ const pathMatch = line.match(/^path\s*=\s*(.+)$/);
28
+ if (pathMatch) {
29
+ current.path = pathMatch[1].trim().replace(/\\/g, "/").replace(/\/+$/, "");
30
+ }
31
+ const urlMatch = line.match(/^url\s*=\s*(.+)$/);
32
+ if (urlMatch) current.url = urlMatch[1].trim();
33
+ }
34
+ return modules;
35
+ }
36
+
37
+ function readGitmodules(repoRoot, deps = {}) {
38
+ const file = path.join(repoRoot, ".gitmodules");
39
+ const pathKind =
40
+ deps.pathKind ||
41
+ ((value) => {
42
+ try {
43
+ const stat = fs.lstatSync(value);
44
+ if (stat.isFile()) return "file";
45
+ if (stat.isDirectory()) return "directory";
46
+ return "other";
47
+ } catch (error) {
48
+ if (error.code === "ENOENT") return "missing";
49
+ throw error;
50
+ }
51
+ });
52
+ if (!fs.existsSync(file) || pathKind(file) !== "file") return [];
53
+ return parseGitmodules(fs.readFileSync(file, "utf8"));
54
+ }
55
+
56
+ function gitlinkPaths(repoRoot, deps = {}) {
57
+ const resolvedRoot = path.resolve(repoRoot);
58
+ const useCache = !deps.disableCache && !deps.spawn;
59
+ if (useCache && GITLINK_PATH_CACHE.has(resolvedRoot)) {
60
+ return GITLINK_PATH_CACHE.get(resolvedRoot);
61
+ }
62
+
63
+ const spawn = deps.spawn || spawnSync;
64
+ const result = spawn(
65
+ "git",
66
+ ["-C", resolvedRoot, "ls-files", "--stage", "-z"],
67
+ {
68
+ encoding: "utf8",
69
+ timeout: 5000,
70
+ },
71
+ );
72
+ const paths = new Set();
73
+ if (result.status === 0) {
74
+ for (const record of (result.stdout || "").split("\0")) {
75
+ const match = record.match(/^(160000)\s+[0-9a-f]+\s+\d+\s+(.+)$/i);
76
+ if (match) paths.add(match[2].replaceAll("\\", "/"));
77
+ }
78
+ }
79
+
80
+ if (useCache) GITLINK_PATH_CACHE.set(resolvedRoot, paths);
81
+ return paths;
82
+ }
83
+
84
+ function clearGitlinkPathCache(repoRoot = null) {
85
+ if (repoRoot === null) {
86
+ GITLINK_PATH_CACHE.clear();
87
+ return;
88
+ }
89
+ GITLINK_PATH_CACHE.delete(path.resolve(repoRoot));
90
+ }
91
+
92
+ function isGitSubmoduleMount(repoRoot, targetPathValue, deps = {}) {
93
+ const relative = posixRelative(repoRoot, path.resolve(targetPathValue));
94
+ if (
95
+ !relative ||
96
+ relative === "." ||
97
+ relative.startsWith("..") ||
98
+ path.isAbsolute(relative)
99
+ ) {
100
+ return false;
101
+ }
102
+ if (readGitmodules(repoRoot, deps).some((item) => item.path === relative)) return true;
103
+ return gitlinkPaths(repoRoot, deps).has(relative);
104
+ }
105
+
106
+ module.exports = {
107
+ GITLINK_MODE,
108
+ GITLINK_PATH_CACHE,
109
+ parseGitmodules,
110
+ readGitmodules,
111
+ gitlinkPaths,
112
+ clearGitlinkPathCache,
113
+ isGitSubmoduleMount,
114
+ posixRelative,
115
+ };
@@ -0,0 +1,69 @@
1
+ "use strict";
2
+
3
+ const fs = require("node:fs");
4
+ const path = require("node:path");
5
+ const { spawnSync } = require("node:child_process");
6
+ const { isGitSubmoduleMount, posixRelative } = require("./submodule");
7
+
8
+ function collectGitRoots(start) {
9
+ const roots = [];
10
+ if (!start) return roots;
11
+ let current = path.resolve(start);
12
+ while (true) {
13
+ const gitPath = path.join(current, ".git");
14
+ let validGitEntry = false;
15
+ try {
16
+ const gitStat = fs.lstatSync(gitPath);
17
+ validGitEntry = gitStat.isDirectory() ? fs.readdirSync(gitPath).length > 0 : gitStat.isFile();
18
+ } catch (error) {
19
+ if (error.code !== "ENOENT") throw error;
20
+ }
21
+ if (validGitEntry || fs.existsSync(path.join(current, ".gitmodules"))) roots.push(current);
22
+ const parent = path.dirname(current);
23
+ if (parent === current) break;
24
+ current = parent;
25
+ }
26
+ return roots;
27
+ }
28
+
29
+ function gitShowSuperproject(cwd, spawn = spawnSync) {
30
+ const result = spawn("git", ["-C", cwd, "rev-parse", "--show-superproject-working-tree"], { encoding: "utf8", timeout: 5000 });
31
+ return result.status === 0 ? (result.stdout || "").trim() : "";
32
+ }
33
+
34
+ function gitAbbrevRef(cwd, spawn = spawnSync) {
35
+ const result = spawn("git", ["-C", cwd, "rev-parse", "--abbrev-ref", "HEAD"], { encoding: "utf8", timeout: 5000 });
36
+ return result.status === 0 ? (result.stdout || "").trim() : null;
37
+ }
38
+
39
+ function isEmptyDir(dir) {
40
+ if (!fs.existsSync(dir)) return true;
41
+ try {
42
+ return fs.readdirSync(dir).filter((name) => name !== "." && name !== "..").length === 0;
43
+ } catch {
44
+ return false;
45
+ }
46
+ }
47
+
48
+ function inspectCheckoutState(repoRoot, targetPathValue, deps = {}) {
49
+ const resolved = path.resolve(targetPathValue);
50
+ const relative = posixRelative(path.resolve(repoRoot), resolved);
51
+ const isMount = isGitSubmoduleMount(repoRoot, resolved, deps) || Boolean(fs.existsSync(path.join(resolved, ".git")) && gitShowSuperproject(resolved, deps.spawn || spawnSync));
52
+ const hasGit = fs.existsSync(path.join(resolved, ".git"));
53
+ if (isMount && !hasGit) return isEmptyDir(resolved) ? "empty-gitlink" : "uninitialized";
54
+ if (isMount && hasGit) return gitAbbrevRef(resolved, deps.spawn || spawnSync) === "HEAD" ? "detached-head" : "attached-branch";
55
+ if (!relative || relative.startsWith("..")) return null;
56
+ return null;
57
+ }
58
+
59
+ function gitDirtyWarning(targetDir, spawn = spawnSync) {
60
+ const probe = spawn("git", ["rev-parse", "--is-inside-work-tree"], { cwd: targetDir, encoding: "utf8", timeout: 5000 });
61
+ if (probe.status !== 0 || (probe.stdout || "").trim() !== "true") return null;
62
+ const status = spawn("git", ["status", "--porcelain"], { cwd: targetDir, encoding: "utf8", timeout: 5000 });
63
+ if (status.status === 0 && (status.stdout || "").trim()) {
64
+ return "警告:目标 Git worktree 存在未提交改动;CLI 不会自动 stash 或提交,请在结果后检查 git diff / git status";
65
+ }
66
+ return null;
67
+ }
68
+
69
+ module.exports = { collectGitRoots, gitShowSuperproject, gitAbbrevRef, isEmptyDir, inspectCheckoutState, gitDirtyWarning };
@@ -0,0 +1,51 @@
1
+ "use strict";
2
+
3
+ const {
4
+ classifyAttachOperations,
5
+ createAttachPlan,
6
+ } = require("./attach-planner");
7
+ const {
8
+ ownershipAwareUnmanagedReason,
9
+ decoratePlanWithOwnership,
10
+ } = require("./ownership-runtime");
11
+ const {
12
+ applyLifecycleToOperations,
13
+ decoratePlanWithLifecycle,
14
+ } = require("./lifecycle-runtime");
15
+
16
+ function buildAttachPlanFromRuntime({
17
+ targetDir,
18
+ desiredOperations,
19
+ migration,
20
+ warning = null,
21
+ getUnmanagedReason,
22
+ getPathKind,
23
+ getFileHash,
24
+ }) {
25
+ const lifecycleOperations = applyLifecycleToOperations(desiredOperations);
26
+ const classified = classifyAttachOperations({
27
+ desiredOperations: lifecycleOperations,
28
+ getUnmanagedReason: (operation) =>
29
+ ownershipAwareUnmanagedReason(operation, getUnmanagedReason),
30
+ getPathKind,
31
+ getFileHash,
32
+ });
33
+
34
+ const basePlan = createAttachPlan({
35
+ targetDir,
36
+ classified,
37
+ migration,
38
+ warnings: warning ? [warning] : [],
39
+ });
40
+ const ownershipPlan = decoratePlanWithOwnership(basePlan, lifecycleOperations);
41
+ const plan = decoratePlanWithLifecycle(ownershipPlan, lifecycleOperations);
42
+
43
+ return {
44
+ classified,
45
+ plan,
46
+ };
47
+ }
48
+
49
+ module.exports = {
50
+ buildAttachPlanFromRuntime,
51
+ };
@@ -0,0 +1,160 @@
1
+ "use strict";
2
+
3
+ function classifyAttachOperations({
4
+ desiredOperations = [],
5
+ getUnmanagedReason = () => null,
6
+ getPathKind,
7
+ getFileHash,
8
+ }) {
9
+ if (typeof getPathKind !== "function") {
10
+ throw new TypeError("classifyAttachOperations requires getPathKind");
11
+ }
12
+ if (typeof getFileHash !== "function") {
13
+ throw new TypeError("classifyAttachOperations requires getFileHash");
14
+ }
15
+
16
+ const missing = [];
17
+ const matched = [];
18
+ const identity = [];
19
+ const conflicts = [];
20
+ const forceableConflicts = [];
21
+ const unsafe = [];
22
+
23
+ for (const operation of desiredOperations) {
24
+ const unmanagedReason = getUnmanagedReason(operation);
25
+ if (unmanagedReason) {
26
+ unsafe.push({ ...operation, reason: unmanagedReason });
27
+ continue;
28
+ }
29
+
30
+ const kind = getPathKind(operation);
31
+ if (kind === "missing") {
32
+ missing.push(operation);
33
+ continue;
34
+ }
35
+
36
+ if (kind !== "file") {
37
+ unsafe.push({
38
+ ...operation,
39
+ reason: `目标路径类型为 ${kind},无法安全判断是否可以替换`,
40
+ });
41
+ continue;
42
+ }
43
+
44
+ const currentHash = getFileHash(operation);
45
+ if (currentHash === operation.desiredHash) {
46
+ matched.push(operation);
47
+ } else if (operation.identityConversion) {
48
+ identity.push(operation);
49
+ } else {
50
+ const conflict = {
51
+ ...operation,
52
+ reason:
53
+ operation.mergeStrategy === "manual"
54
+ ? "目标可定制文件已存在且内容不一致;mergeStrategy=manual,必须人工处理"
55
+ : "目标受管文件已存在且内容不一致",
56
+ };
57
+ conflicts.push(conflict);
58
+ if (operation.mergeStrategy !== "manual") {
59
+ forceableConflicts.push(conflict);
60
+ }
61
+ }
62
+ }
63
+
64
+ return {
65
+ missing,
66
+ matched,
67
+ identity,
68
+ conflicts,
69
+ forceableConflicts,
70
+ unsafe,
71
+ desiredOperations,
72
+ };
73
+ }
74
+
75
+ function createAttachPlan({
76
+ targetDir,
77
+ classified,
78
+ migration = null,
79
+ warnings = [],
80
+ }) {
81
+ if (!classified || typeof classified !== "object") {
82
+ throw new TypeError("createAttachPlan requires classified attach operations");
83
+ }
84
+
85
+ const missing = classified.missing || [];
86
+ const matched = classified.matched || [];
87
+ const identity = classified.identity || [];
88
+ const classifiedConflicts = classified.conflicts || [];
89
+ const forceableConflicts = classified.forceableConflicts || classifiedConflicts;
90
+ const classifiedUnsafe = classified.unsafe || [];
91
+ const migrationConflicts = migration?.conflicts || [];
92
+ const migrationUnsafe = migration?.unsafe || [];
93
+
94
+ const conflicts = [
95
+ ...classifiedConflicts.map((operation) => ({
96
+ path: operation.relativePath,
97
+ reason: operation.reason,
98
+ forceable: forceableConflicts.includes(operation),
99
+ source: "managed-file",
100
+ })),
101
+ ...migrationConflicts.map((item) => ({
102
+ path: item.from || item.path || item.to,
103
+ from: item.from,
104
+ to: item.to,
105
+ reason: item.reason,
106
+ forceable: false,
107
+ source: "migration",
108
+ })),
109
+ ];
110
+ const unsafe = [
111
+ ...classifiedUnsafe.map((operation) => ({
112
+ path: operation.relativePath,
113
+ reason: operation.reason,
114
+ source: "managed-file",
115
+ })),
116
+ ...migrationUnsafe.map((item) => ({
117
+ path: item.path,
118
+ reason: item.reason,
119
+ source: "migration",
120
+ })),
121
+ ];
122
+
123
+ return {
124
+ operation: "attach",
125
+ targetDir,
126
+ template: null,
127
+ changes: [
128
+ ...missing.map((operation) => ({
129
+ action: "add",
130
+ path: operation.relativePath,
131
+ })),
132
+ ...identity.map((operation) => ({
133
+ action: "identity-convert",
134
+ path: operation.relativePath,
135
+ })),
136
+ ],
137
+ conflicts,
138
+ unsafe,
139
+ migration: migration || {
140
+ operations: [],
141
+ legacy: [],
142
+ conflicts: [],
143
+ unsafe: [],
144
+ },
145
+ warnings,
146
+ blocked: unsafe.length > 0 || migrationConflicts.length > 0,
147
+ stats: {
148
+ missing: missing.length,
149
+ matched: matched.length,
150
+ identity: identity.length,
151
+ conflicts: conflicts.length,
152
+ unsafe: unsafe.length,
153
+ },
154
+ };
155
+ }
156
+
157
+ module.exports = {
158
+ classifyAttachOperations,
159
+ createAttachPlan,
160
+ };