create-yss-spec 3.0.0 → 3.1.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 (2463) hide show
  1. package/README.md +2 -2
  2. package/package.json +1 -1
  3. package/src/cli.js +0 -1
  4. package/template/.agents/rules/yss-ai-skills.md +3 -55
  5. package/template/.agents/skills/.strategic-design-skills-manifest.json +40 -0
  6. package/template/.agents/skills/.yss-skills-manifest.json +1 -5
  7. package/template/.agents/skills/alibaba-java-code-style/SKILL.md +1 -0
  8. package/template/.agents/skills/code-review/SKILL.md +1 -1
  9. package/template/.agents/skills/code-review/references/yss-review-standards.md +2 -2
  10. package/template/.agents/skills/domain-modeling/CONTEXT-FORMAT.md +37 -42
  11. package/template/.agents/skills/domain-modeling/SKILL.md +10 -26
  12. package/template/.agents/skills/grill-with-docs/SKILL.md +6 -5
  13. package/template/.agents/skills/lombok/SKILL.md +3 -2
  14. package/template/.agents/skills/mapstruct/SKILL.md +4 -3
  15. package/template/.agents/skills/prototype-review/SKILL.md +7 -6
  16. package/template/.agents/skills/setup-matt-pocock-skills/SKILL.md +5 -6
  17. package/template/.agents/skills/setup-matt-pocock-skills/domain.md +6 -20
  18. package/template/.agents/skills/wait-what/SKILL.md +1 -1
  19. package/template/.agents/skills/yss-antd-design/SKILL.md +8 -7
  20. package/template/.agents/skills/yss-antd-design/references/evidence.md +11 -6
  21. package/template/.agents/skills/yss-antdv-next-design/SKILL.md +48 -0
  22. package/template/.agents/skills/yss-antdv-next-design/references/boundaries.md +25 -0
  23. package/template/.agents/skills/yss-antdv-next-design/references/cli-matrix.md +34 -0
  24. package/template/.agents/skills/yss-antdv-next-design/references/fact-pack.md +38 -0
  25. package/template/.agents/skills/yss-antdv-next-design/scripts/collect-antdv-next-facts.mjs +213 -0
  26. package/template/.agents/skills/yss-antdv-next-design/scripts/validate-fact-pack.mjs +168 -0
  27. package/template/.agents/skills/yss-antdv-next-design/tests/run-scenarios.mjs +139 -0
  28. package/template/.agents/skills/yss-api-integration/SKILL.md +2 -2
  29. package/template/.agents/skills/yss-application/SKILL.md +8 -2
  30. package/template/.agents/skills/yss-application/references/profiles/layered-mvc-service.md +3 -0
  31. package/template/.agents/skills/yss-application/references/profiles/mvc-data-analysis-v1.md +3 -0
  32. package/template/.agents/skills/yss-application/references/profiles/target-domain-model.md +3 -0
  33. package/template/.agents/skills/yss-audit-log/SKILL.md +2 -2
  34. package/template/.agents/skills/yss-audit-log/references/source-index.md +1 -1
  35. package/template/.agents/skills/yss-cache/SKILL.md +2 -2
  36. package/template/.agents/skills/yss-cache/references/source-index.md +1 -1
  37. package/template/.agents/skills/yss-cache/scripts/check-skill-freshness.sh +1 -1
  38. package/template/.agents/skills/yss-components/SKILL.md +1 -1
  39. package/template/.agents/skills/yss-ddd-scaffold-generator/SKILL.md +8 -9
  40. package/template/.agents/skills/yss-ddd-scaffold-generator/agents/openai.yaml +1 -1
  41. package/template/.agents/skills/yss-ddd-scaffold-generator/assets/templates/config/application.yml.template +0 -13
  42. package/template/.agents/skills/yss-ddd-scaffold-generator/assets/templates/pom/bootstrap-pom.xml.template +13 -0
  43. package/template/.agents/skills/yss-ddd-scaffold-generator/references/ARCHITECTURE.md +1 -1
  44. package/template/.agents/skills/yss-ddd-scaffold-generator/references/USAGE_EXAMPLES.md +15 -6
  45. package/template/.agents/skills/yss-ddd-scaffold-generator/references/yss-backend-scaffold-parent/SKILL.md +2 -2
  46. package/template/.agents/skills/yss-ddd-scaffold-generator/scripts/first-slice-compatibility.test.mjs +23 -9
  47. package/template/.agents/skills/yss-ddd-scaffold-generator/scripts/first-slice-verification.test.mjs +3 -3
  48. package/template/.agents/skills/yss-ddd-scaffold-generator/scripts/generate_scaffold.mjs +43 -21
  49. package/template/.agents/skills/yss-ddd-scaffold-generator/scripts/run_first_slice_verification.mjs +23 -11
  50. package/template/.agents/skills/yss-ddd-scaffold-generator/scripts/run_scaffold_verification.mjs +15 -3
  51. package/template/.agents/skills/yss-ddd-scaffold-generator/scripts/scaffold-generator.test.mjs +44 -15
  52. package/template/.agents/skills/yss-design-system/SKILL.md +27 -24
  53. package/template/.agents/skills/yss-design-system/references/design-qa-theme.md +22 -24
  54. package/template/.agents/skills/yss-design-system/references/design-system.md +39 -56
  55. package/template/.agents/skills/yss-distributed-id/SKILL.md +2 -2
  56. package/template/.agents/skills/yss-distributed-id/references/source-index.md +1 -1
  57. package/template/.agents/skills/yss-domain/SKILL.md +2 -2
  58. package/template/.agents/skills/yss-dto/SKILL.md +3 -2
  59. package/template/.agents/skills/yss-dto/references/source-index.md +1 -1
  60. package/template/.agents/skills/yss-excel-mvc/SKILL.md +2 -2
  61. package/template/.agents/skills/yss-excel-mvc/references/source-index.md +1 -1
  62. package/template/.agents/skills/yss-exception/SKILL.md +2 -1
  63. package/template/.agents/skills/yss-exception/references/source-index.md +1 -1
  64. package/template/.agents/skills/yss-frontend-scaffold-generator/SKILL.md +1 -1
  65. package/template/.agents/skills/yss-implementation-contract-compiler/SKILL.md +61 -0
  66. package/template/.agents/skills/yss-implementation-contract-compiler/agents/openai.yaml +4 -0
  67. package/template/.agents/skills/yss-implementation-contract-compiler/references/boundaries.md +142 -0
  68. package/template/.agents/skills/yss-implementation-contract-compiler/references/compiler-contract.yaml +367 -0
  69. package/template/.agents/skills/yss-implementation-contract-compiler/references/slice-implementation-contract.md +201 -0
  70. package/template/.agents/skills/yss-implementation-contract-compiler/references/yss-skill-execution-result.md +71 -0
  71. package/template/.agents/skills/yss-implementation-contract-compiler/tests/backend-profiles.test.mjs +45 -0
  72. package/template/.agents/skills/yss-implementation-contract-compiler/tests/compiler-scenarios.test.mjs +91 -0
  73. package/template/.agents/skills/yss-layered-mvc-scaffold-generator/SKILL.md +64 -0
  74. package/template/.agents/skills/yss-layered-mvc-scaffold-generator/agents/openai.yaml +4 -0
  75. package/template/.agents/skills/yss-layered-mvc-scaffold-generator/references/architecture.md +29 -0
  76. package/template/.agents/skills/yss-layered-mvc-scaffold-generator/scripts/generate_and_verify_scaffold.mjs +61 -0
  77. package/template/.agents/skills/yss-layered-mvc-scaffold-generator/scripts/generate_scaffold.mjs +315 -0
  78. package/template/.agents/skills/yss-layered-mvc-scaffold-generator/scripts/run_scaffold_verification.mjs +30 -0
  79. package/template/.agents/skills/yss-layered-mvc-scaffold-generator/scripts/scaffold-generator.test.mjs +159 -0
  80. package/template/.agents/skills/yss-mvc-data-analysis-project-initializer/SKILL.md +22 -0
  81. package/template/.agents/skills/yss-mvc-data-analysis-project-initializer/scripts/generate_project.mjs +77 -0
  82. package/template/.agents/skills/yss-mvc-data-analysis-project-initializer/scripts/run_scaffold_verification.mjs +9 -0
  83. package/template/.agents/skills/yss-mvc-scaffold-generator/SKILL.md +8 -0
  84. package/template/.agents/skills/yss-mvc-scaffold-generator/agents/openai.yaml +4 -0
  85. package/template/.agents/skills/yss-mvc-scaffold-generator/assets/logback-spring.xml.template +50 -0
  86. package/template/.agents/skills/yss-mvc-scaffold-generator/assets/smart-doc.json.template +42 -0
  87. package/template/.agents/skills/yss-mvc-scaffold-generator/references/architecture.md +28 -0
  88. package/template/.agents/skills/yss-mvc-scaffold-generator/references/history/generate_project.mjs.txt +137 -0
  89. package/template/.agents/skills/yss-mvc-scaffold-generator/references/history/generate_project.test.mjs.txt +341 -0
  90. package/template/.agents/skills/yss-mvc-scaffold-generator/references/history/skill.md +87 -0
  91. package/template/.agents/skills/yss-mvc-scaffold-generator/scripts/generate_project.mjs +3 -0
  92. package/template/.agents/skills/yss-mvc-scaffold-generator/scripts/generate_project.test.mjs +9 -0
  93. package/template/.agents/skills/yss-mvc-scaffold-generator/scripts/lib/envelope.mjs +74 -0
  94. package/template/.agents/skills/yss-mvc-scaffold-generator/scripts/lib/envelope.test.mjs +36 -0
  95. package/template/.agents/skills/yss-mvc-scaffold-generator/scripts/lib/runtime.mjs +115 -0
  96. package/template/.agents/skills/yss-mvc-scaffold-generator/scripts/lib/storage.mjs +90 -0
  97. package/template/.agents/skills/yss-mvc-scaffold-generator/scripts/lib/templates.mjs +54 -0
  98. package/template/.agents/skills/yss-mvc-scaffold-generator/scripts/verify_project.mjs +103 -0
  99. package/template/.agents/skills/yss-mybatis/SKILL.md +4 -4
  100. package/template/.agents/skills/yss-mybatis/references/source-index.md +1 -1
  101. package/template/.agents/skills/yss-product-lifecycle/SKILL.md +35 -11
  102. package/template/.agents/skills/yss-product-lifecycle/references/artifact-dependencies.md +3 -0
  103. package/template/.agents/skills/yss-product-lifecycle/references/matt-yss-adapter.md +9 -11
  104. package/template/.agents/skills/yss-product-lifecycle/references/orchestration-contract.yaml +136 -55
  105. package/template/.agents/skills/yss-product-lifecycle/references/orchestration.md +12 -6
  106. package/template/.agents/skills/yss-product-lifecycle/references/state-model.md +7 -2
  107. package/template/.agents/skills/yss-product-lifecycle/references/user-decisions.md +56 -0
  108. package/template/.agents/skills/yss-prototype-stage/SKILL.md +35 -24
  109. package/template/.agents/skills/yss-prototype-stage/references/product-design-adapter.md +66 -38
  110. package/template/.agents/skills/yss-prototype-stage/references/prototype-profile-routing.md +69 -0
  111. package/template/.agents/skills/yss-prototype-stage/scripts/prototype-contract.mjs +299 -103
  112. package/template/.agents/skills/yss-prototype-stage/scripts/visual-baseline-contract.mjs +314 -0
  113. package/template/.agents/skills/yss-prototype-stage/tests/run-scenarios.mjs +164 -132
  114. package/template/.agents/skills/yss-repository/SKILL.md +8 -2
  115. package/template/.agents/skills/yss-repository/references/profiles/layered-mvc-service.md +3 -0
  116. package/template/.agents/skills/yss-repository/references/profiles/mvc-data-analysis-v1.md +3 -0
  117. package/template/.agents/skills/yss-repository/references/profiles/target-domain-model.md +3 -0
  118. package/template/.agents/skills/yss-resilience4j/SKILL.md +1 -1
  119. package/template/.agents/skills/yss-resilience4j/references/source-index.md +1 -1
  120. package/template/.agents/skills/yss-security-algorithm/SKILL.md +1 -1
  121. package/template/.agents/skills/yss-security-algorithm/references/source-index.md +1 -1
  122. package/template/.agents/skills/yss-skill-source-index-refresh/SKILL.md +63 -0
  123. package/template/.agents/skills/yss-skill-source-index-refresh/agents/openai.yaml +4 -0
  124. package/template/.agents/skills/yss-skill-source-index-refresh/references/source-map-config.md +29 -0
  125. package/template/.agents/skills/yss-skill-source-index-refresh/scripts/refresh-yss-skill-index.mjs +24 -0
  126. package/template/.agents/skills/yss-stage-decision/SKILL.md +16 -12
  127. package/template/.agents/skills/yss-stage-decision/references/domain-strategy-contract.md +16 -10
  128. package/template/.agents/skills/yss-stage-decision/references/domain-strategy.schema.json +23 -5
  129. package/template/.agents/skills/yss-stage-decision/references/stage-decision-package-contract.md +5 -2
  130. package/template/.agents/skills/yss-stage-decision/references/stage-decision-package.schema.json +16 -4
  131. package/template/.agents/skills/yss-stage-decision/references/validation-rules.md +1 -1
  132. package/template/.agents/skills/yss-stage-decision/scripts/migrate-context-references.mjs +62 -0
  133. package/template/.agents/skills/yss-stage-decision/scripts/validate-domain-strategy.mjs +18 -7
  134. package/template/.agents/skills/yss-stage-decision/scripts/validate-stage-decision-package.mjs +20 -9
  135. package/template/.agents/skills/yss-stage-decision/tests/fixtures/domain-strategy-approval.yaml +1 -1
  136. package/template/.agents/skills/yss-stage-decision/tests/fixtures/stage-decision-approval.yaml +1 -1
  137. package/template/.agents/skills/yss-stage-decision/tests/fixtures/valid-stage-decision-package.yaml +12 -7
  138. package/template/.agents/skills/yss-stage-decision/tests/fixtures/valid-supplier-domain.yaml +9 -4
  139. package/template/.agents/skills/yss-stage-decision/tests/run-scenarios.mjs +134 -56
  140. package/template/.agents/skills/yss-tactical-design/SKILL.md +8 -2
  141. package/template/.agents/skills/yss-tactical-design/references/output-template.md +3 -0
  142. package/template/.agents/skills/yss-tactical-design/references/tactical-design-contract.md +3 -1
  143. package/template/.agents/skills/yss-tactical-design/scripts/validate-tactical-design.mjs +10 -2
  144. package/template/.agents/skills/yss-ui/SKILL.md +2 -2
  145. package/template/.agents/skills/yss-ui/assets/docs/guide/llms.md +0 -61
  146. package/template/.agents/skills/yss-ui-business-page-generation/SKILL.md +3 -3
  147. package/template/.agents/skills/yss-up-springboot3/SKILL.md +1 -1
  148. package/template/.agents/skills/yss-userinfo/SKILL.md +1 -1
  149. package/template/.agents/skills/yss-userinfo/references/source-index.md +1 -1
  150. package/template/.agents/skills/yss-validation/SKILL.md +2 -1
  151. package/template/.agents/skills/yss-validation/references/source-index.md +1 -1
  152. package/template/.agents/skills/yss-web-controller/SKILL.md +8 -2
  153. package/template/.agents/skills/yss-web-controller/references/profiles/layered-mvc-service.md +3 -0
  154. package/template/.agents/skills/yss-web-controller/references/profiles/mvc-data-analysis-v1.md +3 -0
  155. package/template/.agents/skills/yss-web-controller/references/profiles/target-domain-model.md +3 -0
  156. package/template/.agents/skills/yss-web-controller/references/web-generation-contract.schema.json +3 -2
  157. package/template/.agents/skills/yss-web-controller/scripts/generate_controller.mjs +27 -10
  158. package/template/.agents/skills/yss-web-controller/scripts/generate_controller.test.mjs +29 -1
  159. package/template/.claude/skills/alibaba-java-code-style/SKILL.md +1 -0
  160. package/template/.claude/skills/code-review/SKILL.md +1 -1
  161. package/template/.claude/skills/code-review/references/yss-review-standards.md +2 -2
  162. package/template/.claude/skills/domain-modeling/CONTEXT-FORMAT.md +37 -42
  163. package/template/.claude/skills/domain-modeling/SKILL.md +10 -26
  164. package/template/.claude/skills/grill-with-docs/SKILL.md +6 -5
  165. package/template/.claude/skills/lombok/SKILL.md +3 -2
  166. package/template/.claude/skills/mapstruct/SKILL.md +4 -3
  167. package/template/.claude/skills/prototype-review/SKILL.md +7 -6
  168. package/template/.claude/skills/setup-matt-pocock-skills/SKILL.md +5 -6
  169. package/template/.claude/skills/setup-matt-pocock-skills/domain.md +6 -20
  170. package/template/.claude/skills/wait-what/SKILL.md +1 -1
  171. package/template/.claude/skills/yss-antd-design/SKILL.md +8 -7
  172. package/template/.claude/skills/yss-antd-design/references/evidence.md +11 -6
  173. package/template/.claude/skills/yss-antdv-next-design/SKILL.md +48 -0
  174. package/template/.claude/skills/yss-antdv-next-design/references/boundaries.md +25 -0
  175. package/template/.claude/skills/yss-antdv-next-design/references/cli-matrix.md +34 -0
  176. package/template/.claude/skills/yss-antdv-next-design/references/fact-pack.md +38 -0
  177. package/template/.claude/skills/yss-antdv-next-design/scripts/collect-antdv-next-facts.mjs +213 -0
  178. package/template/.claude/skills/yss-antdv-next-design/scripts/validate-fact-pack.mjs +168 -0
  179. package/template/.claude/skills/yss-antdv-next-design/tests/run-scenarios.mjs +139 -0
  180. package/template/.claude/skills/yss-api-integration/SKILL.md +2 -2
  181. package/template/.claude/skills/yss-application/SKILL.md +8 -2
  182. package/template/.claude/skills/yss-application/references/profiles/layered-mvc-service.md +3 -0
  183. package/template/.claude/skills/yss-application/references/profiles/mvc-data-analysis-v1.md +3 -0
  184. package/template/.claude/skills/yss-application/references/profiles/target-domain-model.md +3 -0
  185. package/template/.claude/skills/yss-audit-log/SKILL.md +2 -2
  186. package/template/.claude/skills/yss-audit-log/references/source-index.md +1 -1
  187. package/template/.claude/skills/yss-cache/SKILL.md +2 -2
  188. package/template/.claude/skills/yss-cache/references/source-index.md +1 -1
  189. package/template/.claude/skills/yss-cache/scripts/check-skill-freshness.sh +1 -1
  190. package/template/.claude/skills/yss-components/SKILL.md +1 -1
  191. package/template/.claude/skills/yss-ddd-scaffold-generator/SKILL.md +8 -9
  192. package/template/.claude/skills/yss-ddd-scaffold-generator/agents/openai.yaml +1 -1
  193. package/template/.claude/skills/yss-ddd-scaffold-generator/assets/templates/config/application.yml.template +0 -13
  194. package/template/.claude/skills/yss-ddd-scaffold-generator/assets/templates/pom/bootstrap-pom.xml.template +13 -0
  195. package/template/.claude/skills/yss-ddd-scaffold-generator/references/ARCHITECTURE.md +1 -1
  196. package/template/.claude/skills/yss-ddd-scaffold-generator/references/USAGE_EXAMPLES.md +15 -6
  197. package/template/.claude/skills/yss-ddd-scaffold-generator/references/yss-backend-scaffold-parent/SKILL.md +2 -2
  198. package/template/.claude/skills/yss-ddd-scaffold-generator/scripts/first-slice-compatibility.test.mjs +23 -9
  199. package/template/.claude/skills/yss-ddd-scaffold-generator/scripts/first-slice-verification.test.mjs +3 -3
  200. package/template/.claude/skills/yss-ddd-scaffold-generator/scripts/generate_scaffold.mjs +43 -21
  201. package/template/.claude/skills/yss-ddd-scaffold-generator/scripts/run_first_slice_verification.mjs +23 -11
  202. package/template/.claude/skills/yss-ddd-scaffold-generator/scripts/run_scaffold_verification.mjs +15 -3
  203. package/template/.claude/skills/yss-ddd-scaffold-generator/scripts/scaffold-generator.test.mjs +44 -15
  204. package/template/.claude/skills/yss-design-system/SKILL.md +27 -24
  205. package/template/.claude/skills/yss-design-system/references/design-qa-theme.md +22 -24
  206. package/template/.claude/skills/yss-design-system/references/design-system.md +39 -56
  207. package/template/.claude/skills/yss-distributed-id/SKILL.md +2 -2
  208. package/template/.claude/skills/yss-distributed-id/references/source-index.md +1 -1
  209. package/template/.claude/skills/yss-domain/SKILL.md +2 -2
  210. package/template/.claude/skills/yss-dto/SKILL.md +3 -2
  211. package/template/.claude/skills/yss-dto/references/source-index.md +1 -1
  212. package/template/.claude/skills/yss-excel-mvc/SKILL.md +2 -2
  213. package/template/.claude/skills/yss-excel-mvc/references/source-index.md +1 -1
  214. package/template/.claude/skills/yss-exception/SKILL.md +2 -1
  215. package/template/.claude/skills/yss-exception/references/source-index.md +1 -1
  216. package/template/.claude/skills/yss-frontend-scaffold-generator/SKILL.md +1 -1
  217. package/template/.claude/skills/yss-implementation-contract-compiler/SKILL.md +61 -0
  218. package/template/.claude/skills/yss-implementation-contract-compiler/agents/openai.yaml +4 -0
  219. package/template/.claude/skills/yss-implementation-contract-compiler/references/boundaries.md +142 -0
  220. package/template/.claude/skills/yss-implementation-contract-compiler/references/compiler-contract.yaml +367 -0
  221. package/template/.claude/skills/yss-implementation-contract-compiler/references/slice-implementation-contract.md +201 -0
  222. package/template/.claude/skills/yss-implementation-contract-compiler/references/yss-skill-execution-result.md +71 -0
  223. package/template/.claude/skills/yss-implementation-contract-compiler/tests/backend-profiles.test.mjs +45 -0
  224. package/template/.claude/skills/yss-implementation-contract-compiler/tests/compiler-scenarios.test.mjs +91 -0
  225. package/template/.claude/skills/yss-layered-mvc-scaffold-generator/SKILL.md +64 -0
  226. package/template/.claude/skills/yss-layered-mvc-scaffold-generator/agents/openai.yaml +4 -0
  227. package/template/.claude/skills/yss-layered-mvc-scaffold-generator/references/architecture.md +29 -0
  228. package/template/.claude/skills/yss-layered-mvc-scaffold-generator/scripts/generate_and_verify_scaffold.mjs +61 -0
  229. package/template/.claude/skills/yss-layered-mvc-scaffold-generator/scripts/generate_scaffold.mjs +315 -0
  230. package/template/.claude/skills/yss-layered-mvc-scaffold-generator/scripts/run_scaffold_verification.mjs +30 -0
  231. package/template/.claude/skills/yss-layered-mvc-scaffold-generator/scripts/scaffold-generator.test.mjs +159 -0
  232. package/template/.claude/skills/yss-mvc-data-analysis-project-initializer/SKILL.md +22 -0
  233. package/template/.claude/skills/yss-mvc-data-analysis-project-initializer/scripts/generate_project.mjs +77 -0
  234. package/template/.claude/skills/yss-mvc-data-analysis-project-initializer/scripts/run_scaffold_verification.mjs +9 -0
  235. package/template/.claude/skills/yss-mvc-scaffold-generator/SKILL.md +8 -0
  236. package/template/.claude/skills/yss-mvc-scaffold-generator/agents/openai.yaml +4 -0
  237. package/template/.claude/skills/yss-mvc-scaffold-generator/assets/logback-spring.xml.template +50 -0
  238. package/template/.claude/skills/yss-mvc-scaffold-generator/assets/smart-doc.json.template +42 -0
  239. package/template/.claude/skills/yss-mvc-scaffold-generator/references/architecture.md +28 -0
  240. package/template/.claude/skills/yss-mvc-scaffold-generator/references/history/generate_project.mjs.txt +137 -0
  241. package/template/.claude/skills/yss-mvc-scaffold-generator/references/history/generate_project.test.mjs.txt +341 -0
  242. package/template/.claude/skills/yss-mvc-scaffold-generator/references/history/skill.md +87 -0
  243. package/template/.claude/skills/yss-mvc-scaffold-generator/scripts/generate_project.mjs +3 -0
  244. package/template/.claude/skills/yss-mvc-scaffold-generator/scripts/generate_project.test.mjs +9 -0
  245. package/template/.claude/skills/yss-mvc-scaffold-generator/scripts/lib/envelope.mjs +74 -0
  246. package/template/.claude/skills/yss-mvc-scaffold-generator/scripts/lib/envelope.test.mjs +36 -0
  247. package/template/.claude/skills/yss-mvc-scaffold-generator/scripts/lib/runtime.mjs +115 -0
  248. package/template/.claude/skills/yss-mvc-scaffold-generator/scripts/lib/storage.mjs +90 -0
  249. package/template/.claude/skills/yss-mvc-scaffold-generator/scripts/lib/templates.mjs +54 -0
  250. package/template/.claude/skills/yss-mvc-scaffold-generator/scripts/verify_project.mjs +103 -0
  251. package/template/.claude/skills/yss-mybatis/SKILL.md +4 -4
  252. package/template/.claude/skills/yss-mybatis/references/source-index.md +1 -1
  253. package/template/.claude/skills/yss-product-lifecycle/SKILL.md +35 -11
  254. package/template/.claude/skills/yss-product-lifecycle/references/artifact-dependencies.md +3 -0
  255. package/template/.claude/skills/yss-product-lifecycle/references/matt-yss-adapter.md +9 -11
  256. package/template/.claude/skills/yss-product-lifecycle/references/orchestration-contract.yaml +136 -55
  257. package/template/.claude/skills/yss-product-lifecycle/references/orchestration.md +12 -6
  258. package/template/.claude/skills/yss-product-lifecycle/references/state-model.md +7 -2
  259. package/template/.claude/skills/yss-product-lifecycle/references/user-decisions.md +56 -0
  260. package/template/.claude/skills/yss-prototype-stage/SKILL.md +35 -24
  261. package/template/.claude/skills/yss-prototype-stage/references/product-design-adapter.md +66 -38
  262. package/template/.claude/skills/yss-prototype-stage/references/prototype-profile-routing.md +69 -0
  263. package/template/.claude/skills/yss-prototype-stage/scripts/prototype-contract.mjs +299 -103
  264. package/template/.claude/skills/yss-prototype-stage/scripts/visual-baseline-contract.mjs +314 -0
  265. package/template/.claude/skills/yss-prototype-stage/tests/run-scenarios.mjs +164 -132
  266. package/template/.claude/skills/yss-repository/SKILL.md +8 -2
  267. package/template/.claude/skills/yss-repository/references/profiles/layered-mvc-service.md +3 -0
  268. package/template/.claude/skills/yss-repository/references/profiles/mvc-data-analysis-v1.md +3 -0
  269. package/template/.claude/skills/yss-repository/references/profiles/target-domain-model.md +3 -0
  270. package/template/.claude/skills/yss-resilience4j/SKILL.md +1 -1
  271. package/template/.claude/skills/yss-resilience4j/references/source-index.md +1 -1
  272. package/template/.claude/skills/yss-security-algorithm/SKILL.md +1 -1
  273. package/template/.claude/skills/yss-security-algorithm/references/source-index.md +1 -1
  274. package/template/.claude/skills/yss-skill-source-index-refresh/SKILL.md +63 -0
  275. package/template/.claude/skills/yss-skill-source-index-refresh/agents/openai.yaml +4 -0
  276. package/template/.claude/skills/yss-skill-source-index-refresh/references/source-map-config.md +29 -0
  277. package/template/.claude/skills/yss-skill-source-index-refresh/scripts/refresh-yss-skill-index.mjs +24 -0
  278. package/template/.claude/skills/yss-stage-decision/SKILL.md +16 -12
  279. package/template/.claude/skills/yss-stage-decision/references/domain-strategy-contract.md +16 -10
  280. package/template/.claude/skills/yss-stage-decision/references/domain-strategy.schema.json +23 -5
  281. package/template/.claude/skills/yss-stage-decision/references/stage-decision-package-contract.md +5 -2
  282. package/template/.claude/skills/yss-stage-decision/references/stage-decision-package.schema.json +16 -4
  283. package/template/.claude/skills/yss-stage-decision/references/validation-rules.md +1 -1
  284. package/template/.claude/skills/yss-stage-decision/scripts/migrate-context-references.mjs +62 -0
  285. package/template/.claude/skills/yss-stage-decision/scripts/validate-domain-strategy.mjs +18 -7
  286. package/template/.claude/skills/yss-stage-decision/scripts/validate-stage-decision-package.mjs +20 -9
  287. package/template/.claude/skills/yss-stage-decision/tests/fixtures/domain-strategy-approval.yaml +1 -1
  288. package/template/.claude/skills/yss-stage-decision/tests/fixtures/stage-decision-approval.yaml +1 -1
  289. package/template/.claude/skills/yss-stage-decision/tests/fixtures/valid-stage-decision-package.yaml +12 -7
  290. package/template/.claude/skills/yss-stage-decision/tests/fixtures/valid-supplier-domain.yaml +9 -4
  291. package/template/.claude/skills/yss-stage-decision/tests/run-scenarios.mjs +134 -56
  292. package/template/.claude/skills/yss-tactical-design/SKILL.md +8 -2
  293. package/template/.claude/skills/yss-tactical-design/references/output-template.md +3 -0
  294. package/template/.claude/skills/yss-tactical-design/references/tactical-design-contract.md +3 -1
  295. package/template/.claude/skills/yss-tactical-design/scripts/validate-tactical-design.mjs +10 -2
  296. package/template/.claude/skills/yss-ui/SKILL.md +2 -2
  297. package/template/.claude/skills/yss-ui/assets/docs/guide/llms.md +0 -61
  298. package/template/.claude/skills/yss-ui-business-page-generation/SKILL.md +3 -3
  299. package/template/.claude/skills/yss-up-springboot3/SKILL.md +1 -1
  300. package/template/.claude/skills/yss-userinfo/SKILL.md +1 -1
  301. package/template/.claude/skills/yss-userinfo/references/source-index.md +1 -1
  302. package/template/.claude/skills/yss-validation/SKILL.md +2 -1
  303. package/template/.claude/skills/yss-validation/references/source-index.md +1 -1
  304. package/template/.claude/skills/yss-web-controller/SKILL.md +8 -2
  305. package/template/.claude/skills/yss-web-controller/references/profiles/layered-mvc-service.md +3 -0
  306. package/template/.claude/skills/yss-web-controller/references/profiles/mvc-data-analysis-v1.md +3 -0
  307. package/template/.claude/skills/yss-web-controller/references/profiles/target-domain-model.md +3 -0
  308. package/template/.claude/skills/yss-web-controller/references/web-generation-contract.schema.json +3 -2
  309. package/template/.claude/skills/yss-web-controller/scripts/generate_controller.mjs +27 -10
  310. package/template/.claude/skills/yss-web-controller/scripts/generate_controller.test.mjs +29 -1
  311. package/template/.codex/skills/alibaba-java-code-style/SKILL.md +1 -0
  312. package/template/.codex/skills/code-review/SKILL.md +1 -1
  313. package/template/.codex/skills/code-review/references/yss-review-standards.md +2 -2
  314. package/template/.codex/skills/domain-modeling/CONTEXT-FORMAT.md +37 -42
  315. package/template/.codex/skills/domain-modeling/SKILL.md +10 -26
  316. package/template/.codex/skills/grill-with-docs/SKILL.md +6 -5
  317. package/template/.codex/skills/lombok/SKILL.md +3 -2
  318. package/template/.codex/skills/mapstruct/SKILL.md +4 -3
  319. package/template/.codex/skills/prototype-review/SKILL.md +7 -6
  320. package/template/.codex/skills/setup-matt-pocock-skills/SKILL.md +5 -6
  321. package/template/.codex/skills/setup-matt-pocock-skills/domain.md +6 -20
  322. package/template/.codex/skills/wait-what/SKILL.md +1 -1
  323. package/template/.codex/skills/yss-antd-design/SKILL.md +8 -7
  324. package/template/.codex/skills/yss-antd-design/references/evidence.md +11 -6
  325. package/template/.codex/skills/yss-antdv-next-design/SKILL.md +48 -0
  326. package/template/.codex/skills/yss-antdv-next-design/references/boundaries.md +25 -0
  327. package/template/.codex/skills/yss-antdv-next-design/references/cli-matrix.md +34 -0
  328. package/template/.codex/skills/yss-antdv-next-design/references/fact-pack.md +38 -0
  329. package/template/.codex/skills/yss-antdv-next-design/scripts/collect-antdv-next-facts.mjs +213 -0
  330. package/template/.codex/skills/yss-antdv-next-design/scripts/validate-fact-pack.mjs +168 -0
  331. package/template/.codex/skills/yss-antdv-next-design/tests/run-scenarios.mjs +139 -0
  332. package/template/.codex/skills/yss-api-integration/SKILL.md +2 -2
  333. package/template/.codex/skills/yss-application/SKILL.md +8 -2
  334. package/template/.codex/skills/yss-application/references/profiles/layered-mvc-service.md +3 -0
  335. package/template/.codex/skills/yss-application/references/profiles/mvc-data-analysis-v1.md +3 -0
  336. package/template/.codex/skills/yss-application/references/profiles/target-domain-model.md +3 -0
  337. package/template/.codex/skills/yss-audit-log/SKILL.md +2 -2
  338. package/template/.codex/skills/yss-audit-log/references/source-index.md +1 -1
  339. package/template/.codex/skills/yss-cache/SKILL.md +2 -2
  340. package/template/.codex/skills/yss-cache/references/source-index.md +1 -1
  341. package/template/.codex/skills/yss-cache/scripts/check-skill-freshness.sh +1 -1
  342. package/template/.codex/skills/yss-components/SKILL.md +1 -1
  343. package/template/.codex/skills/yss-ddd-scaffold-generator/SKILL.md +8 -9
  344. package/template/.codex/skills/yss-ddd-scaffold-generator/agents/openai.yaml +1 -1
  345. package/template/.codex/skills/yss-ddd-scaffold-generator/assets/templates/config/application.yml.template +0 -13
  346. package/template/.codex/skills/yss-ddd-scaffold-generator/assets/templates/pom/bootstrap-pom.xml.template +13 -0
  347. package/template/.codex/skills/yss-ddd-scaffold-generator/references/ARCHITECTURE.md +1 -1
  348. package/template/.codex/skills/yss-ddd-scaffold-generator/references/USAGE_EXAMPLES.md +15 -6
  349. package/template/.codex/skills/yss-ddd-scaffold-generator/references/yss-backend-scaffold-parent/SKILL.md +2 -2
  350. package/template/.codex/skills/yss-ddd-scaffold-generator/scripts/first-slice-compatibility.test.mjs +23 -9
  351. package/template/.codex/skills/yss-ddd-scaffold-generator/scripts/first-slice-verification.test.mjs +3 -3
  352. package/template/.codex/skills/yss-ddd-scaffold-generator/scripts/generate_scaffold.mjs +43 -21
  353. package/template/.codex/skills/yss-ddd-scaffold-generator/scripts/run_first_slice_verification.mjs +23 -11
  354. package/template/.codex/skills/yss-ddd-scaffold-generator/scripts/run_scaffold_verification.mjs +15 -3
  355. package/template/.codex/skills/yss-ddd-scaffold-generator/scripts/scaffold-generator.test.mjs +44 -15
  356. package/template/.codex/skills/yss-design-system/SKILL.md +27 -24
  357. package/template/.codex/skills/yss-design-system/references/design-qa-theme.md +22 -24
  358. package/template/.codex/skills/yss-design-system/references/design-system.md +39 -56
  359. package/template/.codex/skills/yss-distributed-id/SKILL.md +2 -2
  360. package/template/.codex/skills/yss-distributed-id/references/source-index.md +1 -1
  361. package/template/.codex/skills/yss-domain/SKILL.md +2 -2
  362. package/template/.codex/skills/yss-dto/SKILL.md +3 -2
  363. package/template/.codex/skills/yss-dto/references/source-index.md +1 -1
  364. package/template/.codex/skills/yss-excel-mvc/SKILL.md +2 -2
  365. package/template/.codex/skills/yss-excel-mvc/references/source-index.md +1 -1
  366. package/template/.codex/skills/yss-exception/SKILL.md +2 -1
  367. package/template/.codex/skills/yss-exception/references/source-index.md +1 -1
  368. package/template/.codex/skills/yss-frontend-scaffold-generator/SKILL.md +1 -1
  369. package/template/.codex/skills/yss-implementation-contract-compiler/SKILL.md +61 -0
  370. package/template/.codex/skills/yss-implementation-contract-compiler/agents/openai.yaml +4 -0
  371. package/template/.codex/skills/yss-implementation-contract-compiler/references/boundaries.md +142 -0
  372. package/template/.codex/skills/yss-implementation-contract-compiler/references/compiler-contract.yaml +367 -0
  373. package/template/.codex/skills/yss-implementation-contract-compiler/references/slice-implementation-contract.md +201 -0
  374. package/template/.codex/skills/yss-implementation-contract-compiler/references/yss-skill-execution-result.md +71 -0
  375. package/template/.codex/skills/yss-implementation-contract-compiler/tests/backend-profiles.test.mjs +45 -0
  376. package/template/.codex/skills/yss-implementation-contract-compiler/tests/compiler-scenarios.test.mjs +91 -0
  377. package/template/.codex/skills/yss-layered-mvc-scaffold-generator/SKILL.md +64 -0
  378. package/template/.codex/skills/yss-layered-mvc-scaffold-generator/agents/openai.yaml +4 -0
  379. package/template/.codex/skills/yss-layered-mvc-scaffold-generator/references/architecture.md +29 -0
  380. package/template/.codex/skills/yss-layered-mvc-scaffold-generator/scripts/generate_and_verify_scaffold.mjs +61 -0
  381. package/template/.codex/skills/yss-layered-mvc-scaffold-generator/scripts/generate_scaffold.mjs +315 -0
  382. package/template/.codex/skills/yss-layered-mvc-scaffold-generator/scripts/run_scaffold_verification.mjs +30 -0
  383. package/template/.codex/skills/yss-layered-mvc-scaffold-generator/scripts/scaffold-generator.test.mjs +159 -0
  384. package/template/.codex/skills/yss-mvc-data-analysis-project-initializer/SKILL.md +22 -0
  385. package/template/.codex/skills/yss-mvc-data-analysis-project-initializer/scripts/generate_project.mjs +77 -0
  386. package/template/.codex/skills/yss-mvc-data-analysis-project-initializer/scripts/run_scaffold_verification.mjs +9 -0
  387. package/template/.codex/skills/yss-mvc-scaffold-generator/SKILL.md +8 -0
  388. package/template/.codex/skills/yss-mvc-scaffold-generator/agents/openai.yaml +4 -0
  389. package/template/.codex/skills/yss-mvc-scaffold-generator/assets/logback-spring.xml.template +50 -0
  390. package/template/.codex/skills/yss-mvc-scaffold-generator/assets/smart-doc.json.template +42 -0
  391. package/template/.codex/skills/yss-mvc-scaffold-generator/references/architecture.md +28 -0
  392. package/template/.codex/skills/yss-mvc-scaffold-generator/references/history/generate_project.mjs.txt +137 -0
  393. package/template/.codex/skills/yss-mvc-scaffold-generator/references/history/generate_project.test.mjs.txt +341 -0
  394. package/template/.codex/skills/yss-mvc-scaffold-generator/references/history/skill.md +87 -0
  395. package/template/.codex/skills/yss-mvc-scaffold-generator/scripts/generate_project.mjs +3 -0
  396. package/template/.codex/skills/yss-mvc-scaffold-generator/scripts/generate_project.test.mjs +9 -0
  397. package/template/.codex/skills/yss-mvc-scaffold-generator/scripts/lib/envelope.mjs +74 -0
  398. package/template/.codex/skills/yss-mvc-scaffold-generator/scripts/lib/envelope.test.mjs +36 -0
  399. package/template/.codex/skills/yss-mvc-scaffold-generator/scripts/lib/runtime.mjs +115 -0
  400. package/template/.codex/skills/yss-mvc-scaffold-generator/scripts/lib/storage.mjs +90 -0
  401. package/template/.codex/skills/yss-mvc-scaffold-generator/scripts/lib/templates.mjs +54 -0
  402. package/template/.codex/skills/yss-mvc-scaffold-generator/scripts/verify_project.mjs +103 -0
  403. package/template/.codex/skills/yss-mybatis/SKILL.md +4 -4
  404. package/template/.codex/skills/yss-mybatis/references/source-index.md +1 -1
  405. package/template/.codex/skills/yss-product-lifecycle/SKILL.md +35 -11
  406. package/template/.codex/skills/yss-product-lifecycle/references/artifact-dependencies.md +3 -0
  407. package/template/.codex/skills/yss-product-lifecycle/references/matt-yss-adapter.md +9 -11
  408. package/template/.codex/skills/yss-product-lifecycle/references/orchestration-contract.yaml +136 -55
  409. package/template/.codex/skills/yss-product-lifecycle/references/orchestration.md +12 -6
  410. package/template/.codex/skills/yss-product-lifecycle/references/state-model.md +7 -2
  411. package/template/.codex/skills/yss-product-lifecycle/references/user-decisions.md +56 -0
  412. package/template/.codex/skills/yss-prototype-stage/SKILL.md +35 -24
  413. package/template/.codex/skills/yss-prototype-stage/references/product-design-adapter.md +66 -38
  414. package/template/.codex/skills/yss-prototype-stage/references/prototype-profile-routing.md +69 -0
  415. package/template/.codex/skills/yss-prototype-stage/scripts/prototype-contract.mjs +299 -103
  416. package/template/.codex/skills/yss-prototype-stage/scripts/visual-baseline-contract.mjs +314 -0
  417. package/template/.codex/skills/yss-prototype-stage/tests/run-scenarios.mjs +164 -132
  418. package/template/.codex/skills/yss-repository/SKILL.md +8 -2
  419. package/template/.codex/skills/yss-repository/references/profiles/layered-mvc-service.md +3 -0
  420. package/template/.codex/skills/yss-repository/references/profiles/mvc-data-analysis-v1.md +3 -0
  421. package/template/.codex/skills/yss-repository/references/profiles/target-domain-model.md +3 -0
  422. package/template/.codex/skills/yss-resilience4j/SKILL.md +1 -1
  423. package/template/.codex/skills/yss-resilience4j/references/source-index.md +1 -1
  424. package/template/.codex/skills/yss-security-algorithm/SKILL.md +1 -1
  425. package/template/.codex/skills/yss-security-algorithm/references/source-index.md +1 -1
  426. package/template/.codex/skills/yss-skill-source-index-refresh/SKILL.md +63 -0
  427. package/template/.codex/skills/yss-skill-source-index-refresh/agents/openai.yaml +4 -0
  428. package/template/.codex/skills/yss-skill-source-index-refresh/references/source-map-config.md +29 -0
  429. package/template/.codex/skills/yss-skill-source-index-refresh/scripts/refresh-yss-skill-index.mjs +24 -0
  430. package/template/.codex/skills/yss-stage-decision/SKILL.md +16 -12
  431. package/template/.codex/skills/yss-stage-decision/references/domain-strategy-contract.md +16 -10
  432. package/template/.codex/skills/yss-stage-decision/references/domain-strategy.schema.json +23 -5
  433. package/template/.codex/skills/yss-stage-decision/references/stage-decision-package-contract.md +5 -2
  434. package/template/.codex/skills/yss-stage-decision/references/stage-decision-package.schema.json +16 -4
  435. package/template/.codex/skills/yss-stage-decision/references/validation-rules.md +1 -1
  436. package/template/.codex/skills/yss-stage-decision/scripts/migrate-context-references.mjs +62 -0
  437. package/template/.codex/skills/yss-stage-decision/scripts/validate-domain-strategy.mjs +18 -7
  438. package/template/.codex/skills/yss-stage-decision/scripts/validate-stage-decision-package.mjs +20 -9
  439. package/template/.codex/skills/yss-stage-decision/tests/fixtures/domain-strategy-approval.yaml +1 -1
  440. package/template/.codex/skills/yss-stage-decision/tests/fixtures/stage-decision-approval.yaml +1 -1
  441. package/template/.codex/skills/yss-stage-decision/tests/fixtures/valid-stage-decision-package.yaml +12 -7
  442. package/template/.codex/skills/yss-stage-decision/tests/fixtures/valid-supplier-domain.yaml +9 -4
  443. package/template/.codex/skills/yss-stage-decision/tests/run-scenarios.mjs +134 -56
  444. package/template/.codex/skills/yss-tactical-design/SKILL.md +8 -2
  445. package/template/.codex/skills/yss-tactical-design/references/output-template.md +3 -0
  446. package/template/.codex/skills/yss-tactical-design/references/tactical-design-contract.md +3 -1
  447. package/template/.codex/skills/yss-tactical-design/scripts/validate-tactical-design.mjs +10 -2
  448. package/template/.codex/skills/yss-ui/SKILL.md +2 -2
  449. package/template/.codex/skills/yss-ui/assets/docs/guide/llms.md +0 -61
  450. package/template/.codex/skills/yss-ui-business-page-generation/SKILL.md +3 -3
  451. package/template/.codex/skills/yss-up-springboot3/SKILL.md +1 -1
  452. package/template/.codex/skills/yss-userinfo/SKILL.md +1 -1
  453. package/template/.codex/skills/yss-userinfo/references/source-index.md +1 -1
  454. package/template/.codex/skills/yss-validation/SKILL.md +2 -1
  455. package/template/.codex/skills/yss-validation/references/source-index.md +1 -1
  456. package/template/.codex/skills/yss-web-controller/SKILL.md +8 -2
  457. package/template/.codex/skills/yss-web-controller/references/profiles/layered-mvc-service.md +3 -0
  458. package/template/.codex/skills/yss-web-controller/references/profiles/mvc-data-analysis-v1.md +3 -0
  459. package/template/.codex/skills/yss-web-controller/references/profiles/target-domain-model.md +3 -0
  460. package/template/.codex/skills/yss-web-controller/references/web-generation-contract.schema.json +3 -2
  461. package/template/.codex/skills/yss-web-controller/scripts/generate_controller.mjs +27 -10
  462. package/template/.codex/skills/yss-web-controller/scripts/generate_controller.test.mjs +29 -1
  463. package/template/.cursor/skills/alibaba-java-code-style/SKILL.md +1 -0
  464. package/template/.cursor/skills/code-review/SKILL.md +1 -1
  465. package/template/.cursor/skills/code-review/references/yss-review-standards.md +2 -2
  466. package/template/.cursor/skills/domain-modeling/CONTEXT-FORMAT.md +37 -42
  467. package/template/.cursor/skills/domain-modeling/SKILL.md +10 -26
  468. package/template/.cursor/skills/grill-with-docs/SKILL.md +6 -5
  469. package/template/.cursor/skills/lombok/SKILL.md +3 -2
  470. package/template/.cursor/skills/mapstruct/SKILL.md +4 -3
  471. package/template/.cursor/skills/prototype-review/SKILL.md +7 -6
  472. package/template/.cursor/skills/setup-matt-pocock-skills/SKILL.md +5 -6
  473. package/template/.cursor/skills/setup-matt-pocock-skills/domain.md +6 -20
  474. package/template/.cursor/skills/wait-what/SKILL.md +1 -1
  475. package/template/.cursor/skills/yss-antd-design/SKILL.md +8 -7
  476. package/template/.cursor/skills/yss-antd-design/references/evidence.md +11 -6
  477. package/template/.cursor/skills/yss-antdv-next-design/SKILL.md +48 -0
  478. package/template/.cursor/skills/yss-antdv-next-design/references/boundaries.md +25 -0
  479. package/template/.cursor/skills/yss-antdv-next-design/references/cli-matrix.md +34 -0
  480. package/template/.cursor/skills/yss-antdv-next-design/references/fact-pack.md +38 -0
  481. package/template/.cursor/skills/yss-antdv-next-design/scripts/collect-antdv-next-facts.mjs +213 -0
  482. package/template/.cursor/skills/yss-antdv-next-design/scripts/validate-fact-pack.mjs +168 -0
  483. package/template/.cursor/skills/yss-antdv-next-design/tests/run-scenarios.mjs +139 -0
  484. package/template/.cursor/skills/yss-api-integration/SKILL.md +2 -2
  485. package/template/.cursor/skills/yss-application/SKILL.md +8 -2
  486. package/template/.cursor/skills/yss-application/references/profiles/layered-mvc-service.md +3 -0
  487. package/template/.cursor/skills/yss-application/references/profiles/mvc-data-analysis-v1.md +3 -0
  488. package/template/.cursor/skills/yss-application/references/profiles/target-domain-model.md +3 -0
  489. package/template/.cursor/skills/yss-audit-log/SKILL.md +2 -2
  490. package/template/.cursor/skills/yss-audit-log/references/source-index.md +1 -1
  491. package/template/.cursor/skills/yss-cache/SKILL.md +2 -2
  492. package/template/.cursor/skills/yss-cache/references/source-index.md +1 -1
  493. package/template/.cursor/skills/yss-cache/scripts/check-skill-freshness.sh +1 -1
  494. package/template/.cursor/skills/yss-components/SKILL.md +1 -1
  495. package/template/.cursor/skills/yss-ddd-scaffold-generator/SKILL.md +8 -9
  496. package/template/.cursor/skills/yss-ddd-scaffold-generator/agents/openai.yaml +1 -1
  497. package/template/.cursor/skills/yss-ddd-scaffold-generator/assets/templates/config/application.yml.template +0 -13
  498. package/template/.cursor/skills/yss-ddd-scaffold-generator/assets/templates/pom/bootstrap-pom.xml.template +13 -0
  499. package/template/.cursor/skills/yss-ddd-scaffold-generator/references/ARCHITECTURE.md +1 -1
  500. package/template/.cursor/skills/yss-ddd-scaffold-generator/references/USAGE_EXAMPLES.md +15 -6
  501. package/template/.cursor/skills/yss-ddd-scaffold-generator/references/yss-backend-scaffold-parent/SKILL.md +2 -2
  502. package/template/.cursor/skills/yss-ddd-scaffold-generator/scripts/first-slice-compatibility.test.mjs +23 -9
  503. package/template/.cursor/skills/yss-ddd-scaffold-generator/scripts/first-slice-verification.test.mjs +3 -3
  504. package/template/.cursor/skills/yss-ddd-scaffold-generator/scripts/generate_scaffold.mjs +43 -21
  505. package/template/.cursor/skills/yss-ddd-scaffold-generator/scripts/run_first_slice_verification.mjs +23 -11
  506. package/template/.cursor/skills/yss-ddd-scaffold-generator/scripts/run_scaffold_verification.mjs +15 -3
  507. package/template/.cursor/skills/yss-ddd-scaffold-generator/scripts/scaffold-generator.test.mjs +44 -15
  508. package/template/.cursor/skills/yss-design-system/SKILL.md +27 -24
  509. package/template/.cursor/skills/yss-design-system/references/design-qa-theme.md +22 -24
  510. package/template/.cursor/skills/yss-design-system/references/design-system.md +39 -56
  511. package/template/.cursor/skills/yss-distributed-id/SKILL.md +2 -2
  512. package/template/.cursor/skills/yss-distributed-id/references/source-index.md +1 -1
  513. package/template/.cursor/skills/yss-domain/SKILL.md +2 -2
  514. package/template/.cursor/skills/yss-dto/SKILL.md +3 -2
  515. package/template/.cursor/skills/yss-dto/references/source-index.md +1 -1
  516. package/template/.cursor/skills/yss-excel-mvc/SKILL.md +2 -2
  517. package/template/.cursor/skills/yss-excel-mvc/references/source-index.md +1 -1
  518. package/template/.cursor/skills/yss-exception/SKILL.md +2 -1
  519. package/template/.cursor/skills/yss-exception/references/source-index.md +1 -1
  520. package/template/.cursor/skills/yss-frontend-scaffold-generator/SKILL.md +1 -1
  521. package/template/.cursor/skills/yss-implementation-contract-compiler/SKILL.md +61 -0
  522. package/template/.cursor/skills/yss-implementation-contract-compiler/agents/openai.yaml +4 -0
  523. package/template/.cursor/skills/yss-implementation-contract-compiler/references/boundaries.md +142 -0
  524. package/template/.cursor/skills/yss-implementation-contract-compiler/references/compiler-contract.yaml +367 -0
  525. package/template/.cursor/skills/yss-implementation-contract-compiler/references/slice-implementation-contract.md +201 -0
  526. package/template/.cursor/skills/yss-implementation-contract-compiler/references/yss-skill-execution-result.md +71 -0
  527. package/template/.cursor/skills/yss-implementation-contract-compiler/tests/backend-profiles.test.mjs +45 -0
  528. package/template/.cursor/skills/yss-implementation-contract-compiler/tests/compiler-scenarios.test.mjs +91 -0
  529. package/template/.cursor/skills/yss-layered-mvc-scaffold-generator/SKILL.md +64 -0
  530. package/template/.cursor/skills/yss-layered-mvc-scaffold-generator/agents/openai.yaml +4 -0
  531. package/template/.cursor/skills/yss-layered-mvc-scaffold-generator/references/architecture.md +29 -0
  532. package/template/.cursor/skills/yss-layered-mvc-scaffold-generator/scripts/generate_and_verify_scaffold.mjs +61 -0
  533. package/template/.cursor/skills/yss-layered-mvc-scaffold-generator/scripts/generate_scaffold.mjs +315 -0
  534. package/template/.cursor/skills/yss-layered-mvc-scaffold-generator/scripts/run_scaffold_verification.mjs +30 -0
  535. package/template/.cursor/skills/yss-layered-mvc-scaffold-generator/scripts/scaffold-generator.test.mjs +159 -0
  536. package/template/.cursor/skills/yss-mvc-data-analysis-project-initializer/SKILL.md +22 -0
  537. package/template/.cursor/skills/yss-mvc-data-analysis-project-initializer/scripts/generate_project.mjs +77 -0
  538. package/template/.cursor/skills/yss-mvc-data-analysis-project-initializer/scripts/run_scaffold_verification.mjs +9 -0
  539. package/template/.cursor/skills/yss-mvc-scaffold-generator/SKILL.md +8 -0
  540. package/template/.cursor/skills/yss-mvc-scaffold-generator/agents/openai.yaml +4 -0
  541. package/template/.cursor/skills/yss-mvc-scaffold-generator/assets/logback-spring.xml.template +50 -0
  542. package/template/.cursor/skills/yss-mvc-scaffold-generator/assets/smart-doc.json.template +42 -0
  543. package/template/.cursor/skills/yss-mvc-scaffold-generator/references/architecture.md +28 -0
  544. package/template/.cursor/skills/yss-mvc-scaffold-generator/references/history/generate_project.mjs.txt +137 -0
  545. package/template/.cursor/skills/yss-mvc-scaffold-generator/references/history/generate_project.test.mjs.txt +341 -0
  546. package/template/.cursor/skills/yss-mvc-scaffold-generator/references/history/skill.md +87 -0
  547. package/template/.cursor/skills/yss-mvc-scaffold-generator/scripts/generate_project.mjs +3 -0
  548. package/template/.cursor/skills/yss-mvc-scaffold-generator/scripts/generate_project.test.mjs +9 -0
  549. package/template/.cursor/skills/yss-mvc-scaffold-generator/scripts/lib/envelope.mjs +74 -0
  550. package/template/.cursor/skills/yss-mvc-scaffold-generator/scripts/lib/envelope.test.mjs +36 -0
  551. package/template/.cursor/skills/yss-mvc-scaffold-generator/scripts/lib/runtime.mjs +115 -0
  552. package/template/.cursor/skills/yss-mvc-scaffold-generator/scripts/lib/storage.mjs +90 -0
  553. package/template/.cursor/skills/yss-mvc-scaffold-generator/scripts/lib/templates.mjs +54 -0
  554. package/template/.cursor/skills/yss-mvc-scaffold-generator/scripts/verify_project.mjs +103 -0
  555. package/template/.cursor/skills/yss-mybatis/SKILL.md +4 -4
  556. package/template/.cursor/skills/yss-mybatis/references/source-index.md +1 -1
  557. package/template/.cursor/skills/yss-product-lifecycle/SKILL.md +35 -11
  558. package/template/.cursor/skills/yss-product-lifecycle/references/artifact-dependencies.md +3 -0
  559. package/template/.cursor/skills/yss-product-lifecycle/references/matt-yss-adapter.md +9 -11
  560. package/template/.cursor/skills/yss-product-lifecycle/references/orchestration-contract.yaml +136 -55
  561. package/template/.cursor/skills/yss-product-lifecycle/references/orchestration.md +12 -6
  562. package/template/.cursor/skills/yss-product-lifecycle/references/state-model.md +7 -2
  563. package/template/.cursor/skills/yss-product-lifecycle/references/user-decisions.md +56 -0
  564. package/template/.cursor/skills/yss-prototype-stage/SKILL.md +35 -24
  565. package/template/.cursor/skills/yss-prototype-stage/references/product-design-adapter.md +66 -38
  566. package/template/.cursor/skills/yss-prototype-stage/references/prototype-profile-routing.md +69 -0
  567. package/template/.cursor/skills/yss-prototype-stage/scripts/prototype-contract.mjs +299 -103
  568. package/template/.cursor/skills/yss-prototype-stage/scripts/visual-baseline-contract.mjs +314 -0
  569. package/template/.cursor/skills/yss-prototype-stage/tests/run-scenarios.mjs +164 -132
  570. package/template/.cursor/skills/yss-repository/SKILL.md +8 -2
  571. package/template/.cursor/skills/yss-repository/references/profiles/layered-mvc-service.md +3 -0
  572. package/template/.cursor/skills/yss-repository/references/profiles/mvc-data-analysis-v1.md +3 -0
  573. package/template/.cursor/skills/yss-repository/references/profiles/target-domain-model.md +3 -0
  574. package/template/.cursor/skills/yss-resilience4j/SKILL.md +1 -1
  575. package/template/.cursor/skills/yss-resilience4j/references/source-index.md +1 -1
  576. package/template/.cursor/skills/yss-security-algorithm/SKILL.md +1 -1
  577. package/template/.cursor/skills/yss-security-algorithm/references/source-index.md +1 -1
  578. package/template/.cursor/skills/yss-skill-source-index-refresh/SKILL.md +63 -0
  579. package/template/.cursor/skills/yss-skill-source-index-refresh/agents/openai.yaml +4 -0
  580. package/template/.cursor/skills/yss-skill-source-index-refresh/references/source-map-config.md +29 -0
  581. package/template/.cursor/skills/yss-skill-source-index-refresh/scripts/refresh-yss-skill-index.mjs +24 -0
  582. package/template/.cursor/skills/yss-stage-decision/SKILL.md +16 -12
  583. package/template/.cursor/skills/yss-stage-decision/references/domain-strategy-contract.md +16 -10
  584. package/template/.cursor/skills/yss-stage-decision/references/domain-strategy.schema.json +23 -5
  585. package/template/.cursor/skills/yss-stage-decision/references/stage-decision-package-contract.md +5 -2
  586. package/template/.cursor/skills/yss-stage-decision/references/stage-decision-package.schema.json +16 -4
  587. package/template/.cursor/skills/yss-stage-decision/references/validation-rules.md +1 -1
  588. package/template/.cursor/skills/yss-stage-decision/scripts/migrate-context-references.mjs +62 -0
  589. package/template/.cursor/skills/yss-stage-decision/scripts/validate-domain-strategy.mjs +18 -7
  590. package/template/.cursor/skills/yss-stage-decision/scripts/validate-stage-decision-package.mjs +20 -9
  591. package/template/.cursor/skills/yss-stage-decision/tests/fixtures/domain-strategy-approval.yaml +1 -1
  592. package/template/.cursor/skills/yss-stage-decision/tests/fixtures/stage-decision-approval.yaml +1 -1
  593. package/template/.cursor/skills/yss-stage-decision/tests/fixtures/valid-stage-decision-package.yaml +12 -7
  594. package/template/.cursor/skills/yss-stage-decision/tests/fixtures/valid-supplier-domain.yaml +9 -4
  595. package/template/.cursor/skills/yss-stage-decision/tests/run-scenarios.mjs +134 -56
  596. package/template/.cursor/skills/yss-tactical-design/SKILL.md +8 -2
  597. package/template/.cursor/skills/yss-tactical-design/references/output-template.md +3 -0
  598. package/template/.cursor/skills/yss-tactical-design/references/tactical-design-contract.md +3 -1
  599. package/template/.cursor/skills/yss-tactical-design/scripts/validate-tactical-design.mjs +10 -2
  600. package/template/.cursor/skills/yss-ui/SKILL.md +2 -2
  601. package/template/.cursor/skills/yss-ui/assets/docs/guide/llms.md +0 -61
  602. package/template/.cursor/skills/yss-ui-business-page-generation/SKILL.md +3 -3
  603. package/template/.cursor/skills/yss-up-springboot3/SKILL.md +1 -1
  604. package/template/.cursor/skills/yss-userinfo/SKILL.md +1 -1
  605. package/template/.cursor/skills/yss-userinfo/references/source-index.md +1 -1
  606. package/template/.cursor/skills/yss-validation/SKILL.md +2 -1
  607. package/template/.cursor/skills/yss-validation/references/source-index.md +1 -1
  608. package/template/.cursor/skills/yss-web-controller/SKILL.md +8 -2
  609. package/template/.cursor/skills/yss-web-controller/references/profiles/layered-mvc-service.md +3 -0
  610. package/template/.cursor/skills/yss-web-controller/references/profiles/mvc-data-analysis-v1.md +3 -0
  611. package/template/.cursor/skills/yss-web-controller/references/profiles/target-domain-model.md +3 -0
  612. package/template/.cursor/skills/yss-web-controller/references/web-generation-contract.schema.json +3 -2
  613. package/template/.cursor/skills/yss-web-controller/scripts/generate_controller.mjs +27 -10
  614. package/template/.cursor/skills/yss-web-controller/scripts/generate_controller.test.mjs +29 -1
  615. package/template/.cursorrules +6 -34
  616. package/template/.pi/skills/alibaba-java-code-style/SKILL.md +1 -0
  617. package/template/.pi/skills/code-review/SKILL.md +1 -1
  618. package/template/.pi/skills/code-review/references/yss-review-standards.md +2 -2
  619. package/template/.pi/skills/domain-modeling/CONTEXT-FORMAT.md +37 -42
  620. package/template/.pi/skills/domain-modeling/SKILL.md +10 -26
  621. package/template/.pi/skills/grill-with-docs/SKILL.md +6 -5
  622. package/template/.pi/skills/lombok/SKILL.md +3 -2
  623. package/template/.pi/skills/mapstruct/SKILL.md +4 -3
  624. package/template/.pi/skills/prototype-review/SKILL.md +7 -6
  625. package/template/.pi/skills/setup-matt-pocock-skills/SKILL.md +5 -6
  626. package/template/.pi/skills/setup-matt-pocock-skills/domain.md +6 -20
  627. package/template/.pi/skills/wait-what/SKILL.md +1 -1
  628. package/template/.pi/skills/yss-antd-design/SKILL.md +8 -7
  629. package/template/.pi/skills/yss-antd-design/references/evidence.md +11 -6
  630. package/template/.pi/skills/yss-antdv-next-design/SKILL.md +48 -0
  631. package/template/.pi/skills/yss-antdv-next-design/references/boundaries.md +25 -0
  632. package/template/.pi/skills/yss-antdv-next-design/references/cli-matrix.md +34 -0
  633. package/template/.pi/skills/yss-antdv-next-design/references/fact-pack.md +38 -0
  634. package/template/.pi/skills/yss-antdv-next-design/scripts/collect-antdv-next-facts.mjs +213 -0
  635. package/template/.pi/skills/yss-antdv-next-design/scripts/validate-fact-pack.mjs +168 -0
  636. package/template/.pi/skills/yss-antdv-next-design/tests/run-scenarios.mjs +139 -0
  637. package/template/.pi/skills/yss-api-integration/SKILL.md +2 -2
  638. package/template/.pi/skills/yss-application/SKILL.md +8 -2
  639. package/template/.pi/skills/yss-application/references/profiles/layered-mvc-service.md +3 -0
  640. package/template/.pi/skills/yss-application/references/profiles/mvc-data-analysis-v1.md +3 -0
  641. package/template/.pi/skills/yss-application/references/profiles/target-domain-model.md +3 -0
  642. package/template/.pi/skills/yss-audit-log/SKILL.md +2 -2
  643. package/template/.pi/skills/yss-audit-log/references/source-index.md +1 -1
  644. package/template/.pi/skills/yss-cache/SKILL.md +2 -2
  645. package/template/.pi/skills/yss-cache/references/source-index.md +1 -1
  646. package/template/.pi/skills/yss-cache/scripts/check-skill-freshness.sh +1 -1
  647. package/template/.pi/skills/yss-components/SKILL.md +1 -1
  648. package/template/.pi/skills/yss-ddd-scaffold-generator/SKILL.md +8 -9
  649. package/template/.pi/skills/yss-ddd-scaffold-generator/agents/openai.yaml +1 -1
  650. package/template/.pi/skills/yss-ddd-scaffold-generator/assets/templates/config/application.yml.template +0 -13
  651. package/template/.pi/skills/yss-ddd-scaffold-generator/assets/templates/pom/bootstrap-pom.xml.template +13 -0
  652. package/template/.pi/skills/yss-ddd-scaffold-generator/references/ARCHITECTURE.md +1 -1
  653. package/template/.pi/skills/yss-ddd-scaffold-generator/references/USAGE_EXAMPLES.md +15 -6
  654. package/template/.pi/skills/yss-ddd-scaffold-generator/references/yss-backend-scaffold-parent/SKILL.md +2 -2
  655. package/template/.pi/skills/yss-ddd-scaffold-generator/scripts/first-slice-compatibility.test.mjs +23 -9
  656. package/template/.pi/skills/yss-ddd-scaffold-generator/scripts/first-slice-verification.test.mjs +3 -3
  657. package/template/.pi/skills/yss-ddd-scaffold-generator/scripts/generate_scaffold.mjs +43 -21
  658. package/template/.pi/skills/yss-ddd-scaffold-generator/scripts/run_first_slice_verification.mjs +23 -11
  659. package/template/.pi/skills/yss-ddd-scaffold-generator/scripts/run_scaffold_verification.mjs +15 -3
  660. package/template/.pi/skills/yss-ddd-scaffold-generator/scripts/scaffold-generator.test.mjs +44 -15
  661. package/template/.pi/skills/yss-design-system/SKILL.md +27 -24
  662. package/template/.pi/skills/yss-design-system/references/design-qa-theme.md +22 -24
  663. package/template/.pi/skills/yss-design-system/references/design-system.md +39 -56
  664. package/template/.pi/skills/yss-distributed-id/SKILL.md +2 -2
  665. package/template/.pi/skills/yss-distributed-id/references/source-index.md +1 -1
  666. package/template/.pi/skills/yss-domain/SKILL.md +2 -2
  667. package/template/.pi/skills/yss-dto/SKILL.md +3 -2
  668. package/template/.pi/skills/yss-dto/references/source-index.md +1 -1
  669. package/template/.pi/skills/yss-excel-mvc/SKILL.md +2 -2
  670. package/template/.pi/skills/yss-excel-mvc/references/source-index.md +1 -1
  671. package/template/.pi/skills/yss-exception/SKILL.md +2 -1
  672. package/template/.pi/skills/yss-exception/references/source-index.md +1 -1
  673. package/template/.pi/skills/yss-frontend-scaffold-generator/SKILL.md +1 -1
  674. package/template/.pi/skills/yss-implementation-contract-compiler/SKILL.md +61 -0
  675. package/template/.pi/skills/yss-implementation-contract-compiler/agents/openai.yaml +4 -0
  676. package/template/.pi/skills/yss-implementation-contract-compiler/references/boundaries.md +142 -0
  677. package/template/.pi/skills/yss-implementation-contract-compiler/references/compiler-contract.yaml +367 -0
  678. package/template/.pi/skills/yss-implementation-contract-compiler/references/slice-implementation-contract.md +201 -0
  679. package/template/.pi/skills/yss-implementation-contract-compiler/references/yss-skill-execution-result.md +71 -0
  680. package/template/.pi/skills/yss-implementation-contract-compiler/tests/backend-profiles.test.mjs +45 -0
  681. package/template/.pi/skills/yss-implementation-contract-compiler/tests/compiler-scenarios.test.mjs +91 -0
  682. package/template/.pi/skills/yss-layered-mvc-scaffold-generator/SKILL.md +64 -0
  683. package/template/.pi/skills/yss-layered-mvc-scaffold-generator/agents/openai.yaml +4 -0
  684. package/template/.pi/skills/yss-layered-mvc-scaffold-generator/references/architecture.md +29 -0
  685. package/template/.pi/skills/yss-layered-mvc-scaffold-generator/scripts/generate_and_verify_scaffold.mjs +61 -0
  686. package/template/.pi/skills/yss-layered-mvc-scaffold-generator/scripts/generate_scaffold.mjs +315 -0
  687. package/template/.pi/skills/yss-layered-mvc-scaffold-generator/scripts/run_scaffold_verification.mjs +30 -0
  688. package/template/.pi/skills/yss-layered-mvc-scaffold-generator/scripts/scaffold-generator.test.mjs +159 -0
  689. package/template/.pi/skills/yss-mvc-data-analysis-project-initializer/SKILL.md +22 -0
  690. package/template/.pi/skills/yss-mvc-data-analysis-project-initializer/scripts/generate_project.mjs +77 -0
  691. package/template/.pi/skills/yss-mvc-data-analysis-project-initializer/scripts/run_scaffold_verification.mjs +9 -0
  692. package/template/.pi/skills/yss-mvc-scaffold-generator/SKILL.md +8 -0
  693. package/template/.pi/skills/yss-mvc-scaffold-generator/agents/openai.yaml +4 -0
  694. package/template/.pi/skills/yss-mvc-scaffold-generator/assets/logback-spring.xml.template +50 -0
  695. package/template/.pi/skills/yss-mvc-scaffold-generator/assets/smart-doc.json.template +42 -0
  696. package/template/.pi/skills/yss-mvc-scaffold-generator/references/architecture.md +28 -0
  697. package/template/.pi/skills/yss-mvc-scaffold-generator/references/history/generate_project.mjs.txt +137 -0
  698. package/template/.pi/skills/yss-mvc-scaffold-generator/references/history/generate_project.test.mjs.txt +341 -0
  699. package/template/.pi/skills/yss-mvc-scaffold-generator/references/history/skill.md +87 -0
  700. package/template/.pi/skills/yss-mvc-scaffold-generator/scripts/generate_project.mjs +3 -0
  701. package/template/.pi/skills/yss-mvc-scaffold-generator/scripts/generate_project.test.mjs +9 -0
  702. package/template/.pi/skills/yss-mvc-scaffold-generator/scripts/lib/envelope.mjs +74 -0
  703. package/template/.pi/skills/yss-mvc-scaffold-generator/scripts/lib/envelope.test.mjs +36 -0
  704. package/template/.pi/skills/yss-mvc-scaffold-generator/scripts/lib/runtime.mjs +115 -0
  705. package/template/.pi/skills/yss-mvc-scaffold-generator/scripts/lib/storage.mjs +90 -0
  706. package/template/.pi/skills/yss-mvc-scaffold-generator/scripts/lib/templates.mjs +54 -0
  707. package/template/.pi/skills/yss-mvc-scaffold-generator/scripts/verify_project.mjs +103 -0
  708. package/template/.pi/skills/yss-mybatis/SKILL.md +4 -4
  709. package/template/.pi/skills/yss-mybatis/references/source-index.md +1 -1
  710. package/template/.pi/skills/yss-product-lifecycle/SKILL.md +35 -11
  711. package/template/.pi/skills/yss-product-lifecycle/references/artifact-dependencies.md +3 -0
  712. package/template/.pi/skills/yss-product-lifecycle/references/matt-yss-adapter.md +9 -11
  713. package/template/.pi/skills/yss-product-lifecycle/references/orchestration-contract.yaml +136 -55
  714. package/template/.pi/skills/yss-product-lifecycle/references/orchestration.md +12 -6
  715. package/template/.pi/skills/yss-product-lifecycle/references/state-model.md +7 -2
  716. package/template/.pi/skills/yss-product-lifecycle/references/user-decisions.md +56 -0
  717. package/template/.pi/skills/yss-prototype-stage/SKILL.md +35 -24
  718. package/template/.pi/skills/yss-prototype-stage/references/product-design-adapter.md +66 -38
  719. package/template/.pi/skills/yss-prototype-stage/references/prototype-profile-routing.md +69 -0
  720. package/template/.pi/skills/yss-prototype-stage/scripts/prototype-contract.mjs +299 -103
  721. package/template/.pi/skills/yss-prototype-stage/scripts/visual-baseline-contract.mjs +314 -0
  722. package/template/.pi/skills/yss-prototype-stage/tests/run-scenarios.mjs +164 -132
  723. package/template/.pi/skills/yss-repository/SKILL.md +8 -2
  724. package/template/.pi/skills/yss-repository/references/profiles/layered-mvc-service.md +3 -0
  725. package/template/.pi/skills/yss-repository/references/profiles/mvc-data-analysis-v1.md +3 -0
  726. package/template/.pi/skills/yss-repository/references/profiles/target-domain-model.md +3 -0
  727. package/template/.pi/skills/yss-resilience4j/SKILL.md +1 -1
  728. package/template/.pi/skills/yss-resilience4j/references/source-index.md +1 -1
  729. package/template/.pi/skills/yss-security-algorithm/SKILL.md +1 -1
  730. package/template/.pi/skills/yss-security-algorithm/references/source-index.md +1 -1
  731. package/template/.pi/skills/yss-skill-source-index-refresh/SKILL.md +63 -0
  732. package/template/.pi/skills/yss-skill-source-index-refresh/agents/openai.yaml +4 -0
  733. package/template/.pi/skills/yss-skill-source-index-refresh/references/source-map-config.md +29 -0
  734. package/template/.pi/skills/yss-skill-source-index-refresh/scripts/refresh-yss-skill-index.mjs +24 -0
  735. package/template/.pi/skills/yss-stage-decision/SKILL.md +16 -12
  736. package/template/.pi/skills/yss-stage-decision/references/domain-strategy-contract.md +16 -10
  737. package/template/.pi/skills/yss-stage-decision/references/domain-strategy.schema.json +23 -5
  738. package/template/.pi/skills/yss-stage-decision/references/stage-decision-package-contract.md +5 -2
  739. package/template/.pi/skills/yss-stage-decision/references/stage-decision-package.schema.json +16 -4
  740. package/template/.pi/skills/yss-stage-decision/references/validation-rules.md +1 -1
  741. package/template/.pi/skills/yss-stage-decision/scripts/migrate-context-references.mjs +62 -0
  742. package/template/.pi/skills/yss-stage-decision/scripts/validate-domain-strategy.mjs +18 -7
  743. package/template/.pi/skills/yss-stage-decision/scripts/validate-stage-decision-package.mjs +20 -9
  744. package/template/.pi/skills/yss-stage-decision/tests/fixtures/domain-strategy-approval.yaml +1 -1
  745. package/template/.pi/skills/yss-stage-decision/tests/fixtures/stage-decision-approval.yaml +1 -1
  746. package/template/.pi/skills/yss-stage-decision/tests/fixtures/valid-stage-decision-package.yaml +12 -7
  747. package/template/.pi/skills/yss-stage-decision/tests/fixtures/valid-supplier-domain.yaml +9 -4
  748. package/template/.pi/skills/yss-stage-decision/tests/run-scenarios.mjs +134 -56
  749. package/template/.pi/skills/yss-tactical-design/SKILL.md +8 -2
  750. package/template/.pi/skills/yss-tactical-design/references/output-template.md +3 -0
  751. package/template/.pi/skills/yss-tactical-design/references/tactical-design-contract.md +3 -1
  752. package/template/.pi/skills/yss-tactical-design/scripts/validate-tactical-design.mjs +10 -2
  753. package/template/.pi/skills/yss-ui/SKILL.md +2 -2
  754. package/template/.pi/skills/yss-ui/assets/docs/guide/llms.md +0 -61
  755. package/template/.pi/skills/yss-ui-business-page-generation/SKILL.md +3 -3
  756. package/template/.pi/skills/yss-up-springboot3/SKILL.md +1 -1
  757. package/template/.pi/skills/yss-userinfo/SKILL.md +1 -1
  758. package/template/.pi/skills/yss-userinfo/references/source-index.md +1 -1
  759. package/template/.pi/skills/yss-validation/SKILL.md +2 -1
  760. package/template/.pi/skills/yss-validation/references/source-index.md +1 -1
  761. package/template/.pi/skills/yss-web-controller/SKILL.md +8 -2
  762. package/template/.pi/skills/yss-web-controller/references/profiles/layered-mvc-service.md +3 -0
  763. package/template/.pi/skills/yss-web-controller/references/profiles/mvc-data-analysis-v1.md +3 -0
  764. package/template/.pi/skills/yss-web-controller/references/profiles/target-domain-model.md +3 -0
  765. package/template/.pi/skills/yss-web-controller/references/web-generation-contract.schema.json +3 -2
  766. package/template/.pi/skills/yss-web-controller/scripts/generate_controller.mjs +27 -10
  767. package/template/.pi/skills/yss-web-controller/scripts/generate_controller.test.mjs +29 -1
  768. package/template/.qoder/skills/alibaba-java-code-style/SKILL.md +1 -0
  769. package/template/.qoder/skills/code-review/SKILL.md +1 -1
  770. package/template/.qoder/skills/code-review/references/yss-review-standards.md +2 -2
  771. package/template/.qoder/skills/domain-modeling/CONTEXT-FORMAT.md +37 -42
  772. package/template/.qoder/skills/domain-modeling/SKILL.md +10 -26
  773. package/template/.qoder/skills/grill-with-docs/SKILL.md +6 -5
  774. package/template/.qoder/skills/lombok/SKILL.md +3 -2
  775. package/template/.qoder/skills/mapstruct/SKILL.md +4 -3
  776. package/template/.qoder/skills/prototype-review/SKILL.md +7 -6
  777. package/template/.qoder/skills/setup-matt-pocock-skills/SKILL.md +5 -6
  778. package/template/.qoder/skills/setup-matt-pocock-skills/domain.md +6 -20
  779. package/template/.qoder/skills/wait-what/SKILL.md +1 -1
  780. package/template/.qoder/skills/yss-antd-design/SKILL.md +8 -7
  781. package/template/.qoder/skills/yss-antd-design/references/evidence.md +11 -6
  782. package/template/.qoder/skills/yss-antdv-next-design/SKILL.md +48 -0
  783. package/template/.qoder/skills/yss-antdv-next-design/references/boundaries.md +25 -0
  784. package/template/.qoder/skills/yss-antdv-next-design/references/cli-matrix.md +34 -0
  785. package/template/.qoder/skills/yss-antdv-next-design/references/fact-pack.md +38 -0
  786. package/template/.qoder/skills/yss-antdv-next-design/scripts/collect-antdv-next-facts.mjs +213 -0
  787. package/template/.qoder/skills/yss-antdv-next-design/scripts/validate-fact-pack.mjs +168 -0
  788. package/template/.qoder/skills/yss-antdv-next-design/tests/run-scenarios.mjs +139 -0
  789. package/template/.qoder/skills/yss-api-integration/SKILL.md +2 -2
  790. package/template/.qoder/skills/yss-application/SKILL.md +8 -2
  791. package/template/.qoder/skills/yss-application/references/profiles/layered-mvc-service.md +3 -0
  792. package/template/.qoder/skills/yss-application/references/profiles/mvc-data-analysis-v1.md +3 -0
  793. package/template/.qoder/skills/yss-application/references/profiles/target-domain-model.md +3 -0
  794. package/template/.qoder/skills/yss-audit-log/SKILL.md +2 -2
  795. package/template/.qoder/skills/yss-audit-log/references/source-index.md +1 -1
  796. package/template/.qoder/skills/yss-cache/SKILL.md +2 -2
  797. package/template/.qoder/skills/yss-cache/references/source-index.md +1 -1
  798. package/template/.qoder/skills/yss-cache/scripts/check-skill-freshness.sh +1 -1
  799. package/template/.qoder/skills/yss-components/SKILL.md +1 -1
  800. package/template/.qoder/skills/yss-ddd-scaffold-generator/SKILL.md +8 -9
  801. package/template/.qoder/skills/yss-ddd-scaffold-generator/agents/openai.yaml +1 -1
  802. package/template/.qoder/skills/yss-ddd-scaffold-generator/assets/templates/config/application.yml.template +0 -13
  803. package/template/.qoder/skills/yss-ddd-scaffold-generator/assets/templates/pom/bootstrap-pom.xml.template +13 -0
  804. package/template/.qoder/skills/yss-ddd-scaffold-generator/references/ARCHITECTURE.md +1 -1
  805. package/template/.qoder/skills/yss-ddd-scaffold-generator/references/USAGE_EXAMPLES.md +15 -6
  806. package/template/.qoder/skills/yss-ddd-scaffold-generator/references/yss-backend-scaffold-parent/SKILL.md +2 -2
  807. package/template/.qoder/skills/yss-ddd-scaffold-generator/scripts/first-slice-compatibility.test.mjs +23 -9
  808. package/template/.qoder/skills/yss-ddd-scaffold-generator/scripts/first-slice-verification.test.mjs +3 -3
  809. package/template/.qoder/skills/yss-ddd-scaffold-generator/scripts/generate_scaffold.mjs +43 -21
  810. package/template/.qoder/skills/yss-ddd-scaffold-generator/scripts/run_first_slice_verification.mjs +23 -11
  811. package/template/.qoder/skills/yss-ddd-scaffold-generator/scripts/run_scaffold_verification.mjs +15 -3
  812. package/template/.qoder/skills/yss-ddd-scaffold-generator/scripts/scaffold-generator.test.mjs +44 -15
  813. package/template/.qoder/skills/yss-design-system/SKILL.md +27 -24
  814. package/template/.qoder/skills/yss-design-system/references/design-qa-theme.md +22 -24
  815. package/template/.qoder/skills/yss-design-system/references/design-system.md +39 -56
  816. package/template/.qoder/skills/yss-distributed-id/SKILL.md +2 -2
  817. package/template/.qoder/skills/yss-distributed-id/references/source-index.md +1 -1
  818. package/template/.qoder/skills/yss-domain/SKILL.md +2 -2
  819. package/template/.qoder/skills/yss-dto/SKILL.md +3 -2
  820. package/template/.qoder/skills/yss-dto/references/source-index.md +1 -1
  821. package/template/.qoder/skills/yss-excel-mvc/SKILL.md +2 -2
  822. package/template/.qoder/skills/yss-excel-mvc/references/source-index.md +1 -1
  823. package/template/.qoder/skills/yss-exception/SKILL.md +2 -1
  824. package/template/.qoder/skills/yss-exception/references/source-index.md +1 -1
  825. package/template/.qoder/skills/yss-frontend-scaffold-generator/SKILL.md +1 -1
  826. package/template/.qoder/skills/yss-implementation-contract-compiler/SKILL.md +61 -0
  827. package/template/.qoder/skills/yss-implementation-contract-compiler/agents/openai.yaml +4 -0
  828. package/template/.qoder/skills/yss-implementation-contract-compiler/references/boundaries.md +142 -0
  829. package/template/.qoder/skills/yss-implementation-contract-compiler/references/compiler-contract.yaml +367 -0
  830. package/template/.qoder/skills/yss-implementation-contract-compiler/references/slice-implementation-contract.md +201 -0
  831. package/template/.qoder/skills/yss-implementation-contract-compiler/references/yss-skill-execution-result.md +71 -0
  832. package/template/.qoder/skills/yss-implementation-contract-compiler/tests/backend-profiles.test.mjs +45 -0
  833. package/template/.qoder/skills/yss-implementation-contract-compiler/tests/compiler-scenarios.test.mjs +91 -0
  834. package/template/.qoder/skills/yss-layered-mvc-scaffold-generator/SKILL.md +64 -0
  835. package/template/.qoder/skills/yss-layered-mvc-scaffold-generator/agents/openai.yaml +4 -0
  836. package/template/.qoder/skills/yss-layered-mvc-scaffold-generator/references/architecture.md +29 -0
  837. package/template/.qoder/skills/yss-layered-mvc-scaffold-generator/scripts/generate_and_verify_scaffold.mjs +61 -0
  838. package/template/.qoder/skills/yss-layered-mvc-scaffold-generator/scripts/generate_scaffold.mjs +315 -0
  839. package/template/.qoder/skills/yss-layered-mvc-scaffold-generator/scripts/run_scaffold_verification.mjs +30 -0
  840. package/template/.qoder/skills/yss-layered-mvc-scaffold-generator/scripts/scaffold-generator.test.mjs +159 -0
  841. package/template/.qoder/skills/yss-mvc-data-analysis-project-initializer/SKILL.md +22 -0
  842. package/template/.qoder/skills/yss-mvc-data-analysis-project-initializer/scripts/generate_project.mjs +77 -0
  843. package/template/.qoder/skills/yss-mvc-data-analysis-project-initializer/scripts/run_scaffold_verification.mjs +9 -0
  844. package/template/.qoder/skills/yss-mvc-scaffold-generator/SKILL.md +8 -0
  845. package/template/.qoder/skills/yss-mvc-scaffold-generator/agents/openai.yaml +4 -0
  846. package/template/.qoder/skills/yss-mvc-scaffold-generator/assets/logback-spring.xml.template +50 -0
  847. package/template/.qoder/skills/yss-mvc-scaffold-generator/assets/smart-doc.json.template +42 -0
  848. package/template/.qoder/skills/yss-mvc-scaffold-generator/references/architecture.md +28 -0
  849. package/template/.qoder/skills/yss-mvc-scaffold-generator/references/history/generate_project.mjs.txt +137 -0
  850. package/template/.qoder/skills/yss-mvc-scaffold-generator/references/history/generate_project.test.mjs.txt +341 -0
  851. package/template/.qoder/skills/yss-mvc-scaffold-generator/references/history/skill.md +87 -0
  852. package/template/.qoder/skills/yss-mvc-scaffold-generator/scripts/generate_project.mjs +3 -0
  853. package/template/.qoder/skills/yss-mvc-scaffold-generator/scripts/generate_project.test.mjs +9 -0
  854. package/template/.qoder/skills/yss-mvc-scaffold-generator/scripts/lib/envelope.mjs +74 -0
  855. package/template/.qoder/skills/yss-mvc-scaffold-generator/scripts/lib/envelope.test.mjs +36 -0
  856. package/template/.qoder/skills/yss-mvc-scaffold-generator/scripts/lib/runtime.mjs +115 -0
  857. package/template/.qoder/skills/yss-mvc-scaffold-generator/scripts/lib/storage.mjs +90 -0
  858. package/template/.qoder/skills/yss-mvc-scaffold-generator/scripts/lib/templates.mjs +54 -0
  859. package/template/.qoder/skills/yss-mvc-scaffold-generator/scripts/verify_project.mjs +103 -0
  860. package/template/.qoder/skills/yss-mybatis/SKILL.md +4 -4
  861. package/template/.qoder/skills/yss-mybatis/references/source-index.md +1 -1
  862. package/template/.qoder/skills/yss-product-lifecycle/SKILL.md +35 -11
  863. package/template/.qoder/skills/yss-product-lifecycle/references/artifact-dependencies.md +3 -0
  864. package/template/.qoder/skills/yss-product-lifecycle/references/matt-yss-adapter.md +9 -11
  865. package/template/.qoder/skills/yss-product-lifecycle/references/orchestration-contract.yaml +136 -55
  866. package/template/.qoder/skills/yss-product-lifecycle/references/orchestration.md +12 -6
  867. package/template/.qoder/skills/yss-product-lifecycle/references/state-model.md +7 -2
  868. package/template/.qoder/skills/yss-product-lifecycle/references/user-decisions.md +56 -0
  869. package/template/.qoder/skills/yss-prototype-stage/SKILL.md +35 -24
  870. package/template/.qoder/skills/yss-prototype-stage/references/product-design-adapter.md +66 -38
  871. package/template/.qoder/skills/yss-prototype-stage/references/prototype-profile-routing.md +69 -0
  872. package/template/.qoder/skills/yss-prototype-stage/scripts/prototype-contract.mjs +299 -103
  873. package/template/.qoder/skills/yss-prototype-stage/scripts/visual-baseline-contract.mjs +314 -0
  874. package/template/.qoder/skills/yss-prototype-stage/tests/run-scenarios.mjs +164 -132
  875. package/template/.qoder/skills/yss-repository/SKILL.md +8 -2
  876. package/template/.qoder/skills/yss-repository/references/profiles/layered-mvc-service.md +3 -0
  877. package/template/.qoder/skills/yss-repository/references/profiles/mvc-data-analysis-v1.md +3 -0
  878. package/template/.qoder/skills/yss-repository/references/profiles/target-domain-model.md +3 -0
  879. package/template/.qoder/skills/yss-resilience4j/SKILL.md +1 -1
  880. package/template/.qoder/skills/yss-resilience4j/references/source-index.md +1 -1
  881. package/template/.qoder/skills/yss-security-algorithm/SKILL.md +1 -1
  882. package/template/.qoder/skills/yss-security-algorithm/references/source-index.md +1 -1
  883. package/template/.qoder/skills/yss-skill-source-index-refresh/SKILL.md +63 -0
  884. package/template/.qoder/skills/yss-skill-source-index-refresh/agents/openai.yaml +4 -0
  885. package/template/.qoder/skills/yss-skill-source-index-refresh/references/source-map-config.md +29 -0
  886. package/template/.qoder/skills/yss-skill-source-index-refresh/scripts/refresh-yss-skill-index.mjs +24 -0
  887. package/template/.qoder/skills/yss-stage-decision/SKILL.md +16 -12
  888. package/template/.qoder/skills/yss-stage-decision/references/domain-strategy-contract.md +16 -10
  889. package/template/.qoder/skills/yss-stage-decision/references/domain-strategy.schema.json +23 -5
  890. package/template/.qoder/skills/yss-stage-decision/references/stage-decision-package-contract.md +5 -2
  891. package/template/.qoder/skills/yss-stage-decision/references/stage-decision-package.schema.json +16 -4
  892. package/template/.qoder/skills/yss-stage-decision/references/validation-rules.md +1 -1
  893. package/template/.qoder/skills/yss-stage-decision/scripts/migrate-context-references.mjs +62 -0
  894. package/template/.qoder/skills/yss-stage-decision/scripts/validate-domain-strategy.mjs +18 -7
  895. package/template/.qoder/skills/yss-stage-decision/scripts/validate-stage-decision-package.mjs +20 -9
  896. package/template/.qoder/skills/yss-stage-decision/tests/fixtures/domain-strategy-approval.yaml +1 -1
  897. package/template/.qoder/skills/yss-stage-decision/tests/fixtures/stage-decision-approval.yaml +1 -1
  898. package/template/.qoder/skills/yss-stage-decision/tests/fixtures/valid-stage-decision-package.yaml +12 -7
  899. package/template/.qoder/skills/yss-stage-decision/tests/fixtures/valid-supplier-domain.yaml +9 -4
  900. package/template/.qoder/skills/yss-stage-decision/tests/run-scenarios.mjs +134 -56
  901. package/template/.qoder/skills/yss-tactical-design/SKILL.md +8 -2
  902. package/template/.qoder/skills/yss-tactical-design/references/output-template.md +3 -0
  903. package/template/.qoder/skills/yss-tactical-design/references/tactical-design-contract.md +3 -1
  904. package/template/.qoder/skills/yss-tactical-design/scripts/validate-tactical-design.mjs +10 -2
  905. package/template/.qoder/skills/yss-ui/SKILL.md +2 -2
  906. package/template/.qoder/skills/yss-ui/assets/docs/guide/llms.md +0 -61
  907. package/template/.qoder/skills/yss-ui-business-page-generation/SKILL.md +3 -3
  908. package/template/.qoder/skills/yss-up-springboot3/SKILL.md +1 -1
  909. package/template/.qoder/skills/yss-userinfo/SKILL.md +1 -1
  910. package/template/.qoder/skills/yss-userinfo/references/source-index.md +1 -1
  911. package/template/.qoder/skills/yss-validation/SKILL.md +2 -1
  912. package/template/.qoder/skills/yss-validation/references/source-index.md +1 -1
  913. package/template/.qoder/skills/yss-web-controller/SKILL.md +8 -2
  914. package/template/.qoder/skills/yss-web-controller/references/profiles/layered-mvc-service.md +3 -0
  915. package/template/.qoder/skills/yss-web-controller/references/profiles/mvc-data-analysis-v1.md +3 -0
  916. package/template/.qoder/skills/yss-web-controller/references/profiles/target-domain-model.md +3 -0
  917. package/template/.qoder/skills/yss-web-controller/references/web-generation-contract.schema.json +3 -2
  918. package/template/.qoder/skills/yss-web-controller/scripts/generate_controller.mjs +27 -10
  919. package/template/.qoder/skills/yss-web-controller/scripts/generate_controller.test.mjs +29 -1
  920. package/template/.trae/skills/alibaba-java-code-style/SKILL.md +1 -0
  921. package/template/.trae/skills/code-review/SKILL.md +1 -1
  922. package/template/.trae/skills/code-review/references/yss-review-standards.md +2 -2
  923. package/template/.trae/skills/domain-modeling/CONTEXT-FORMAT.md +37 -42
  924. package/template/.trae/skills/domain-modeling/SKILL.md +10 -26
  925. package/template/.trae/skills/grill-with-docs/SKILL.md +6 -5
  926. package/template/.trae/skills/lombok/SKILL.md +3 -2
  927. package/template/.trae/skills/mapstruct/SKILL.md +4 -3
  928. package/template/.trae/skills/prototype-review/SKILL.md +7 -6
  929. package/template/.trae/skills/setup-matt-pocock-skills/SKILL.md +5 -6
  930. package/template/.trae/skills/setup-matt-pocock-skills/domain.md +6 -20
  931. package/template/.trae/skills/wait-what/SKILL.md +1 -1
  932. package/template/.trae/skills/yss-antd-design/SKILL.md +8 -7
  933. package/template/.trae/skills/yss-antd-design/references/evidence.md +11 -6
  934. package/template/.trae/skills/yss-antdv-next-design/SKILL.md +48 -0
  935. package/template/.trae/skills/yss-antdv-next-design/references/boundaries.md +25 -0
  936. package/template/.trae/skills/yss-antdv-next-design/references/cli-matrix.md +34 -0
  937. package/template/.trae/skills/yss-antdv-next-design/references/fact-pack.md +38 -0
  938. package/template/.trae/skills/yss-antdv-next-design/scripts/collect-antdv-next-facts.mjs +213 -0
  939. package/template/.trae/skills/yss-antdv-next-design/scripts/validate-fact-pack.mjs +168 -0
  940. package/template/.trae/skills/yss-antdv-next-design/tests/run-scenarios.mjs +139 -0
  941. package/template/.trae/skills/yss-api-integration/SKILL.md +2 -2
  942. package/template/.trae/skills/yss-application/SKILL.md +8 -2
  943. package/template/.trae/skills/yss-application/references/profiles/layered-mvc-service.md +3 -0
  944. package/template/.trae/skills/yss-application/references/profiles/mvc-data-analysis-v1.md +3 -0
  945. package/template/.trae/skills/yss-application/references/profiles/target-domain-model.md +3 -0
  946. package/template/.trae/skills/yss-audit-log/SKILL.md +2 -2
  947. package/template/.trae/skills/yss-audit-log/references/source-index.md +1 -1
  948. package/template/.trae/skills/yss-cache/SKILL.md +2 -2
  949. package/template/.trae/skills/yss-cache/references/source-index.md +1 -1
  950. package/template/.trae/skills/yss-cache/scripts/check-skill-freshness.sh +1 -1
  951. package/template/.trae/skills/yss-components/SKILL.md +1 -1
  952. package/template/.trae/skills/yss-ddd-scaffold-generator/SKILL.md +8 -9
  953. package/template/.trae/skills/yss-ddd-scaffold-generator/agents/openai.yaml +1 -1
  954. package/template/.trae/skills/yss-ddd-scaffold-generator/assets/templates/config/application.yml.template +0 -13
  955. package/template/.trae/skills/yss-ddd-scaffold-generator/assets/templates/pom/bootstrap-pom.xml.template +13 -0
  956. package/template/.trae/skills/yss-ddd-scaffold-generator/references/ARCHITECTURE.md +1 -1
  957. package/template/.trae/skills/yss-ddd-scaffold-generator/references/USAGE_EXAMPLES.md +15 -6
  958. package/template/.trae/skills/yss-ddd-scaffold-generator/references/yss-backend-scaffold-parent/SKILL.md +2 -2
  959. package/template/.trae/skills/yss-ddd-scaffold-generator/scripts/first-slice-compatibility.test.mjs +23 -9
  960. package/template/.trae/skills/yss-ddd-scaffold-generator/scripts/first-slice-verification.test.mjs +3 -3
  961. package/template/.trae/skills/yss-ddd-scaffold-generator/scripts/generate_scaffold.mjs +43 -21
  962. package/template/.trae/skills/yss-ddd-scaffold-generator/scripts/run_first_slice_verification.mjs +23 -11
  963. package/template/.trae/skills/yss-ddd-scaffold-generator/scripts/run_scaffold_verification.mjs +15 -3
  964. package/template/.trae/skills/yss-ddd-scaffold-generator/scripts/scaffold-generator.test.mjs +44 -15
  965. package/template/.trae/skills/yss-design-system/SKILL.md +27 -24
  966. package/template/.trae/skills/yss-design-system/references/design-qa-theme.md +22 -24
  967. package/template/.trae/skills/yss-design-system/references/design-system.md +39 -56
  968. package/template/.trae/skills/yss-distributed-id/SKILL.md +2 -2
  969. package/template/.trae/skills/yss-distributed-id/references/source-index.md +1 -1
  970. package/template/.trae/skills/yss-domain/SKILL.md +2 -2
  971. package/template/.trae/skills/yss-dto/SKILL.md +3 -2
  972. package/template/.trae/skills/yss-dto/references/source-index.md +1 -1
  973. package/template/.trae/skills/yss-excel-mvc/SKILL.md +2 -2
  974. package/template/.trae/skills/yss-excel-mvc/references/source-index.md +1 -1
  975. package/template/.trae/skills/yss-exception/SKILL.md +2 -1
  976. package/template/.trae/skills/yss-exception/references/source-index.md +1 -1
  977. package/template/.trae/skills/yss-frontend-scaffold-generator/SKILL.md +1 -1
  978. package/template/.trae/skills/yss-implementation-contract-compiler/SKILL.md +61 -0
  979. package/template/.trae/skills/yss-implementation-contract-compiler/agents/openai.yaml +4 -0
  980. package/template/.trae/skills/yss-implementation-contract-compiler/references/boundaries.md +142 -0
  981. package/template/.trae/skills/yss-implementation-contract-compiler/references/compiler-contract.yaml +367 -0
  982. package/template/.trae/skills/yss-implementation-contract-compiler/references/slice-implementation-contract.md +201 -0
  983. package/template/.trae/skills/yss-implementation-contract-compiler/references/yss-skill-execution-result.md +71 -0
  984. package/template/.trae/skills/yss-implementation-contract-compiler/tests/backend-profiles.test.mjs +45 -0
  985. package/template/.trae/skills/yss-implementation-contract-compiler/tests/compiler-scenarios.test.mjs +91 -0
  986. package/template/.trae/skills/yss-layered-mvc-scaffold-generator/SKILL.md +64 -0
  987. package/template/.trae/skills/yss-layered-mvc-scaffold-generator/agents/openai.yaml +4 -0
  988. package/template/.trae/skills/yss-layered-mvc-scaffold-generator/references/architecture.md +29 -0
  989. package/template/.trae/skills/yss-layered-mvc-scaffold-generator/scripts/generate_and_verify_scaffold.mjs +61 -0
  990. package/template/.trae/skills/yss-layered-mvc-scaffold-generator/scripts/generate_scaffold.mjs +315 -0
  991. package/template/.trae/skills/yss-layered-mvc-scaffold-generator/scripts/run_scaffold_verification.mjs +30 -0
  992. package/template/.trae/skills/yss-layered-mvc-scaffold-generator/scripts/scaffold-generator.test.mjs +159 -0
  993. package/template/.trae/skills/yss-mvc-data-analysis-project-initializer/SKILL.md +22 -0
  994. package/template/.trae/skills/yss-mvc-data-analysis-project-initializer/scripts/generate_project.mjs +77 -0
  995. package/template/.trae/skills/yss-mvc-data-analysis-project-initializer/scripts/run_scaffold_verification.mjs +9 -0
  996. package/template/.trae/skills/yss-mvc-scaffold-generator/SKILL.md +8 -0
  997. package/template/.trae/skills/yss-mvc-scaffold-generator/agents/openai.yaml +4 -0
  998. package/template/.trae/skills/yss-mvc-scaffold-generator/assets/logback-spring.xml.template +50 -0
  999. package/template/.trae/skills/yss-mvc-scaffold-generator/assets/smart-doc.json.template +42 -0
  1000. package/template/.trae/skills/yss-mvc-scaffold-generator/references/architecture.md +28 -0
  1001. package/template/.trae/skills/yss-mvc-scaffold-generator/references/history/generate_project.mjs.txt +137 -0
  1002. package/template/.trae/skills/yss-mvc-scaffold-generator/references/history/generate_project.test.mjs.txt +341 -0
  1003. package/template/.trae/skills/yss-mvc-scaffold-generator/references/history/skill.md +87 -0
  1004. package/template/.trae/skills/yss-mvc-scaffold-generator/scripts/generate_project.mjs +3 -0
  1005. package/template/.trae/skills/yss-mvc-scaffold-generator/scripts/generate_project.test.mjs +9 -0
  1006. package/template/.trae/skills/yss-mvc-scaffold-generator/scripts/lib/envelope.mjs +74 -0
  1007. package/template/.trae/skills/yss-mvc-scaffold-generator/scripts/lib/envelope.test.mjs +36 -0
  1008. package/template/.trae/skills/yss-mvc-scaffold-generator/scripts/lib/runtime.mjs +115 -0
  1009. package/template/.trae/skills/yss-mvc-scaffold-generator/scripts/lib/storage.mjs +90 -0
  1010. package/template/.trae/skills/yss-mvc-scaffold-generator/scripts/lib/templates.mjs +54 -0
  1011. package/template/.trae/skills/yss-mvc-scaffold-generator/scripts/verify_project.mjs +103 -0
  1012. package/template/.trae/skills/yss-mybatis/SKILL.md +4 -4
  1013. package/template/.trae/skills/yss-mybatis/references/source-index.md +1 -1
  1014. package/template/.trae/skills/yss-product-lifecycle/SKILL.md +35 -11
  1015. package/template/.trae/skills/yss-product-lifecycle/references/artifact-dependencies.md +3 -0
  1016. package/template/.trae/skills/yss-product-lifecycle/references/matt-yss-adapter.md +9 -11
  1017. package/template/.trae/skills/yss-product-lifecycle/references/orchestration-contract.yaml +136 -55
  1018. package/template/.trae/skills/yss-product-lifecycle/references/orchestration.md +12 -6
  1019. package/template/.trae/skills/yss-product-lifecycle/references/state-model.md +7 -2
  1020. package/template/.trae/skills/yss-product-lifecycle/references/user-decisions.md +56 -0
  1021. package/template/.trae/skills/yss-prototype-stage/SKILL.md +35 -24
  1022. package/template/.trae/skills/yss-prototype-stage/references/product-design-adapter.md +66 -38
  1023. package/template/.trae/skills/yss-prototype-stage/references/prototype-profile-routing.md +69 -0
  1024. package/template/.trae/skills/yss-prototype-stage/scripts/prototype-contract.mjs +299 -103
  1025. package/template/.trae/skills/yss-prototype-stage/scripts/visual-baseline-contract.mjs +314 -0
  1026. package/template/.trae/skills/yss-prototype-stage/tests/run-scenarios.mjs +164 -132
  1027. package/template/.trae/skills/yss-repository/SKILL.md +8 -2
  1028. package/template/.trae/skills/yss-repository/references/profiles/layered-mvc-service.md +3 -0
  1029. package/template/.trae/skills/yss-repository/references/profiles/mvc-data-analysis-v1.md +3 -0
  1030. package/template/.trae/skills/yss-repository/references/profiles/target-domain-model.md +3 -0
  1031. package/template/.trae/skills/yss-resilience4j/SKILL.md +1 -1
  1032. package/template/.trae/skills/yss-resilience4j/references/source-index.md +1 -1
  1033. package/template/.trae/skills/yss-security-algorithm/SKILL.md +1 -1
  1034. package/template/.trae/skills/yss-security-algorithm/references/source-index.md +1 -1
  1035. package/template/.trae/skills/yss-skill-source-index-refresh/SKILL.md +63 -0
  1036. package/template/.trae/skills/yss-skill-source-index-refresh/agents/openai.yaml +4 -0
  1037. package/template/.trae/skills/yss-skill-source-index-refresh/references/source-map-config.md +29 -0
  1038. package/template/.trae/skills/yss-skill-source-index-refresh/scripts/refresh-yss-skill-index.mjs +24 -0
  1039. package/template/.trae/skills/yss-stage-decision/SKILL.md +16 -12
  1040. package/template/.trae/skills/yss-stage-decision/references/domain-strategy-contract.md +16 -10
  1041. package/template/.trae/skills/yss-stage-decision/references/domain-strategy.schema.json +23 -5
  1042. package/template/.trae/skills/yss-stage-decision/references/stage-decision-package-contract.md +5 -2
  1043. package/template/.trae/skills/yss-stage-decision/references/stage-decision-package.schema.json +16 -4
  1044. package/template/.trae/skills/yss-stage-decision/references/validation-rules.md +1 -1
  1045. package/template/.trae/skills/yss-stage-decision/scripts/migrate-context-references.mjs +62 -0
  1046. package/template/.trae/skills/yss-stage-decision/scripts/validate-domain-strategy.mjs +18 -7
  1047. package/template/.trae/skills/yss-stage-decision/scripts/validate-stage-decision-package.mjs +20 -9
  1048. package/template/.trae/skills/yss-stage-decision/tests/fixtures/domain-strategy-approval.yaml +1 -1
  1049. package/template/.trae/skills/yss-stage-decision/tests/fixtures/stage-decision-approval.yaml +1 -1
  1050. package/template/.trae/skills/yss-stage-decision/tests/fixtures/valid-stage-decision-package.yaml +12 -7
  1051. package/template/.trae/skills/yss-stage-decision/tests/fixtures/valid-supplier-domain.yaml +9 -4
  1052. package/template/.trae/skills/yss-stage-decision/tests/run-scenarios.mjs +134 -56
  1053. package/template/.trae/skills/yss-tactical-design/SKILL.md +8 -2
  1054. package/template/.trae/skills/yss-tactical-design/references/output-template.md +3 -0
  1055. package/template/.trae/skills/yss-tactical-design/references/tactical-design-contract.md +3 -1
  1056. package/template/.trae/skills/yss-tactical-design/scripts/validate-tactical-design.mjs +10 -2
  1057. package/template/.trae/skills/yss-ui/SKILL.md +2 -2
  1058. package/template/.trae/skills/yss-ui/assets/docs/guide/llms.md +0 -61
  1059. package/template/.trae/skills/yss-ui-business-page-generation/SKILL.md +3 -3
  1060. package/template/.trae/skills/yss-up-springboot3/SKILL.md +1 -1
  1061. package/template/.trae/skills/yss-userinfo/SKILL.md +1 -1
  1062. package/template/.trae/skills/yss-userinfo/references/source-index.md +1 -1
  1063. package/template/.trae/skills/yss-validation/SKILL.md +2 -1
  1064. package/template/.trae/skills/yss-validation/references/source-index.md +1 -1
  1065. package/template/.trae/skills/yss-web-controller/SKILL.md +8 -2
  1066. package/template/.trae/skills/yss-web-controller/references/profiles/layered-mvc-service.md +3 -0
  1067. package/template/.trae/skills/yss-web-controller/references/profiles/mvc-data-analysis-v1.md +3 -0
  1068. package/template/.trae/skills/yss-web-controller/references/profiles/target-domain-model.md +3 -0
  1069. package/template/.trae/skills/yss-web-controller/references/web-generation-contract.schema.json +3 -2
  1070. package/template/.trae/skills/yss-web-controller/scripts/generate_controller.mjs +27 -10
  1071. package/template/.trae/skills/yss-web-controller/scripts/generate_controller.test.mjs +29 -1
  1072. package/template/AGENTS.md +52 -91
  1073. package/template/CONTEXT.md +23 -12
  1074. package/template/DESIGN.md +85 -41
  1075. package/template/README.md +0 -1
  1076. package/template/__yss_dotfile__.gitignore +1 -0
  1077. package/template/docs/agents/backend-architecture-profiles.md +25 -0
  1078. package/template/docs/agents/digital-human-roles.md +6 -6
  1079. package/template/docs/agents/digital-human-roles.yaml +48 -15
  1080. package/template/docs/agents/domain.md +7 -6
  1081. package/template/docs/agents/skill-migrations.md +36 -5
  1082. package/template/docs/agents/skills-maintenance.md +5 -5
  1083. package/template/docs/agents/strategic-design-skills-integration.md +46 -0
  1084. package/template/docs/agents/yss-skill-registry.yaml +199 -109
  1085. package/template/docs/agents/yss-ui-skills-integration.md +3 -3
  1086. package/template/docs/api/templates/openapi-draft-review-checklist.md +3 -3
  1087. package/template/docs/architecture/templates/engineering-baseline-review-template.md +20 -8
  1088. package/template/docs/design/README.md +11 -8
  1089. package/template/docs/design/design-system-sync.yaml +1 -1
  1090. package/template/docs/design/design.md +108 -132
  1091. package/template/docs/design/facts/antdv-next/1.5.2/cli-help.txt +38 -0
  1092. package/template/docs/design/facts/antdv-next/1.5.2/component-list.json +434 -0
  1093. package/template/docs/design/facts/antdv-next/1.5.2/components/Alert/demo-basic.json +7 -0
  1094. package/template/docs/design/facts/antdv-next/1.5.2/components/Alert/info.json +246 -0
  1095. package/template/docs/design/facts/antdv-next/1.5.2/components/Alert/semantic.json +40 -0
  1096. package/template/docs/design/facts/antdv-next/1.5.2/components/Alert/token.json +32 -0
  1097. package/template/docs/design/facts/antdv-next/1.5.2/components/Button/demo-basic.json +7 -0
  1098. package/template/docs/design/facts/antdv-next/1.5.2/components/Button/info.json +190 -0
  1099. package/template/docs/design/facts/antdv-next/1.5.2/components/Button/semantic.json +20 -0
  1100. package/template/docs/design/facts/antdv-next/1.5.2/components/Button/token.json +256 -0
  1101. package/template/docs/design/facts/antdv-next/1.5.2/components/Input/demo-basic.json +7 -0
  1102. package/template/docs/design/facts/antdv-next/1.5.2/components/Input/info.json +460 -0
  1103. package/template/docs/design/facts/antdv-next/1.5.2/components/Input/semantic.json +70 -0
  1104. package/template/docs/design/facts/antdv-next/1.5.2/components/Input/token.json +123 -0
  1105. package/template/docs/design/facts/antdv-next/1.5.2/components/Modal/demo-basic.json +7 -0
  1106. package/template/docs/design/facts/antdv-next/1.5.2/components/Modal/info.json +646 -0
  1107. package/template/docs/design/facts/antdv-next/1.5.2/components/Modal/semantic.json +50 -0
  1108. package/template/docs/design/facts/antdv-next/1.5.2/components/Modal/token.json +130 -0
  1109. package/template/docs/design/facts/antdv-next/1.5.2/components/Select/demo-basic.json +7 -0
  1110. package/template/docs/design/facts/antdv-next/1.5.2/components/Select/info.json +640 -0
  1111. package/template/docs/design/facts/antdv-next/1.5.2/components/Select/semantic.json +70 -0
  1112. package/template/docs/design/facts/antdv-next/1.5.2/components/Select/token.json +172 -0
  1113. package/template/docs/design/facts/antdv-next/1.5.2/components/Table/demo-basic.json +7 -0
  1114. package/template/docs/design/facts/antdv-next/1.5.2/components/Table/info.json +1010 -0
  1115. package/template/docs/design/facts/antdv-next/1.5.2/components/Table/semantic.json +70 -0
  1116. package/template/docs/design/facts/antdv-next/1.5.2/components/Table/token.json +263 -0
  1117. package/template/docs/design/facts/antdv-next/1.5.2/components/Tag/demo-basic.json +7 -0
  1118. package/template/docs/design/facts/antdv-next/1.5.2/components/Tag/info.json +321 -0
  1119. package/template/docs/design/facts/antdv-next/1.5.2/components/Tag/semantic.json +25 -0
  1120. package/template/docs/design/facts/antdv-next/1.5.2/components/Tag/token.json +25 -0
  1121. package/template/docs/design/facts/antdv-next/1.5.2/design-md.json +3 -0
  1122. package/template/docs/design/facts/antdv-next/1.5.2/manifest.json +215 -0
  1123. package/template/docs/design/facts/antdv-next/1.5.2/resolution-probe.json +5 -0
  1124. package/template/docs/design/preview-dark.html +170 -7
  1125. package/template/docs/design/preview.css +730 -0
  1126. package/template/docs/design/preview.html +168 -10
  1127. package/template/docs/design/preview.js +71 -0
  1128. package/template/docs/design/schemas/visual-baseline.schema.json +66 -0
  1129. package/template/docs/design/templates/interaction-spec-template.md +4 -4
  1130. package/template/docs/design/templates/product-overview-design-template.md +6 -6
  1131. package/template/docs/design/templates/prototype-confirmation-template.md +13 -15
  1132. package/template/docs/design/templates/prototype-evidence-template.yaml +112 -75
  1133. package/template/docs/design/templates/prototype-review-checklist.md +5 -4
  1134. package/template/docs/design/templates/state-matrix-template.md +11 -0
  1135. package/template/docs/design/templates/visual-baseline-template.yaml +70 -0
  1136. package/template/docs/design/tokens/.design-md-projection.json +3 -3
  1137. package/template/docs/design/tokens/theme.json +2 -2
  1138. package/template/docs/design/tokens/variables.css +5 -0
  1139. package/template/docs/discovery/reports/agent-governance-options.md +8 -8
  1140. package/template/docs/process/MATT-POCOCK-ENGINEERING-SKILLS.md +1 -1
  1141. package/template/docs/process/harness-executive-blueprint.md +1 -1
  1142. package/template/docs/process/harness-process-tailoring.md +1 -0
  1143. package/template/docs/process/implementation-repo-integration.md +1 -1
  1144. package/template/docs/process/lifecycle-artifact-map.md +9 -6
  1145. package/template/docs/process/lifecycle-registry-baseline.json +9 -4
  1146. package/template/docs/process/lifecycle-registry.yaml +37 -9
  1147. package/template/docs/process/schemas/backend-architecture-identity.schema.json +19 -0
  1148. package/template/docs/process/schemas/context-reconciliation.schema.json +57 -0
  1149. package/template/docs/process/schemas/digital-human-task-package.schema.json +10 -0
  1150. package/template/docs/process/schemas/frontend-implementation-evidence.schema.json +62 -29
  1151. package/template/docs/process/schemas/lifecycle-checkpoint.schema.json +16 -2
  1152. package/template/docs/process/schemas/lifecycle-registry.schema.json +4 -4
  1153. package/template/docs/process/schemas/scaffold-architecture-decisions.schema.json +68 -0
  1154. package/template/docs/process/schemas/strategic-design-handoff.schema.json +670 -0
  1155. package/template/docs/process/schemas/strategic-handoff-domain-strategy.schema.json +146 -0
  1156. package/template/docs/process/schemas/strategic-handoff-export.schema.json +295 -0
  1157. package/template/docs/process/schemas/strategic-handoff-package.schema.json +97 -0
  1158. package/template/docs/process/schemas/strategic-handoff-stage-decision-package.schema.json +98 -0
  1159. package/template/docs/process/schemas/user-decision.schema.json +357 -0
  1160. package/template/docs/process/strategic-handoff-package.md +56 -0
  1161. package/template/docs/process/template-engineering-overview.md +2 -2
  1162. package/template/docs/process/template-verification-profiles.yaml +87 -7
  1163. package/template/docs/process/templates/context-reconciliation-template.yaml +18 -0
  1164. package/template/docs/process/templates/frontend-implementation-plan-template.yaml +11 -5
  1165. package/template/docs/process/templates/frontend-implementation-verification-template.yaml +25 -5
  1166. package/template/docs/process/templates/lifecycle-checkpoint-template.yaml +9 -0
  1167. package/template/docs/process/templates/scaffold-architecture-decisions-template.yaml +32 -0
  1168. package/template/docs/process/templates/stage-checkpoint-template.md +5 -0
  1169. package/template/docs/process/templates/user-decision-template.yaml +30 -0
  1170. package/template/docs/templates/approval-record-template.yaml +4 -0
  1171. package/template/docs/templates/build-architecture-checklist-template.md +7 -7
  1172. package/template/docs/templates/implementation-repo-registry-template.md +3 -1
  1173. package/template/docs/templates/implementation-routing-template.md +14 -12
  1174. package/template/docs/templates/requirement-freeze-template.md +2 -2
  1175. package/template/docs/templates/review-report-template.md +5 -5
  1176. package/template/docs/templates/spec-template.md +6 -6
  1177. package/template/docs/templates/vertical-slice-ticket-template.md +4 -4
  1178. package/template/docs/user-guide/yss-ui-mcp.md +0 -2
  1179. 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 +5 -3
  1180. package/template/docs/user-guide//347/224/250/346/210/267/346/211/213/345/206/214.md +5 -5
  1181. package/template/docs/user-guide//347/224/250/346/210/267/346/211/213/345/206/214/347/264/242/345/274/225.md +4 -4
  1182. package/template/scripts/audit-yss-backend-skills +56 -0
  1183. package/template/scripts/fixtures/strategic-handoff/base-stage.json +91 -0
  1184. package/template/scripts/fixtures/strategic-handoff/base-strategy.json +205 -0
  1185. package/template/scripts/fixtures/strategic-handoff/fixture.mjs +57 -0
  1186. package/template/scripts/fixtures/strategic-handoff/source-roles.json +528 -0
  1187. package/template/scripts/fixtures/user-decision/build-fixture.mjs +61 -0
  1188. package/template/scripts/generate-yss-skill-boundaries +67 -0
  1189. package/template/scripts/lib/approval-record.mjs +32 -1
  1190. package/template/scripts/lib/backend-architecture.mjs +43 -0
  1191. package/template/scripts/lib/context-contract.mjs +203 -0
  1192. package/template/scripts/lib/digital-human-roles.mjs +21 -3
  1193. package/template/scripts/lib/export-skills.mjs +4 -4
  1194. package/template/scripts/lib/first-slice-architecture.mjs +23 -0
  1195. package/template/scripts/lib/implementation-contract-compiler.mjs +227 -0
  1196. package/template/scripts/lib/lifecycle-registry.mjs +14 -6
  1197. package/template/scripts/lib/lifecycle-transition.mjs +19 -4
  1198. package/template/scripts/lib/scaffold-local-database.mjs +26 -0
  1199. package/template/scripts/lib/scenario-checks.mjs +34 -18
  1200. package/template/scripts/lib/skill-governance.mjs +46 -9
  1201. package/template/scripts/lib/skill-registry.mjs +107 -63
  1202. package/template/scripts/lib/skill-supply-chain.mjs +45 -5
  1203. package/template/scripts/lib/strategic-handoff-consumption.mjs +76 -0
  1204. package/template/scripts/lib/strategic-handoff-io.mjs +75 -0
  1205. package/template/scripts/lib/strategic-handoff-rules.mjs +37 -0
  1206. package/template/scripts/lib/strategic-handoff-zip.py +52 -0
  1207. package/template/scripts/lib/strategic-handoff.mjs +259 -0
  1208. package/template/scripts/lib/task-package.mjs +10 -2
  1209. package/template/scripts/lib/user-decision.mjs +210 -0
  1210. package/template/scripts/strategic-handoff +14 -0
  1211. package/template/scripts/sync-strategic-handoff-tools +18 -0
  1212. package/template/scripts/verify-approval-record +5 -4
  1213. package/template/scripts/verify-business-language-scenarios +59 -0
  1214. package/template/scripts/verify-context-contract +15 -0
  1215. package/template/scripts/verify-context-contract-scenarios +105 -0
  1216. package/template/scripts/verify-context-reconciliation +58 -0
  1217. package/template/scripts/verify-context-reconciliation-scenarios +69 -0
  1218. package/template/scripts/verify-digital-human-roles-scenarios +1 -1
  1219. package/template/scripts/verify-frontend-implementation-evidence +31 -8
  1220. package/template/scripts/verify-frontend-implementation-evidence-scenarios +56 -0
  1221. package/template/scripts/verify-grill-with-docs-context-scenarios +15 -0
  1222. package/template/scripts/verify-lifecycle-checkpoint +9 -1
  1223. package/template/scripts/verify-lifecycle-transition-scenarios +13 -3
  1224. package/template/scripts/verify-repository-scope-scenarios +2 -2
  1225. package/template/scripts/verify-retired-skill-ids +63 -0
  1226. package/template/scripts/verify-scaffold-architecture-decision-scenarios +30 -0
  1227. package/template/scripts/verify-scaffold-architecture-decisions +61 -0
  1228. package/template/scripts/verify-scaffold-generator-scenarios +92 -21
  1229. package/template/scripts/verify-strategic-context-import +65 -0
  1230. package/template/scripts/verify-strategic-context-import-scenarios +50 -0
  1231. package/template/scripts/verify-strategic-handoff-consumption +10 -0
  1232. package/template/scripts/verify-strategic-handoff-package-scenarios +102 -0
  1233. package/template/scripts/verify-subagent-task-package-scenarios +17 -3
  1234. package/template/scripts/verify-template-verification-scenarios +10 -2
  1235. package/template/scripts/verify-user-decision +17 -0
  1236. package/template/scripts/verify-user-decision-scenarios +103 -0
  1237. package/template/scripts/verify-yss-implementation-contract-compiler-scenarios +14 -0
  1238. package/template/skills-lock.json +130 -393
  1239. package/template/yss-public-skills.json +8 -8
  1240. package/template.manifest.json +0 -3
  1241. package/template.snapshot.json +5 -5
  1242. package/template/.agents/skills/ask-matt/PHASE-BOUNDARIES.md +0 -55
  1243. package/template/.agents/skills/ask-matt/SKILL.md +0 -95
  1244. package/template/.agents/skills/ask-matt/agents/openai.yaml +0 -5
  1245. package/template/.agents/skills/dispatching-parallel-agents/SKILL.md +0 -185
  1246. package/template/.agents/skills/loop-me/SKILL.md +0 -32
  1247. package/template/.agents/skills/loop-me/agents/openai.yaml +0 -5
  1248. package/template/.agents/skills/migrate-to-shoehorn/SKILL.md +0 -118
  1249. package/template/.agents/skills/migrate-to-shoehorn/agents/openai.yaml +0 -3
  1250. package/template/.agents/skills/prototype-page-acceptance/SKILL.md +0 -62
  1251. package/template/.agents/skills/scaffold-exercises/SKILL.md +0 -106
  1252. package/template/.agents/skills/scaffold-exercises/agents/openai.yaml +0 -3
  1253. package/template/.agents/skills/setup-pre-commit/SKILL.md +0 -91
  1254. package/template/.agents/skills/setup-pre-commit/agents/openai.yaml +0 -3
  1255. package/template/.agents/skills/setup-ts-deep-modules/SKILL.md +0 -102
  1256. package/template/.agents/skills/setup-ts-deep-modules/agents/openai.yaml +0 -5
  1257. package/template/.agents/skills/setup-ts-deep-modules/dependency-cruiser.config.cjs +0 -95
  1258. package/template/.agents/skills/teach/GLOSSARY-FORMAT.md +0 -35
  1259. package/template/.agents/skills/teach/LEARNING-RECORD-FORMAT.md +0 -46
  1260. package/template/.agents/skills/teach/MISSION-FORMAT.md +0 -31
  1261. package/template/.agents/skills/teach/RESOURCES-FORMAT.md +0 -32
  1262. package/template/.agents/skills/teach/SKILL.md +0 -140
  1263. package/template/.agents/skills/teach/agents/openai.yaml +0 -5
  1264. package/template/.agents/skills/writing-beats/SKILL.md +0 -67
  1265. package/template/.agents/skills/writing-beats/agents/openai.yaml +0 -5
  1266. package/template/.agents/skills/writing-fragments/SKILL.md +0 -79
  1267. package/template/.agents/skills/writing-fragments/agents/openai.yaml +0 -5
  1268. package/template/.agents/skills/writing-shape/SKILL.md +0 -79
  1269. package/template/.agents/skills/writing-shape/agents/openai.yaml +0 -5
  1270. package/template/.agents/skills/yss-microapp-commit/SKILL.md +0 -201
  1271. package/template/.agents/skills/yss-microapp-commit/agents/openai.yaml +0 -5
  1272. package/template/.agents/skills/yss-microapp-commit/references/scope-mapping.md +0 -204
  1273. package/template/.agents/skills/yss-page-module-development/SKILL.md +0 -165
  1274. package/template/.agents/skills/yss-page-module-development/agents/openai.yaml +0 -5
  1275. package/template/.agents/skills/yss-page-module-development/examples/AdvancedFormPage/constant.ts +0 -32
  1276. package/template/.agents/skills/yss-page-module-development/examples/AdvancedFormPage/hooks/useRuleConfig.ts +0 -158
  1277. package/template/.agents/skills/yss-page-module-development/examples/AdvancedFormPage/index.vue +0 -188
  1278. package/template/.agents/skills/yss-page-module-development/examples/AdvancedFormPage/schemas/ruleConfigSchema.ts +0 -256
  1279. package/template/.agents/skills/yss-page-module-development/examples/AdvancedFormPage/style.less +0 -76
  1280. package/template/.agents/skills/yss-page-module-development/examples/StandardListPage/constant.ts +0 -128
  1281. package/template/.agents/skills/yss-page-module-development/examples/StandardListPage/hooks/useQualityRuleList.ts +0 -144
  1282. package/template/.agents/skills/yss-page-module-development/examples/StandardListPage/hooks/useRuleActions.ts +0 -141
  1283. package/template/.agents/skills/yss-page-module-development/examples/StandardListPage/index.vue +0 -175
  1284. package/template/.agents/skills/yss-page-module-development/examples/StandardListPage/style.less +0 -83
  1285. package/template/.agents/skills/yss-page-module-development/references/component-map.md +0 -34
  1286. package/template/.agents/skills/yss-page-module-development/references/frontend-docs.md +0 -11
  1287. package/template/.agents/skills/yss-page-module-development/references/hooks-map.md +0 -11
  1288. package/template/.agents/skills/yss-page-module-development/references/utils-map.md +0 -14
  1289. package/template/.agents/skills/yss-router/SKILL.md +0 -51
  1290. package/template/.agents/skills/yss-router/agents/openai.yaml +0 -4
  1291. package/template/.agents/skills/yss-router/references/boundaries.md +0 -50
  1292. package/template/.agents/skills/yss-router/references/router-contract.yaml +0 -349
  1293. package/template/.agents/skills/yss-router/references/slice-implementation-contract.md +0 -185
  1294. package/template/.agents/skills/yss-router/references/yss-skill-execution-result.md +0 -67
  1295. package/template/.agents/skills/yss-source-index/SKILL.md +0 -63
  1296. package/template/.agents/skills/yss-source-index/agents/openai.yaml +0 -4
  1297. package/template/.agents/skills/yss-source-index/references/source-map-config.md +0 -30
  1298. package/template/.agents/skills/yss-source-index/scripts/refresh-yss-skill-index.mjs +0 -24
  1299. package/template/.claude/skills/ask-matt/PHASE-BOUNDARIES.md +0 -55
  1300. package/template/.claude/skills/ask-matt/SKILL.md +0 -95
  1301. package/template/.claude/skills/ask-matt/agents/openai.yaml +0 -5
  1302. package/template/.claude/skills/dispatching-parallel-agents/SKILL.md +0 -185
  1303. package/template/.claude/skills/loop-me/SKILL.md +0 -32
  1304. package/template/.claude/skills/loop-me/agents/openai.yaml +0 -5
  1305. package/template/.claude/skills/migrate-to-shoehorn/SKILL.md +0 -118
  1306. package/template/.claude/skills/migrate-to-shoehorn/agents/openai.yaml +0 -3
  1307. package/template/.claude/skills/prototype-page-acceptance/SKILL.md +0 -62
  1308. package/template/.claude/skills/scaffold-exercises/SKILL.md +0 -106
  1309. package/template/.claude/skills/scaffold-exercises/agents/openai.yaml +0 -3
  1310. package/template/.claude/skills/setup-pre-commit/SKILL.md +0 -91
  1311. package/template/.claude/skills/setup-pre-commit/agents/openai.yaml +0 -3
  1312. package/template/.claude/skills/setup-ts-deep-modules/SKILL.md +0 -102
  1313. package/template/.claude/skills/setup-ts-deep-modules/agents/openai.yaml +0 -5
  1314. package/template/.claude/skills/setup-ts-deep-modules/dependency-cruiser.config.cjs +0 -95
  1315. package/template/.claude/skills/teach/GLOSSARY-FORMAT.md +0 -35
  1316. package/template/.claude/skills/teach/LEARNING-RECORD-FORMAT.md +0 -46
  1317. package/template/.claude/skills/teach/MISSION-FORMAT.md +0 -31
  1318. package/template/.claude/skills/teach/RESOURCES-FORMAT.md +0 -32
  1319. package/template/.claude/skills/teach/SKILL.md +0 -140
  1320. package/template/.claude/skills/teach/agents/openai.yaml +0 -5
  1321. package/template/.claude/skills/writing-beats/SKILL.md +0 -67
  1322. package/template/.claude/skills/writing-beats/agents/openai.yaml +0 -5
  1323. package/template/.claude/skills/writing-fragments/SKILL.md +0 -79
  1324. package/template/.claude/skills/writing-fragments/agents/openai.yaml +0 -5
  1325. package/template/.claude/skills/writing-shape/SKILL.md +0 -79
  1326. package/template/.claude/skills/writing-shape/agents/openai.yaml +0 -5
  1327. package/template/.claude/skills/yss-microapp-commit/SKILL.md +0 -201
  1328. package/template/.claude/skills/yss-microapp-commit/agents/openai.yaml +0 -5
  1329. package/template/.claude/skills/yss-microapp-commit/references/scope-mapping.md +0 -204
  1330. package/template/.claude/skills/yss-page-module-development/SKILL.md +0 -165
  1331. package/template/.claude/skills/yss-page-module-development/agents/openai.yaml +0 -5
  1332. package/template/.claude/skills/yss-page-module-development/examples/AdvancedFormPage/constant.ts +0 -32
  1333. package/template/.claude/skills/yss-page-module-development/examples/AdvancedFormPage/hooks/useRuleConfig.ts +0 -158
  1334. package/template/.claude/skills/yss-page-module-development/examples/AdvancedFormPage/index.vue +0 -188
  1335. package/template/.claude/skills/yss-page-module-development/examples/AdvancedFormPage/schemas/ruleConfigSchema.ts +0 -256
  1336. package/template/.claude/skills/yss-page-module-development/examples/AdvancedFormPage/style.less +0 -76
  1337. package/template/.claude/skills/yss-page-module-development/examples/StandardListPage/constant.ts +0 -128
  1338. package/template/.claude/skills/yss-page-module-development/examples/StandardListPage/hooks/useQualityRuleList.ts +0 -144
  1339. package/template/.claude/skills/yss-page-module-development/examples/StandardListPage/hooks/useRuleActions.ts +0 -141
  1340. package/template/.claude/skills/yss-page-module-development/examples/StandardListPage/index.vue +0 -175
  1341. package/template/.claude/skills/yss-page-module-development/examples/StandardListPage/style.less +0 -83
  1342. package/template/.claude/skills/yss-page-module-development/references/component-map.md +0 -34
  1343. package/template/.claude/skills/yss-page-module-development/references/frontend-docs.md +0 -11
  1344. package/template/.claude/skills/yss-page-module-development/references/hooks-map.md +0 -11
  1345. package/template/.claude/skills/yss-page-module-development/references/utils-map.md +0 -14
  1346. package/template/.claude/skills/yss-router/SKILL.md +0 -51
  1347. package/template/.claude/skills/yss-router/agents/openai.yaml +0 -4
  1348. package/template/.claude/skills/yss-router/references/boundaries.md +0 -50
  1349. package/template/.claude/skills/yss-router/references/router-contract.yaml +0 -349
  1350. package/template/.claude/skills/yss-router/references/slice-implementation-contract.md +0 -185
  1351. package/template/.claude/skills/yss-router/references/yss-skill-execution-result.md +0 -67
  1352. package/template/.claude/skills/yss-source-index/SKILL.md +0 -63
  1353. package/template/.claude/skills/yss-source-index/agents/openai.yaml +0 -4
  1354. package/template/.claude/skills/yss-source-index/references/source-map-config.md +0 -30
  1355. package/template/.claude/skills/yss-source-index/scripts/refresh-yss-skill-index.mjs +0 -24
  1356. package/template/.codex/skills/ask-matt/PHASE-BOUNDARIES.md +0 -55
  1357. package/template/.codex/skills/ask-matt/SKILL.md +0 -95
  1358. package/template/.codex/skills/ask-matt/agents/openai.yaml +0 -5
  1359. package/template/.codex/skills/dispatching-parallel-agents/SKILL.md +0 -185
  1360. package/template/.codex/skills/loop-me/SKILL.md +0 -32
  1361. package/template/.codex/skills/loop-me/agents/openai.yaml +0 -5
  1362. package/template/.codex/skills/migrate-to-shoehorn/SKILL.md +0 -118
  1363. package/template/.codex/skills/migrate-to-shoehorn/agents/openai.yaml +0 -3
  1364. package/template/.codex/skills/prototype-page-acceptance/SKILL.md +0 -62
  1365. package/template/.codex/skills/scaffold-exercises/SKILL.md +0 -106
  1366. package/template/.codex/skills/scaffold-exercises/agents/openai.yaml +0 -3
  1367. package/template/.codex/skills/setup-pre-commit/SKILL.md +0 -91
  1368. package/template/.codex/skills/setup-pre-commit/agents/openai.yaml +0 -3
  1369. package/template/.codex/skills/setup-ts-deep-modules/SKILL.md +0 -102
  1370. package/template/.codex/skills/setup-ts-deep-modules/agents/openai.yaml +0 -5
  1371. package/template/.codex/skills/setup-ts-deep-modules/dependency-cruiser.config.cjs +0 -95
  1372. package/template/.codex/skills/teach/GLOSSARY-FORMAT.md +0 -35
  1373. package/template/.codex/skills/teach/LEARNING-RECORD-FORMAT.md +0 -46
  1374. package/template/.codex/skills/teach/MISSION-FORMAT.md +0 -31
  1375. package/template/.codex/skills/teach/RESOURCES-FORMAT.md +0 -32
  1376. package/template/.codex/skills/teach/SKILL.md +0 -140
  1377. package/template/.codex/skills/teach/agents/openai.yaml +0 -5
  1378. package/template/.codex/skills/writing-beats/SKILL.md +0 -67
  1379. package/template/.codex/skills/writing-beats/agents/openai.yaml +0 -5
  1380. package/template/.codex/skills/writing-fragments/SKILL.md +0 -79
  1381. package/template/.codex/skills/writing-fragments/agents/openai.yaml +0 -5
  1382. package/template/.codex/skills/writing-shape/SKILL.md +0 -79
  1383. package/template/.codex/skills/writing-shape/agents/openai.yaml +0 -5
  1384. package/template/.codex/skills/yss-microapp-commit/SKILL.md +0 -201
  1385. package/template/.codex/skills/yss-microapp-commit/agents/openai.yaml +0 -5
  1386. package/template/.codex/skills/yss-microapp-commit/references/scope-mapping.md +0 -204
  1387. package/template/.codex/skills/yss-page-module-development/SKILL.md +0 -165
  1388. package/template/.codex/skills/yss-page-module-development/agents/openai.yaml +0 -5
  1389. package/template/.codex/skills/yss-page-module-development/examples/AdvancedFormPage/constant.ts +0 -32
  1390. package/template/.codex/skills/yss-page-module-development/examples/AdvancedFormPage/hooks/useRuleConfig.ts +0 -158
  1391. package/template/.codex/skills/yss-page-module-development/examples/AdvancedFormPage/index.vue +0 -188
  1392. package/template/.codex/skills/yss-page-module-development/examples/AdvancedFormPage/schemas/ruleConfigSchema.ts +0 -256
  1393. package/template/.codex/skills/yss-page-module-development/examples/AdvancedFormPage/style.less +0 -76
  1394. package/template/.codex/skills/yss-page-module-development/examples/StandardListPage/constant.ts +0 -128
  1395. package/template/.codex/skills/yss-page-module-development/examples/StandardListPage/hooks/useQualityRuleList.ts +0 -144
  1396. package/template/.codex/skills/yss-page-module-development/examples/StandardListPage/hooks/useRuleActions.ts +0 -141
  1397. package/template/.codex/skills/yss-page-module-development/examples/StandardListPage/index.vue +0 -175
  1398. package/template/.codex/skills/yss-page-module-development/examples/StandardListPage/style.less +0 -83
  1399. package/template/.codex/skills/yss-page-module-development/references/component-map.md +0 -34
  1400. package/template/.codex/skills/yss-page-module-development/references/frontend-docs.md +0 -11
  1401. package/template/.codex/skills/yss-page-module-development/references/hooks-map.md +0 -11
  1402. package/template/.codex/skills/yss-page-module-development/references/utils-map.md +0 -14
  1403. package/template/.codex/skills/yss-router/SKILL.md +0 -51
  1404. package/template/.codex/skills/yss-router/agents/openai.yaml +0 -4
  1405. package/template/.codex/skills/yss-router/references/boundaries.md +0 -50
  1406. package/template/.codex/skills/yss-router/references/router-contract.yaml +0 -349
  1407. package/template/.codex/skills/yss-router/references/slice-implementation-contract.md +0 -185
  1408. package/template/.codex/skills/yss-router/references/yss-skill-execution-result.md +0 -67
  1409. package/template/.codex/skills/yss-source-index/SKILL.md +0 -63
  1410. package/template/.codex/skills/yss-source-index/agents/openai.yaml +0 -4
  1411. package/template/.codex/skills/yss-source-index/references/source-map-config.md +0 -30
  1412. package/template/.codex/skills/yss-source-index/scripts/refresh-yss-skill-index.mjs +0 -24
  1413. package/template/.cursor/skills/ask-matt/PHASE-BOUNDARIES.md +0 -55
  1414. package/template/.cursor/skills/ask-matt/SKILL.md +0 -95
  1415. package/template/.cursor/skills/ask-matt/agents/openai.yaml +0 -5
  1416. package/template/.cursor/skills/dispatching-parallel-agents/SKILL.md +0 -185
  1417. package/template/.cursor/skills/loop-me/SKILL.md +0 -32
  1418. package/template/.cursor/skills/loop-me/agents/openai.yaml +0 -5
  1419. package/template/.cursor/skills/migrate-to-shoehorn/SKILL.md +0 -118
  1420. package/template/.cursor/skills/migrate-to-shoehorn/agents/openai.yaml +0 -3
  1421. package/template/.cursor/skills/prototype-page-acceptance/SKILL.md +0 -62
  1422. package/template/.cursor/skills/scaffold-exercises/SKILL.md +0 -106
  1423. package/template/.cursor/skills/scaffold-exercises/agents/openai.yaml +0 -3
  1424. package/template/.cursor/skills/setup-pre-commit/SKILL.md +0 -91
  1425. package/template/.cursor/skills/setup-pre-commit/agents/openai.yaml +0 -3
  1426. package/template/.cursor/skills/setup-ts-deep-modules/SKILL.md +0 -102
  1427. package/template/.cursor/skills/setup-ts-deep-modules/agents/openai.yaml +0 -5
  1428. package/template/.cursor/skills/setup-ts-deep-modules/dependency-cruiser.config.cjs +0 -95
  1429. package/template/.cursor/skills/teach/GLOSSARY-FORMAT.md +0 -35
  1430. package/template/.cursor/skills/teach/LEARNING-RECORD-FORMAT.md +0 -46
  1431. package/template/.cursor/skills/teach/MISSION-FORMAT.md +0 -31
  1432. package/template/.cursor/skills/teach/RESOURCES-FORMAT.md +0 -32
  1433. package/template/.cursor/skills/teach/SKILL.md +0 -140
  1434. package/template/.cursor/skills/teach/agents/openai.yaml +0 -5
  1435. package/template/.cursor/skills/writing-beats/SKILL.md +0 -67
  1436. package/template/.cursor/skills/writing-beats/agents/openai.yaml +0 -5
  1437. package/template/.cursor/skills/writing-fragments/SKILL.md +0 -79
  1438. package/template/.cursor/skills/writing-fragments/agents/openai.yaml +0 -5
  1439. package/template/.cursor/skills/writing-shape/SKILL.md +0 -79
  1440. package/template/.cursor/skills/writing-shape/agents/openai.yaml +0 -5
  1441. package/template/.cursor/skills/yss-microapp-commit/SKILL.md +0 -201
  1442. package/template/.cursor/skills/yss-microapp-commit/agents/openai.yaml +0 -5
  1443. package/template/.cursor/skills/yss-microapp-commit/references/scope-mapping.md +0 -204
  1444. package/template/.cursor/skills/yss-page-module-development/SKILL.md +0 -165
  1445. package/template/.cursor/skills/yss-page-module-development/agents/openai.yaml +0 -5
  1446. package/template/.cursor/skills/yss-page-module-development/examples/AdvancedFormPage/constant.ts +0 -32
  1447. package/template/.cursor/skills/yss-page-module-development/examples/AdvancedFormPage/hooks/useRuleConfig.ts +0 -158
  1448. package/template/.cursor/skills/yss-page-module-development/examples/AdvancedFormPage/index.vue +0 -188
  1449. package/template/.cursor/skills/yss-page-module-development/examples/AdvancedFormPage/schemas/ruleConfigSchema.ts +0 -256
  1450. package/template/.cursor/skills/yss-page-module-development/examples/AdvancedFormPage/style.less +0 -76
  1451. package/template/.cursor/skills/yss-page-module-development/examples/StandardListPage/constant.ts +0 -128
  1452. package/template/.cursor/skills/yss-page-module-development/examples/StandardListPage/hooks/useQualityRuleList.ts +0 -144
  1453. package/template/.cursor/skills/yss-page-module-development/examples/StandardListPage/hooks/useRuleActions.ts +0 -141
  1454. package/template/.cursor/skills/yss-page-module-development/examples/StandardListPage/index.vue +0 -175
  1455. package/template/.cursor/skills/yss-page-module-development/examples/StandardListPage/style.less +0 -83
  1456. package/template/.cursor/skills/yss-page-module-development/references/component-map.md +0 -34
  1457. package/template/.cursor/skills/yss-page-module-development/references/frontend-docs.md +0 -11
  1458. package/template/.cursor/skills/yss-page-module-development/references/hooks-map.md +0 -11
  1459. package/template/.cursor/skills/yss-page-module-development/references/utils-map.md +0 -14
  1460. package/template/.cursor/skills/yss-router/SKILL.md +0 -51
  1461. package/template/.cursor/skills/yss-router/agents/openai.yaml +0 -4
  1462. package/template/.cursor/skills/yss-router/references/boundaries.md +0 -50
  1463. package/template/.cursor/skills/yss-router/references/router-contract.yaml +0 -349
  1464. package/template/.cursor/skills/yss-router/references/slice-implementation-contract.md +0 -185
  1465. package/template/.cursor/skills/yss-router/references/yss-skill-execution-result.md +0 -67
  1466. package/template/.cursor/skills/yss-source-index/SKILL.md +0 -63
  1467. package/template/.cursor/skills/yss-source-index/agents/openai.yaml +0 -4
  1468. package/template/.cursor/skills/yss-source-index/references/source-map-config.md +0 -30
  1469. package/template/.cursor/skills/yss-source-index/scripts/refresh-yss-skill-index.mjs +0 -24
  1470. package/template/.gemini/settings.json +0 -8
  1471. package/template/.hermes/skills/alibaba-java-code-style/SKILL.md +0 -51
  1472. package/template/.hermes/skills/alibaba-java-code-style/agents/openai.yaml +0 -4
  1473. package/template/.hermes/skills/alibaba-java-code-style/references/database-engineering-design.md +0 -147
  1474. package/template/.hermes/skills/alibaba-java-code-style/references/java-programming.md +0 -178
  1475. package/template/.hermes/skills/alibaba-java-code-style/references/reliability-test-security.md +0 -89
  1476. package/template/.hermes/skills/archify/LICENSE +0 -22
  1477. package/template/.hermes/skills/archify/SKILL.md +0 -156
  1478. package/template/.hermes/skills/archify/assets/template.html +0 -14787
  1479. package/template/.hermes/skills/archify/bin/archify.mjs +0 -1990
  1480. package/template/.hermes/skills/archify/bin/open-artifact.mjs +0 -86
  1481. package/template/.hermes/skills/archify/bin/preview.mjs +0 -648
  1482. package/template/.hermes/skills/archify/bin/visual-check.mjs +0 -829
  1483. package/template/.hermes/skills/archify/brand-marks/README.md +0 -31
  1484. package/template/.hermes/skills/archify/brand-marks/catalog.json +0 -131
  1485. package/template/.hermes/skills/archify/delta/architecture-delta.mjs +0 -1214
  1486. package/template/.hermes/skills/archify/examples/agent-run.lifecycle.json +0 -71
  1487. package/template/.hermes/skills/archify/examples/agent-tool-call.workflow.json +0 -94
  1488. package/template/.hermes/skills/archify/examples/async-job-roundtrip.sequence.json +0 -61
  1489. package/template/.hermes/skills/archify/examples/brand-aware-delivery.architecture.json +0 -47
  1490. package/template/.hermes/skills/archify/examples/cache-miss-request.sequence.json +0 -81
  1491. package/template/.hermes/skills/archify/examples/checkout-platform.base.architecture.json +0 -31
  1492. package/template/.hermes/skills/archify/examples/checkout-platform.head.architecture.json +0 -31
  1493. package/template/.hermes/skills/archify/examples/dataflow-product-analytics.html +0 -14898
  1494. package/template/.hermes/skills/archify/examples/deployment-release.lifecycle.json +0 -49
  1495. package/template/.hermes/skills/archify/examples/event-stream.dataflow.json +0 -57
  1496. package/template/.hermes/skills/archify/examples/incident-response.workflow.json +0 -64
  1497. package/template/.hermes/skills/archify/examples/lifecycle-agent-run.html +0 -14847
  1498. package/template/.hermes/skills/archify/examples/product-analytics.dataflow.json +0 -76
  1499. package/template/.hermes/skills/archify/examples/production-deployment.architecture.json +0 -71
  1500. package/template/.hermes/skills/archify/examples/release-delivery.workflow.json +0 -62
  1501. package/template/.hermes/skills/archify/examples/sequence-cache-miss-request.html +0 -14913
  1502. package/template/.hermes/skills/archify/examples/web-app-rendered.html +0 -14862
  1503. package/template/.hermes/skills/archify/examples/web-app.architecture.json +0 -46
  1504. package/template/.hermes/skills/archify/examples/workflow-agent-tool-call-rendered.html +0 -14904
  1505. package/template/.hermes/skills/archify/migrations/workflow-v2.mjs +0 -279
  1506. package/template/.hermes/skills/archify/package-lock.json +0 -149
  1507. package/template/.hermes/skills/archify/package.json +0 -37
  1508. package/template/.hermes/skills/archify/recipes/scenarios.mjs +0 -391
  1509. package/template/.hermes/skills/archify/references/authoring-contract.md +0 -191
  1510. package/template/.hermes/skills/archify/references/brand-marks.md +0 -65
  1511. package/template/.hermes/skills/archify/references/delivery-contract.md +0 -112
  1512. package/template/.hermes/skills/archify/references/viewer-runtime.md +0 -45
  1513. package/template/.hermes/skills/archify/renderers/architecture/grid.mjs +0 -62
  1514. package/template/.hermes/skills/archify/renderers/architecture/render-architecture.mjs +0 -1078
  1515. package/template/.hermes/skills/archify/renderers/dataflow/README.md +0 -104
  1516. package/template/.hermes/skills/archify/renderers/dataflow/render-dataflow.mjs +0 -483
  1517. package/template/.hermes/skills/archify/renderers/lifecycle/README.md +0 -115
  1518. package/template/.hermes/skills/archify/renderers/lifecycle/render-lifecycle.mjs +0 -561
  1519. package/template/.hermes/skills/archify/renderers/sequence/README.md +0 -114
  1520. package/template/.hermes/skills/archify/renderers/sequence/render-sequence.mjs +0 -453
  1521. package/template/.hermes/skills/archify/renderers/shared/brand-marks.mjs +0 -563
  1522. package/template/.hermes/skills/archify/renderers/shared/cli.mjs +0 -218
  1523. package/template/.hermes/skills/archify/renderers/shared/desktop-readability.mjs +0 -26
  1524. package/template/.hermes/skills/archify/renderers/shared/diagnostics.mjs +0 -127
  1525. package/template/.hermes/skills/archify/renderers/shared/engineering-profiles.mjs +0 -157
  1526. package/template/.hermes/skills/archify/renderers/shared/generated-brand-marks.mjs +0 -2003
  1527. package/template/.hermes/skills/archify/renderers/shared/generated-validators.mjs +0 -13
  1528. package/template/.hermes/skills/archify/renderers/shared/geometry.mjs +0 -1423
  1529. package/template/.hermes/skills/archify/renderers/shared/i18n.mjs +0 -594
  1530. package/template/.hermes/skills/archify/renderers/shared/layout-report.mjs +0 -40
  1531. package/template/.hermes/skills/archify/renderers/shared/legend.mjs +0 -217
  1532. package/template/.hermes/skills/archify/renderers/shared/output-path.mjs +0 -321
  1533. package/template/.hermes/skills/archify/renderers/shared/repository-evidence.mjs +0 -235
  1534. package/template/.hermes/skills/archify/renderers/shared/text-fit.mjs +0 -49
  1535. package/template/.hermes/skills/archify/renderers/shared/utils.mjs +0 -232
  1536. package/template/.hermes/skills/archify/renderers/shared/validator.mjs +0 -86
  1537. package/template/.hermes/skills/archify/renderers/workflow/README.md +0 -223
  1538. package/template/.hermes/skills/archify/renderers/workflow/render-workflow.mjs +0 -35
  1539. package/template/.hermes/skills/archify/renderers/workflow/workflow-compiler.mjs +0 -4400
  1540. package/template/.hermes/skills/archify/renderers/workflow/workflow-migration-geometry.mjs +0 -144
  1541. package/template/.hermes/skills/archify/schemas/README.md +0 -211
  1542. package/template/.hermes/skills/archify/schemas/architecture.schema.json +0 -176
  1543. package/template/.hermes/skills/archify/schemas/common.schema.json +0 -115
  1544. package/template/.hermes/skills/archify/schemas/dataflow.schema.json +0 -243
  1545. package/template/.hermes/skills/archify/schemas/lifecycle.schema.json +0 -266
  1546. package/template/.hermes/skills/archify/schemas/sequence.schema.json +0 -223
  1547. package/template/.hermes/skills/archify/schemas/workflow.schema.json +0 -428
  1548. package/template/.hermes/skills/archify/scripts/check-render-output.mjs +0 -835
  1549. package/template/.hermes/skills/archify/scripts/check-update.mjs +0 -1667
  1550. package/template/.hermes/skills/archify/scripts/generate-brand-marks.mjs +0 -141
  1551. package/template/.hermes/skills/archify/scripts/generate-validators.mjs +0 -66
  1552. package/template/.hermes/skills/archify/scripts/render-examples.mjs +0 -26
  1553. package/template/.hermes/skills/archify/scripts/update-contract.mjs +0 -182
  1554. package/template/.hermes/skills/archify/scripts/yss-safe-deliver.mjs +0 -214
  1555. package/template/.hermes/skills/archify/skill-release.json +0 -10
  1556. package/template/.hermes/skills/archify/test/adaptive-reader-layout.test.mjs +0 -86
  1557. package/template/.hermes/skills/archify/test/animation.test.mjs +0 -179
  1558. package/template/.hermes/skills/archify/test/architecture-delta.test.mjs +0 -518
  1559. package/template/.hermes/skills/archify/test/authored-reachability.test.mjs +0 -95
  1560. package/template/.hermes/skills/archify/test/authoring-safety-contract.test.mjs +0 -54
  1561. package/template/.hermes/skills/archify/test/automatic-port-spread.test.mjs +0 -376
  1562. package/template/.hermes/skills/archify/test/base-input-compatibility.test.mjs +0 -42
  1563. package/template/.hermes/skills/archify/test/brand-marks.test.mjs +0 -654
  1564. package/template/.hermes/skills/archify/test/chapter-delta-preview.test.mjs +0 -157
  1565. package/template/.hermes/skills/archify/test/chapter-handoff.test.mjs +0 -97
  1566. package/template/.hermes/skills/archify/test/chapter-rail.test.mjs +0 -86
  1567. package/template/.hermes/skills/archify/test/checkout-line-endings.test.mjs +0 -72
  1568. package/template/.hermes/skills/archify/test/clean-skill-staging.test.mjs +0 -244
  1569. package/template/.hermes/skills/archify/test/cli.test.mjs +0 -809
  1570. package/template/.hermes/skills/archify/test/community-proof-intake.test.mjs +0 -104
  1571. package/template/.hermes/skills/archify/test/cursor-onboarding.test.mjs +0 -74
  1572. package/template/.hermes/skills/archify/test/degraded.test.mjs +0 -161
  1573. package/template/.hermes/skills/archify/test/delivery-contract.test.mjs +0 -52
  1574. package/template/.hermes/skills/archify/test/desktop-reader-browser.test.mjs +0 -58
  1575. package/template/.hermes/skills/archify/test/diagram-guide.test.mjs +0 -92
  1576. package/template/.hermes/skills/archify/test/engineering-profile.test.mjs +0 -209
  1577. package/template/.hermes/skills/archify/test/finder.test.mjs +0 -104
  1578. package/template/.hermes/skills/archify/test/fixtures/automatic-routing-node-border-clearance.workflow.json +0 -40
  1579. package/template/.hermes/skills/archify/test/fixtures/fail-migration-cleanup.mjs +0 -17
  1580. package/template/.hermes/skills/archify/test/fixtures/issue-126/custom-widths.workflow.json +0 -18
  1581. package/template/.hermes/skills/archify/test/fixtures/issue-126/explicit-route.workflow.json +0 -28
  1582. package/template/.hermes/skills/archify/test/fixtures/issue-126/explicit-viewbox.workflow.json +0 -19
  1583. package/template/.hermes/skills/archify/test/fixtures/issue-126/labels.workflow.json +0 -18
  1584. package/template/.hermes/skills/archify/test/fixtures/v1-baseline/agent-run.lifecycle.json +0 -64
  1585. package/template/.hermes/skills/archify/test/fixtures/v1-baseline/agent-tool-call.workflow.json +0 -88
  1586. package/template/.hermes/skills/archify/test/fixtures/v1-baseline/cache-miss-request.sequence.json +0 -75
  1587. package/template/.hermes/skills/archify/test/fixtures/v1-baseline/event-stream.dataflow.json +0 -57
  1588. package/template/.hermes/skills/archify/test/fixtures/v1-baseline/product-analytics.dataflow.json +0 -70
  1589. package/template/.hermes/skills/archify/test/fixtures/v1-baseline/production-deployment.architecture.json +0 -71
  1590. package/template/.hermes/skills/archify/test/fixtures/v1-baseline/web-app.architecture.json +0 -41
  1591. package/template/.hermes/skills/archify/test/fixtures/v1-workflow-700x400.workflow.json +0 -22
  1592. package/template/.hermes/skills/archify/test/fixtures/v1-workflow-explicit-coordinates.workflow.json +0 -47
  1593. package/template/.hermes/skills/archify/test/gallery.test.mjs +0 -130
  1594. package/template/.hermes/skills/archify/test/generate-validators.test.mjs +0 -59
  1595. package/template/.hermes/skills/archify/test/generated-artifact-xml.test.mjs +0 -88
  1596. package/template/.hermes/skills/archify/test/geometry.test.mjs +0 -739
  1597. package/template/.hermes/skills/archify/test/golden.mjs +0 -207
  1598. package/template/.hermes/skills/archify/test/grid.test.mjs +0 -47
  1599. package/template/.hermes/skills/archify/test/guide-page.test.mjs +0 -59
  1600. package/template/.hermes/skills/archify/test/guide.test.mjs +0 -81
  1601. package/template/.hermes/skills/archify/test/guided-views.test.mjs +0 -144
  1602. package/template/.hermes/skills/archify/test/helpers/xml.mjs +0 -37
  1603. package/template/.hermes/skills/archify/test/i18n.test.mjs +0 -422
  1604. package/template/.hermes/skills/archify/test/intent-trace.test.mjs +0 -111
  1605. package/template/.hermes/skills/archify/test/landing.test.mjs +0 -97
  1606. package/template/.hermes/skills/archify/test/layout-rules.test.mjs +0 -1449
  1607. package/template/.hermes/skills/archify/test/legend-contract.test.mjs +0 -404
  1608. package/template/.hermes/skills/archify/test/motion-governor.test.mjs +0 -111
  1609. package/template/.hermes/skills/archify/test/open-artifact.test.mjs +0 -118
  1610. package/template/.hermes/skills/archify/test/ordinary-model-floor.test.mjs +0 -1024
  1611. package/template/.hermes/skills/archify/test/output-path.test.mjs +0 -587
  1612. package/template/.hermes/skills/archify/test/presentation.test.mjs +0 -71
  1613. package/template/.hermes/skills/archify/test/preset-tryon.test.mjs +0 -113
  1614. package/template/.hermes/skills/archify/test/preview-contract.test.mjs +0 -40
  1615. package/template/.hermes/skills/archify/test/preview.test.mjs +0 -499
  1616. package/template/.hermes/skills/archify/test/proof-aperture.test.mjs +0 -78
  1617. package/template/.hermes/skills/archify/test/reach-share-card.test.mjs +0 -149
  1618. package/template/.hermes/skills/archify/test/readme-showcase.test.mjs +0 -318
  1619. package/template/.hermes/skills/archify/test/real-repository-proof.test.mjs +0 -209
  1620. package/template/.hermes/skills/archify/test/relationship-direct-explorer.test.mjs +0 -115
  1621. package/template/.hermes/skills/archify/test/relationship-lens.test.mjs +0 -128
  1622. package/template/.hermes/skills/archify/test/relationship-permalink.test.mjs +0 -130
  1623. package/template/.hermes/skills/archify/test/relationship-pulse.test.mjs +0 -122
  1624. package/template/.hermes/skills/archify/test/release-identity.test.mjs +0 -504
  1625. package/template/.hermes/skills/archify/test/release-package-gates.test.mjs +0 -508
  1626. package/template/.hermes/skills/archify/test/render-output-checks.test.mjs +0 -435
  1627. package/template/.hermes/skills/archify/test/repair-receipt.test.mjs +0 -181
  1628. package/template/.hermes/skills/archify/test/repository-evidence.test.mjs +0 -217
  1629. package/template/.hermes/skills/archify/test/repository-language-metadata.test.mjs +0 -52
  1630. package/template/.hermes/skills/archify/test/route-journey.test.mjs +0 -123
  1631. package/template/.hermes/skills/archify/test/route-probe.test.mjs +0 -114
  1632. package/template/.hermes/skills/archify/test/route-share-card.test.mjs +0 -163
  1633. package/template/.hermes/skills/archify/test/semantic-camera.test.mjs +0 -88
  1634. package/template/.hermes/skills/archify/test/semantic-flow.test.mjs +0 -90
  1635. package/template/.hermes/skills/archify/test/semantic-legend-gateway.test.mjs +0 -156
  1636. package/template/.hermes/skills/archify/test/semantic-lens.test.mjs +0 -103
  1637. package/template/.hermes/skills/archify/test/semantic-passport.test.mjs +0 -99
  1638. package/template/.hermes/skills/archify/test/semantic-radar.test.mjs +0 -575
  1639. package/template/.hermes/skills/archify/test/semantic-zoom.test.mjs +0 -86
  1640. package/template/.hermes/skills/archify/test/sequence-column-fit.test.mjs +0 -137
  1641. package/template/.hermes/skills/archify/test/settled-flow.test.mjs +0 -97
  1642. package/template/.hermes/skills/archify/test/share-card-export.test.mjs +0 -132
  1643. package/template/.hermes/skills/archify/test/site-language-continuity.test.mjs +0 -562
  1644. package/template/.hermes/skills/archify/test/site-language-integration.mjs +0 -9
  1645. package/template/.hermes/skills/archify/test/skill-metadata.test.mjs +0 -84
  1646. package/template/.hermes/skills/archify/test/stable-update-manifest.test.mjs +0 -167
  1647. package/template/.hermes/skills/archify/test/start-page.test.mjs +0 -312
  1648. package/template/.hermes/skills/archify/test/story-beat-navigator.test.mjs +0 -103
  1649. package/template/.hermes/skills/archify/test/story-carrier.test.mjs +0 -90
  1650. package/template/.hermes/skills/archify/test/story-director-strip.test.mjs +0 -91
  1651. package/template/.hermes/skills/archify/test/story-follow-camera.test.mjs +0 -103
  1652. package/template/.hermes/skills/archify/test/story-horizon.test.mjs +0 -89
  1653. package/template/.hermes/skills/archify/test/story-moment-link.test.mjs +0 -93
  1654. package/template/.hermes/skills/archify/test/story-shelf.test.mjs +0 -84
  1655. package/template/.hermes/skills/archify/test/story-trail.test.mjs +0 -81
  1656. package/template/.hermes/skills/archify/test/toolbar-polish.test.mjs +0 -57
  1657. package/template/.hermes/skills/archify/test/update-contract.test.mjs +0 -133
  1658. package/template/.hermes/skills/archify/test/update-notifier.test.mjs +0 -3317
  1659. package/template/.hermes/skills/archify/test/v1-compatibility.test.mjs +0 -329
  1660. package/template/.hermes/skills/archify/test/vertical-edge.test.mjs +0 -68
  1661. package/template/.hermes/skills/archify/test/viewer-chrome-layout.test.mjs +0 -872
  1662. package/template/.hermes/skills/archify/test/visual-check.test.mjs +0 -400
  1663. package/template/.hermes/skills/archify/test/webm-artifact.smoke.mjs +0 -1840
  1664. package/template/.hermes/skills/archify/test/workflow-compiler-hard-contract.test.mjs +0 -2135
  1665. package/template/.hermes/skills/archify/test/workflow-compiler.test.mjs +0 -1163
  1666. package/template/.hermes/skills/archify/test/workflow-migration.test.mjs +0 -620
  1667. package/template/.hermes/skills/archify/test/workflow-semantic-contract.test.mjs +0 -131
  1668. package/template/.hermes/skills/archify/test/yss-safe-deliver.test.mjs +0 -153
  1669. package/template/.hermes/skills/ask-matt/PHASE-BOUNDARIES.md +0 -55
  1670. package/template/.hermes/skills/ask-matt/SKILL.md +0 -95
  1671. package/template/.hermes/skills/ask-matt/agents/openai.yaml +0 -5
  1672. package/template/.hermes/skills/code-review/SKILL.md +0 -122
  1673. package/template/.hermes/skills/code-review/agents/openai.yaml +0 -3
  1674. package/template/.hermes/skills/code-review/references/yss-review-standards.md +0 -54
  1675. package/template/.hermes/skills/codebase-design/DEEPENING.md +0 -37
  1676. package/template/.hermes/skills/codebase-design/DESIGN-IT-TWICE.md +0 -44
  1677. package/template/.hermes/skills/codebase-design/SKILL.md +0 -118
  1678. package/template/.hermes/skills/codebase-design/agents/openai.yaml +0 -3
  1679. package/template/.hermes/skills/competitive-intelligence/SKILL.md +0 -94
  1680. package/template/.hermes/skills/component-selection-imports/SKILL.md +0 -64
  1681. package/template/.hermes/skills/cross-repo-implementation-routing/SKILL.md +0 -51
  1682. package/template/.hermes/skills/diagnosing-bugs/SKILL.md +0 -138
  1683. package/template/.hermes/skills/diagnosing-bugs/agents/openai.yaml +0 -3
  1684. package/template/.hermes/skills/diagnosing-bugs/scripts/hitl-loop.template.sh +0 -44
  1685. package/template/.hermes/skills/dispatching-parallel-agents/SKILL.md +0 -185
  1686. package/template/.hermes/skills/domain-modeling/ADR-FORMAT.md +0 -47
  1687. package/template/.hermes/skills/domain-modeling/CONTEXT-FORMAT.md +0 -60
  1688. package/template/.hermes/skills/domain-modeling/SKILL.md +0 -74
  1689. package/template/.hermes/skills/domain-modeling/agents/openai.yaml +0 -3
  1690. package/template/.hermes/skills/file-export-download/SKILL.md +0 -160
  1691. package/template/.hermes/skills/file-export-download/agents/openai.yaml +0 -4
  1692. package/template/.hermes/skills/formily-foundation/SKILL.md +0 -176
  1693. package/template/.hermes/skills/formily-foundation/references/examples.md +0 -486
  1694. package/template/.hermes/skills/formily-linkage-effects/SKILL.md +0 -167
  1695. package/template/.hermes/skills/formily-mode-slot-detail/SKILL.md +0 -137
  1696. package/template/.hermes/skills/formily-step-flow/SKILL.md +0 -194
  1697. package/template/.hermes/skills/frontend-commit/SKILL.md +0 -118
  1698. package/template/.hermes/skills/frontend-commit/agents/openai.yaml +0 -7
  1699. package/template/.hermes/skills/frontend-commit/references/scope-and-examples.md +0 -111
  1700. package/template/.hermes/skills/grill-me/SKILL.md +0 -7
  1701. package/template/.hermes/skills/grill-me/agents/openai.yaml +0 -5
  1702. package/template/.hermes/skills/grill-with-docs/SKILL.md +0 -19
  1703. package/template/.hermes/skills/grill-with-docs/agents/openai.yaml +0 -5
  1704. package/template/.hermes/skills/grilling/SKILL.md +0 -28
  1705. package/template/.hermes/skills/grilling/agents/openai.yaml +0 -3
  1706. package/template/.hermes/skills/handoff/SKILL.md +0 -16
  1707. package/template/.hermes/skills/handoff/agents/openai.yaml +0 -5
  1708. package/template/.hermes/skills/implement/SKILL.md +0 -15
  1709. package/template/.hermes/skills/implement/agents/openai.yaml +0 -5
  1710. package/template/.hermes/skills/implementation-repo-onboarding/SKILL.md +0 -50
  1711. package/template/.hermes/skills/improve-codebase-architecture/HTML-REPORT.md +0 -123
  1712. package/template/.hermes/skills/improve-codebase-architecture/SKILL.md +0 -71
  1713. package/template/.hermes/skills/improve-codebase-architecture/agents/openai.yaml +0 -5
  1714. package/template/.hermes/skills/java-backend-commit/SKILL.md +0 -121
  1715. package/template/.hermes/skills/java-backend-commit/agents/openai.yaml +0 -7
  1716. package/template/.hermes/skills/java-backend-commit/references/scope-and-examples.md +0 -118
  1717. package/template/.hermes/skills/llm-wiki/SKILL.md +0 -60
  1718. package/template/.hermes/skills/llm-wiki/assets/CLAUDE.md.template +0 -26
  1719. package/template/.hermes/skills/llm-wiki/assets/fixtures/broken-wiki/wiki/CLAUDE.md +0 -3
  1720. package/template/.hermes/skills/llm-wiki/assets/fixtures/broken-wiki/wiki/index.md +0 -5
  1721. package/template/.hermes/skills/llm-wiki/assets/fixtures/broken-wiki/wiki/log.md +0 -1
  1722. package/template/.hermes/skills/llm-wiki/assets/fixtures/broken-wiki/wiki//345/255/230/345/234/250/347/232/204/351/241/265.md +0 -7
  1723. package/template/.hermes/skills/llm-wiki/references/compile.md +0 -126
  1724. package/template/.hermes/skills/llm-wiki/references/discover.md +0 -42
  1725. package/template/.hermes/skills/llm-wiki/references/ingest.md +0 -36
  1726. package/template/.hermes/skills/llm-wiki/references/lint.md +0 -54
  1727. package/template/.hermes/skills/llm-wiki/references/query.md +0 -21
  1728. package/template/.hermes/skills/llm-wiki/references/schema.md +0 -45
  1729. package/template/.hermes/skills/llm-wiki/references/writing.md +0 -35
  1730. package/template/.hermes/skills/llm-wiki/scripts/advise.mjs +0 -196
  1731. package/template/.hermes/skills/llm-wiki/scripts/advise.test.mjs +0 -91
  1732. package/template/.hermes/skills/llm-wiki/scripts/extract.mjs +0 -55
  1733. package/template/.hermes/skills/llm-wiki/scripts/extract.test.mjs +0 -34
  1734. package/template/.hermes/skills/llm-wiki/scripts/inventory.mjs +0 -174
  1735. package/template/.hermes/skills/llm-wiki/scripts/inventory.test.mjs +0 -98
  1736. package/template/.hermes/skills/llm-wiki/scripts/lint-wikilinks.mjs +0 -177
  1737. package/template/.hermes/skills/llm-wiki/scripts/lint-wikilinks.test.mjs +0 -212
  1738. package/template/.hermes/skills/lombok/SKILL.md +0 -351
  1739. package/template/.hermes/skills/loop-me/SKILL.md +0 -32
  1740. package/template/.hermes/skills/loop-me/agents/openai.yaml +0 -5
  1741. package/template/.hermes/skills/maintaining-skills/SKILL.md +0 -27
  1742. package/template/.hermes/skills/mapstruct/SKILL.md +0 -334
  1743. package/template/.hermes/skills/migrate-to-shoehorn/SKILL.md +0 -118
  1744. package/template/.hermes/skills/migrate-to-shoehorn/agents/openai.yaml +0 -3
  1745. package/template/.hermes/skills/page-form-module/SKILL.md +0 -168
  1746. package/template/.hermes/skills/page-list-module/SKILL.md +0 -137
  1747. package/template/.hermes/skills/page-skeleton/SKILL.md +0 -76
  1748. package/template/.hermes/skills/page-skeleton/examples/AdvancedFormPage/constant.ts +0 -34
  1749. package/template/.hermes/skills/page-skeleton/examples/AdvancedFormPage/hooks/useRuleConfig.ts +0 -75
  1750. package/template/.hermes/skills/page-skeleton/examples/AdvancedFormPage/index.vue +0 -107
  1751. package/template/.hermes/skills/page-skeleton/examples/AdvancedFormPage/schemas/ruleConfigSchema.ts +0 -256
  1752. package/template/.hermes/skills/page-skeleton/examples/AdvancedFormPage/style.less +0 -30
  1753. package/template/.hermes/skills/page-skeleton/examples/StandardListPage/constant.ts +0 -28
  1754. package/template/.hermes/skills/page-skeleton/examples/StandardListPage/hooks/useQualityRuleList.ts +0 -58
  1755. package/template/.hermes/skills/page-skeleton/examples/StandardListPage/hooks/useRuleActions.ts +0 -65
  1756. package/template/.hermes/skills/page-skeleton/examples/StandardListPage/index.vue +0 -91
  1757. package/template/.hermes/skills/page-skeleton/examples/StandardListPage/style.less +0 -49
  1758. package/template/.hermes/skills/prototype/LOGIC.md +0 -67
  1759. package/template/.hermes/skills/prototype/SKILL.md +0 -26
  1760. package/template/.hermes/skills/prototype/UI.md +0 -112
  1761. package/template/.hermes/skills/prototype/agents/openai.yaml +0 -3
  1762. package/template/.hermes/skills/prototype-page-acceptance/SKILL.md +0 -62
  1763. package/template/.hermes/skills/prototype-review/SKILL.md +0 -74
  1764. package/template/.hermes/skills/prototype-review/agents/openai.yaml +0 -4
  1765. package/template/.hermes/skills/resolving-merge-conflicts/SKILL.md +0 -14
  1766. package/template/.hermes/skills/resolving-merge-conflicts/agents/openai.yaml +0 -3
  1767. package/template/.hermes/skills/scaffold-exercises/SKILL.md +0 -106
  1768. package/template/.hermes/skills/scaffold-exercises/agents/openai.yaml +0 -3
  1769. package/template/.hermes/skills/setup-matt-pocock-skills/SKILL.md +0 -125
  1770. package/template/.hermes/skills/setup-matt-pocock-skills/agents/openai.yaml +0 -5
  1771. package/template/.hermes/skills/setup-matt-pocock-skills/domain.md +0 -51
  1772. package/template/.hermes/skills/setup-matt-pocock-skills/issue-tracker-github.md +0 -45
  1773. package/template/.hermes/skills/setup-matt-pocock-skills/issue-tracker-gitlab.md +0 -46
  1774. package/template/.hermes/skills/setup-matt-pocock-skills/issue-tracker-local.md +0 -66
  1775. package/template/.hermes/skills/setup-matt-pocock-skills/triage-labels.md +0 -15
  1776. package/template/.hermes/skills/setup-pre-commit/SKILL.md +0 -91
  1777. package/template/.hermes/skills/setup-pre-commit/agents/openai.yaml +0 -3
  1778. package/template/.hermes/skills/setup-ts-deep-modules/SKILL.md +0 -102
  1779. package/template/.hermes/skills/setup-ts-deep-modules/agents/openai.yaml +0 -5
  1780. package/template/.hermes/skills/setup-ts-deep-modules/dependency-cruiser.config.cjs +0 -95
  1781. package/template/.hermes/skills/tdd/SKILL.md +0 -38
  1782. package/template/.hermes/skills/tdd/agents/openai.yaml +0 -3
  1783. package/template/.hermes/skills/tdd/mocking.md +0 -59
  1784. package/template/.hermes/skills/tdd/tests.md +0 -77
  1785. package/template/.hermes/skills/teach/GLOSSARY-FORMAT.md +0 -35
  1786. package/template/.hermes/skills/teach/LEARNING-RECORD-FORMAT.md +0 -46
  1787. package/template/.hermes/skills/teach/MISSION-FORMAT.md +0 -31
  1788. package/template/.hermes/skills/teach/RESOURCES-FORMAT.md +0 -32
  1789. package/template/.hermes/skills/teach/SKILL.md +0 -140
  1790. package/template/.hermes/skills/teach/agents/openai.yaml +0 -5
  1791. package/template/.hermes/skills/theme-token-usage/SKILL.md +0 -123
  1792. package/template/.hermes/skills/theme-token-usage/agents/openai.yaml +0 -4
  1793. package/template/.hermes/skills/to-questionnaire/SKILL.md +0 -53
  1794. package/template/.hermes/skills/to-questionnaire/agents/openai.yaml +0 -5
  1795. package/template/.hermes/skills/to-spec/SKILL.md +0 -75
  1796. package/template/.hermes/skills/to-spec/agents/openai.yaml +0 -5
  1797. package/template/.hermes/skills/to-tickets/SKILL.md +0 -105
  1798. package/template/.hermes/skills/to-tickets/agents/openai.yaml +0 -5
  1799. package/template/.hermes/skills/triage/AGENT-BRIEF.md +0 -207
  1800. package/template/.hermes/skills/triage/OUT-OF-SCOPE.md +0 -105
  1801. package/template/.hermes/skills/triage/SKILL.md +0 -112
  1802. package/template/.hermes/skills/triage/agents/openai.yaml +0 -5
  1803. package/template/.hermes/skills/using-git-worktrees/SKILL.md +0 -202
  1804. package/template/.hermes/skills/vue3-best-practices/SKILL.md +0 -68
  1805. package/template/.hermes/skills/wait-what/SKILL.md +0 -7
  1806. package/template/.hermes/skills/wait-what/agents/openai.yaml +0 -5
  1807. package/template/.hermes/skills/wayfinder/SKILL.md +0 -128
  1808. package/template/.hermes/skills/wayfinder/agents/openai.yaml +0 -5
  1809. package/template/.hermes/skills/writing-beats/SKILL.md +0 -67
  1810. package/template/.hermes/skills/writing-beats/agents/openai.yaml +0 -5
  1811. package/template/.hermes/skills/writing-for-agents/SKILL-MECHANICS.md +0 -22
  1812. package/template/.hermes/skills/writing-for-agents/SKILL.md +0 -81
  1813. package/template/.hermes/skills/writing-for-agents/agents/openai.yaml +0 -3
  1814. package/template/.hermes/skills/writing-fragments/SKILL.md +0 -79
  1815. package/template/.hermes/skills/writing-fragments/agents/openai.yaml +0 -5
  1816. package/template/.hermes/skills/writing-shape/SKILL.md +0 -79
  1817. package/template/.hermes/skills/writing-shape/agents/openai.yaml +0 -5
  1818. package/template/.hermes/skills/yedit-table-usage/SKILL.md +0 -227
  1819. package/template/.hermes/skills/yss-antd-design/SKILL.md +0 -34
  1820. package/template/.hermes/skills/yss-antd-design/references/boundaries.md +0 -30
  1821. package/template/.hermes/skills/yss-antd-design/references/cli-matrix.md +0 -38
  1822. package/template/.hermes/skills/yss-antd-design/references/evidence.md +0 -30
  1823. package/template/.hermes/skills/yss-antd-design/scripts/validate-frontmatter.mjs +0 -46
  1824. package/template/.hermes/skills/yss-antd-design/scripts/validate-frontmatter.test.mjs +0 -27
  1825. package/template/.hermes/skills/yss-api-integration/SKILL.md +0 -185
  1826. package/template/.hermes/skills/yss-api-integration/agents/openai.yaml +0 -5
  1827. package/template/.hermes/skills/yss-application/SKILL.md +0 -54
  1828. package/template/.hermes/skills/yss-application/agents/openai.yaml +0 -5
  1829. package/template/.hermes/skills/yss-application/references/application-layer-guide.md +0 -87
  1830. package/template/.hermes/skills/yss-audit-log/SKILL.md +0 -67
  1831. package/template/.hermes/skills/yss-audit-log/agents/openai.yaml +0 -5
  1832. package/template/.hermes/skills/yss-audit-log/assets/AuditLogAspect.java +0 -262
  1833. package/template/.hermes/skills/yss-audit-log/assets/YssAuditLogPrintSubscriberImpl.java +0 -37
  1834. package/template/.hermes/skills/yss-audit-log/assets/YssAuditLogSysManagerSubscriberImpl.java +0 -18
  1835. package/template/.hermes/skills/yss-audit-log/assets/YssAuditPublishService.java +0 -69
  1836. package/template/.hermes/skills/yss-audit-log/references/README.md +0 -69
  1837. package/template/.hermes/skills/yss-audit-log/references/source-index.md +0 -43
  1838. package/template/.hermes/skills/yss-cache/SKILL.md +0 -44
  1839. package/template/.hermes/skills/yss-cache/agents/openai.yaml +0 -5
  1840. package/template/.hermes/skills/yss-cache/references/annotations.md +0 -39
  1841. package/template/.hermes/skills/yss-cache/references/architecture.md +0 -25
  1842. package/template/.hermes/skills/yss-cache/references/configuration.md +0 -34
  1843. package/template/.hermes/skills/yss-cache/references/redis-fallback.md +0 -23
  1844. package/template/.hermes/skills/yss-cache/references/redis-topology.md +0 -62
  1845. package/template/.hermes/skills/yss-cache/references/serialization.md +0 -17
  1846. package/template/.hermes/skills/yss-cache/references/source-index.md +0 -67
  1847. package/template/.hermes/skills/yss-cache/references/troubleshooting.md +0 -33
  1848. package/template/.hermes/skills/yss-cache/references/verification.md +0 -34
  1849. package/template/.hermes/skills/yss-cache/scripts/check-skill-freshness.sh +0 -84
  1850. package/template/.hermes/skills/yss-cache/scripts/inspect-cache-usage.sh +0 -96
  1851. package/template/.hermes/skills/yss-cache/scripts/verify-cache-component.sh +0 -101
  1852. package/template/.hermes/skills/yss-components/SKILL.md +0 -386
  1853. package/template/.hermes/skills/yss-components/agents/openai.yaml +0 -5
  1854. package/template/.hermes/skills/yss-components/references/frontend-docs.md +0 -9
  1855. package/template/.hermes/skills/yss-ddd-scaffold-generator/SKILL.md +0 -121
  1856. package/template/.hermes/skills/yss-ddd-scaffold-generator/agents/openai.yaml +0 -5
  1857. package/template/.hermes/skills/yss-ddd-scaffold-generator/assets/templates/config/application-local.yml.template +0 -8
  1858. package/template/.hermes/skills/yss-ddd-scaffold-generator/assets/templates/config/application.yml.template +0 -36
  1859. package/template/.hermes/skills/yss-ddd-scaffold-generator/assets/templates/config/logback-spring.xml.template +0 -15
  1860. package/template/.hermes/skills/yss-ddd-scaffold-generator/assets/templates/java/architecture-rules-test.java.template +0 -36
  1861. package/template/.hermes/skills/yss-ddd-scaffold-generator/assets/templates/java/bootstrap-application.java.template +0 -15
  1862. package/template/.hermes/skills/yss-ddd-scaffold-generator/assets/templates/pom/adapter-pom.xml.template +0 -19
  1863. package/template/.hermes/skills/yss-ddd-scaffold-generator/assets/templates/pom/application-pom.xml.template +0 -52
  1864. package/template/.hermes/skills/yss-ddd-scaffold-generator/assets/templates/pom/bootstrap-pom.xml.template +0 -70
  1865. package/template/.hermes/skills/yss-ddd-scaffold-generator/assets/templates/pom/domain-pom.xml.template +0 -22
  1866. package/template/.hermes/skills/yss-ddd-scaffold-generator/assets/templates/pom/infrastructure-pom.xml.template +0 -54
  1867. package/template/.hermes/skills/yss-ddd-scaffold-generator/assets/templates/pom/parent-pom.xml.template +0 -155
  1868. package/template/.hermes/skills/yss-ddd-scaffold-generator/assets/templates/pom/web-pom.xml.template +0 -58
  1869. package/template/.hermes/skills/yss-ddd-scaffold-generator/assets/wrapper/.mvn/jvm.config +0 -1
  1870. package/template/.hermes/skills/yss-ddd-scaffold-generator/assets/wrapper/.mvn/maven.config +0 -2
  1871. package/template/.hermes/skills/yss-ddd-scaffold-generator/assets/wrapper/.mvn/settings.xml +0 -41
  1872. package/template/.hermes/skills/yss-ddd-scaffold-generator/assets/wrapper/.mvn/wrapper/MavenWrapperDownloader.java +0 -117
  1873. package/template/.hermes/skills/yss-ddd-scaffold-generator/assets/wrapper/.mvn/wrapper/maven-wrapper.jar +0 -0
  1874. package/template/.hermes/skills/yss-ddd-scaffold-generator/assets/wrapper/.mvn/wrapper/maven-wrapper.properties +0 -20
  1875. package/template/.hermes/skills/yss-ddd-scaffold-generator/assets/wrapper/mvnw +0 -316
  1876. package/template/.hermes/skills/yss-ddd-scaffold-generator/assets/wrapper/mvnw.cmd +0 -188
  1877. package/template/.hermes/skills/yss-ddd-scaffold-generator/references/ARCHITECTURE.md +0 -116
  1878. package/template/.hermes/skills/yss-ddd-scaffold-generator/references/USAGE_EXAMPLES.md +0 -125
  1879. package/template/.hermes/skills/yss-ddd-scaffold-generator/references/yss-backend-scaffold-adapter/SKILL.md +0 -31
  1880. package/template/.hermes/skills/yss-ddd-scaffold-generator/references/yss-backend-scaffold-adapter/agents/openai.yaml +0 -5
  1881. package/template/.hermes/skills/yss-ddd-scaffold-generator/references/yss-backend-scaffold-application/SKILL.md +0 -8
  1882. package/template/.hermes/skills/yss-ddd-scaffold-generator/references/yss-backend-scaffold-application/agents/openai.yaml +0 -5
  1883. package/template/.hermes/skills/yss-ddd-scaffold-generator/references/yss-backend-scaffold-domain/SKILL.md +0 -8
  1884. package/template/.hermes/skills/yss-ddd-scaffold-generator/references/yss-backend-scaffold-domain/agents/openai.yaml +0 -5
  1885. package/template/.hermes/skills/yss-ddd-scaffold-generator/references/yss-backend-scaffold-infrastructure/SKILL.md +0 -8
  1886. package/template/.hermes/skills/yss-ddd-scaffold-generator/references/yss-backend-scaffold-infrastructure/agents/openai.yaml +0 -5
  1887. package/template/.hermes/skills/yss-ddd-scaffold-generator/references/yss-backend-scaffold-parent/SKILL.md +0 -58
  1888. package/template/.hermes/skills/yss-ddd-scaffold-generator/references/yss-backend-scaffold-parent/agents/openai.yaml +0 -5
  1889. package/template/.hermes/skills/yss-ddd-scaffold-generator/references/yss-backend-scaffold-web/SKILL.md +0 -8
  1890. package/template/.hermes/skills/yss-ddd-scaffold-generator/references/yss-backend-scaffold-web/agents/openai.yaml +0 -5
  1891. package/template/.hermes/skills/yss-ddd-scaffold-generator/scripts/first-slice-compatibility.test.mjs +0 -225
  1892. package/template/.hermes/skills/yss-ddd-scaffold-generator/scripts/first-slice-verification.test.mjs +0 -164
  1893. package/template/.hermes/skills/yss-ddd-scaffold-generator/scripts/generate_and_verify_scaffold.mjs +0 -126
  1894. package/template/.hermes/skills/yss-ddd-scaffold-generator/scripts/generate_scaffold.mjs +0 -363
  1895. package/template/.hermes/skills/yss-ddd-scaffold-generator/scripts/run_first_slice_verification.mjs +0 -172
  1896. package/template/.hermes/skills/yss-ddd-scaffold-generator/scripts/run_scaffold_verification.mjs +0 -112
  1897. package/template/.hermes/skills/yss-ddd-scaffold-generator/scripts/scaffold-generator.test.mjs +0 -401
  1898. package/template/.hermes/skills/yss-design-system/SKILL.md +0 -105
  1899. package/template/.hermes/skills/yss-design-system/agents/openai.yaml +0 -5
  1900. package/template/.hermes/skills/yss-design-system/references/design-qa-theme.md +0 -64
  1901. package/template/.hermes/skills/yss-design-system/references/design-system.md +0 -245
  1902. package/template/.hermes/skills/yss-design-system/scripts/validate-frontmatter.mjs +0 -36
  1903. package/template/.hermes/skills/yss-design-system/scripts/validate-frontmatter.test.mjs +0 -12
  1904. package/template/.hermes/skills/yss-distributed-id/SKILL.md +0 -69
  1905. package/template/.hermes/skills/yss-distributed-id/agents/openai.yaml +0 -5
  1906. package/template/.hermes/skills/yss-distributed-id/assets/AutoIdInterceptor.java +0 -246
  1907. package/template/.hermes/skills/yss-distributed-id/assets/EnableDistributedId.java +0 -25
  1908. package/template/.hermes/skills/yss-distributed-id/assets/LeafConf.java +0 -36
  1909. package/template/.hermes/skills/yss-distributed-id/references/README.md +0 -51
  1910. package/template/.hermes/skills/yss-distributed-id/references/source-index.md +0 -86
  1911. package/template/.hermes/skills/yss-domain/SKILL.md +0 -70
  1912. package/template/.hermes/skills/yss-domain/agents/openai.yaml +0 -5
  1913. package/template/.hermes/skills/yss-domain/references/domain-layer-guide.md +0 -101
  1914. package/template/.hermes/skills/yss-dto/SKILL.md +0 -92
  1915. package/template/.hermes/skills/yss-dto/agents/openai.yaml +0 -5
  1916. package/template/.hermes/skills/yss-dto/assets/CommandDTO.java +0 -8
  1917. package/template/.hermes/skills/yss-dto/assets/PageQuery.java +0 -133
  1918. package/template/.hermes/skills/yss-dto/assets/QueryDTO.java +0 -6
  1919. package/template/.hermes/skills/yss-dto/assets/Result.java +0 -105
  1920. package/template/.hermes/skills/yss-dto/references/README.md +0 -67
  1921. package/template/.hermes/skills/yss-dto/references/openapi-wire-profile.yaml +0 -187
  1922. package/template/.hermes/skills/yss-dto/references/source-index.md +0 -55
  1923. package/template/.hermes/skills/yss-excel-mvc/SKILL.md +0 -66
  1924. package/template/.hermes/skills/yss-excel-mvc/agents/openai.yaml +0 -5
  1925. package/template/.hermes/skills/yss-excel-mvc/assets/ExcelDynamicData.java +0 -66
  1926. package/template/.hermes/skills/yss-excel-mvc/assets/RequestExcel.java +0 -33
  1927. package/template/.hermes/skills/yss-excel-mvc/assets/RequestFastExcelArgumentResolver.java +0 -272
  1928. package/template/.hermes/skills/yss-excel-mvc/assets/ResponseExcel.java +0 -46
  1929. package/template/.hermes/skills/yss-excel-mvc/assets/ResponseFastExcelReturnValueHandler.java +0 -154
  1930. package/template/.hermes/skills/yss-excel-mvc/references/README.md +0 -5
  1931. package/template/.hermes/skills/yss-excel-mvc/references/source-index.md +0 -74
  1932. package/template/.hermes/skills/yss-exception/SKILL.md +0 -57
  1933. package/template/.hermes/skills/yss-exception/agents/openai.yaml +0 -4
  1934. package/template/.hermes/skills/yss-exception/references/source-index.md +0 -35
  1935. package/template/.hermes/skills/yss-formily/SKILL.md +0 -272
  1936. package/template/.hermes/skills/yss-formily-schema-generator/SKILL.md +0 -189
  1937. package/template/.hermes/skills/yss-formily-schema-generator/agents/openai.yaml +0 -5
  1938. package/template/.hermes/skills/yss-formily-schema-generator/assets/java-sdk/ExampleUsage.java +0 -111
  1939. package/template/.hermes/skills/yss-formily-schema-generator/assets/java-sdk/YssFormilyDsl.java +0 -1219
  1940. package/template/.hermes/skills/yss-formily-schema-generator/references/workflow.md +0 -240
  1941. package/template/.hermes/skills/yss-frontend-scaffold-generator/SKILL.md +0 -76
  1942. package/template/.hermes/skills/yss-hook/SKILL.md +0 -200
  1943. package/template/.hermes/skills/yss-hook/agents/openai.yaml +0 -5
  1944. package/template/.hermes/skills/yss-hook/references/frontend-docs.md +0 -10
  1945. package/template/.hermes/skills/yss-microapp-commit/SKILL.md +0 -201
  1946. package/template/.hermes/skills/yss-microapp-commit/agents/openai.yaml +0 -5
  1947. package/template/.hermes/skills/yss-microapp-commit/references/scope-mapping.md +0 -204
  1948. package/template/.hermes/skills/yss-mybatis/SKILL.md +0 -77
  1949. package/template/.hermes/skills/yss-mybatis/agents/openai.yaml +0 -5
  1950. package/template/.hermes/skills/yss-mybatis/assets/BaseRepository.java +0 -112
  1951. package/template/.hermes/skills/yss-mybatis/assets/EntityQueryAspect.java +0 -37
  1952. package/template/.hermes/skills/yss-mybatis/assets/MybatisBaseConfiguration.java +0 -18
  1953. package/template/.hermes/skills/yss-mybatis/assets/PageQueryEntityConfigration.java +0 -18
  1954. package/template/.hermes/skills/yss-mybatis/references/README.md +0 -57
  1955. package/template/.hermes/skills/yss-mybatis/references/source-index.md +0 -93
  1956. package/template/.hermes/skills/yss-openapi-draft-review/SKILL.md +0 -82
  1957. package/template/.hermes/skills/yss-openapi-governance/SKILL.md +0 -130
  1958. package/template/.hermes/skills/yss-openapi-governance/agents/openai.yaml +0 -4
  1959. package/template/.hermes/skills/yss-page-module-development/SKILL.md +0 -165
  1960. package/template/.hermes/skills/yss-page-module-development/agents/openai.yaml +0 -5
  1961. package/template/.hermes/skills/yss-page-module-development/examples/AdvancedFormPage/constant.ts +0 -32
  1962. package/template/.hermes/skills/yss-page-module-development/examples/AdvancedFormPage/hooks/useRuleConfig.ts +0 -158
  1963. package/template/.hermes/skills/yss-page-module-development/examples/AdvancedFormPage/index.vue +0 -188
  1964. package/template/.hermes/skills/yss-page-module-development/examples/AdvancedFormPage/schemas/ruleConfigSchema.ts +0 -256
  1965. package/template/.hermes/skills/yss-page-module-development/examples/AdvancedFormPage/style.less +0 -76
  1966. package/template/.hermes/skills/yss-page-module-development/examples/StandardListPage/constant.ts +0 -128
  1967. package/template/.hermes/skills/yss-page-module-development/examples/StandardListPage/hooks/useQualityRuleList.ts +0 -144
  1968. package/template/.hermes/skills/yss-page-module-development/examples/StandardListPage/hooks/useRuleActions.ts +0 -141
  1969. package/template/.hermes/skills/yss-page-module-development/examples/StandardListPage/index.vue +0 -175
  1970. package/template/.hermes/skills/yss-page-module-development/examples/StandardListPage/style.less +0 -83
  1971. package/template/.hermes/skills/yss-page-module-development/references/component-map.md +0 -34
  1972. package/template/.hermes/skills/yss-page-module-development/references/frontend-docs.md +0 -11
  1973. package/template/.hermes/skills/yss-page-module-development/references/hooks-map.md +0 -11
  1974. package/template/.hermes/skills/yss-page-module-development/references/utils-map.md +0 -14
  1975. package/template/.hermes/skills/yss-product-lifecycle/SKILL.md +0 -52
  1976. package/template/.hermes/skills/yss-product-lifecycle/agents/openai.yaml +0 -4
  1977. package/template/.hermes/skills/yss-product-lifecycle/references/artifact-dependencies.md +0 -36
  1978. package/template/.hermes/skills/yss-product-lifecycle/references/matt-yss-adapter.md +0 -122
  1979. package/template/.hermes/skills/yss-product-lifecycle/references/orchestration-contract.yaml +0 -865
  1980. package/template/.hermes/skills/yss-product-lifecycle/references/orchestration.md +0 -116
  1981. package/template/.hermes/skills/yss-product-lifecycle/references/state-model.md +0 -112
  1982. package/template/.hermes/skills/yss-prototype-stage/SKILL.md +0 -47
  1983. package/template/.hermes/skills/yss-prototype-stage/references/product-design-adapter.md +0 -54
  1984. package/template/.hermes/skills/yss-prototype-stage/scripts/prototype-contract.mjs +0 -207
  1985. package/template/.hermes/skills/yss-prototype-stage/tests/run-scenarios.mjs +0 -154
  1986. package/template/.hermes/skills/yss-repository/SKILL.md +0 -80
  1987. package/template/.hermes/skills/yss-repository/agents/openai.yaml +0 -5
  1988. package/template/.hermes/skills/yss-repository/references/infrastructure-layer-guide.md +0 -107
  1989. package/template/.hermes/skills/yss-research/SKILL.md +0 -73
  1990. package/template/.hermes/skills/yss-research/agents/openai.yaml +0 -3
  1991. package/template/.hermes/skills/yss-research/assets/evidence-template.yaml +0 -68
  1992. package/template/.hermes/skills/yss-research/assets/research-brief-template.md +0 -36
  1993. package/template/.hermes/skills/yss-research/references/evidence-contract.md +0 -42
  1994. package/template/.hermes/skills/yss-research/scripts/validate-research-package.mjs +0 -128
  1995. package/template/.hermes/skills/yss-research/tests/run-scenarios.mjs +0 -81
  1996. package/template/.hermes/skills/yss-resilience4j/SKILL.md +0 -46
  1997. package/template/.hermes/skills/yss-resilience4j/agents/openai.yaml +0 -4
  1998. package/template/.hermes/skills/yss-resilience4j/references/source-index.md +0 -33
  1999. package/template/.hermes/skills/yss-router/SKILL.md +0 -51
  2000. package/template/.hermes/skills/yss-router/agents/openai.yaml +0 -4
  2001. package/template/.hermes/skills/yss-router/references/boundaries.md +0 -50
  2002. package/template/.hermes/skills/yss-router/references/router-contract.yaml +0 -349
  2003. package/template/.hermes/skills/yss-router/references/slice-implementation-contract.md +0 -185
  2004. package/template/.hermes/skills/yss-router/references/yss-skill-execution-result.md +0 -67
  2005. package/template/.hermes/skills/yss-security-algorithm/SKILL.md +0 -52
  2006. package/template/.hermes/skills/yss-security-algorithm/agents/openai.yaml +0 -4
  2007. package/template/.hermes/skills/yss-security-algorithm/references/source-index.md +0 -35
  2008. package/template/.hermes/skills/yss-source-index/SKILL.md +0 -63
  2009. package/template/.hermes/skills/yss-source-index/agents/openai.yaml +0 -4
  2010. package/template/.hermes/skills/yss-source-index/references/source-map-config.md +0 -30
  2011. package/template/.hermes/skills/yss-source-index/scripts/refresh-yss-skill-index.mjs +0 -24
  2012. package/template/.hermes/skills/yss-stage-decision/SKILL.md +0 -51
  2013. package/template/.hermes/skills/yss-stage-decision/references/domain-strategy-contract.md +0 -26
  2014. package/template/.hermes/skills/yss-stage-decision/references/domain-strategy.schema.json +0 -128
  2015. package/template/.hermes/skills/yss-stage-decision/references/stage-decision-package-contract.md +0 -19
  2016. package/template/.hermes/skills/yss-stage-decision/references/stage-decision-package.schema.json +0 -86
  2017. package/template/.hermes/skills/yss-stage-decision/references/validation-rules.md +0 -18
  2018. package/template/.hermes/skills/yss-stage-decision/scripts/validate-domain-strategy.mjs +0 -169
  2019. package/template/.hermes/skills/yss-stage-decision/scripts/validate-stage-decision-package.mjs +0 -100
  2020. package/template/.hermes/skills/yss-stage-decision/tests/fixtures/domain-strategy-approval.yaml +0 -15
  2021. package/template/.hermes/skills/yss-stage-decision/tests/fixtures/invalid-direction.yaml +0 -58
  2022. package/template/.hermes/skills/yss-stage-decision/tests/fixtures/invalid-stage-decision-blocker.yaml +0 -44
  2023. package/template/.hermes/skills/yss-stage-decision/tests/fixtures/stage-decision-approval.yaml +0 -15
  2024. package/template/.hermes/skills/yss-stage-decision/tests/fixtures/valid-stage-decision-package.yaml +0 -49
  2025. package/template/.hermes/skills/yss-stage-decision/tests/fixtures/valid-supplier-domain.yaml +0 -108
  2026. package/template/.hermes/skills/yss-stage-decision/tests/run-scenarios.mjs +0 -68
  2027. package/template/.hermes/skills/yss-tactical-design/SKILL.md +0 -35
  2028. package/template/.hermes/skills/yss-tactical-design/agents/openai.yaml +0 -4
  2029. package/template/.hermes/skills/yss-tactical-design/references/output-template.md +0 -28
  2030. package/template/.hermes/skills/yss-tactical-design/references/tactical-design-contract.md +0 -41
  2031. package/template/.hermes/skills/yss-tactical-design/references/tactical-design.schema.json +0 -31
  2032. package/template/.hermes/skills/yss-tactical-design/references/validation-rules.md +0 -13
  2033. package/template/.hermes/skills/yss-tactical-design/scripts/validate-tactical-design.mjs +0 -213
  2034. package/template/.hermes/skills/yss-tactical-design/tests/fixtures/invalid-api-leaks-aggregate.yaml +0 -21
  2035. package/template/.hermes/skills/yss-tactical-design/tests/fixtures/invalid-missing-consistency-policy.yaml +0 -21
  2036. package/template/.hermes/skills/yss-tactical-design/tests/fixtures/invalid-missing-invariant.yaml +0 -21
  2037. package/template/.hermes/skills/yss-tactical-design/tests/fixtures/invalid-stale-upstream-ref.yaml +0 -21
  2038. package/template/.hermes/skills/yss-tactical-design/tests/fixtures/invalid-strategic-as-tactical.yaml +0 -21
  2039. package/template/.hermes/skills/yss-tactical-design/tests/fixtures/valid-tactical-design.yaml +0 -80
  2040. package/template/.hermes/skills/yss-tactical-design/tests/run-scenarios.mjs +0 -47
  2041. package/template/.hermes/skills/yss-ui/SKILL.md +0 -170
  2042. package/template/.hermes/skills/yss-ui/agents/openai.yaml +0 -5
  2043. package/template/.hermes/skills/yss-ui/assets/demos/button/auth-basic.vue +0 -24
  2044. package/template/.hermes/skills/yss-ui/assets/demos/button/auth-dropdown.vue +0 -29
  2045. package/template/.hermes/skills/yss-ui/assets/demos/button/permission.vue +0 -10
  2046. package/template/.hermes/skills/yss-ui/assets/demos/button/size.vue +0 -12
  2047. package/template/.hermes/skills/yss-ui/assets/demos/button/states.vue +0 -12
  2048. package/template/.hermes/skills/yss-ui/assets/demos/card/basic/index.vue +0 -54
  2049. package/template/.hermes/skills/yss-ui/assets/demos/card/basic/style.less +0 -41
  2050. package/template/.hermes/skills/yss-ui/assets/demos/card/cover/index.vue +0 -25
  2051. package/template/.hermes/skills/yss-ui/assets/demos/card/flexible-layout/index.vue +0 -122
  2052. package/template/.hermes/skills/yss-ui/assets/demos/card/flexible-layout/style.less +0 -191
  2053. package/template/.hermes/skills/yss-ui/assets/demos/card/header-extra/index.vue +0 -260
  2054. package/template/.hermes/skills/yss-ui/assets/demos/card/header-extra/style.less +0 -124
  2055. package/template/.hermes/skills/yss-ui/assets/demos/card/layout-metrics/constants.ts +0 -61
  2056. package/template/.hermes/skills/yss-ui/assets/demos/card/layout-metrics/index.vue +0 -72
  2057. package/template/.hermes/skills/yss-ui/assets/demos/card/layout-metrics/metrics-cards.vue +0 -70
  2058. package/template/.hermes/skills/yss-ui/assets/demos/card/layout-metrics/style.less +0 -232
  2059. package/template/.hermes/skills/yss-ui/assets/demos/card/loading/index.vue +0 -19
  2060. package/template/.hermes/skills/yss-ui/assets/demos/card/meta/index.vue +0 -19
  2061. package/template/.hermes/skills/yss-ui/assets/demos/condition-builder/basic/constants.ts +0 -44
  2062. package/template/.hermes/skills/yss-ui/assets/demos/condition-builder/basic/hooks/useConditionBasic.ts +0 -18
  2063. package/template/.hermes/skills/yss-ui/assets/demos/condition-builder/basic/index.vue +0 -100
  2064. package/template/.hermes/skills/yss-ui/assets/demos/condition-builder/linked/constants.ts +0 -51
  2065. package/template/.hermes/skills/yss-ui/assets/demos/condition-builder/linked/hooks/useConditionLinked.ts +0 -29
  2066. package/template/.hermes/skills/yss-ui/assets/demos/condition-builder/linked/index.vue +0 -23
  2067. package/template/.hermes/skills/yss-ui/assets/demos/condition-builder/nesting-between/constants.ts +0 -35
  2068. package/template/.hermes/skills/yss-ui/assets/demos/condition-builder/nesting-between/hooks/useConditionNesting.ts +0 -25
  2069. package/template/.hermes/skills/yss-ui/assets/demos/condition-builder/nesting-between/index.vue +0 -24
  2070. package/template/.hermes/skills/yss-ui/assets/demos/condition-builder/remote/constants.ts +0 -7
  2071. package/template/.hermes/skills/yss-ui/assets/demos/condition-builder/remote/hooks/useConditionRemote.ts +0 -75
  2072. package/template/.hermes/skills/yss-ui/assets/demos/condition-builder/remote/index.vue +0 -23
  2073. package/template/.hermes/skills/yss-ui/assets/demos/condition-builder/validation/constants.ts +0 -42
  2074. package/template/.hermes/skills/yss-ui/assets/demos/condition-builder/validation/hooks/useConditionBasic.ts +0 -22
  2075. package/template/.hermes/skills/yss-ui/assets/demos/condition-builder/validation/index.vue +0 -138
  2076. package/template/.hermes/skills/yss-ui/assets/demos/condition-builder/validation-custom/constants.ts +0 -42
  2077. package/template/.hermes/skills/yss-ui/assets/demos/condition-builder/validation-custom/hooks/useConditionBasic.ts +0 -22
  2078. package/template/.hermes/skills/yss-ui/assets/demos/condition-builder/validation-custom/index.vue +0 -134
  2079. package/template/.hermes/skills/yss-ui/assets/demos/cron/basic/index.vue +0 -54
  2080. package/template/.hermes/skills/yss-ui/assets/demos/cron/select/index.vue +0 -145
  2081. package/template/.hermes/skills/yss-ui/assets/demos/echarts/basic.vue +0 -30
  2082. package/template/.hermes/skills/yss-ui/assets/demos/echarts/calendar-heatmap.vue +0 -49
  2083. package/template/.hermes/skills/yss-ui/assets/demos/echarts/candlestick.vue +0 -30
  2084. package/template/.hermes/skills/yss-ui/assets/demos/echarts/dark.vue +0 -40
  2085. package/template/.hermes/skills/yss-ui/assets/demos/echarts/expose-methods.vue +0 -97
  2086. package/template/.hermes/skills/yss-ui/assets/demos/echarts/funnel.vue +0 -42
  2087. package/template/.hermes/skills/yss-ui/assets/demos/echarts/gauge.vue +0 -25
  2088. package/template/.hermes/skills/yss-ui/assets/demos/echarts/line.vue +0 -24
  2089. package/template/.hermes/skills/yss-ui/assets/demos/echarts/mix.vue +0 -33
  2090. package/template/.hermes/skills/yss-ui/assets/demos/echarts/pie.vue +0 -34
  2091. package/template/.hermes/skills/yss-ui/assets/demos/echarts/radar.vue +0 -38
  2092. package/template/.hermes/skills/yss-ui/assets/demos/echarts/ring-segment.vue +0 -77
  2093. package/template/.hermes/skills/yss-ui/assets/demos/echarts/scatter.vue +0 -23
  2094. package/template/.hermes/skills/yss-ui/assets/demos/echarts/stacked-area.vue +0 -55
  2095. package/template/.hermes/skills/yss-ui/assets/demos/echarts/stacked-bar.vue +0 -52
  2096. package/template/.hermes/skills/yss-ui/assets/demos/echarts/treemap.vue +0 -30
  2097. package/template/.hermes/skills/yss-ui/assets/demos/edit-table/all-types/hooks/useAllTypes.ts +0 -259
  2098. package/template/.hermes/skills/yss-ui/assets/demos/edit-table/all-types/index.vue +0 -33
  2099. package/template/.hermes/skills/yss-ui/assets/demos/edit-table/async-remote/hooks/useAsyncRemote.ts +0 -201
  2100. package/template/.hermes/skills/yss-ui/assets/demos/edit-table/async-remote/index.vue +0 -45
  2101. package/template/.hermes/skills/yss-ui/assets/demos/edit-table/basic/index.vue +0 -104
  2102. package/template/.hermes/skills/yss-ui/assets/demos/edit-table/big-data/index.vue +0 -82
  2103. package/template/.hermes/skills/yss-ui/assets/demos/edit-table/custom-rule/index.vue +0 -114
  2104. package/template/.hermes/skills/yss-ui/assets/demos/edit-table/direct-editable/index.vue +0 -94
  2105. package/template/.hermes/skills/yss-ui/assets/demos/edit-table/drag/index.vue +0 -125
  2106. package/template/.hermes/skills/yss-ui/assets/demos/edit-table/filter/index.vue +0 -107
  2107. package/template/.hermes/skills/yss-ui/assets/demos/edit-table/linkage/index.vue +0 -181
  2108. package/template/.hermes/skills/yss-ui/assets/demos/edit-table/pagination-action/index.vue +0 -131
  2109. package/template/.hermes/skills/yss-ui/assets/demos/edit-table/required/index.vue +0 -95
  2110. package/template/.hermes/skills/yss-ui/assets/demos/edit-table/row-edit/index.vue +0 -220
  2111. package/template/.hermes/skills/yss-ui/assets/demos/edit-table/row-options/index.vue +0 -165
  2112. package/template/.hermes/skills/yss-ui/assets/demos/edit-table/slot-linkage/index.vue +0 -184
  2113. package/template/.hermes/skills/yss-ui/assets/demos/edit-table/submit-view/index.vue +0 -107
  2114. package/template/.hermes/skills/yss-ui/assets/demos/file-import/basic.vue +0 -54
  2115. package/template/.hermes/skills/yss-ui/assets/demos/file-import/formily.vue +0 -42
  2116. package/template/.hermes/skills/yss-ui/assets/demos/file-import/multiple.vue +0 -33
  2117. package/template/.hermes/skills/yss-ui/assets/demos/file-import/result-slot.vue +0 -30
  2118. package/template/.hermes/skills/yss-ui/assets/demos/formily/actions.vue +0 -61
  2119. package/template/.hermes/skills/yss-ui/assets/demos/formily/align.vue +0 -56
  2120. package/template/.hermes/skills/yss-ui/assets/demos/formily/async-validate.vue +0 -69
  2121. package/template/.hermes/skills/yss-ui/assets/demos/formily/basic.vue +0 -317
  2122. package/template/.hermes/skills/yss-ui/assets/demos/formily/collapse.vue +0 -104
  2123. package/template/.hermes/skills/yss-ui/assets/demos/formily/custom-component.vue +0 -75
  2124. package/template/.hermes/skills/yss-ui/assets/demos/formily/disabled.vue +0 -71
  2125. package/template/.hermes/skills/yss-ui/assets/demos/formily/dynamic-array.vue +0 -74
  2126. package/template/.hermes/skills/yss-ui/assets/demos/formily/dynamic.vue +0 -59
  2127. package/template/.hermes/skills/yss-ui/assets/demos/formily/effects.vue +0 -117
  2128. package/template/.hermes/skills/yss-ui/assets/demos/formily/events-inline.vue +0 -82
  2129. package/template/.hermes/skills/yss-ui/assets/demos/formily/events-scope.vue +0 -101
  2130. package/template/.hermes/skills/yss-ui/assets/demos/formily/grid.vue +0 -71
  2131. package/template/.hermes/skills/yss-ui/assets/demos/formily/group.vue +0 -102
  2132. package/template/.hermes/skills/yss-ui/assets/demos/formily/helper-slot.vue +0 -50
  2133. package/template/.hermes/skills/yss-ui/assets/demos/formily/label-tip.vue +0 -42
  2134. package/template/.hermes/skills/yss-ui/assets/demos/formily/linkage-multi.vue +0 -127
  2135. package/template/.hermes/skills/yss-ui/assets/demos/formily/linkage.vue +0 -78
  2136. package/template/.hermes/skills/yss-ui/assets/demos/formily/modes.vue +0 -72
  2137. package/template/.hermes/skills/yss-ui/assets/demos/formily/remote-enum.vue +0 -88
  2138. package/template/.hermes/skills/yss-ui/assets/demos/formily/slot.vue +0 -54
  2139. package/template/.hermes/skills/yss-ui/assets/demos/formily/steps.vue +0 -135
  2140. package/template/.hermes/skills/yss-ui/assets/demos/formily/submit-failed.vue +0 -72
  2141. package/template/.hermes/skills/yss-ui/assets/demos/monaco/basic.vue +0 -40
  2142. package/template/.hermes/skills/yss-ui/assets/demos/monaco/diff-basic.vue +0 -143
  2143. package/template/.hermes/skills/yss-ui/assets/demos/monaco/fullscreen.vue +0 -84
  2144. package/template/.hermes/skills/yss-ui/assets/demos/monaco/history-log-viewer.vue +0 -586
  2145. package/template/.hermes/skills/yss-ui/assets/demos/monaco/log-viewer.vue +0 -260
  2146. package/template/.hermes/skills/yss-ui/assets/demos/monaco/mock/mockLogApi.ts +0 -199
  2147. package/template/.hermes/skills/yss-ui/assets/demos/monaco/monaco.vue +0 -66
  2148. package/template/.hermes/skills/yss-ui/assets/demos/monaco/readonly.vue +0 -20
  2149. package/template/.hermes/skills/yss-ui/assets/demos/monaco/resizable.vue +0 -22
  2150. package/template/.hermes/skills/yss-ui/assets/demos/monaco/sql-schema.vue +0 -20
  2151. package/template/.hermes/skills/yss-ui/assets/demos/monaco/switch-lang-theme.vue +0 -48
  2152. package/template/.hermes/skills/yss-ui/assets/demos/split-pane/tree-table/constant.ts +0 -18
  2153. package/template/.hermes/skills/yss-ui/assets/demos/split-pane/tree-table/index.vue +0 -60
  2154. package/template/.hermes/skills/yss-ui/assets/demos/split-pane/tree-table/style.less +0 -39
  2155. package/template/.hermes/skills/yss-ui/assets/demos/split-pane/tree-table-layout/hooks/useTreeTable.ts +0 -158
  2156. package/template/.hermes/skills/yss-ui/assets/demos/split-pane/tree-table-layout/index.vue +0 -88
  2157. package/template/.hermes/skills/yss-ui/assets/demos/split-pane/tree-table-layout/style.less +0 -73
  2158. package/template/.hermes/skills/yss-ui/assets/demos/table/action/index.vue +0 -83
  2159. package/template/.hermes/skills/yss-ui/assets/demos/table/action/style.less +0 -3
  2160. package/template/.hermes/skills/yss-ui/assets/demos/table/action-auth/index.vue +0 -41
  2161. package/template/.hermes/skills/yss-ui/assets/demos/table/action-slot/index.vue +0 -62
  2162. package/template/.hermes/skills/yss-ui/assets/demos/table/action-slot/style.less +0 -36
  2163. package/template/.hermes/skills/yss-ui/assets/demos/table/basic/hooks/useBasicTable.ts +0 -205
  2164. package/template/.hermes/skills/yss-ui/assets/demos/table/basic/index.vue +0 -89
  2165. package/template/.hermes/skills/yss-ui/assets/demos/table/basic/style.less +0 -28
  2166. package/template/.hermes/skills/yss-ui/assets/demos/table/column-custom-search/hooks/useColumnCustomSearch.ts +0 -236
  2167. package/template/.hermes/skills/yss-ui/assets/demos/table/column-custom-search/index.vue +0 -141
  2168. package/template/.hermes/skills/yss-ui/assets/demos/table/column-custom-search/style.less +0 -48
  2169. package/template/.hermes/skills/yss-ui/assets/demos/table/drag/index.vue +0 -42
  2170. package/template/.hermes/skills/yss-ui/assets/demos/table/expand/action-expand.vue +0 -142
  2171. package/template/.hermes/skills/yss-ui/assets/demos/table/expand/index.vue +0 -35
  2172. package/template/.hermes/skills/yss-ui/assets/demos/table/filter-async/index.vue +0 -93
  2173. package/template/.hermes/skills/yss-ui/assets/demos/table/filter-auto/index.vue +0 -99
  2174. package/template/.hermes/skills/yss-ui/assets/demos/table/filter-custom/index.vue +0 -72
  2175. package/template/.hermes/skills/yss-ui/assets/demos/table/filter-local/index.vue +0 -112
  2176. package/template/.hermes/skills/yss-ui/assets/demos/table/filter-mixed/index.vue +0 -142
  2177. package/template/.hermes/skills/yss-ui/assets/demos/table/filter-remote/constant.ts +0 -129
  2178. package/template/.hermes/skills/yss-ui/assets/demos/table/filter-remote/hooks/useTableData.ts +0 -186
  2179. package/template/.hermes/skills/yss-ui/assets/demos/table/filter-remote/index.vue +0 -73
  2180. package/template/.hermes/skills/yss-ui/assets/demos/table/group-header/index.vue +0 -86
  2181. package/template/.hermes/skills/yss-ui/assets/demos/table/group-header/style.less +0 -3
  2182. package/template/.hermes/skills/yss-ui/assets/demos/table/header-height/index.vue +0 -29
  2183. package/template/.hermes/skills/yss-ui/assets/demos/table/header-height/style.less +0 -9
  2184. package/template/.hermes/skills/yss-ui/assets/demos/table/merge-cells/hooks/useMergeCells.ts +0 -183
  2185. package/template/.hermes/skills/yss-ui/assets/demos/table/merge-cells/index.vue +0 -17
  2186. package/template/.hermes/skills/yss-ui/assets/demos/table/merge-cells/style.less +0 -3
  2187. package/template/.hermes/skills/yss-ui/assets/demos/table/pagination-remote/hooks/usePaginationRemote.ts +0 -106
  2188. package/template/.hermes/skills/yss-ui/assets/demos/table/pagination-remote/index.vue +0 -24
  2189. package/template/.hermes/skills/yss-ui/assets/demos/table/renderers/index.vue +0 -64
  2190. package/template/.hermes/skills/yss-ui/assets/demos/table/selection-checkbox/index.vue +0 -88
  2191. package/template/.hermes/skills/yss-ui/assets/demos/table/selection-checkbox/style.less +0 -9
  2192. package/template/.hermes/skills/yss-ui/assets/demos/table/selection-radio/index.vue +0 -57
  2193. package/template/.hermes/skills/yss-ui/assets/demos/table/selection-radio/style.less +0 -9
  2194. package/template/.hermes/skills/yss-ui/assets/demos/table/transform/index.vue +0 -32
  2195. package/template/.hermes/skills/yss-ui/assets/demos/tree/basic-left/index.vue +0 -124
  2196. package/template/.hermes/skills/yss-ui/assets/demos/tree/datasource-group/index.vue +0 -31
  2197. package/template/.hermes/skills/yss-ui/assets/demos/tree/multi-checkable/index.vue +0 -86
  2198. package/template/.hermes/skills/yss-ui/assets/demos/tree/multiple-select/index.vue +0 -76
  2199. package/template/.hermes/skills/yss-ui/assets/demos/tree/resource-list/index.vue +0 -41
  2200. package/template/.hermes/skills/yss-ui/assets/demos/tree/search-toolbar/index.vue +0 -156
  2201. package/template/.hermes/skills/yss-ui/assets/demos/tree/slot-icon/index.vue +0 -36
  2202. package/template/.hermes/skills/yss-ui/assets/demos/tree/slot-switcher-icon/index.vue +0 -34
  2203. package/template/.hermes/skills/yss-ui/assets/docs/components/button.md +0 -79
  2204. package/template/.hermes/skills/yss-ui/assets/docs/components/card.md +0 -162
  2205. package/template/.hermes/skills/yss-ui/assets/docs/components/conditionBuilder.md +0 -114
  2206. package/template/.hermes/skills/yss-ui/assets/docs/components/cron.md +0 -77
  2207. package/template/.hermes/skills/yss-ui/assets/docs/components/echarts.md +0 -110
  2208. package/template/.hermes/skills/yss-ui/assets/docs/components/editTable.md +0 -212
  2209. package/template/.hermes/skills/yss-ui/assets/docs/components/fileImport.md +0 -85
  2210. package/template/.hermes/skills/yss-ui/assets/docs/components/formily.md +0 -370
  2211. package/template/.hermes/skills/yss-ui/assets/docs/components/monaco.md +0 -369
  2212. package/template/.hermes/skills/yss-ui/assets/docs/components/sheet.md +0 -169
  2213. package/template/.hermes/skills/yss-ui/assets/docs/components/split-pane.md +0 -45
  2214. package/template/.hermes/skills/yss-ui/assets/docs/components/table.md +0 -398
  2215. package/template/.hermes/skills/yss-ui/assets/docs/components/tree.md +0 -102
  2216. package/template/.hermes/skills/yss-ui/assets/docs/guide/gitlab-ci-integration.md +0 -166
  2217. package/template/.hermes/skills/yss-ui/assets/docs/guide/index.md +0 -132
  2218. package/template/.hermes/skills/yss-ui/assets/docs/guide/installation.md +0 -97
  2219. package/template/.hermes/skills/yss-ui/assets/docs/guide/jsp.md +0 -227
  2220. package/template/.hermes/skills/yss-ui/assets/docs/guide/llms.md +0 -295
  2221. package/template/.hermes/skills/yss-ui/assets/docs/guide/monorepo-versioning.md +0 -149
  2222. package/template/.hermes/skills/yss-ui/assets/docs/guide/release-workflow.md +0 -251
  2223. package/template/.hermes/skills/yss-ui/assets/docs/hooks/use-table-height.md +0 -101
  2224. package/template/.hermes/skills/yss-ui/assets/docs/hooks/use-tree-height.md +0 -115
  2225. package/template/.hermes/skills/yss-ui/assets/docs/hooks/useFullscreen.md +0 -130
  2226. package/template/.hermes/skills/yss-ui/assets/docs/hooks/useLoading.md +0 -97
  2227. package/template/.hermes/skills/yss-ui/assets/docs/root/resources.md +0 -18
  2228. package/template/.hermes/skills/yss-ui/assets/keyword-index.json +0 -53
  2229. package/template/.hermes/skills/yss-ui/assets/keyword-index.md +0 -47
  2230. package/template/.hermes/skills/yss-ui/assets/reference-index.json +0 -55
  2231. package/template/.hermes/skills/yss-ui/assets/reference-index.md +0 -74
  2232. package/template/.hermes/skills/yss-ui/assets/scenario-index.json +0 -50
  2233. package/template/.hermes/skills/yss-ui/assets/scenario-index.md +0 -41
  2234. package/template/.hermes/skills/yss-ui/references/accessibility.md +0 -23
  2235. package/template/.hermes/skills/yss-ui/references/antdv-compatibility.md +0 -39
  2236. package/template/.hermes/skills/yss-ui/references/checklist.md +0 -110
  2237. package/template/.hermes/skills/yss-ui/references/component-routing.md +0 -31
  2238. package/template/.hermes/skills/yss-ui/references/frontend-docs.md +0 -11
  2239. package/template/.hermes/skills/yss-ui/references/migration-antdv-to-yss.md +0 -20
  2240. package/template/.hermes/skills/yss-ui/references/quick-recipes.md +0 -280
  2241. package/template/.hermes/skills/yss-ui/references/theme-locale-overlay.md +0 -25
  2242. package/template/.hermes/skills/yss-ui/references/verification.md +0 -20
  2243. package/template/.hermes/skills/yss-ui-business-page-generation/SKILL.md +0 -159
  2244. package/template/.hermes/skills/yss-ui-business-page-generation/references/component-map.md +0 -39
  2245. package/template/.hermes/skills/yss-ui-business-page-generation/references/hooks-map.md +0 -70
  2246. package/template/.hermes/skills/yss-ui-business-page-generation/references/utils-map.md +0 -51
  2247. package/template/.hermes/skills/yss-up-springboot3/SKILL.md +0 -40
  2248. package/template/.hermes/skills/yss-up-springboot3/agents/openai.yaml +0 -4
  2249. package/template/.hermes/skills/yss-use-table-height/SKILL.md +0 -130
  2250. package/template/.hermes/skills/yss-use-table-height/agents/openai.yaml +0 -5
  2251. package/template/.hermes/skills/yss-use-table-height/references/frontend-docs.md +0 -9
  2252. package/template/.hermes/skills/yss-use-tree-height/SKILL.md +0 -98
  2253. package/template/.hermes/skills/yss-use-tree-height/agents/openai.yaml +0 -5
  2254. package/template/.hermes/skills/yss-use-tree-height/references/frontend-docs.md +0 -9
  2255. package/template/.hermes/skills/yss-userinfo/SKILL.md +0 -49
  2256. package/template/.hermes/skills/yss-userinfo/agents/openai.yaml +0 -4
  2257. package/template/.hermes/skills/yss-userinfo/references/source-index.md +0 -34
  2258. package/template/.hermes/skills/yss-validation/SKILL.md +0 -56
  2259. package/template/.hermes/skills/yss-validation/agents/openai.yaml +0 -4
  2260. package/template/.hermes/skills/yss-validation/references/source-index.md +0 -33
  2261. package/template/.hermes/skills/yss-web-controller/SKILL.md +0 -85
  2262. package/template/.hermes/skills/yss-web-controller/agents/openai.yaml +0 -5
  2263. package/template/.hermes/skills/yss-web-controller/assets/templates/Controller.java.template +0 -72
  2264. package/template/.hermes/skills/yss-web-controller/assets/templates/WebConvertor.java.template +0 -30
  2265. package/template/.hermes/skills/yss-web-controller/assets/templates/web/dto/CreateRequest.java.template +0 -19
  2266. package/template/.hermes/skills/yss-web-controller/assets/templates/web/dto/PageRequest.java.template +0 -21
  2267. package/template/.hermes/skills/yss-web-controller/assets/templates/web/dto/Response.java.template +0 -18
  2268. package/template/.hermes/skills/yss-web-controller/assets/templates/web/dto/UpdateRequest.java.template +0 -19
  2269. package/template/.hermes/skills/yss-web-controller/references/web-adapter-layer-guide.md +0 -86
  2270. package/template/.hermes/skills/yss-web-controller/references/web-generation-contract.schema.json +0 -97
  2271. package/template/.hermes/skills/yss-web-controller/scripts/generate_controller.mjs +0 -226
  2272. package/template/.hermes/skills/yss-web-controller/scripts/generate_controller.test.mjs +0 -156
  2273. package/template/.hermes/skills/ytable-usage/SKILL.md +0 -251
  2274. package/template/.hermes/skills/ytree-usage/SKILL.md +0 -132
  2275. package/template/.kiro/settings/mcp.json +0 -8
  2276. package/template/.pi/skills/ask-matt/PHASE-BOUNDARIES.md +0 -55
  2277. package/template/.pi/skills/ask-matt/SKILL.md +0 -95
  2278. package/template/.pi/skills/ask-matt/agents/openai.yaml +0 -5
  2279. package/template/.pi/skills/dispatching-parallel-agents/SKILL.md +0 -185
  2280. package/template/.pi/skills/loop-me/SKILL.md +0 -32
  2281. package/template/.pi/skills/loop-me/agents/openai.yaml +0 -5
  2282. package/template/.pi/skills/migrate-to-shoehorn/SKILL.md +0 -118
  2283. package/template/.pi/skills/migrate-to-shoehorn/agents/openai.yaml +0 -3
  2284. package/template/.pi/skills/prototype-page-acceptance/SKILL.md +0 -62
  2285. package/template/.pi/skills/scaffold-exercises/SKILL.md +0 -106
  2286. package/template/.pi/skills/scaffold-exercises/agents/openai.yaml +0 -3
  2287. package/template/.pi/skills/setup-pre-commit/SKILL.md +0 -91
  2288. package/template/.pi/skills/setup-pre-commit/agents/openai.yaml +0 -3
  2289. package/template/.pi/skills/setup-ts-deep-modules/SKILL.md +0 -102
  2290. package/template/.pi/skills/setup-ts-deep-modules/agents/openai.yaml +0 -5
  2291. package/template/.pi/skills/setup-ts-deep-modules/dependency-cruiser.config.cjs +0 -95
  2292. package/template/.pi/skills/teach/GLOSSARY-FORMAT.md +0 -35
  2293. package/template/.pi/skills/teach/LEARNING-RECORD-FORMAT.md +0 -46
  2294. package/template/.pi/skills/teach/MISSION-FORMAT.md +0 -31
  2295. package/template/.pi/skills/teach/RESOURCES-FORMAT.md +0 -32
  2296. package/template/.pi/skills/teach/SKILL.md +0 -140
  2297. package/template/.pi/skills/teach/agents/openai.yaml +0 -5
  2298. package/template/.pi/skills/writing-beats/SKILL.md +0 -67
  2299. package/template/.pi/skills/writing-beats/agents/openai.yaml +0 -5
  2300. package/template/.pi/skills/writing-fragments/SKILL.md +0 -79
  2301. package/template/.pi/skills/writing-fragments/agents/openai.yaml +0 -5
  2302. package/template/.pi/skills/writing-shape/SKILL.md +0 -79
  2303. package/template/.pi/skills/writing-shape/agents/openai.yaml +0 -5
  2304. package/template/.pi/skills/yss-microapp-commit/SKILL.md +0 -201
  2305. package/template/.pi/skills/yss-microapp-commit/agents/openai.yaml +0 -5
  2306. package/template/.pi/skills/yss-microapp-commit/references/scope-mapping.md +0 -204
  2307. package/template/.pi/skills/yss-page-module-development/SKILL.md +0 -165
  2308. package/template/.pi/skills/yss-page-module-development/agents/openai.yaml +0 -5
  2309. package/template/.pi/skills/yss-page-module-development/examples/AdvancedFormPage/constant.ts +0 -32
  2310. package/template/.pi/skills/yss-page-module-development/examples/AdvancedFormPage/hooks/useRuleConfig.ts +0 -158
  2311. package/template/.pi/skills/yss-page-module-development/examples/AdvancedFormPage/index.vue +0 -188
  2312. package/template/.pi/skills/yss-page-module-development/examples/AdvancedFormPage/schemas/ruleConfigSchema.ts +0 -256
  2313. package/template/.pi/skills/yss-page-module-development/examples/AdvancedFormPage/style.less +0 -76
  2314. package/template/.pi/skills/yss-page-module-development/examples/StandardListPage/constant.ts +0 -128
  2315. package/template/.pi/skills/yss-page-module-development/examples/StandardListPage/hooks/useQualityRuleList.ts +0 -144
  2316. package/template/.pi/skills/yss-page-module-development/examples/StandardListPage/hooks/useRuleActions.ts +0 -141
  2317. package/template/.pi/skills/yss-page-module-development/examples/StandardListPage/index.vue +0 -175
  2318. package/template/.pi/skills/yss-page-module-development/examples/StandardListPage/style.less +0 -83
  2319. package/template/.pi/skills/yss-page-module-development/references/component-map.md +0 -34
  2320. package/template/.pi/skills/yss-page-module-development/references/frontend-docs.md +0 -11
  2321. package/template/.pi/skills/yss-page-module-development/references/hooks-map.md +0 -11
  2322. package/template/.pi/skills/yss-page-module-development/references/utils-map.md +0 -14
  2323. package/template/.pi/skills/yss-router/SKILL.md +0 -51
  2324. package/template/.pi/skills/yss-router/agents/openai.yaml +0 -4
  2325. package/template/.pi/skills/yss-router/references/boundaries.md +0 -50
  2326. package/template/.pi/skills/yss-router/references/router-contract.yaml +0 -349
  2327. package/template/.pi/skills/yss-router/references/slice-implementation-contract.md +0 -185
  2328. package/template/.pi/skills/yss-router/references/yss-skill-execution-result.md +0 -67
  2329. package/template/.pi/skills/yss-source-index/SKILL.md +0 -63
  2330. package/template/.pi/skills/yss-source-index/agents/openai.yaml +0 -4
  2331. package/template/.pi/skills/yss-source-index/references/source-map-config.md +0 -30
  2332. package/template/.pi/skills/yss-source-index/scripts/refresh-yss-skill-index.mjs +0 -24
  2333. package/template/.qoder/skills/ask-matt/PHASE-BOUNDARIES.md +0 -55
  2334. package/template/.qoder/skills/ask-matt/SKILL.md +0 -95
  2335. package/template/.qoder/skills/ask-matt/agents/openai.yaml +0 -5
  2336. package/template/.qoder/skills/dispatching-parallel-agents/SKILL.md +0 -185
  2337. package/template/.qoder/skills/loop-me/SKILL.md +0 -32
  2338. package/template/.qoder/skills/loop-me/agents/openai.yaml +0 -5
  2339. package/template/.qoder/skills/migrate-to-shoehorn/SKILL.md +0 -118
  2340. package/template/.qoder/skills/migrate-to-shoehorn/agents/openai.yaml +0 -3
  2341. package/template/.qoder/skills/prototype-page-acceptance/SKILL.md +0 -62
  2342. package/template/.qoder/skills/scaffold-exercises/SKILL.md +0 -106
  2343. package/template/.qoder/skills/scaffold-exercises/agents/openai.yaml +0 -3
  2344. package/template/.qoder/skills/setup-pre-commit/SKILL.md +0 -91
  2345. package/template/.qoder/skills/setup-pre-commit/agents/openai.yaml +0 -3
  2346. package/template/.qoder/skills/setup-ts-deep-modules/SKILL.md +0 -102
  2347. package/template/.qoder/skills/setup-ts-deep-modules/agents/openai.yaml +0 -5
  2348. package/template/.qoder/skills/setup-ts-deep-modules/dependency-cruiser.config.cjs +0 -95
  2349. package/template/.qoder/skills/teach/GLOSSARY-FORMAT.md +0 -35
  2350. package/template/.qoder/skills/teach/LEARNING-RECORD-FORMAT.md +0 -46
  2351. package/template/.qoder/skills/teach/MISSION-FORMAT.md +0 -31
  2352. package/template/.qoder/skills/teach/RESOURCES-FORMAT.md +0 -32
  2353. package/template/.qoder/skills/teach/SKILL.md +0 -140
  2354. package/template/.qoder/skills/teach/agents/openai.yaml +0 -5
  2355. package/template/.qoder/skills/writing-beats/SKILL.md +0 -67
  2356. package/template/.qoder/skills/writing-beats/agents/openai.yaml +0 -5
  2357. package/template/.qoder/skills/writing-fragments/SKILL.md +0 -79
  2358. package/template/.qoder/skills/writing-fragments/agents/openai.yaml +0 -5
  2359. package/template/.qoder/skills/writing-shape/SKILL.md +0 -79
  2360. package/template/.qoder/skills/writing-shape/agents/openai.yaml +0 -5
  2361. package/template/.qoder/skills/yss-microapp-commit/SKILL.md +0 -201
  2362. package/template/.qoder/skills/yss-microapp-commit/agents/openai.yaml +0 -5
  2363. package/template/.qoder/skills/yss-microapp-commit/references/scope-mapping.md +0 -204
  2364. package/template/.qoder/skills/yss-page-module-development/SKILL.md +0 -165
  2365. package/template/.qoder/skills/yss-page-module-development/agents/openai.yaml +0 -5
  2366. package/template/.qoder/skills/yss-page-module-development/examples/AdvancedFormPage/constant.ts +0 -32
  2367. package/template/.qoder/skills/yss-page-module-development/examples/AdvancedFormPage/hooks/useRuleConfig.ts +0 -158
  2368. package/template/.qoder/skills/yss-page-module-development/examples/AdvancedFormPage/index.vue +0 -188
  2369. package/template/.qoder/skills/yss-page-module-development/examples/AdvancedFormPage/schemas/ruleConfigSchema.ts +0 -256
  2370. package/template/.qoder/skills/yss-page-module-development/examples/AdvancedFormPage/style.less +0 -76
  2371. package/template/.qoder/skills/yss-page-module-development/examples/StandardListPage/constant.ts +0 -128
  2372. package/template/.qoder/skills/yss-page-module-development/examples/StandardListPage/hooks/useQualityRuleList.ts +0 -144
  2373. package/template/.qoder/skills/yss-page-module-development/examples/StandardListPage/hooks/useRuleActions.ts +0 -141
  2374. package/template/.qoder/skills/yss-page-module-development/examples/StandardListPage/index.vue +0 -175
  2375. package/template/.qoder/skills/yss-page-module-development/examples/StandardListPage/style.less +0 -83
  2376. package/template/.qoder/skills/yss-page-module-development/references/component-map.md +0 -34
  2377. package/template/.qoder/skills/yss-page-module-development/references/frontend-docs.md +0 -11
  2378. package/template/.qoder/skills/yss-page-module-development/references/hooks-map.md +0 -11
  2379. package/template/.qoder/skills/yss-page-module-development/references/utils-map.md +0 -14
  2380. package/template/.qoder/skills/yss-router/SKILL.md +0 -51
  2381. package/template/.qoder/skills/yss-router/agents/openai.yaml +0 -4
  2382. package/template/.qoder/skills/yss-router/references/boundaries.md +0 -50
  2383. package/template/.qoder/skills/yss-router/references/router-contract.yaml +0 -349
  2384. package/template/.qoder/skills/yss-router/references/slice-implementation-contract.md +0 -185
  2385. package/template/.qoder/skills/yss-router/references/yss-skill-execution-result.md +0 -67
  2386. package/template/.qoder/skills/yss-source-index/SKILL.md +0 -63
  2387. package/template/.qoder/skills/yss-source-index/agents/openai.yaml +0 -4
  2388. package/template/.qoder/skills/yss-source-index/references/source-map-config.md +0 -30
  2389. package/template/.qoder/skills/yss-source-index/scripts/refresh-yss-skill-index.mjs +0 -24
  2390. package/template/.trae/skills/ask-matt/PHASE-BOUNDARIES.md +0 -55
  2391. package/template/.trae/skills/ask-matt/SKILL.md +0 -95
  2392. package/template/.trae/skills/ask-matt/agents/openai.yaml +0 -5
  2393. package/template/.trae/skills/dispatching-parallel-agents/SKILL.md +0 -185
  2394. package/template/.trae/skills/loop-me/SKILL.md +0 -32
  2395. package/template/.trae/skills/loop-me/agents/openai.yaml +0 -5
  2396. package/template/.trae/skills/migrate-to-shoehorn/SKILL.md +0 -118
  2397. package/template/.trae/skills/migrate-to-shoehorn/agents/openai.yaml +0 -3
  2398. package/template/.trae/skills/prototype-page-acceptance/SKILL.md +0 -62
  2399. package/template/.trae/skills/scaffold-exercises/SKILL.md +0 -106
  2400. package/template/.trae/skills/scaffold-exercises/agents/openai.yaml +0 -3
  2401. package/template/.trae/skills/setup-pre-commit/SKILL.md +0 -91
  2402. package/template/.trae/skills/setup-pre-commit/agents/openai.yaml +0 -3
  2403. package/template/.trae/skills/setup-ts-deep-modules/SKILL.md +0 -102
  2404. package/template/.trae/skills/setup-ts-deep-modules/agents/openai.yaml +0 -5
  2405. package/template/.trae/skills/setup-ts-deep-modules/dependency-cruiser.config.cjs +0 -95
  2406. package/template/.trae/skills/teach/GLOSSARY-FORMAT.md +0 -35
  2407. package/template/.trae/skills/teach/LEARNING-RECORD-FORMAT.md +0 -46
  2408. package/template/.trae/skills/teach/MISSION-FORMAT.md +0 -31
  2409. package/template/.trae/skills/teach/RESOURCES-FORMAT.md +0 -32
  2410. package/template/.trae/skills/teach/SKILL.md +0 -140
  2411. package/template/.trae/skills/teach/agents/openai.yaml +0 -5
  2412. package/template/.trae/skills/writing-beats/SKILL.md +0 -67
  2413. package/template/.trae/skills/writing-beats/agents/openai.yaml +0 -5
  2414. package/template/.trae/skills/writing-fragments/SKILL.md +0 -79
  2415. package/template/.trae/skills/writing-fragments/agents/openai.yaml +0 -5
  2416. package/template/.trae/skills/writing-shape/SKILL.md +0 -79
  2417. package/template/.trae/skills/writing-shape/agents/openai.yaml +0 -5
  2418. package/template/.trae/skills/yss-microapp-commit/SKILL.md +0 -201
  2419. package/template/.trae/skills/yss-microapp-commit/agents/openai.yaml +0 -5
  2420. package/template/.trae/skills/yss-microapp-commit/references/scope-mapping.md +0 -204
  2421. package/template/.trae/skills/yss-page-module-development/SKILL.md +0 -165
  2422. package/template/.trae/skills/yss-page-module-development/agents/openai.yaml +0 -5
  2423. package/template/.trae/skills/yss-page-module-development/examples/AdvancedFormPage/constant.ts +0 -32
  2424. package/template/.trae/skills/yss-page-module-development/examples/AdvancedFormPage/hooks/useRuleConfig.ts +0 -158
  2425. package/template/.trae/skills/yss-page-module-development/examples/AdvancedFormPage/index.vue +0 -188
  2426. package/template/.trae/skills/yss-page-module-development/examples/AdvancedFormPage/schemas/ruleConfigSchema.ts +0 -256
  2427. package/template/.trae/skills/yss-page-module-development/examples/AdvancedFormPage/style.less +0 -76
  2428. package/template/.trae/skills/yss-page-module-development/examples/StandardListPage/constant.ts +0 -128
  2429. package/template/.trae/skills/yss-page-module-development/examples/StandardListPage/hooks/useQualityRuleList.ts +0 -144
  2430. package/template/.trae/skills/yss-page-module-development/examples/StandardListPage/hooks/useRuleActions.ts +0 -141
  2431. package/template/.trae/skills/yss-page-module-development/examples/StandardListPage/index.vue +0 -175
  2432. package/template/.trae/skills/yss-page-module-development/examples/StandardListPage/style.less +0 -83
  2433. package/template/.trae/skills/yss-page-module-development/references/component-map.md +0 -34
  2434. package/template/.trae/skills/yss-page-module-development/references/frontend-docs.md +0 -11
  2435. package/template/.trae/skills/yss-page-module-development/references/hooks-map.md +0 -11
  2436. package/template/.trae/skills/yss-page-module-development/references/utils-map.md +0 -14
  2437. package/template/.trae/skills/yss-router/SKILL.md +0 -51
  2438. package/template/.trae/skills/yss-router/agents/openai.yaml +0 -4
  2439. package/template/.trae/skills/yss-router/references/boundaries.md +0 -50
  2440. package/template/.trae/skills/yss-router/references/router-contract.yaml +0 -349
  2441. package/template/.trae/skills/yss-router/references/slice-implementation-contract.md +0 -185
  2442. package/template/.trae/skills/yss-router/references/yss-skill-execution-result.md +0 -67
  2443. package/template/.trae/skills/yss-source-index/SKILL.md +0 -63
  2444. package/template/.trae/skills/yss-source-index/agents/openai.yaml +0 -4
  2445. package/template/.trae/skills/yss-source-index/references/source-location.md +0 -18
  2446. package/template/.trae/skills/yss-source-index/references/source-map-config.md +0 -30
  2447. package/template/.trae/skills/yss-source-index/scripts/refresh-yss-skill-index.mjs +0 -24
  2448. package/template/.trae/skills/yss-source-index/scripts/refresh-yss-skill-index.test.mjs +0 -15
  2449. package/template/scripts/verify-yss-router-scenarios +0 -3
  2450. /package/template/.agents/skills/{yss-source-index → yss-skill-source-index-refresh}/references/source-location.md +0 -0
  2451. /package/template/.agents/skills/{yss-source-index → yss-skill-source-index-refresh}/scripts/refresh-yss-skill-index.test.mjs +0 -0
  2452. /package/template/.claude/skills/{yss-source-index → yss-skill-source-index-refresh}/references/source-location.md +0 -0
  2453. /package/template/.claude/skills/{yss-source-index → yss-skill-source-index-refresh}/scripts/refresh-yss-skill-index.test.mjs +0 -0
  2454. /package/template/.codex/skills/{yss-source-index → yss-skill-source-index-refresh}/references/source-location.md +0 -0
  2455. /package/template/.codex/skills/{yss-source-index → yss-skill-source-index-refresh}/scripts/refresh-yss-skill-index.test.mjs +0 -0
  2456. /package/template/.cursor/skills/{yss-source-index → yss-skill-source-index-refresh}/references/source-location.md +0 -0
  2457. /package/template/.cursor/skills/{yss-source-index → yss-skill-source-index-refresh}/scripts/refresh-yss-skill-index.test.mjs +0 -0
  2458. /package/template/{.hermes/skills/yss-source-index → .pi/skills/yss-skill-source-index-refresh}/references/source-location.md +0 -0
  2459. /package/template/{.hermes/skills/yss-source-index → .pi/skills/yss-skill-source-index-refresh}/scripts/refresh-yss-skill-index.test.mjs +0 -0
  2460. /package/template/{.pi/skills/yss-source-index → .qoder/skills/yss-skill-source-index-refresh}/references/source-location.md +0 -0
  2461. /package/template/{.pi/skills/yss-source-index → .qoder/skills/yss-skill-source-index-refresh}/scripts/refresh-yss-skill-index.test.mjs +0 -0
  2462. /package/template/{.qoder/skills/yss-source-index → .trae/skills/yss-skill-source-index-refresh}/references/source-location.md +0 -0
  2463. /package/template/{.qoder/skills/yss-source-index → .trae/skills/yss-skill-source-index-refresh}/scripts/refresh-yss-skill-index.test.mjs +0 -0
@@ -1,4400 +0,0 @@
1
- import { esc, renderDefinitions, renderSemanticSigil, textUnits } from '../shared/utils.mjs';
2
- import { animateAttr, focusEdgeAttrs, focusNodeAttrs, focusNodeTitle, svgAccessibleText, svgRootAttrs } from '../shared/cli.mjs';
3
- import {
4
- throwDiagnosticError,
5
- throwDiagnosticProblems,
6
- withDiagnosticRecordingSuppressed,
7
- } from '../shared/diagnostics.mjs';
8
- import { validateSchema } from '../shared/validator.mjs';
9
- import {
10
- legendFootprint,
11
- measureLegend,
12
- relationshipLegendObstacles,
13
- resolveLegend,
14
- renderLegend as renderResolvedLegend,
15
- } from '../shared/legend.mjs';
16
- import { availableNodeTextWidth, fittedNodeFontSize, minimumNodeTextWidth } from '../shared/text-fit.mjs';
17
- import { brandLabelFitWidth, brandMetadataFor, brandTopRailProblem, renderBrandMark } from '../shared/brand-marks.mjs';
18
- import { translateMessage as i18nText } from '../shared/i18n.mjs';
19
- import {
20
- createMappedWorkflowCandidate,
21
- intrinsicWorkflow,
22
- planningWorkflow,
23
- } from './workflow-migration-geometry.mjs';
24
- import {
25
- asArray,
26
- isFinitePoint,
27
- rectsOverlap,
28
- segmentIntersectsRect,
29
- segmentRectClearance,
30
- cleanEndpointSideProblems,
31
- cleanFlowProblems,
32
- cleanCrossingProblems,
33
- cleanAmbiguousCorridorProblems,
34
- cleanBorderRunProblems,
35
- cleanRouteRhythmProblems,
36
- cleanLabelRouteClearanceProblems,
37
- collectAmbiguousCorridors,
38
- collectLabelRouteClearance,
39
- collectBorderRuns,
40
- forwardCollinearAnalysisSegments,
41
- sourceSegmentIndexAtPoint,
42
- suggestLabelObstacleFix,
43
- suggestLabelPairFix,
44
- anchor,
45
- automaticPortSpread,
46
- defaultFromSide,
47
- defaultToSide,
48
- chosenSide,
49
- normalizeRoutePoints,
50
- routeHonorsEndpointSides,
51
- polylinePath,
52
- routePointsValue,
53
- labelPoint,
54
- componentFill,
55
- componentText,
56
- arrowClassMap,
57
- variantAccent
58
- } from '../shared/geometry.mjs';
59
-
60
- const LEGACY_COLUMN_CENTERS = Object.freeze([88, 220, 300, 430, 500, 625]);
61
- const READABLE_CANDIDATE_COST_PRIORITY = Object.freeze([
62
- 'automaticForwardReversePx',
63
- 'properCrossingCount',
64
- 'sharedCorridorPx',
65
- 'labelRouteClearanceDeficit',
66
- 'interiorPreferred28Deficit',
67
- 'bendCount',
68
- 'stretchMilli',
69
- 'canvasGrowthPx',
70
- 'portDisplacementMilli',
71
- 'legacyCoordinateDisplacement',
72
- 'stableCandidateOrdinal',
73
- ]);
74
- const MAX_READABLE_LAYOUT_FEEDBACK_ROUNDS = 3;
75
- const GROUP_FRAME_TOP_INSET = 8;
76
- const GROUP_FRAME_BOTTOM_INSET = 4;
77
- const GROUP_LABEL_BASELINE_OFFSET = -2;
78
- const GROUP_LABEL_MASK_ASCENT = 10;
79
- const GROUP_LABEL_MASK_H = 14;
80
- const GROUP_NODE_INSET = 4;
81
-
82
- class WorkflowLayoutFeedback extends Error {
83
- constructor(request) {
84
- super(`Workflow layout requires ${request.kind} feedback.`);
85
- this.name = 'WorkflowLayoutFeedback';
86
- this.request = request;
87
- }
88
- }
89
-
90
- function createLegacyLayout() {
91
- return {
92
- contract: 'fixed-v1',
93
- laneX: 40,
94
- laneY: 52,
95
- laneW: 640,
96
- laneH: 104,
97
- laneGap: 20,
98
- laneTitleH: 30,
99
- colXs: [...LEGACY_COLUMN_CENTERS],
100
- nodeW: 92,
101
- nodeH: 52,
102
- defaultViewBoxWidth: 720,
103
- };
104
- }
105
-
106
- function authoredNodeWidth(node) {
107
- return Number.isFinite(node?.width) ? node.width : 92;
108
- }
109
-
110
- function nodeWidthContributor(node) {
111
- return `node ${node.id} width ${authoredNodeWidth(node)}px`;
112
- }
113
-
114
- function authoredNodeHeight(node) {
115
- if (Number.isFinite(node?.height)) return node.height;
116
- return node?.tag ? 68 : 52;
117
- }
118
-
119
- function workflowLabelWidth(label) {
120
- return Math.max(30, textUnits(label) * 4.8 + 10);
121
- }
122
-
123
- function readableGroupBounds(workflow, group, colXs) {
124
- if (!Number.isInteger(group.fromCol) || !Number.isInteger(group.toCol)
125
- || group.fromCol < 0 || group.fromCol > group.toCol || group.toCol >= colXs.length) {
126
- return { x: 0, width: 0, cx: 0 };
127
- }
128
- const start = colXs[group.fromCol] - 50;
129
- const end = colXs[group.toCol] + 50;
130
- const naturalWidth = end - start;
131
- const minimumWidth = textUnits(group.label) * 5.6 + 20;
132
- let width = Math.max(naturalWidth, minimumWidth);
133
- let left = group.fromCol === group.toCol && width > naturalWidth
134
- ? start
135
- : (start + end - width) / 2;
136
- let right = left + width;
137
- for (const node of asArray(workflow.nodes)) {
138
- if (node.lane !== group.lane
139
- || !Number.isInteger(node.col)
140
- || node.col < group.fromCol
141
- || node.col > group.toCol
142
- || node.col < 0
143
- || node.col >= colXs.length) continue;
144
- const halfWidth = authoredNodeWidth(node) / 2;
145
- left = Math.min(left, colXs[node.col] - halfWidth - GROUP_NODE_INSET);
146
- right = Math.max(right, colXs[node.col] + halfWidth + GROUP_NODE_INSET);
147
- }
148
- width = right - left;
149
- return { x: left, width, cx: left + width / 2 };
150
- }
151
-
152
- function verticalIntervalsOverlap(a, b, clearance = 0) {
153
- const aCenter = Number(a?.yOffset) || 0;
154
- const bCenter = Number(b?.yOffset) || 0;
155
- return Math.abs(aCenter - bCenter)
156
- < authoredNodeHeight(a) / 2 + authoredNodeHeight(b) / 2 + clearance;
157
- }
158
-
159
- function createReadableLayout(workflow, layoutFeedback = {}) {
160
- const columnCount = 6;
161
- const baselinePitch = 120;
162
- const columnStart = 94;
163
- const maxLayoutIterations = 3;
164
- const channelDetourBudgetPx = 4 * 28;
165
- const constraints = [];
166
- const feedbackConstraints = [];
167
- const channelLabelEdgeKeys = new Set();
168
- const widthContributors = new Set();
169
- const heightContributors = new Set();
170
- const nodes = asArray(workflow.nodes);
171
- const nodesById = new Map(nodes.map((node) => [node.id, node]));
172
-
173
- for (let col = 0; col < columnCount - 1; col += 1) {
174
- constraints.push({ from: col, to: col + 1, minimum: baselinePitch });
175
- }
176
- for (const [key, minimum] of Object.entries(layoutFeedback.rankGapMinimums || {}).sort()) {
177
- const [from, to] = key.split(':').map(Number);
178
- constraints.push({
179
- from,
180
- to,
181
- minimum,
182
- contributors: layoutFeedback.rankGapContributors?.[key]
183
- || [`rank ${from}→${to} route clearance`],
184
- });
185
- }
186
-
187
- for (let leftIndex = 0; leftIndex < nodes.length; leftIndex += 1) {
188
- for (let rightIndex = leftIndex + 1; rightIndex < nodes.length; rightIndex += 1) {
189
- const leftNode = nodes[leftIndex];
190
- const rightNode = nodes[rightIndex];
191
- if (leftNode.lane !== rightNode.lane || leftNode.col === rightNode.col) continue;
192
- if (!verticalIntervalsOverlap(leftNode, rightNode, 8)) continue;
193
- const fromNode = leftNode.col < rightNode.col ? leftNode : rightNode;
194
- const toNode = fromNode === leftNode ? rightNode : leftNode;
195
- constraints.push({
196
- from: fromNode.col,
197
- to: toNode.col,
198
- minimum: authoredNodeWidth(fromNode) / 2 + 8 + authoredNodeWidth(toNode) / 2,
199
- contributors: [
200
- `rank ${fromNode.col}→${toNode.col} node width clearance`,
201
- nodeWidthContributor(fromNode),
202
- nodeWidthContributor(toNode),
203
- ],
204
- });
205
- }
206
- }
207
-
208
- for (const edge of asArray(workflow.edges)) {
209
- const fromNode = nodesById.get(edge.from);
210
- const toNode = nodesById.get(edge.to);
211
- if (!fromNode || !toNode || fromNode.lane !== toNode.lane || fromNode.col === toNode.col) continue;
212
- if (edge.via || edge.channelX !== undefined || edge.channelY !== undefined
213
- || !['auto', 'straight'].includes(edge.route || 'auto')) continue;
214
- if ((Number(fromNode.yOffset) || 0) !== (Number(toNode.yOffset) || 0)) continue;
215
- const earlier = fromNode.col < toNode.col ? fromNode : toNode;
216
- const later = earlier === fromNode ? toNode : fromNode;
217
- const labeledDirectClearance = edge.label && !edge.labelAt
218
- ? Math.max(28, workflowLabelWidth(edge.label) + 8)
219
- : 28;
220
- const directLabelExpansionCost = Math.max(0, labeledDirectClearance - 28);
221
- const canUseAutomaticLabelChannel = edge.label
222
- && !edge.labelAt
223
- && (edge.route || 'auto') === 'auto'
224
- && !edge.fromSide
225
- && !edge.toSide
226
- && edge.channelX === undefined
227
- && edge.channelY === undefined;
228
- const preferLabelChannel = canUseAutomaticLabelChannel
229
- && directLabelExpansionCost > channelDetourBudgetPx;
230
- if (preferLabelChannel) channelLabelEdgeKeys.add(stableValueKey(edge));
231
- constraints.push({
232
- from: earlier.col,
233
- to: later.col,
234
- minimum: authoredNodeWidth(earlier) / 2 + 28 + authoredNodeWidth(later) / 2,
235
- contributors: [
236
- `rank ${earlier.col}→${later.col} direct clearance`,
237
- `rank ${earlier.col}→${later.col} node width clearance`,
238
- nodeWidthContributor(earlier),
239
- nodeWidthContributor(later),
240
- ],
241
- });
242
- if (!preferLabelChannel && labeledDirectClearance > 28) {
243
- const labelConstraintMinimum = authoredNodeWidth(earlier) / 2
244
- + labeledDirectClearance
245
- + authoredNodeWidth(later) / 2;
246
- feedbackConstraints.push({
247
- from: earlier.col,
248
- to: later.col,
249
- minimum: labelConstraintMinimum,
250
- contributors: [
251
- `rank ${earlier.col}→${later.col} direct clearance`,
252
- `edge ${workflowEdgeName(edge)} label mask`,
253
- nodeWidthContributor(earlier),
254
- nodeWidthContributor(later),
255
- ],
256
- });
257
- }
258
- }
259
-
260
- for (const phase of asArray(workflow.phases)) {
261
- if (!Number.isInteger(phase.fromCol) || !Number.isInteger(phase.toCol)
262
- || phase.fromCol < 0 || phase.fromCol > phase.toCol || phase.toCol >= columnCount) continue;
263
- const minimumWidth = textUnits(phase.label) * 5.6 + 8;
264
- if (phase.fromCol === phase.toCol) {
265
- if (phase.toCol < columnCount - 1) {
266
- constraints.push({
267
- from: phase.toCol,
268
- to: phase.toCol + 1,
269
- minimum: baselinePitch + Math.max(0, minimumWidth - 92),
270
- contributors: [`phase ${phase.id || phase.label} label span`],
271
- });
272
- }
273
- continue;
274
- }
275
- constraints.push({
276
- from: phase.fromCol,
277
- to: phase.toCol,
278
- minimum: Math.max(0, minimumWidth - 92),
279
- contributors: [`phase ${phase.id || phase.label} label span`],
280
- });
281
- }
282
-
283
- for (const group of asArray(workflow.groups)) {
284
- if (!Number.isInteger(group.fromCol) || !Number.isInteger(group.toCol)
285
- || group.fromCol < 0 || group.fromCol > group.toCol || group.toCol >= columnCount) continue;
286
- const minimumWidth = textUnits(group.label) * 5.6 + 20;
287
- if (group.fromCol === group.toCol) {
288
- if (group.toCol < columnCount - 1) {
289
- constraints.push({
290
- from: group.toCol,
291
- to: group.toCol + 1,
292
- minimum: baselinePitch + Math.max(0, minimumWidth - 100),
293
- contributors: [`group ${group.id || group.label} label span`],
294
- });
295
- }
296
- continue;
297
- }
298
- constraints.push({
299
- from: group.fromCol,
300
- to: group.toCol,
301
- minimum: Math.max(0, minimumWidth - 100),
302
- contributors: [`group ${group.id || group.label} label span`],
303
- });
304
- }
305
-
306
- let activeConstraints = [...constraints];
307
- let colXs;
308
- let colProvenance;
309
- for (let iteration = 0; iteration < maxLayoutIterations; iteration += 1) {
310
- colXs = Array.from({ length: columnCount }, (_, col) => columnStart + col * baselinePitch);
311
- colProvenance = Array.from({ length: columnCount }, () => new Set());
312
- const orderedConstraints = activeConstraints
313
- .filter(({ from, to, minimum }) => (
314
- Number.isInteger(from) && Number.isInteger(to)
315
- && from >= 0 && from < to && to < columnCount
316
- && Number.isFinite(minimum)
317
- ))
318
- .sort((a, b) => a.to - b.to || a.from - b.from || a.minimum - b.minimum);
319
- for (let to = 1; to < columnCount; to += 1) {
320
- for (const constraint of orderedConstraints) {
321
- if (constraint.to !== to) continue;
322
- const candidate = colXs[constraint.from] + constraint.minimum;
323
- const candidateProvenance = new Set([
324
- ...colProvenance[constraint.from],
325
- ...asArray(constraint.contributors),
326
- ]);
327
- if (candidate > colXs[to] + 0.0001) {
328
- colXs[to] = candidate;
329
- colProvenance[to] = candidateProvenance;
330
- } else if (Math.abs(candidate - colXs[to]) <= 0.0001
331
- && candidate > columnStart + to * baselinePitch + 0.0001) {
332
- for (const contributor of candidateProvenance) colProvenance[to].add(contributor);
333
- }
334
- }
335
- }
336
- if (iteration > 0 || !feedbackConstraints.length) break;
337
- activeConstraints = [...activeConstraints, ...feedbackConstraints];
338
- }
339
-
340
- const firstRankNodes = nodes.filter((node) => node.col === 0);
341
- const firstExtent = firstRankNodes.reduce(
342
- (maximum, node) => Math.max(maximum, authoredNodeWidth(node) / 2),
343
- 46,
344
- );
345
- const leftInset = 8;
346
- const leftShift = Math.max(0, 40 + leftInset + firstExtent - colXs[0]);
347
- if (leftShift) {
348
- for (let col = 0; col < colXs.length; col += 1) colXs[col] += leftShift;
349
- for (const node of firstRankNodes) {
350
- if (Math.abs(authoredNodeWidth(node) / 2 - firstExtent) > 0.0001) continue;
351
- for (const provenance of colProvenance) provenance.add(nodeWidthContributor(node));
352
- }
353
- }
354
-
355
- const unpinnedTopEndpointIds = new Set();
356
- for (const edge of asArray(workflow.edges)) {
357
- const preservesHorizontalPins = Array.isArray(edge.via) || edge.channelX !== undefined;
358
- if (preservesHorizontalPins) continue;
359
- if (edge.fromSide === 'top') unpinnedTopEndpointIds.add(edge.from);
360
- if (edge.toSide === 'top') unpinnedTopEndpointIds.add(edge.to);
361
- }
362
- const laneOrder = new Map(asArray(workflow.lanes).map((lane, index) => [lane.id, index]));
363
- let laneHeaderShift = 0;
364
- const laneHeaderShiftContributors = new Set();
365
- for (const nodeId of unpinnedTopEndpointIds) {
366
- const node = nodesById.get(nodeId);
367
- if (!node || !Number.isInteger(node.col) || node.col < 0 || node.col >= columnCount) continue;
368
- const lanePosition = laneOrder.get(node.lane);
369
- const lane = asArray(workflow.lanes)[lanePosition];
370
- if (!lane) continue;
371
- const prefix = lane.variant === 'exception'
372
- ? 'EX'
373
- : String(lanePosition + 1).padStart(2, '0');
374
- const laneHeaderRight = 40 + 14 + textUnits(`${prefix} / ${lane.label}`) * 6.2;
375
- const requiredShift = laneHeaderRight + 2 - colXs[node.col];
376
- if (requiredShift > laneHeaderShift + 0.0001) {
377
- laneHeaderShift = requiredShift;
378
- laneHeaderShiftContributors.clear();
379
- laneHeaderShiftContributors.add(`lane ${lane.id} label width`);
380
- } else if (requiredShift > 0 && Math.abs(requiredShift - laneHeaderShift) <= 0.0001) {
381
- laneHeaderShiftContributors.add(`lane ${lane.id} label width`);
382
- }
383
- }
384
- if (laneHeaderShift > 0) {
385
- for (let col = 0; col < colXs.length; col += 1) colXs[col] += laneHeaderShift;
386
- for (const provenance of colProvenance) {
387
- for (const contributor of laneHeaderShiftContributors) provenance.add(contributor);
388
- }
389
- }
390
-
391
- let measuredContentLeftShift = asArray(workflow.edges).reduce((maximum, edge) => {
392
- if (!channelLabelEdgeKeys.has(stableValueKey(edge))) return maximum;
393
- const fromNode = nodesById.get(edge.from);
394
- const toNode = nodesById.get(edge.to);
395
- if (!fromNode || !toNode) return maximum;
396
- const labelCenter = (colXs[fromNode.col] + colXs[toNode.col]) / 2;
397
- const labelLeft = labelCenter - workflowLabelWidth(edge.label) / 2;
398
- return Math.max(maximum, 16 - labelLeft);
399
- }, 0);
400
- for (const phase of asArray(workflow.phases)) {
401
- if (!Number.isInteger(phase.fromCol) || !Number.isInteger(phase.toCol)) continue;
402
- const width = Math.max(
403
- colXs[phase.toCol] - colXs[phase.fromCol] + 92,
404
- textUnits(phase.label) * 5.6 + 8,
405
- );
406
- const left = phase.fromCol === phase.toCol
407
- ? colXs[phase.fromCol] - 46
408
- : (colXs[phase.fromCol] + colXs[phase.toCol] - width) / 2;
409
- measuredContentLeftShift = Math.max(measuredContentLeftShift, 16 - left);
410
- }
411
- for (const group of asArray(workflow.groups)) {
412
- if (!Number.isInteger(group.fromCol) || !Number.isInteger(group.toCol)) continue;
413
- const bounds = readableGroupBounds(workflow, group, colXs);
414
- measuredContentLeftShift = Math.max(measuredContentLeftShift, 44 - bounds.x);
415
- }
416
- if (measuredContentLeftShift > 0) {
417
- for (let col = 0; col < colXs.length; col += 1) colXs[col] += measuredContentLeftShift;
418
- }
419
-
420
- let rightmost = colXs.at(-1) + 50;
421
- let rightmostContributors = new Set(colProvenance.at(-1));
422
- for (const node of nodes) {
423
- if (!Number.isInteger(node.col) || node.col < 0 || node.col >= columnCount) continue;
424
- const nodeRight = colXs[node.col] + authoredNodeWidth(node) / 2;
425
- const nodeContributors = new Set([
426
- ...colProvenance[node.col],
427
- nodeWidthContributor(node),
428
- ]);
429
- if (nodeRight > rightmost + 0.0001) {
430
- rightmost = nodeRight;
431
- rightmostContributors = nodeContributors;
432
- } else if (Math.abs(nodeRight - rightmost) <= 0.0001) {
433
- for (const contributor of nodeContributors) rightmostContributors.add(contributor);
434
- }
435
- }
436
- for (const group of asArray(workflow.groups)) {
437
- if (!Number.isInteger(group.fromCol) || !Number.isInteger(group.toCol)) continue;
438
- const bounds = readableGroupBounds(workflow, group, colXs);
439
- const groupRight = bounds.x + bounds.width;
440
- const groupContributors = new Set([
441
- ...colProvenance[group.fromCol],
442
- ...colProvenance[group.toCol],
443
- `group ${group.id || group.label} label span`,
444
- ...nodes
445
- .filter((node) => node.lane === group.lane
446
- && node.col >= group.fromCol && node.col <= group.toCol)
447
- .map(nodeWidthContributor),
448
- ]);
449
- if (groupRight > rightmost + 0.0001) {
450
- rightmost = groupRight;
451
- rightmostContributors = groupContributors;
452
- } else if (Math.abs(groupRight - rightmost) <= 0.0001) {
453
- for (const contributor of groupContributors) rightmostContributors.add(contributor);
454
- }
455
- }
456
- const widestLaneLabel = asArray(workflow.lanes).reduce((widest, lane, index) => {
457
- const width = textUnits(`${String(index + 1).padStart(2, '0')} / ${lane.label}`) * 6.2 + 30;
458
- return width > widest.width ? { width, lane } : widest;
459
- }, { width: 0, lane: null });
460
- const laneLabelWidth = widestLaneLabel.width;
461
- const rightmostLaneWidth = Math.ceil(rightmost - 40 + 8);
462
- const laneW = Math.max(
463
- 640,
464
- rightmostLaneWidth,
465
- Math.ceil(laneLabelWidth),
466
- );
467
- if (laneW > 640) {
468
- if (rightmostLaneWidth === laneW) {
469
- for (const contributor of rightmostContributors) widthContributors.add(contributor);
470
- }
471
- if (Math.ceil(laneLabelWidth) === laneW && widestLaneLabel.lane) {
472
- widthContributors.add(`lane ${widestLaneLabel.lane.id || widestLaneLabel.lane.label} label width`);
473
- }
474
- }
475
- let maxVerticalExtent = 0;
476
- const verticalExtentContributors = new Set();
477
- for (const node of nodes) {
478
- const yOffset = Number(node.yOffset) || 0;
479
- const extent = authoredNodeHeight(node) / 2 + Math.abs(yOffset);
480
- const contributor = `node ${node.id} height ${authoredNodeHeight(node)}px${yOffset ? ` with yOffset ${yOffset}px` : ''}`;
481
- if (extent > maxVerticalExtent + 0.0001) {
482
- maxVerticalExtent = extent;
483
- verticalExtentContributors.clear();
484
- verticalExtentContributors.add(contributor);
485
- } else if (Math.abs(extent - maxVerticalExtent) <= 0.0001) {
486
- verticalExtentContributors.add(contributor);
487
- }
488
- }
489
- const baseContentH = Math.max(74, Math.ceil(maxVerticalExtent * 2 + 8));
490
- const laneH = 30 + baseContentH;
491
- const groupsByLane = new Map();
492
- for (const group of asArray(workflow.groups)) {
493
- groupsByLane.set(group.lane, [...(groupsByLane.get(group.lane) || []), group]);
494
- }
495
- const groupLaneReserves = asArray(workflow.lanes).map((lane) => {
496
- let header = 0;
497
- let footer = 0;
498
- for (const group of groupsByLane.get(lane.id) || []) {
499
- const bounds = readableGroupBounds(workflow, group, colXs);
500
- const labelLeft = bounds.x + 10;
501
- const labelRight = labelLeft + textUnits(group.label) * 5.6;
502
- for (const node of nodes) {
503
- if (node.lane !== group.lane
504
- || !Number.isInteger(node.col)
505
- || node.col < group.fromCol
506
- || node.col > group.toCol
507
- || node.col < 0
508
- || node.col >= colXs.length) continue;
509
- const halfWidth = authoredNodeWidth(node) / 2;
510
- const nodeLeft = colXs[node.col] - halfWidth;
511
- const nodeRight = colXs[node.col] + halfWidth;
512
- const overlapsLabel = nodeRight > labelLeft && nodeLeft < labelRight;
513
- const topOffset = (baseContentH - authoredNodeHeight(node)) / 2
514
- + (Number(node.yOffset) || 0);
515
- const minimumTopOffset = overlapsLabel ? 11 : 9;
516
- header = Math.max(header, Math.ceil(minimumTopOffset - topOffset));
517
- const bottomMargin = baseContentH - GROUP_FRAME_BOTTOM_INSET
518
- - topOffset - authoredNodeHeight(node);
519
- footer = Math.max(footer, Math.ceil(1 - bottomMargin));
520
- }
521
- }
522
- return { header: Math.max(0, header), footer: Math.max(0, footer) };
523
- });
524
- const groupHeaderHeights = groupLaneReserves.map(({ header }) => header);
525
- const groupFooterHeights = groupLaneReserves.map(({ footer }) => footer);
526
- const laneHeights = groupLaneReserves.map(({ header, footer }) => laneH + header + footer);
527
- const laneGap = Math.max(20, Math.ceil(layoutFeedback.laneGapMin || 0));
528
- for (const [index, reserve] of groupHeaderHeights.entries()) {
529
- if (!reserve) continue;
530
- const lane = asArray(workflow.lanes)[index];
531
- heightContributors.add(`lane ${lane.id || lane.label} group label clearance ${reserve}px`);
532
- }
533
- for (const [index, reserve] of groupFooterHeights.entries()) {
534
- if (!reserve) continue;
535
- const lane = asArray(workflow.lanes)[index];
536
- heightContributors.add(`lane ${lane.id || lane.label} group frame containment ${reserve}px`);
537
- }
538
- if (laneH > 104) {
539
- for (const contributor of verticalExtentContributors) heightContributors.add(contributor);
540
- }
541
- if (laneGap > 20) {
542
- for (const contributor of asArray(layoutFeedback.laneGapContributors)) {
543
- heightContributors.add(contributor);
544
- }
545
- }
546
- const requiredWidth = 40 + laneW + 16;
547
-
548
- return {
549
- contract: 'readable-v2',
550
- laneX: 40,
551
- laneY: 52,
552
- laneW,
553
- laneH,
554
- laneHeights,
555
- laneGap,
556
- laneTitleH: 30,
557
- groupHeaderHeights,
558
- groupFooterHeights,
559
- colXs,
560
- nodeW: 92,
561
- nodeH: 52,
562
- defaultViewBoxWidth: requiredWidth,
563
- channelLabelEdgeKeys,
564
- widthContributors: [...widthContributors].sort(stableCompare),
565
- heightContributors: [...heightContributors].sort(stableCompare),
566
- };
567
- }
568
-
569
- function compilerFailure(contract, diagnostics, error = diagnostics.map(({ message }) => message).join('\n')) {
570
- return {
571
- ok: false,
572
- error,
573
- diagnostics,
574
- receipt: { contract, diagnostics },
575
- };
576
- }
577
-
578
- function workflowEdgeName(edge) {
579
- return edge.id || `${edge.from}->${edge.to}`;
580
- }
581
-
582
- function stableText(value) {
583
- return value == null ? '' : String(value);
584
- }
585
-
586
- function stableCompare(left, right) {
587
- const a = stableText(left);
588
- const b = stableText(right);
589
- return a < b ? -1 : a > b ? 1 : 0;
590
- }
591
-
592
- function stableValueKey(value) {
593
- if (Array.isArray(value)) return `[${value.map(stableValueKey).join(',')}]`;
594
- if (value && typeof value === 'object') {
595
- return `{${Object.keys(value).sort(stableCompare).map((key) => `${JSON.stringify(key)}:${stableValueKey(value[key])}`).join(',')}}`;
596
- }
597
- return JSON.stringify(value);
598
- }
599
-
600
- function cloneWorkflow(value) {
601
- return JSON.parse(JSON.stringify(value));
602
- }
603
-
604
- function canonicalReadableWorkflow(workflow) {
605
- if (workflow.schema_version !== 2) return workflow;
606
- const laneOrder = new Map(asArray(workflow.lanes).map((lane, index) => [lane.id, index]));
607
- const nodes = [...asArray(workflow.nodes)].sort((left, right) => (
608
- (laneOrder.get(left.lane) ?? Number.MAX_SAFE_INTEGER) - (laneOrder.get(right.lane) ?? Number.MAX_SAFE_INTEGER)
609
- || left.col - right.col
610
- || stableCompare(left.id, right.id)
611
- ));
612
- const edges = [...asArray(workflow.edges)].sort((left, right) => (
613
- stableCompare(left.id, right.id)
614
- || stableCompare(left.from, right.from)
615
- || stableCompare(left.to, right.to)
616
- || stableCompare(left.label, right.label)
617
- || stableCompare(left.route, right.route)
618
- || stableCompare(stableValueKey(left), stableValueKey(right))
619
- ));
620
- const phases = workflow.phases === undefined ? undefined : [...asArray(workflow.phases)].sort((left, right) => (
621
- left.fromCol - right.fromCol || left.toCol - right.toCol
622
- || stableCompare(left.id, right.id)
623
- ));
624
- const groups = workflow.groups === undefined ? undefined : [...asArray(workflow.groups)].sort((left, right) => (
625
- (laneOrder.get(left.lane) ?? Number.MAX_SAFE_INTEGER) - (laneOrder.get(right.lane) ?? Number.MAX_SAFE_INTEGER)
626
- || left.fromCol - right.fromCol || left.toCol - right.toCol
627
- || stableCompare(left.id, right.id)
628
- ));
629
- return {
630
- ...workflow,
631
- nodes,
632
- edges,
633
- ...(phases ? { phases } : {}),
634
- ...(groups ? { groups } : {}),
635
- };
636
- }
637
-
638
- function semanticContractDiagnostics(workflow) {
639
- const checks = workflow.semanticChecks;
640
- if (!checks) return [];
641
-
642
- const nodeIds = new Set(asArray(workflow.nodes).map((node) => node.id));
643
- const incoming = new Map([...nodeIds].map((id) => [id, 0]));
644
- const outgoing = new Map([...nodeIds].map((id) => [id, 0]));
645
- const adjacency = new Map([...nodeIds].map((id) => [id, new Set()]));
646
- for (const edge of asArray(workflow.edges)) {
647
- if (!nodeIds.has(edge.from) || !nodeIds.has(edge.to)) continue;
648
- outgoing.set(edge.from, outgoing.get(edge.from) + 1);
649
- incoming.set(edge.to, incoming.get(edge.to) + 1);
650
- adjacency.get(edge.from).add(edge.to);
651
- }
652
-
653
- const diagnostics = [];
654
- const diagnostic = (code, message, subject, evidence, supportedFixes) => ({
655
- code,
656
- severity: 'error',
657
- message,
658
- subject: { diagramType: 'workflow', ...subject },
659
- evidence,
660
- supportedFixes,
661
- });
662
- const referencedNodes = [
663
- ...asArray(checks.allowedRoots).map((id, index) => ({ id, path: `/semanticChecks/allowedRoots/${index}` })),
664
- ...asArray(checks.allowedTerminals).map((id, index) => ({ id, path: `/semanticChecks/allowedTerminals/${index}` })),
665
- ...asArray(checks.requiredEdges).flatMap((relation, index) => [
666
- { id: relation.from, path: `/semanticChecks/requiredEdges/${index}/from` },
667
- { id: relation.to, path: `/semanticChecks/requiredEdges/${index}/to` },
668
- ]),
669
- ...asArray(checks.requiredPaths).flatMap((relation, index) => [
670
- { id: relation.from, path: `/semanticChecks/requiredPaths/${index}/from` },
671
- { id: relation.to, path: `/semanticChecks/requiredPaths/${index}/to` },
672
- ]),
673
- ];
674
- for (const { id, path } of referencedNodes) {
675
- if (nodeIds.has(id)) continue;
676
- diagnostics.push(diagnostic(
677
- 'workflow/semantic-node-reference',
678
- `Workflow semantic contract references unknown node "${id}" at ${path}.`,
679
- { node: id, path },
680
- { knownNodes: [...nodeIds] },
681
- [`replace "${id}" with an existing node id`, 'add the missing node before compiling'],
682
- ));
683
- }
684
- if (diagnostics.length) return diagnostics;
685
-
686
- if (checks.allowedRoots !== undefined) {
687
- const allowed = new Set(checks.allowedRoots);
688
- for (const [node, count] of incoming) {
689
- if (count > 0 || allowed.has(node)) continue;
690
- diagnostics.push(diagnostic(
691
- 'workflow/unexpected-root',
692
- `Workflow node "${node}" has no incoming edge and is not declared in semanticChecks.allowedRoots.`,
693
- { node, path: '/semanticChecks/allowedRoots' },
694
- { incomingEdges: 0, allowedRoots: [...allowed] },
695
- [`add the missing incoming edge to "${node}"`, `declare "${node}" in semanticChecks.allowedRoots if it is an intentional source`],
696
- ));
697
- }
698
- }
699
-
700
- if (checks.allowedTerminals !== undefined) {
701
- const allowed = new Set(checks.allowedTerminals);
702
- for (const [node, count] of outgoing) {
703
- if (count > 0 || allowed.has(node)) continue;
704
- diagnostics.push(diagnostic(
705
- 'workflow/unexpected-terminal',
706
- `Workflow node "${node}" has no outgoing edge and is not declared in semanticChecks.allowedTerminals.`,
707
- { node, path: '/semanticChecks/allowedTerminals' },
708
- { outgoingEdges: 0, allowedTerminals: [...allowed] },
709
- [`add the missing outgoing edge from "${node}"`, `declare "${node}" in semanticChecks.allowedTerminals if it is an intentional sink`],
710
- ));
711
- }
712
- }
713
-
714
- const authoredEdges = new Set(asArray(workflow.edges).map((edge) => `${edge.from}\u0000${edge.to}`));
715
- for (const [index, relation] of asArray(checks.requiredEdges).entries()) {
716
- if (authoredEdges.has(`${relation.from}\u0000${relation.to}`)) continue;
717
- diagnostics.push(diagnostic(
718
- 'workflow/required-edge',
719
- `Workflow semantic contract requires edge "${relation.from}" -> "${relation.to}", but no authored edge matches it.`,
720
- { from: relation.from, to: relation.to, path: `/semanticChecks/requiredEdges/${index}` },
721
- { authoredEdgeCount: asArray(workflow.edges).length },
722
- [`add an edge from "${relation.from}" to "${relation.to}" without deleting the semantic requirement`],
723
- ));
724
- }
725
-
726
- function reachable(from, to) {
727
- const visited = new Set([from]);
728
- const pending = [from];
729
- while (pending.length) {
730
- const current = pending.shift();
731
- if (current === to) return true;
732
- for (const next of adjacency.get(current) || []) {
733
- if (visited.has(next)) continue;
734
- visited.add(next);
735
- pending.push(next);
736
- }
737
- }
738
- return false;
739
- }
740
-
741
- for (const [index, relation] of asArray(checks.requiredPaths).entries()) {
742
- if (reachable(relation.from, relation.to)) continue;
743
- diagnostics.push(diagnostic(
744
- 'workflow/required-path',
745
- `Workflow semantic contract requires a directed path from "${relation.from}" to "${relation.to}", but none exists.`,
746
- { from: relation.from, to: relation.to, path: `/semanticChecks/requiredPaths/${index}` },
747
- { reachableNodes: [...new Set([relation.from, ...(adjacency.get(relation.from) || [])])] },
748
- [`restore a directed path from "${relation.from}" to "${relation.to}" without weakening the semantic requirement`],
749
- ));
750
- }
751
-
752
- return diagnostics;
753
- }
754
-
755
- function compileWorkflowInternal({
756
- workflow: inputWorkflow,
757
- qualityProfile,
758
- discoverFixes = true,
759
- layoutFeedback = {},
760
- } = {}) {
761
- if (!inputWorkflow || typeof inputWorkflow !== 'object' || Array.isArray(inputWorkflow)) {
762
- const diagnostics = [{
763
- code: 'workflow/input-contract',
764
- severity: 'error',
765
- message: 'compileWorkflow requires one parsed workflow document object.',
766
- subject: { diagramType: 'workflow', path: '/' },
767
- evidence: {},
768
- supportedFixes: [],
769
- }];
770
- return compilerFailure('fixed-v1', diagnostics, diagnostics[0].message);
771
- }
772
- const resolvedQualityProfile = qualityProfile || inputWorkflow.meta?.quality_profile;
773
- const authoredQualityProfile = inputWorkflow.meta?.quality_profile;
774
- const qualityResolvedWorkflow = resolvedQualityProfile && resolvedQualityProfile !== inputWorkflow.meta?.quality_profile
775
- ? { ...inputWorkflow, meta: { ...inputWorkflow.meta, quality_profile: resolvedQualityProfile } }
776
- : inputWorkflow;
777
- let inputDiagnostics = [];
778
- try {
779
- validateSchema('workflow', qualityResolvedWorkflow);
780
- } catch (error) {
781
- inputDiagnostics = Array.isArray(error?.archifyDiagnostics)
782
- ? error.archifyDiagnostics.map((diagnostic) => ({
783
- ...diagnostic,
784
- supportedFixes: [],
785
- }))
786
- : [{
787
- code: 'workflow/input-contract',
788
- severity: 'error',
789
- message: 'Workflow schema validation failed unexpectedly.',
790
- subject: { diagramType: 'workflow', path: '/' },
791
- evidence: { reason: error?.message || String(error) },
792
- supportedFixes: [],
793
- }];
794
- }
795
- if (inputDiagnostics.length) {
796
- return compilerFailure(
797
- inputWorkflow.schema_version === 2 ? 'readable-v2' : 'fixed-v1',
798
- inputDiagnostics,
799
- );
800
- }
801
- const workflow = canonicalReadableWorkflow(qualityResolvedWorkflow);
802
- const semanticDiagnostics = semanticContractDiagnostics(workflow);
803
- if (semanticDiagnostics.length) {
804
- return compilerFailure(
805
- workflow.schema_version === 2 ? 'readable-v2' : 'fixed-v1',
806
- semanticDiagnostics,
807
- );
808
- }
809
- const sourceIndexes = {
810
- lanes: new Map(asArray(qualityResolvedWorkflow.lanes).map((lane, index) => [lane, index])),
811
- nodes: new Map(asArray(qualityResolvedWorkflow.nodes).map((node, index) => [node, index])),
812
- edges: new Map(asArray(qualityResolvedWorkflow.edges).map((edge, index) => [edge, index])),
813
- };
814
- const layout = workflow.schema_version === 2
815
- ? createReadableLayout(workflow, layoutFeedback)
816
- : createLegacyLayout();
817
-
818
- const LEGEND_CATALOG = [
819
- 'frontend',
820
- 'backend',
821
- 'security',
822
- 'messagebus',
823
- 'database',
824
- 'cloud',
825
- 'external',
826
- ].map((kind) => ({ kind, label: i18nText(workflow.meta.locale, `legend.workflow.${kind}`) }));
827
- const presentLegendKinds = new Set(asArray(workflow.nodes).map((node) => node.type));
828
- const workflowLegendEntries = resolveLegend(
829
- workflow.meta?.legend,
830
- LEGEND_CATALOG,
831
- presentLegendKinds,
832
- );
833
- const legendFootprintOptions = { fontSize: 7, itemGap: 7 };
834
- const oneRowLegendFootprint = legendFootprint(workflowLegendEntries, {
835
- ...legendFootprintOptions,
836
- width: Number.MAX_SAFE_INTEGER,
837
- });
838
- const minimumCanvasWidth = workflow.schema_version === 2
839
- ? Math.max(layout.defaultViewBoxWidth, oneRowLegendFootprint.minWidth + 40)
840
- : layout.defaultViewBoxWidth;
841
- const legendPackingWidth = Math.max(
842
- 1,
843
- (workflow.schema_version === 2
844
- ? minimumCanvasWidth
845
- : (workflow.meta?.viewBox?.[0] ?? minimumCanvasWidth)) - 40,
846
- );
847
- const packedLegendFootprint = legendFootprint(workflowLegendEntries, {
848
- ...legendFootprintOptions,
849
- width: legendPackingWidth,
850
- });
851
- const legendExtraHeight = workflow.schema_version === 2
852
- ? packedLegendFootprint.extraHeight
853
- : 0;
854
-
855
- // Content is 680px wide (laneX + laneW); auto height fits the lanes plus legend.
856
- const autoHeight = layout.laneY
857
- + (layout.laneHeights?.reduce((total, height) => total + height, 0)
858
- ?? (workflow.lanes?.length || 1) * layout.laneH)
859
- + ((workflow.lanes?.length || 1) - 1) * layout.laneGap
860
- + 124
861
- + legendExtraHeight;
862
- let viewBox = workflow.meta?.viewBox || [minimumCanvasWidth, autoHeight];
863
- let requiredViewBox = [...viewBox];
864
-
865
- const laneIndex = new Map(asArray(workflow.lanes).map((lane, index) => [lane.id, index]));
866
- const laneLabels = new Map(asArray(workflow.lanes).map((lane) => [lane.id, lane.label]));
867
-
868
- function nodeContext(node) {
869
- const group = asArray(workflow.groups).find((candidate) => (
870
- candidate.lane === node.lane && node.col >= candidate.fromCol && node.col <= candidate.toCol
871
- ));
872
- const phase = asArray(workflow.phases).find((candidate) => (
873
- node.col >= candidate.fromCol && node.col <= candidate.toCol
874
- ));
875
- return [laneLabels.get(node.lane), group?.label, phase?.label].filter(Boolean).join(' › ')
876
- || i18nText(workflow.meta.locale, 'node.context.workflow');
877
- }
878
-
879
- function laneHeight(idOrIndex) {
880
- const index = typeof idOrIndex === 'number' ? idOrIndex : laneIndex.get(idOrIndex);
881
- return layout.laneHeights?.[index] ?? layout.laneH;
882
- }
883
-
884
- function laneGroupHeaderH(idOrIndex) {
885
- const index = typeof idOrIndex === 'number' ? idOrIndex : laneIndex.get(idOrIndex);
886
- return layout.groupHeaderHeights?.[index] ?? 0;
887
- }
888
-
889
- function laneGroupFooterH(idOrIndex) {
890
- const index = typeof idOrIndex === 'number' ? idOrIndex : laneIndex.get(idOrIndex);
891
- return layout.groupFooterHeights?.[index] ?? 0;
892
- }
893
-
894
- function laneTop(id) {
895
- const index = laneIndex.get(id);
896
- const precedingHeight = asArray(workflow.lanes).slice(0, index)
897
- .reduce((total, _lane, lanePosition) => total + laneHeight(lanePosition), 0);
898
- return layout.laneY + precedingHeight + index * layout.laneGap;
899
- }
900
-
901
- function lastLaneBottom() {
902
- return layout.laneY
903
- + asArray(workflow.lanes).reduce((total, _lane, index) => total + laneHeight(index), 0)
904
- + (workflow.lanes.length - 1) * layout.laneGap;
905
- }
906
-
907
- function legendY() {
908
- return lastLaneBottom() + 44 + legendExtraHeight;
909
- }
910
-
911
- function workflowLegendLayout(obstacles = []) {
912
- return {
913
- x: 20,
914
- baselineY: legendY(),
915
- width: workflow.schema_version === 2 ? legendPackingWidth : viewBox[0] - 40,
916
- fontSize: 7,
917
- itemGap: 7,
918
- minTitleY: lastLaneBottom() + 8,
919
- obstacles,
920
- unfit: workflow.meta?.legend === undefined ? 'hide' : 'error',
921
- diagramType: 'workflow',
922
- };
923
- }
924
-
925
- function workflowLegendRects() {
926
- if (!workflowLegendEntries.length) return [];
927
- const measured = measureLegend(workflowLegendEntries, workflowLegendLayout());
928
- if (!measured) return [];
929
- return [
930
- { kind: 'title', x: 20, y: measured.titleY - 10, width: 48, height: 14 },
931
- ...measured.entries.map((entry) => ({
932
- kind: entry.kind,
933
- x: entry.x,
934
- y: entry.baseline - 10,
935
- width: entry.width,
936
- height: 14,
937
- })),
938
- ];
939
- }
940
-
941
- function measureNode(node) {
942
- const width = node.width || layout.nodeW;
943
- const height = node.height || (node.tag ? 68 : layout.nodeH);
944
- const cx = layout.colXs[node.col];
945
- const groupHeaderH = laneGroupHeaderH(node.lane);
946
- const contentH = laneHeight(node.lane) - layout.laneTitleH
947
- - groupHeaderH - laneGroupFooterH(node.lane);
948
- const y = laneTop(node.lane) + layout.laneTitleH + groupHeaderH
949
- + (contentH - height) / 2 + (node.yOffset || 0);
950
- return {
951
- ...node,
952
- width,
953
- height,
954
- x: cx - width / 2,
955
- y,
956
- cx,
957
- cy: y + height / 2
958
- };
959
- }
960
-
961
- // Font sizes for this renderer's node text; the fitting geometry is shared.
962
- const nodeTextFit = {
963
- labelPreferred: 11,
964
- labelMinimum: 9,
965
- sublabelPreferred: 8,
966
- sublabelMinimum: 6,
967
- tagPreferred: 7,
968
- tagMinimum: 6,
969
- };
970
-
971
- const nodes = new Map(asArray(workflow.nodes).map((node) => [node.id, measureNode(node)]));
972
-
973
- function workflowCompositionFrames() {
974
- const frames = [];
975
- for (const [index, lane] of asArray(workflow.lanes).entries()) {
976
- const y = laneTop(lane.id);
977
- const height = laneHeight(index);
978
- frames.push({ id: `lane-${index}`, label: lane.label, kind: 'lane', x: layout.laneX, y, width: layout.laneW, height, radius: 10 });
979
- if (lane.variant === 'exception') {
980
- frames.push({ id: `lane-${index}-exception`, label: `${lane.label} exception`, kind: 'exception-lane', x: layout.laneX + 6, y: y + 6, width: layout.laneW - 12, height: height - 12, radius: 8 });
981
- }
982
- }
983
- for (const [index, group] of asArray(workflow.groups).entries()) {
984
- const span = groupSpan(group);
985
- frames.push({
986
- id: `group-${index}`,
987
- label: group.label,
988
- kind: 'group',
989
- x: span.x,
990
- y: laneTop(group.lane) + layout.laneTitleH + GROUP_FRAME_TOP_INSET,
991
- width: span.width,
992
- height: workflow.schema_version === 2
993
- ? laneHeight(group.lane) - layout.laneTitleH
994
- - GROUP_FRAME_TOP_INSET - GROUP_FRAME_BOTTOM_INSET
995
- : layout.laneH - layout.laneTitleH - 16,
996
- radius: 9,
997
- });
998
- }
999
- return frames;
1000
- }
1001
-
1002
- function workflowSceneLabelObstacles() {
1003
- const obstacles = [];
1004
- for (const [index, lane] of asArray(workflow.lanes).entries()) {
1005
- const prefix = lane.variant === 'exception' ? 'EX' : String(index + 1).padStart(2, '0');
1006
- const label = `${prefix} / ${lane.label}`;
1007
- obstacles.push({
1008
- kind: 'lane-header',
1009
- id: lane.id,
1010
- x: layout.laneX + 14,
1011
- y: laneTop(lane.id) + 12,
1012
- width: textUnits(label) * 6.2,
1013
- height: 14,
1014
- });
1015
- }
1016
- for (const phase of asArray(workflow.phases)) {
1017
- if (!Number.isInteger(phase.fromCol) || !Number.isInteger(phase.toCol)
1018
- || phase.fromCol < 0 || phase.toCol >= layout.colXs.length || phase.fromCol > phase.toCol) continue;
1019
- const span = phaseSpan(phase);
1020
- obstacles.push({
1021
- kind: 'phase-header',
1022
- id: phase.id ?? null,
1023
- x: span.x,
1024
- y: 27,
1025
- width: span.width,
1026
- height: 16,
1027
- });
1028
- }
1029
- for (const group of asArray(workflow.groups)) {
1030
- if (!laneIndex.has(group.lane)
1031
- || !Number.isInteger(group.fromCol) || !Number.isInteger(group.toCol)
1032
- || group.fromCol < 0 || group.toCol >= layout.colXs.length || group.fromCol > group.toCol) continue;
1033
- const span = groupSpan(group);
1034
- const frameY = laneTop(group.lane) + layout.laneTitleH + GROUP_FRAME_TOP_INSET;
1035
- const labelBaseline = frameY + GROUP_LABEL_BASELINE_OFFSET;
1036
- obstacles.push({
1037
- kind: 'group-label',
1038
- id: group.id ?? null,
1039
- x: span.x + 10,
1040
- y: labelBaseline - GROUP_LABEL_MASK_ASCENT,
1041
- width: textUnits(group.label) * 5.6,
1042
- height: GROUP_LABEL_MASK_H,
1043
- });
1044
- }
1045
- return obstacles;
1046
- }
1047
-
1048
- const mainPathSteps = new Map(asArray(workflow.mainPath).map((id, index) => [id, index]));
1049
- const edgeSteps = new Map(asArray(workflow.edges).map((edge, index) => {
1050
- const fromStep = mainPathSteps.get(edge.from);
1051
- const toStep = mainPathSteps.get(edge.to);
1052
- const mainStep = Number.isInteger(fromStep) && toStep === fromStep + 1 ? fromStep : null;
1053
- return [edge, mainStep ?? asArray(workflow.mainPath).length + index];
1054
- }));
1055
-
1056
- function nodeStep(node) {
1057
- return mainPathSteps.get(node.id) ?? asArray(workflow.mainPath).length + asArray(workflow.nodes).findIndex((item) => item.id === node.id);
1058
- }
1059
-
1060
- function acceptsFix(mutator) {
1061
- if (!discoverFixes) return false;
1062
- const candidate = cloneWorkflow(workflow);
1063
- mutator(candidate);
1064
- return withDiagnosticRecordingSuppressed(() => compileWorkflowWithFeedback({
1065
- workflow: candidate,
1066
- qualityProfile: resolvedQualityProfile,
1067
- discoverFixes: false,
1068
- }).ok);
1069
- }
1070
-
1071
- function verifiedLegacyAlternative(edge, from, to, requiredClearance) {
1072
- const occupied = [...nodes.values()].filter((node) => node.lane === to.lane && node.id !== to.id);
1073
- const candidates = layout.colXs.map((center, col) => ({ center, col }))
1074
- .filter(({ col }) => col !== to.col)
1075
- .sort((a, b) => Math.abs(a.col - to.col) - Math.abs(b.col - to.col) || a.col - b.col);
1076
- for (const candidate of candidates) {
1077
- const candidateRect = { ...to, col: candidate.col, cx: candidate.center, x: candidate.center - to.width / 2 };
1078
- if (occupied.some((node) => rectsOverlap(candidateRect, node, 8))) continue;
1079
- const centerDistance = Math.abs(candidate.center - from.cx);
1080
- const signedClearance = centerDistance - from.width / 2 - to.width / 2;
1081
- if (signedClearance < requiredClearance) continue;
1082
- if (acceptsFix((document) => {
1083
- document.nodes.find((node) => node.id === to.id).col = candidate.col;
1084
- })) return candidate.col;
1085
- }
1086
- return null;
1087
- }
1088
-
1089
- function readableMigrationProvidesCapacity(from, to, requiredClearance) {
1090
- const readable = createReadableLayout({ ...workflow, schema_version: 2 });
1091
- const centerDistance = Math.abs(readable.colXs[to.col] - readable.colXs[from.col]);
1092
- if (centerDistance - from.width / 2 - to.width / 2 < requiredClearance) return false;
1093
- if (!discoverFixes) return false;
1094
-
1095
- return withDiagnosticRecordingSuppressed(() => {
1096
- const migrationQualityProfile = authoredQualityProfile;
1097
- let planned = compileWorkflowWithFeedback({
1098
- workflow: intrinsicWorkflow(workflow),
1099
- qualityProfile: migrationQualityProfile,
1100
- discoverFixes: false,
1101
- });
1102
- if (!planned.ok) {
1103
- planned = compileWorkflowWithFeedback({
1104
- workflow: planningWorkflow(workflow),
1105
- qualityProfile: migrationQualityProfile,
1106
- discoverFixes: false,
1107
- });
1108
- }
1109
- if (!planned.ok || !Array.isArray(planned.receipt?.columns)) return false;
1110
-
1111
- let candidate;
1112
- try {
1113
- candidate = createMappedWorkflowCandidate(
1114
- workflow,
1115
- LEGACY_COLUMN_CENTERS,
1116
- planned.receipt.columns,
1117
- ).document;
1118
- } catch {
1119
- return false;
1120
- }
1121
- let compiled = compileWorkflowWithFeedback({
1122
- workflow: candidate,
1123
- qualityProfile: migrationQualityProfile,
1124
- discoverFixes: false,
1125
- });
1126
- const requiredViewBox = compiled.diagnostics?.length
1127
- && compiled.diagnostics.every(({ code }) => code === 'workflow/viewbox-capacity')
1128
- ? compiled.diagnostics.find(({ evidence }) => Array.isArray(evidence?.requiredViewBox))
1129
- ?.evidence.requiredViewBox
1130
- : null;
1131
- if (!compiled.ok && Array.isArray(candidate.meta?.viewBox) && requiredViewBox) {
1132
- candidate.meta.viewBox = [
1133
- Math.max(candidate.meta.viewBox[0], requiredViewBox[0]),
1134
- Math.max(candidate.meta.viewBox[1], requiredViewBox[1]),
1135
- ];
1136
- compiled = compileWorkflowWithFeedback({
1137
- workflow: candidate,
1138
- qualityProfile: migrationQualityProfile,
1139
- discoverFixes: false,
1140
- });
1141
- }
1142
- return compiled.ok;
1143
- });
1144
- }
1145
-
1146
- function verifiedReducedWidths(from, to, requiredClearance) {
1147
- const widthBudget = 2 * (Math.abs(to.cx - from.cx) - requiredClearance);
1148
- if (widthBudget < 64) return null;
1149
- const widths = [from.width, to.width];
1150
- let excess = widths[0] + widths[1] - widthBudget;
1151
- for (const index of widths[0] >= widths[1] ? [0, 1] : [1, 0]) {
1152
- const reduction = Math.min(excess, widths[index] - 32);
1153
- widths[index] -= reduction;
1154
- excess -= reduction;
1155
- }
1156
- if (excess > 0.0001) return null;
1157
- const candidates = [from, to];
1158
- const labelsFit = candidates.every((node, index) => (
1159
- textUnits(node.label) * 6.8 <= widths[index] + 6
1160
- && (!node.sublabel || minimumNodeTextWidth(node.sublabel, nodeTextFit.sublabelMinimum) <= availableNodeTextWidth(widths[index]))
1161
- && (!node.tag || minimumNodeTextWidth(node.tag, nodeTextFit.tagMinimum) <= availableNodeTextWidth(widths[index]))
1162
- ));
1163
- if (!labelsFit) return null;
1164
- const serializedWidths = widths.map((width) => Math.floor((width + 1e-9) * 100) / 100);
1165
- const signedClearance = Math.abs(to.cx - from.cx)
1166
- - serializedWidths[0] / 2 - serializedWidths[1] / 2;
1167
- if (signedClearance + 0.0001 < requiredClearance) return null;
1168
- const accepted = acceptsFix((document) => {
1169
- document.nodes.find((node) => node.id === from.id).width = serializedWidths[0];
1170
- document.nodes.find((node) => node.id === to.id).width = serializedWidths[1];
1171
- });
1172
- return accepted ? serializedWidths : null;
1173
- }
1174
-
1175
- function enforceLegacyColumnCapacity() {
1176
- if (workflow.schema_version !== 1) return;
1177
- for (const edge of workflow.edges) {
1178
- const from = nodes.get(edge.from);
1179
- const to = nodes.get(edge.to);
1180
- if (!from || !to || from.lane !== to.lane || from.col === to.col) continue;
1181
- if (!verticalIntervalsOverlap(from, to, 8)) continue;
1182
- const centerDistance = Math.abs(to.cx - from.cx);
1183
- const actualSignedClearance = centerDistance - from.width / 2 - to.width / 2;
1184
- const direct = !edge.via && ['auto', 'straight'].includes(edge.route || 'auto')
1185
- && Math.abs(from.cy - to.cy) < 0.0001;
1186
- const requiredDirectClearance = direct ? 28 : 8;
1187
- if (actualSignedClearance >= requiredDirectClearance) continue;
1188
- const alternative = verifiedLegacyAlternative(edge, from, to, requiredDirectClearance);
1189
- const reducedWidths = verifiedReducedWidths(from, to, requiredDirectClearance);
1190
- const capacity = actualSignedClearance < 0
1191
- ? `overlap by ${Math.abs(Math.round(actualSignedClearance))}px`
1192
- : `leave only ${Math.round(actualSignedClearance)}px of direct clearance`;
1193
- const message = `Workflow columns ${from.col}→${to.col} place nodes "${from.id}" and "${to.id}" so they ${capacity} under the fixed-v1 layout.`;
1194
- const supportedFixes = [];
1195
- if (readableMigrationProvidesCapacity(from, to, requiredDirectClearance)) {
1196
- supportedFixes.push('migrate this workflow to schema_version 2');
1197
- }
1198
- if (alternative !== null) supportedFixes.push(`move node "${to.id}" to verified free column ${alternative}`);
1199
- if (reducedWidths) {
1200
- supportedFixes.push(`set node widths "${from.id}"=${Math.round(reducedWidths[0] * 100) / 100}px and "${to.id}"=${Math.round(reducedWidths[1] * 100) / 100}px`);
1201
- }
1202
- throwDiagnosticError(message, [{
1203
- code: 'workflow/column-capacity',
1204
- severity: 'error',
1205
- message,
1206
- subject: {
1207
- diagramType: 'workflow',
1208
- edge: edge.id ?? null,
1209
- from: edge.from,
1210
- to: edge.to,
1211
- fromCol: from.col,
1212
- toCol: to.col,
1213
- },
1214
- evidence: {
1215
- centerDistancePx: centerDistance,
1216
- nodeWidthsPx: [from.width, to.width],
1217
- actualSignedClearancePx: actualSignedClearance,
1218
- requiredDirectClearancePx: requiredDirectClearance,
1219
- },
1220
- supportedFixes,
1221
- suppresses: [
1222
- 'workflow/short-edge',
1223
- 'clean-flow/endpoint-side-direction',
1224
- 'workflow/label-node-overlap',
1225
- ],
1226
- }]);
1227
- }
1228
- }
1229
-
1230
- function verifiedEdgeFix(edge, message, mutator) {
1231
- const edgeIndex = workflow.edges.indexOf(edge);
1232
- if (edgeIndex < 0) return null;
1233
- const accepted = acceptsFix((document) => mutator(document.edges[edgeIndex], document));
1234
- return accepted ? message : null;
1235
- }
1236
-
1237
- function verifiedAutomaticRouteFix(edge, { clearSides = false } = {}) {
1238
- const edgeName = workflowEdgeName(edge);
1239
- return verifiedEdgeFix(
1240
- edge,
1241
- clearSides
1242
- ? `remove explicit route geometry and endpoint sides from edge "${edgeName}" so readable-v2 can use its verified automatic candidate`
1243
- : `remove explicit route geometry from edge "${edgeName}" so readable-v2 can use its verified automatic candidate`,
1244
- (candidate) => {
1245
- delete candidate.via;
1246
- delete candidate.channelX;
1247
- delete candidate.channelY;
1248
- delete candidate.route;
1249
- if (clearSides) {
1250
- delete candidate.fromSide;
1251
- delete candidate.toSide;
1252
- }
1253
- },
1254
- );
1255
- }
1256
-
1257
- function authoredPinEvidence(edge, field) {
1258
- const authoredEdgeIndex = sourceIndexes.edges.get(edge);
1259
- const value = Array.isArray(edge[field])
1260
- ? edge[field].map((item) => (Array.isArray(item) ? [...item] : item))
1261
- : edge[field];
1262
- return {
1263
- edge: workflowEdgeName(edge),
1264
- field,
1265
- ...(Number.isInteger(authoredEdgeIndex) ? { path: `/edges/${authoredEdgeIndex}/${field}` } : {}),
1266
- value,
1267
- };
1268
- }
1269
-
1270
- function combinations(values, size, start = 0, prefix = [], output = []) {
1271
- if (prefix.length === size) {
1272
- output.push([...prefix]);
1273
- return output;
1274
- }
1275
- for (let index = start; index <= values.length - (size - prefix.length); index += 1) {
1276
- prefix.push(values[index]);
1277
- combinations(values, size, index + 1, prefix, output);
1278
- prefix.pop();
1279
- }
1280
- return output;
1281
- }
1282
-
1283
- function verifiedPinRemovalAlternatives(edge, fields, reason) {
1284
- if (!discoverFixes) return { removalSets: [], supportedFixes: [] };
1285
- const edgeIndex = workflow.edges.indexOf(edge);
1286
- if (edgeIndex < 0) return { removalSets: [], supportedFixes: [] };
1287
- const uniqueFields = [...new Set(fields.filter((field) => edge[field] !== undefined))];
1288
- for (let size = 1; size <= uniqueFields.length; size += 1) {
1289
- const removalSets = combinations(uniqueFields, size).filter((fieldSet) => (
1290
- acceptsFix((document) => {
1291
- for (const field of fieldSet) delete document.edges[edgeIndex][field];
1292
- })
1293
- ));
1294
- if (!removalSets.length) continue;
1295
- const edgeName = workflowEdgeName(edge);
1296
- return {
1297
- removalSets,
1298
- supportedFixes: removalSets.map((fieldSet) => (
1299
- `remove ${fieldSet.join(' and ')} from edge "${edgeName}" ${reason}`
1300
- )),
1301
- };
1302
- }
1303
- return { removalSets: [], supportedFixes: [] };
1304
- }
1305
-
1306
- function conflictPinsFromRemovalSets(edge, removalSets, fallbackFields = []) {
1307
- const fields = removalSets.length
1308
- ? [...new Set(removalSets.flat())]
1309
- : [...new Set(fallbackFields)];
1310
- return fields.map((field) => authoredPinEvidence(edge, field));
1311
- }
1312
-
1313
- function authoredRouteAssertionFields(edge) {
1314
- return [
1315
- ...(Array.isArray(edge?.via) ? ['via'] : []),
1316
- ...(edge?.channelX !== undefined ? ['channelX'] : []),
1317
- ...(edge?.channelY !== undefined ? ['channelY'] : []),
1318
- ...(edge?.route && edge.route !== 'auto' ? ['route'] : []),
1319
- ...(edge?.fromSide && edge.fromSide !== 'auto' ? ['fromSide'] : []),
1320
- ...(edge?.toSide && edge.toSide !== 'auto' ? ['toSide'] : []),
1321
- ];
1322
- }
1323
-
1324
- function hasAuthoredRouteAssertions(edge) {
1325
- return authoredRouteAssertionFields(edge).length > 0;
1326
- }
1327
-
1328
- function verifiedPinReferenceAlternatives(candidateRefs, reason) {
1329
- const seenRefs = new Set();
1330
- const refs = candidateRefs.filter(({ edge, edgeIndex, field }) => {
1331
- if (edgeIndex < 0 || edge?.[field] === undefined) return false;
1332
- const key = `${edgeIndex}:${field}`;
1333
- if (seenRefs.has(key)) return false;
1334
- seenRefs.add(key);
1335
- return true;
1336
- });
1337
- const fallbackPins = refs.map(({ edge, field }) => authoredPinEvidence(edge, field));
1338
- if (!discoverFixes) {
1339
- return {
1340
- removalSets: [], conflictingRefs: refs, conflictingPins: fallbackPins, repairs: [], supportedFixes: [],
1341
- };
1342
- }
1343
-
1344
- for (let size = 1; size <= refs.length; size += 1) {
1345
- const removalSets = combinations(refs, size).filter((removalSet) => (
1346
- acceptsFix((document) => {
1347
- for (const { edgeIndex, field } of removalSet) delete document.edges[edgeIndex][field];
1348
- })
1349
- ));
1350
- if (!removalSets.length) continue;
1351
- const conflictingRefs = [];
1352
- const conflictingPins = [];
1353
- const seenPins = new Set();
1354
- for (const removalSet of removalSets) {
1355
- for (const { edge, field } of removalSet) {
1356
- const key = `${workflow.edges.indexOf(edge)}:${field}`;
1357
- if (seenPins.has(key)) continue;
1358
- seenPins.add(key);
1359
- conflictingRefs.push({ edge, edgeIndex: workflow.edges.indexOf(edge), field });
1360
- conflictingPins.push(authoredPinEvidence(edge, field));
1361
- }
1362
- }
1363
- const repairs = removalSets.map((removalSet) => {
1364
- const grouped = [];
1365
- for (const ref of removalSet) {
1366
- let group = grouped.find(({ edge }) => edge === ref.edge);
1367
- if (!group) {
1368
- group = { edge: ref.edge, fields: [] };
1369
- grouped.push(group);
1370
- }
1371
- group.fields.push(ref.field);
1372
- }
1373
- const removals = grouped.map(({ edge, fields }) => (
1374
- `remove ${fields.join(' and ')} from edge "${workflowEdgeName(edge)}"`
1375
- ));
1376
- return { removalSet, message: `${removals.join(' and ')} ${reason}` };
1377
- });
1378
- return {
1379
- removalSets,
1380
- conflictingRefs,
1381
- conflictingPins,
1382
- repairs,
1383
- supportedFixes: repairs.map(({ message }) => message),
1384
- };
1385
- }
1386
- return {
1387
- removalSets: [], conflictingRefs: refs, conflictingPins: fallbackPins, repairs: [], supportedFixes: [],
1388
- };
1389
- }
1390
-
1391
- function verifiedRoutePairPinAlternatives(leftEdge, rightEdge, reason) {
1392
- const refs = [leftEdge, rightEdge].flatMap((edge) => {
1393
- const edgeIndex = workflow.edges.indexOf(edge);
1394
- return authoredRouteAssertionFields(edge).map((field) => ({ edge, edgeIndex, field }));
1395
- });
1396
- return verifiedPinReferenceAlternatives(refs, reason);
1397
- }
1398
-
1399
- function verifiedLabelRoutePinAlternatives(labelEdge, routeEdge) {
1400
- const refs = [];
1401
- const labelEdgeIndex = workflow.edges.indexOf(labelEdge);
1402
- if (Array.isArray(labelEdge?.labelAt)) {
1403
- refs.push({ edge: labelEdge, edgeIndex: labelEdgeIndex, field: 'labelAt' });
1404
- }
1405
- const routeEdgeIndex = workflow.edges.indexOf(routeEdge);
1406
- for (const field of authoredRouteAssertionFields(routeEdge)) {
1407
- refs.push({ edge: routeEdge, edgeIndex: routeEdgeIndex, field });
1408
- }
1409
- return verifiedPinReferenceAlternatives(
1410
- refs,
1411
- Array.isArray(labelEdge?.labelAt)
1412
- ? 'so readable-v2 can replan the remaining authored label-route pins'
1413
- : 'so readable-v2 can replan the remaining authored route assertions',
1414
- );
1415
- }
1416
-
1417
- function verifiedLabelPairPinAlternatives(leftEdge, rightEdge) {
1418
- return verifiedPinReferenceAlternatives(
1419
- [leftEdge, rightEdge].flatMap((edge) => (
1420
- Array.isArray(edge?.labelAt)
1421
- ? [{ edge, edgeIndex: workflow.edges.indexOf(edge), field: 'labelAt' }]
1422
- : []
1423
- )),
1424
- 'so readable-v2 can replan the remaining authored label pins',
1425
- );
1426
- }
1427
-
1428
- function verifiedRepairsWithLabelNudges(alternatives) {
1429
- return alternatives.repairs.flatMap(({ removalSet, message }) => {
1430
- if (removalSet.length !== 1 || removalSet[0].field !== 'labelAt') return [message];
1431
- const nudges = verifiedLabelAtAlternatives(removalSet[0].edge);
1432
- return nudges.length ? nudges : [message];
1433
- });
1434
- }
1435
-
1436
- function throwExplicitPinConflict(edge, invariant, evidence, supportedFixes = []) {
1437
- const message = `Workflow edge "${workflowEdgeName(edge)}" has explicit geometry that violates ${invariant}.`;
1438
- const [onlyPin] = asArray(evidence?.conflictingPins);
1439
- const authoredEdgeIndex = sourceIndexes.edges.get(edge);
1440
- const pinPath = asArray(evidence?.conflictingPins).length === 1
1441
- && Number.isInteger(authoredEdgeIndex)
1442
- && onlyPin?.field
1443
- ? onlyPin.path || `/edges/${authoredEdgeIndex}/${onlyPin.field}`
1444
- : null;
1445
- throwDiagnosticError(message, [{
1446
- code: 'workflow/explicit-pin-conflict',
1447
- severity: 'error',
1448
- message,
1449
- subject: {
1450
- diagramType: 'workflow',
1451
- edge: edge.id ?? null,
1452
- from: edge.from,
1453
- to: edge.to,
1454
- ...(pinPath ? { path: pinPath } : {}),
1455
- },
1456
- evidence: { invariant, ...evidence },
1457
- supportedFixes: supportedFixes.filter(Boolean),
1458
- }]);
1459
- }
1460
-
1461
- function hasAbsoluteRoutePins(edge) {
1462
- return Array.isArray(edge?.via)
1463
- || edge?.channelX !== undefined
1464
- || edge?.channelY !== undefined;
1465
- }
1466
-
1467
- function presentRouteGeometryFields(edge) {
1468
- return [
1469
- ...(Array.isArray(edge?.via) ? ['via'] : []),
1470
- ...(edge?.channelX !== undefined ? ['channelX'] : []),
1471
- ...(edge?.channelY !== undefined ? ['channelY'] : []),
1472
- ];
1473
- }
1474
-
1475
- function verifiedRouteGeometryPinAlternatives(
1476
- edge,
1477
- reason = 'so readable-v2 can replan the remaining explicit route assertions',
1478
- ) {
1479
- const edgeIndex = workflow.edges.indexOf(edge);
1480
- return verifiedPinReferenceAlternatives(
1481
- authoredRouteAssertionFields(edge).map((field) => ({ edge, edgeIndex, field })),
1482
- reason,
1483
- );
1484
- }
1485
-
1486
- function properOrthogonalIntersection(leftStart, leftEnd, rightStart, rightEnd) {
1487
- const leftOrientation = segmentOrientation(leftStart, leftEnd);
1488
- const rightOrientation = segmentOrientation(rightStart, rightEnd);
1489
- if (leftOrientation === rightOrientation
1490
- || leftOrientation === 'diagonal'
1491
- || rightOrientation === 'diagonal') return null;
1492
- const horizontalStart = leftOrientation === 'horizontal' ? leftStart : rightStart;
1493
- const horizontalEnd = leftOrientation === 'horizontal' ? leftEnd : rightEnd;
1494
- const verticalStart = leftOrientation === 'vertical' ? leftStart : rightStart;
1495
- const verticalEnd = leftOrientation === 'vertical' ? leftEnd : rightEnd;
1496
- const point = [verticalStart[0], horizontalStart[1]];
1497
- const epsilon = 0.0001;
1498
- const insideHorizontal = point[0] > Math.min(horizontalStart[0], horizontalEnd[0]) + epsilon
1499
- && point[0] < Math.max(horizontalStart[0], horizontalEnd[0]) - epsilon;
1500
- const insideVertical = point[1] > Math.min(verticalStart[1], verticalEnd[1]) + epsilon
1501
- && point[1] < Math.max(verticalStart[1], verticalEnd[1]) - epsilon;
1502
- return insideHorizontal && insideVertical ? point : null;
1503
- }
1504
-
1505
- function verifiedLabelAtAlternatives(edge) {
1506
- if (!Array.isArray(edge.labelAt)) return [];
1507
- const [x, y] = edge.labelAt;
1508
- return [
1509
- [0, 24], [0, -24], [24, 0], [-24, 0],
1510
- [0, 48], [0, -48], [48, 0], [-48, 0],
1511
- ].map(([dx, dy]) => {
1512
- const next = [x + dx, y + dy];
1513
- return verifiedEdgeFix(
1514
- edge,
1515
- `set labelAt on edge "${workflowEdgeName(edge)}" to [${next[0]}, ${next[1]}]`,
1516
- (candidate) => { candidate.labelAt = next; },
1517
- );
1518
- }).filter(Boolean);
1519
- }
1520
-
1521
- function verifiedLabelAtNudge(edge) {
1522
- const [alternative] = verifiedLabelAtAlternatives(edge);
1523
- if (alternative) return alternative;
1524
- return verifiedEdgeFix(
1525
- edge,
1526
- `remove labelAt from edge "${workflowEdgeName(edge)}" so readable-v2 can use verified automatic label placement`,
1527
- (candidate) => { delete candidate.labelAt; },
1528
- );
1529
- }
1530
-
1531
- function throwReadableLabelRoutePinConflict(hit, routePoints = null) {
1532
- const labelEdge = hit.labelRelation;
1533
- const routeEdge = hit.otherRelation;
1534
- const labelPinned = Array.isArray(labelEdge?.labelAt);
1535
- const routePinned = hasAuthoredRouteAssertions(routeEdge);
1536
- if (!labelPinned && !routePinned) return false;
1537
- const alternatives = verifiedLabelRoutePinAlternatives(labelEdge, routeEdge);
1538
- const actualRoutePoints = routePoints
1539
- || pathCache.get(routeEdge)?.points
1540
- || pathFor(routeEdge).points;
1541
- const diagnosticEdge = alternatives.conflictingRefs[0]?.edge
1542
- || (labelPinned ? labelEdge : routeEdge);
1543
- throwExplicitPinConflict(diagnosticEdge, 'explicit label-route clearance', {
1544
- conflictingPins: alternatives.conflictingPins,
1545
- ...(labelPinned ? { labelAt: [...labelEdge.labelAt] } : {}),
1546
- labelRect: {
1547
- x: hit.rect.x,
1548
- y: hit.rect.y,
1549
- width: hit.rect.width,
1550
- height: hit.rect.height,
1551
- },
1552
- collidedRoute: {
1553
- edge: routeEdge.id || `${routeEdge.from}->${routeEdge.to}`,
1554
- from: routeEdge.from,
1555
- to: routeEdge.to,
1556
- points: actualRoutePoints.map((point) => [...point]),
1557
- },
1558
- routeSegmentIndex: hit.segmentIndex,
1559
- routeSegment: { from: [...hit.start], to: [...hit.end] },
1560
- clearancePx: Math.round(hit.clearance * 10) / 10,
1561
- minimumPx: hit.threshold,
1562
- }, [
1563
- ...verifiedRepairsWithLabelNudges(alternatives),
1564
- ]);
1565
- return true;
1566
- }
1567
-
1568
- function throwReadableLabelLabelPinConflict(left, right) {
1569
- const leftEdge = left.relation;
1570
- const rightEdge = right.relation;
1571
- const pinnedEdges = [leftEdge, rightEdge].filter((edge) => Array.isArray(edge?.labelAt));
1572
- if (!pinnedEdges.length) return false;
1573
- const alternatives = verifiedLabelPairPinAlternatives(leftEdge, rightEdge);
1574
- const causalLabelEdges = [...new Set(alternatives.conflictingRefs.map(({ edge }) => edge))];
1575
- const diagnosticEdge = causalLabelEdges[0] || pinnedEdges[0];
1576
- throwExplicitPinConflict(diagnosticEdge, 'explicit label-label clearance', {
1577
- conflictingPins: alternatives.conflictingPins,
1578
- labelRects: [left, right].map((rect) => ({
1579
- edge: rect.relation.id ?? null,
1580
- x: rect.x,
1581
- y: rect.y,
1582
- width: rect.width,
1583
- height: rect.height,
1584
- })),
1585
- minimumGapPx: -2,
1586
- }, verifiedRepairsWithLabelNudges(alternatives));
1587
- return true;
1588
- }
1589
-
1590
- function classifyFailedAutomaticCandidatePins(edge, rawCandidates) {
1591
- const relationIndex = workflow.edges.indexOf(edge);
1592
- const priorRoutes = [...pathCache.entries()]
1593
- .filter(([otherEdge]) => otherEdge !== edge)
1594
- .map(([relation, routed]) => ({
1595
- relation,
1596
- relationIndex: workflow.edges.indexOf(relation),
1597
- points: routed.points,
1598
- }));
1599
- if (!priorRoutes.length) return;
1600
- const priorLabels = priorRoutes.map(({ relation, relationIndex }) => (
1601
- labelRectFor(relation, relationIndex)
1602
- )).filter(Boolean);
1603
-
1604
- for (const { points } of rawCandidates) {
1605
- const candidateRect = candidateLabelRect(edge, points);
1606
- const candidateLabel = candidateRect
1607
- ? { ...candidateRect, relation: edge, relationIndex, label: edge.label }
1608
- : null;
1609
- if (candidateLabel) {
1610
- const priorLabel = priorLabels.find((otherLabel) => (
1611
- rectsOverlap(candidateLabel, otherLabel, -2)
1612
- && (Array.isArray(edge.labelAt) || Array.isArray(otherLabel.relation?.labelAt))
1613
- ));
1614
- if (priorLabel) throwReadableLabelLabelPinConflict(candidateLabel, priorLabel);
1615
-
1616
- const labelRouteHit = collectLabelRouteClearance({
1617
- labels: [candidateLabel],
1618
- routedRelations: priorRoutes,
1619
- threshold: 4,
1620
- }).find((hit) => (
1621
- Array.isArray(edge.labelAt) || hasAbsoluteRoutePins(hit.otherRelation)
1622
- ));
1623
- if (labelRouteHit) {
1624
- const collidedRoute = priorRoutes.find(({ relation }) => relation === labelRouteHit.otherRelation);
1625
- throwReadableLabelRoutePinConflict(labelRouteHit, collidedRoute?.points);
1626
- }
1627
- }
1628
-
1629
- const reverseHit = collectLabelRouteClearance({
1630
- labels: priorLabels,
1631
- routedRelations: [{ relation: edge, relationIndex, points }],
1632
- threshold: 4,
1633
- }).find((hit) => Array.isArray(hit.labelRelation?.labelAt));
1634
- if (reverseHit) throwReadableLabelRoutePinConflict(reverseHit, points);
1635
- }
1636
- }
1637
-
1638
- function validateReadablePairwisePinConflicts() {
1639
- const labels = workflow.edges.map((edge, relationIndex) => (
1640
- labelRectFor(edge, relationIndex)
1641
- )).filter(Boolean);
1642
- const routedRelations = workflow.edges.map((edge, relationIndex) => (
1643
- nodes.has(edge.from) && nodes.has(edge.to)
1644
- ? { relation: edge, relationIndex, points: pathFor(edge).points }
1645
- : null
1646
- )).filter(Boolean);
1647
-
1648
- const labelRouteHit = collectLabelRouteClearance({
1649
- labels,
1650
- routedRelations,
1651
- threshold: 4,
1652
- }).find((hit) => (
1653
- Array.isArray(hit.labelRelation?.labelAt) || hasAuthoredRouteAssertions(hit.otherRelation)
1654
- ));
1655
- if (labelRouteHit) throwReadableLabelRoutePinConflict(labelRouteHit);
1656
-
1657
- for (let leftIndex = 0; leftIndex < labels.length; leftIndex += 1) {
1658
- for (let rightIndex = leftIndex + 1; rightIndex < labels.length; rightIndex += 1) {
1659
- const left = labels[leftIndex];
1660
- const right = labels[rightIndex];
1661
- if (!rectsOverlap(left, right, -2)) continue;
1662
- throwReadableLabelLabelPinConflict(left, right);
1663
- }
1664
- }
1665
-
1666
- const requestedProfile = workflow.meta?.quality_profile;
1667
- if (requestedProfile !== 'showcase') return;
1668
- for (let leftIndex = 0; leftIndex < routedRelations.length; leftIndex += 1) {
1669
- const left = routedRelations[leftIndex];
1670
- for (let rightIndex = leftIndex + 1; rightIndex < routedRelations.length; rightIndex += 1) {
1671
- const right = routedRelations[rightIndex];
1672
- const leftPinned = hasAuthoredRouteAssertions(left.relation);
1673
- const rightPinned = hasAuthoredRouteAssertions(right.relation);
1674
- if (!leftPinned && !rightPinned) continue;
1675
- if ([left.relation.from, left.relation.to].some((id) => (
1676
- id === right.relation.from || id === right.relation.to
1677
- ))) continue;
1678
- const leftAnalysis = forwardCollinearAnalysisSegments(left.points);
1679
- const rightAnalysis = forwardCollinearAnalysisSegments(right.points);
1680
- for (const leftSegment of leftAnalysis) {
1681
- for (const rightSegment of rightAnalysis) {
1682
- const point = properOrthogonalIntersection(
1683
- leftSegment.start,
1684
- leftSegment.end,
1685
- rightSegment.start,
1686
- rightSegment.end,
1687
- );
1688
- if (!point) continue;
1689
- const leftSourceIndex = sourceSegmentIndexAtPoint(leftSegment, point);
1690
- const rightSourceIndex = sourceSegmentIndexAtPoint(rightSegment, point);
1691
- const leftSource = {
1692
- from: left.points[leftSourceIndex],
1693
- to: left.points[leftSourceIndex + 1],
1694
- };
1695
- const rightSource = {
1696
- from: right.points[rightSourceIndex],
1697
- to: right.points[rightSourceIndex + 1],
1698
- };
1699
- const alternatives = verifiedRoutePairPinAlternatives(
1700
- left.relation,
1701
- right.relation,
1702
- 'so readable-v2 can replan the remaining authored route assertions',
1703
- );
1704
- const diagnosticEdge = leftPinned ? left.relation : right.relation;
1705
- throwExplicitPinConflict(diagnosticEdge, 'explicit route-route crossing', {
1706
- conflictingPins: alternatives.conflictingPins,
1707
- point,
1708
- segmentIndex: leftSourceIndex,
1709
- otherSegmentIndex: rightSourceIndex,
1710
- routeSegments: [
1711
- { edge: left.relation.id ?? null, from: [...leftSegment.start], to: [...leftSegment.end] },
1712
- { edge: right.relation.id ?? null, from: [...rightSegment.start], to: [...rightSegment.end] },
1713
- ],
1714
- sourceRouteSegments: [
1715
- { edge: left.relation.id ?? null, from: [...leftSource.from], to: [...leftSource.to] },
1716
- { edge: right.relation.id ?? null, from: [...rightSource.from], to: [...rightSource.to] },
1717
- ],
1718
- }, alternatives.supportedFixes);
1719
- }
1720
- }
1721
- }
1722
- }
1723
-
1724
- const corridorHit = collectAmbiguousCorridors({
1725
- routedRelations,
1726
- minOverlapPx: 8,
1727
- }).find((hit) => (
1728
- hasAuthoredRouteAssertions(hit.left.relation)
1729
- || hasAuthoredRouteAssertions(hit.right.relation)
1730
- ));
1731
- if (corridorHit) {
1732
- const leftSegment = {
1733
- from: corridorHit.left.points[corridorHit.leftSegment],
1734
- to: corridorHit.left.points[corridorHit.leftSegment + 1],
1735
- };
1736
- const rightSegment = {
1737
- from: corridorHit.right.points[corridorHit.rightSegment],
1738
- to: corridorHit.right.points[corridorHit.rightSegment + 1],
1739
- };
1740
- const leftPinned = hasAuthoredRouteAssertions(corridorHit.left.relation);
1741
- const alternatives = verifiedRoutePairPinAlternatives(
1742
- corridorHit.left.relation,
1743
- corridorHit.right.relation,
1744
- 'so readable-v2 can replan the remaining authored route assertions',
1745
- );
1746
- const diagnosticEdge = leftPinned ? corridorHit.left.relation : corridorHit.right.relation;
1747
- throwExplicitPinConflict(diagnosticEdge, 'explicit route-route corridor clearance', {
1748
- conflictingPins: alternatives.conflictingPins,
1749
- segmentIndex: corridorHit.leftSegment,
1750
- otherSegmentIndex: corridorHit.rightSegment,
1751
- routeSegments: [
1752
- {
1753
- edge: corridorHit.left.relation.id ?? null,
1754
- from: [...leftSegment.from],
1755
- to: [...leftSegment.to],
1756
- },
1757
- {
1758
- edge: corridorHit.right.relation.id ?? null,
1759
- from: [...rightSegment.from],
1760
- to: [...rightSegment.to],
1761
- },
1762
- ],
1763
- overlapStart: [...corridorHit.overlapStart],
1764
- overlapEnd: [...corridorHit.overlapEnd],
1765
- overlapLengthPx: corridorHit.overlapLength,
1766
- minimumClearancePx: 8,
1767
- }, alternatives.supportedFixes);
1768
- }
1769
- }
1770
-
1771
- const READABLE_PRESET_PIN_FIELDS = Object.freeze({
1772
- straight: [],
1773
- drop: ['channelY'],
1774
- 'outside-right': ['channelX'],
1775
- 'return-left': ['channelX'],
1776
- 'bottom-channel': ['channelY'],
1777
- 'up-channel': ['channelY'],
1778
- });
1779
-
1780
- function presentChannelPins(edge) {
1781
- return ['channelX', 'channelY'].filter((field) => edge[field] !== undefined);
1782
- }
1783
-
1784
- function validateReadableRouteControls(edge) {
1785
- const channelPins = presentChannelPins(edge);
1786
- const preset = edge.route || 'auto';
1787
- if (preset === 'auto') return;
1788
- const allowedPins = new Set(READABLE_PRESET_PIN_FIELDS[preset] || []);
1789
- const conflictingPins = channelPins.filter((field) => !allowedPins.has(field));
1790
- if (!conflictingPins.length) return;
1791
- const edgeIndex = workflow.edges.indexOf(edge);
1792
- const alternatives = verifiedPinReferenceAlternatives([
1793
- { edge, edgeIndex, field: 'route' },
1794
- ...conflictingPins.map((field) => ({ edge, edgeIndex, field })),
1795
- ], 'and keep the remaining verified route assertions');
1796
- throwExplicitPinConflict(edge, 'route preset compatibility', {
1797
- route: preset,
1798
- allowedPins: [...allowedPins],
1799
- conflictingPins: alternatives.conflictingPins,
1800
- }, alternatives.supportedFixes);
1801
- }
1802
-
1803
- function segmentOrientation(start, end) {
1804
- if (Math.abs(start[0] - end[0]) <= 0.0001) return 'vertical';
1805
- if (Math.abs(start[1] - end[1]) <= 0.0001) return 'horizontal';
1806
- return 'diagonal';
1807
- }
1808
-
1809
- function routeSegments(points) {
1810
- return points.slice(0, -1).map((start, index) => ({
1811
- start,
1812
- end: points[index + 1],
1813
- orientation: segmentOrientation(start, points[index + 1]),
1814
- }));
1815
- }
1816
-
1817
- function endpointSideIsHonored(points, side, endpoint) {
1818
- if (!side || side === 'auto' || points.length < 2) return true;
1819
- const source = endpoint === 'source';
1820
- const from = source ? points[0] : points.at(-2);
1821
- const to = source ? points[1] : points.at(-1);
1822
- const dx = to[0] - from[0];
1823
- const dy = to[1] - from[1];
1824
- if (source) {
1825
- if (side === 'right') return dx > 0 && Math.abs(dy) <= 0.0001;
1826
- if (side === 'left') return dx < 0 && Math.abs(dy) <= 0.0001;
1827
- if (side === 'bottom') return dy > 0 && Math.abs(dx) <= 0.0001;
1828
- if (side === 'top') return dy < 0 && Math.abs(dx) <= 0.0001;
1829
- return false;
1830
- }
1831
- if (side === 'right') return dx < 0 && Math.abs(dy) <= 0.0001;
1832
- if (side === 'left') return dx > 0 && Math.abs(dy) <= 0.0001;
1833
- if (side === 'bottom') return dy < 0 && Math.abs(dx) <= 0.0001;
1834
- if (side === 'top') return dy > 0 && Math.abs(dx) <= 0.0001;
1835
- return false;
1836
- }
1837
-
1838
- function corridorTopologyMatches(points, axis, coordinate) {
1839
- const collapsed = normalizeRoutePoints(points.map((point) => [...point]));
1840
- const start = collapsed[0];
1841
- const end = collapsed.at(-1);
1842
- const via = axis === 'x'
1843
- ? [[coordinate, start[1]], [coordinate, end[1]]]
1844
- : [[start[0], coordinate], [end[0], coordinate]];
1845
- const expected = normalizeRoutePoints([start, ...via, end]);
1846
- const actualPattern = routeSegments(collapsed).map(({ orientation }) => orientation);
1847
- const expectedPattern = routeSegments(expected).map(({ orientation }) => orientation);
1848
- return actualPattern.length === expectedPattern.length
1849
- && actualPattern.every((orientation, index) => orientation === expectedPattern[index])
1850
- && routeContainsChannelPin(
1851
- collapsed,
1852
- axis === 'x' ? 'channelX' : 'channelY',
1853
- coordinate,
1854
- );
1855
- }
1856
-
1857
- function routeMatchesPresetFamily(preset, points, from, to) {
1858
- const collapsed = normalizeRoutePoints(points.map((point) => [...point]));
1859
- const segments = routeSegments(collapsed);
1860
- if (preset === 'straight') return collapsed.length === 2;
1861
- if (preset === 'drop') {
1862
- if (from.lane === to.lane) return false;
1863
- if (collapsed.length === 2 && segments[0]?.orientation === 'vertical') return true;
1864
- const upper = from.cy <= to.cy ? from : to;
1865
- const lower = upper === from ? to : from;
1866
- return segments.some(({ start, orientation }) => (
1867
- orientation === 'horizontal'
1868
- && start[1] >= upper.y + upper.height - 0.0001
1869
- && start[1] <= lower.y + 0.0001
1870
- && corridorTopologyMatches(points, 'y', start[1])
1871
- ));
1872
- }
1873
- if (preset === 'outside-right' || preset === 'return-left') {
1874
- const boundary = preset === 'outside-right'
1875
- ? Math.max(from.x + from.width, to.x + to.width)
1876
- : Math.min(from.x, to.x);
1877
- return segments.some(({ start, orientation }) => (
1878
- orientation === 'vertical'
1879
- && (preset === 'outside-right'
1880
- ? start[0] > boundary + 0.0001
1881
- : start[0] < boundary - 0.0001)
1882
- && corridorTopologyMatches(points, 'x', start[0])
1883
- ));
1884
- }
1885
- if (preset === 'bottom-channel' || preset === 'up-channel') {
1886
- const boundary = preset === 'bottom-channel'
1887
- ? Math.max(from.y + from.height, to.y + to.height)
1888
- : Math.min(from.y, to.y);
1889
- return segments.some(({ start, orientation }) => (
1890
- orientation === 'horizontal'
1891
- && (preset === 'bottom-channel'
1892
- ? start[1] > boundary + 0.0001
1893
- : start[1] < boundary - 0.0001)
1894
- && corridorTopologyMatches(points, 'y', start[1])
1895
- ));
1896
- }
1897
- return false;
1898
- }
1899
-
1900
- function routeContainsChannelPin(points, field, value) {
1901
- return points.slice(0, -1).some((start, index) => {
1902
- const end = points[index + 1];
1903
- if (field === 'channelX') {
1904
- return start[0] === value
1905
- && end[0] === value
1906
- && Math.abs(end[1] - start[1]) > 0.0001;
1907
- }
1908
- return start[1] === value
1909
- && end[1] === value
1910
- && Math.abs(end[0] - start[0]) > 0.0001;
1911
- });
1912
- }
1913
-
1914
- function validateReadablePinnedGeometry() {
1915
- if (workflow.schema_version !== 2) return;
1916
- for (const edge of workflow.edges) {
1917
- if (!nodes.has(edge.from) || !nodes.has(edge.to)) continue;
1918
- validateReadableRouteControls(edge);
1919
- const edgeName = workflowEdgeName(edge);
1920
- const edgeIndex = sourceIndexes.edges.get(edge);
1921
- if (Array.isArray(edge.labelAt)) {
1922
- const rect = labelRectFor(edge, workflow.edges.indexOf(edge));
1923
- if (rect && (rect.x < 0 || rect.y < 0)) {
1924
- throwExplicitPinConflict(edge, 'viewBox-origin containment', {
1925
- conflictingPins: [{
1926
- edge: edgeName,
1927
- field: 'labelAt',
1928
- path: `/edges/${edgeIndex}/labelAt`,
1929
- value: [...edge.labelAt],
1930
- }],
1931
- offendingRect: { x: rect.x, y: rect.y, width: rect.width, height: rect.height },
1932
- minimumCoordinate: 0,
1933
- }, [verifiedLabelAtNudge(edge)]);
1934
- }
1935
- }
1936
- const negativeViaIndex = asArray(edge.via).findIndex(([x, y]) => x < 0 || y < 0);
1937
- const negativeRoutePin = negativeViaIndex >= 0
1938
- ? {
1939
- field: 'via',
1940
- path: `/edges/${edgeIndex}/via/${negativeViaIndex}`,
1941
- value: [...edge.via[negativeViaIndex]],
1942
- }
1943
- : edge.channelX < 0
1944
- ? { field: 'channelX', path: `/edges/${edgeIndex}/channelX`, value: edge.channelX }
1945
- : edge.channelY < 0
1946
- ? { field: 'channelY', path: `/edges/${edgeIndex}/channelY`, value: edge.channelY }
1947
- : null;
1948
- if (negativeRoutePin) {
1949
- throwExplicitPinConflict(edge, 'viewBox-origin containment', {
1950
- conflictingPins: [{ edge: edgeName, ...negativeRoutePin }],
1951
- minimumCoordinate: 0,
1952
- }, [
1953
- verifiedAutomaticRouteFix(edge),
1954
- verifiedAutomaticRouteFix(edge, { clearSides: true }),
1955
- ]);
1956
- }
1957
- const hasPinnedRoute = Array.isArray(edge.via)
1958
- || edge.channelX !== undefined
1959
- || edge.channelY !== undefined;
1960
- const points = pathFor(edge).points;
1961
- if (hasPinnedRoute) {
1962
- const invalidPointIndex = points.findIndex((point) => (
1963
- !Array.isArray(point) || point.length !== 2 || !isFinitePoint(...point)
1964
- ));
1965
- if (invalidPointIndex !== -1) {
1966
- const alternatives = verifiedRouteGeometryPinAlternatives(edge);
1967
- throwExplicitPinConflict(edge, 'finite route coordinates', {
1968
- conflictingPins: alternatives.conflictingPins,
1969
- pointIndex: invalidPointIndex,
1970
- point: points[invalidPointIndex],
1971
- }, alternatives.supportedFixes);
1972
- }
1973
- for (let segmentIndex = 0; segmentIndex < points.length - 1; segmentIndex += 1) {
1974
- const start = points[segmentIndex];
1975
- const end = points[segmentIndex + 1];
1976
- const dx = Math.abs(end[0] - start[0]);
1977
- const dy = Math.abs(end[1] - start[1]);
1978
- if (dx <= 0.0001 && dy <= 0.0001) {
1979
- const duplicateFix = Array.isArray(edge.via) && edge.via.length
1980
- ? verifiedEdgeFix(
1981
- edge,
1982
- `remove duplicate via[${Math.min(segmentIndex, edge.via.length - 1)}] and keep the remaining authored pins unchanged`,
1983
- (candidate) => candidate.via.splice(Math.min(segmentIndex, candidate.via.length - 1), 1),
1984
- )
1985
- : verifiedAutomaticRouteFix(edge);
1986
- const alternatives = Array.isArray(edge.via)
1987
- ? null
1988
- : verifiedRouteGeometryPinAlternatives(edge);
1989
- throwExplicitPinConflict(edge, 'non-zero route segments', {
1990
- conflictingPins: alternatives?.conflictingPins
1991
- || [authoredPinEvidence(edge, 'via')],
1992
- segmentIndex,
1993
- from: start,
1994
- to: end,
1995
- }, alternatives?.supportedFixes || [duplicateFix]);
1996
- }
1997
- if (dx > 0.0001 && dy > 0.0001) {
1998
- const alternatives = verifiedRouteGeometryPinAlternatives(edge);
1999
- throwExplicitPinConflict(edge, 'orthogonal route segments', {
2000
- conflictingPins: alternatives.conflictingPins,
2001
- segmentIndex,
2002
- from: start,
2003
- to: end,
2004
- }, alternatives.supportedFixes);
2005
- }
2006
- const endpoint = segmentIndex === 0 || segmentIndex === points.length - 2;
2007
- const minimumPx = points.length === 2 ? 28 : endpoint ? 8 : 16;
2008
- const lengthPx = dx + dy;
2009
- if (lengthPx + 0.0001 < minimumPx) {
2010
- const alternatives = verifiedRouteGeometryPinAlternatives(edge);
2011
- throwExplicitPinConflict(edge, endpoint ? '8px endpoint stub clearance' : '16px interior turn clearance', {
2012
- conflictingPins: alternatives.conflictingPins,
2013
- segmentIndex,
2014
- position: segmentIndex === 0 ? 'source-stub' : segmentIndex === points.length - 2 ? 'target-stub' : 'interior',
2015
- from: start,
2016
- to: end,
2017
- lengthPx,
2018
- minimumPx,
2019
- }, alternatives.supportedFixes);
2020
- }
2021
- }
2022
- const { fromSide, toSide } = edgeSides(edge);
2023
- if (Array.isArray(edge.via)) {
2024
- const missingChannelPins = presentChannelPins(edge).filter((field) => (
2025
- !routeContainsChannelPin(points, field, edge[field])
2026
- ));
2027
- if (missingChannelPins.length) {
2028
- const candidateFields = ['via', ...missingChannelPins];
2029
- const alternatives = verifiedPinRemovalAlternatives(
2030
- edge,
2031
- candidateFields,
2032
- 'and replan the remaining explicit route assertions',
2033
- );
2034
- throwExplicitPinConflict(edge, 'channel pin preservation', {
2035
- route: edge.route || 'auto',
2036
- conflictingPins: conflictPinsFromRemovalSets(
2037
- edge,
2038
- alternatives.removalSets,
2039
- candidateFields,
2040
- ),
2041
- points: points.map((point) => [...point]),
2042
- }, alternatives.supportedFixes);
2043
- }
2044
- }
2045
- if (edge.route
2046
- && edge.route !== 'auto'
2047
- && !routeMatchesPresetFamily(
2048
- edge.route,
2049
- points,
2050
- nodes.get(edge.from),
2051
- nodes.get(edge.to),
2052
- )) {
2053
- const authoredEdgeIndex = workflow.edges.indexOf(edge);
2054
- const alternatives = verifiedPinReferenceAlternatives([
2055
- { edge, edgeIndex: authoredEdgeIndex, field: 'route' },
2056
- ...presentRouteGeometryFields(edge)
2057
- .map((field) => ({ edge, edgeIndex: authoredEdgeIndex, field })),
2058
- ], 'and keep the remaining verified route assertions');
2059
- throwExplicitPinConflict(edge, 'route preset compatibility', {
2060
- route: edge.route,
2061
- conflictingPins: alternatives.conflictingPins,
2062
- points: points.map((point) => [...point]),
2063
- }, alternatives.supportedFixes);
2064
- }
2065
- if (!routeHonorsEndpointSides(points, fromSide, toSide)) {
2066
- const mismatchedSideFields = [
2067
- ...(edge.fromSide && edge.fromSide !== 'auto'
2068
- && !endpointSideIsHonored(points, fromSide, 'source') ? ['fromSide'] : []),
2069
- ...(edge.toSide && edge.toSide !== 'auto'
2070
- && !endpointSideIsHonored(points, toSide, 'target') ? ['toSide'] : []),
2071
- ];
2072
- const candidateFields = [
2073
- ...mismatchedSideFields,
2074
- ...presentRouteGeometryFields(edge),
2075
- ];
2076
- const alternatives = verifiedPinRemovalAlternatives(
2077
- edge,
2078
- candidateFields,
2079
- 'and replan the remaining explicit pins',
2080
- );
2081
- throwExplicitPinConflict(edge, 'perpendicular endpoint-side direction', {
2082
- conflictingPins: conflictPinsFromRemovalSets(
2083
- edge,
2084
- alternatives.removalSets,
2085
- candidateFields,
2086
- ),
2087
- points: points.map((point) => [...point]),
2088
- fromSide,
2089
- toSide,
2090
- }, alternatives.supportedFixes);
2091
- }
2092
- const nodeCollision = firstRouteNodeCollision(edge, points);
2093
- if (nodeCollision) {
2094
- const alternatives = verifiedRouteGeometryPinAlternatives(edge);
2095
- throwExplicitPinConflict(edge, 'node clearance', {
2096
- conflictingPins: alternatives.conflictingPins,
2097
- ...nodeCollision,
2098
- }, alternatives.supportedFixes);
2099
- }
2100
- const legendObstacle = workflowLegendRects().find((rect) => points.slice(0, -1).some((point, index) => (
2101
- segmentIntersectsRect({ start: point, end: points[index + 1] }, rect)
2102
- )));
2103
- if (legendObstacle) {
2104
- const alternatives = verifiedRouteGeometryPinAlternatives(edge);
2105
- throwExplicitPinConflict(edge, 'legend clearance', {
2106
- conflictingPins: alternatives.conflictingPins,
2107
- points: points.map((point) => [...point]),
2108
- legendObstacle,
2109
- }, alternatives.supportedFixes);
2110
- }
2111
- const compositionObstacle = workflowSceneLabelObstacles().find((rect) => (
2112
- points.slice(0, -1).some((point, index) => (
2113
- segmentIntersectsRect({ start: point, end: points[index + 1] }, rect)
2114
- ))
2115
- ));
2116
- if (compositionObstacle) {
2117
- const alternatives = verifiedRouteGeometryPinAlternatives(edge);
2118
- throwExplicitPinConflict(edge, 'lane/phase/group label clearance', {
2119
- conflictingPins: alternatives.conflictingPins,
2120
- points: points.map((point) => [...point]),
2121
- compositionObstacle,
2122
- }, alternatives.supportedFixes);
2123
- }
2124
- const [frameRun] = collectBorderRuns({
2125
- routedRelations: [{ points }],
2126
- frames: workflowCompositionFrames(),
2127
- });
2128
- if (frameRun) {
2129
- const alternatives = verifiedRouteGeometryPinAlternatives(edge);
2130
- throwExplicitPinConflict(edge, 'structural-frame border clearance', {
2131
- conflictingPins: alternatives.conflictingPins,
2132
- points: points.map((point) => [...point]),
2133
- frame: frameRun.frame?.id ?? frameRun.frameIndex,
2134
- side: frameRun.side,
2135
- overlapLengthPx: frameRun.overlapLength,
2136
- }, alternatives.supportedFixes);
2137
- }
2138
- }
2139
-
2140
- if (edge.labelAt) {
2141
- const rect = labelRectFor(edge, workflow.edges.indexOf(edge));
2142
- const obstacle = rect && [...nodes.values()].find((node) => rectsOverlap(rect, node, -2));
2143
- if (obstacle) {
2144
- throwExplicitPinConflict(edge, 'edge-label node clearance', {
2145
- conflictingPins: [authoredPinEvidence(edge, 'labelAt')],
2146
- labelAt: [...edge.labelAt],
2147
- labelRect: { x: rect.x, y: rect.y, width: rect.width, height: rect.height },
2148
- obstacleNode: obstacle.id,
2149
- }, [verifiedEdgeFix(
2150
- edge,
2151
- 'remove labelAt so readable-v2 can use its verified automatic label placement',
2152
- (candidate) => { delete candidate.labelAt; },
2153
- )]);
2154
- }
2155
- const legendObstacle = rect && workflowLegendRects().find((legendRect) => (
2156
- rectsOverlap(rect, legendRect)
2157
- ));
2158
- if (legendObstacle) {
2159
- throwExplicitPinConflict(edge, 'edge-label legend clearance', {
2160
- conflictingPins: [authoredPinEvidence(edge, 'labelAt')],
2161
- labelAt: [...edge.labelAt],
2162
- labelRect: { x: rect.x, y: rect.y, width: rect.width, height: rect.height },
2163
- legendObstacle,
2164
- }, [verifiedEdgeFix(
2165
- edge,
2166
- 'remove labelAt so readable-v2 can use its verified automatic label placement',
2167
- (candidate) => { delete candidate.labelAt; },
2168
- )]);
2169
- }
2170
- const compositionObstacle = rect && workflowSceneLabelObstacles().find((candidate) => (
2171
- rectsOverlap(rect, candidate)
2172
- ));
2173
- if (compositionObstacle) {
2174
- throwExplicitPinConflict(edge, 'edge-label lane/phase/group clearance', {
2175
- conflictingPins: [authoredPinEvidence(edge, 'labelAt')],
2176
- labelAt: [...edge.labelAt],
2177
- labelRect: { x: rect.x, y: rect.y, width: rect.width, height: rect.height },
2178
- compositionObstacle,
2179
- }, [verifiedEdgeFix(
2180
- edge,
2181
- `remove labelAt from edge "${workflowEdgeName(edge)}" so readable-v2 can use its verified automatic label placement`,
2182
- (candidate) => { delete candidate.labelAt; },
2183
- )]);
2184
- }
2185
- }
2186
- }
2187
- validateReadablePairwisePinConflicts();
2188
- }
2189
-
2190
- function validateWorkflow() {
2191
- const problems = [];
2192
- if (workflow.schema_version !== 1 && workflow.schema_version !== 2) {
2193
- problems.push('Workflow files must set "schema_version" to 1 or 2.');
2194
- }
2195
- if (workflow.diagram_type !== 'workflow') {
2196
- problems.push(`Unsupported diagram_type "${workflow.diagram_type}". Expected "workflow".`);
2197
- }
2198
- if (!workflow.meta || !workflow.meta.title) {
2199
- problems.push('Workflow files must include meta.title.');
2200
- }
2201
- if (!Array.isArray(workflow.lanes) || !workflow.lanes.length) {
2202
- problems.push('Workflow files must include at least one lane.');
2203
- }
2204
- if (!Array.isArray(workflow.nodes)) {
2205
- problems.push('Workflow files must include a nodes array.');
2206
- }
2207
- if (!Array.isArray(workflow.edges)) {
2208
- problems.push('Workflow files must include an edges array.');
2209
- }
2210
- if (workflow.phases !== undefined && !Array.isArray(workflow.phases)) {
2211
- problems.push('Workflow "phases" must be an array.');
2212
- }
2213
- if (workflow.groups !== undefined && !Array.isArray(workflow.groups)) {
2214
- problems.push('Workflow "groups" must be an array.');
2215
- }
2216
- if (workflow.mainPath !== undefined && !Array.isArray(workflow.mainPath)) {
2217
- problems.push('Workflow "mainPath" must be an array of node ids.');
2218
- }
2219
- if (workflow.cards !== undefined && !Array.isArray(workflow.cards)) {
2220
- problems.push('Workflow "cards" must be an array.');
2221
- }
2222
- if (problems.length) {
2223
- throwDiagnosticProblems('Workflow layout validation failed', problems, {
2224
- subject: { diagramType: 'workflow' },
2225
- });
2226
- }
2227
-
2228
- enforceLegacyColumnCapacity();
2229
-
2230
- const laneIds = new Set(workflow.lanes.map((lane) => lane.id));
2231
- if (laneIds.size !== workflow.lanes.length) {
2232
- problems.push('Lane ids must be unique.');
2233
- }
2234
- if (nodes.size !== workflow.nodes.length) {
2235
- problems.push('Node ids must be unique.');
2236
- }
2237
- const phaseIds = new Set(asArray(workflow.phases).map((phase) => phase.id));
2238
- if (phaseIds.size !== asArray(workflow.phases).length) {
2239
- problems.push('Phase ids must be unique.');
2240
- }
2241
- const groupIds = new Set(asArray(workflow.groups).map((group) => group.id));
2242
- if (groupIds.size !== asArray(workflow.groups).length) {
2243
- problems.push('Group ids must be unique.');
2244
- }
2245
-
2246
- for (const node of nodes.values()) {
2247
- if (!laneIds.has(node.lane)) {
2248
- problems.push(`Node "${node.id}" uses unknown lane "${node.lane}".`);
2249
- continue;
2250
- }
2251
- if (!Number.isInteger(node.col) || node.col < 0 || node.col >= layout.colXs.length) {
2252
- problems.push(`Node "${node.id}" uses column ${node.col}, but valid columns are integers 0..${layout.colXs.length - 1}.`);
2253
- continue;
2254
- }
2255
- if (!isFinitePoint(node.x, node.y, node.cx, node.cy)) {
2256
- problems.push(`Node "${node.id}" produced non-finite coordinates — check col, width, height, and yOffset are numbers.`);
2257
- continue;
2258
- }
2259
- const estLabelW = textUnits(node.label) * 6.8;
2260
- if (estLabelW > node.width + 6) {
2261
- problems.push(`Label "${node.label}" (~${Math.round(estLabelW)}px) is wider than node "${node.id}" (${node.width}px) — shorten the label or increase node.width.`);
2262
- }
2263
- const brandRailProblem = brandTopRailProblem(node, node.width, nodeTextFit.labelMinimum);
2264
- if (brandRailProblem) problems.push(brandRailProblem);
2265
- const availableTextW = availableNodeTextWidth(node.width);
2266
- for (const [field, value, minimum] of [
2267
- ['Sublabel', node.sublabel, nodeTextFit.sublabelMinimum],
2268
- ['Tag', node.tag, nodeTextFit.tagMinimum],
2269
- ]) {
2270
- if (!value) continue;
2271
- const minimumW = minimumNodeTextWidth(value, minimum);
2272
- if (minimumW > availableTextW) {
2273
- problems.push(`${field} "${value}" needs ~${Math.ceil(minimumW)}px at the ${minimum}px legible minimum, but node "${node.id}" provides ${availableTextW}px — shorten the ${field.toLowerCase()} or increase node.width.`);
2274
- }
2275
- }
2276
-
2277
- const top = laneTop(node.lane);
2278
- const contentTop = top + layout.laneTitleH + laneGroupHeaderH(node.lane);
2279
- const laneRight = layout.laneX + layout.laneW;
2280
- if (node.x < layout.laneX || node.x + node.width > laneRight) {
2281
- problems.push(`Node "${node.id}" exceeds the horizontal bounds of lane "${node.lane}".`);
2282
- }
2283
- if (node.y < contentTop || node.y + node.height > top + laneHeight(node.lane)) {
2284
- problems.push(`Node "${node.id}" collides with the title or boundary of lane "${node.lane}".`);
2285
- }
2286
- }
2287
-
2288
- const phaseRanges = [];
2289
- for (const phase of asArray(workflow.phases)) {
2290
- if (!Number.isInteger(phase.fromCol) || !Number.isInteger(phase.toCol)) {
2291
- problems.push(`Phase "${phase.id}" must use integer fromCol/toCol values.`);
2292
- continue;
2293
- }
2294
- if (phase.fromCol < 0 || phase.toCol >= layout.colXs.length || phase.fromCol > phase.toCol) {
2295
- problems.push(`Phase "${phase.id}" uses invalid columns ${phase.fromCol}..${phase.toCol}; use an ordered range within 0..${layout.colXs.length - 1}.`);
2296
- } else {
2297
- phaseRanges.push(phase);
2298
- }
2299
- const estLabelW = textUnits(phase.label) * 5.6;
2300
- const width = phaseSpan(phase).width;
2301
- if (estLabelW > width + 8) {
2302
- problems.push(`Phase label "${phase.label}" (~${Math.round(estLabelW)}px) is wider than its ${Math.round(width)}px span — shorten the label or widen the phase range.`);
2303
- }
2304
- }
2305
- phaseRanges.sort((a, b) => a.fromCol - b.fromCol || a.toCol - b.toCol);
2306
- for (let i = 0; i < phaseRanges.length; i += 1) {
2307
- for (let j = i + 1; j < phaseRanges.length; j += 1) {
2308
- const earlier = phaseRanges[i];
2309
- const later = phaseRanges[j];
2310
- if (later.fromCol > earlier.toCol) break;
2311
- problems.push(`Phase "${later.id}" (${later.fromCol}..${later.toCol}) overlaps phase "${earlier.id}" (${earlier.fromCol}..${earlier.toCol}) — start at col ${earlier.toCol + 1} or later, or end the earlier phase at col ${later.fromCol - 1}.`);
2312
- }
2313
- }
2314
-
2315
- for (const group of asArray(workflow.groups)) {
2316
- if (!laneIds.has(group.lane)) {
2317
- problems.push(`Group "${group.id}" uses unknown lane "${group.lane}".`);
2318
- continue;
2319
- }
2320
- if (!Number.isInteger(group.fromCol) || !Number.isInteger(group.toCol)) {
2321
- problems.push(`Group "${group.id}" must use integer fromCol/toCol values.`);
2322
- continue;
2323
- }
2324
- if (group.fromCol < 0 || group.toCol >= layout.colXs.length || group.fromCol > group.toCol) {
2325
- problems.push(`Group "${group.id}" uses invalid columns ${group.fromCol}..${group.toCol}; use an ordered range within 0..${layout.colXs.length - 1}.`);
2326
- }
2327
- const contained = [...nodes.values()].some((node) => node.lane === group.lane && node.col >= group.fromCol && node.col <= group.toCol);
2328
- if (!contained) {
2329
- problems.push(`Group "${group.id}" does not contain any nodes — align its lane/columns with the parallel or branch work it frames.`);
2330
- }
2331
- }
2332
-
2333
- const byLane = new Map();
2334
- for (const node of nodes.values()) {
2335
- byLane.set(node.lane, [...(byLane.get(node.lane) || []), node]);
2336
- }
2337
- for (const [lane, laneNodes] of byLane) {
2338
- for (let i = 0; i < laneNodes.length; i += 1) {
2339
- for (let j = i + 1; j < laneNodes.length; j += 1) {
2340
- if (rectsOverlap(laneNodes[i], laneNodes[j], 8)) {
2341
- problems.push(`Nodes "${laneNodes[i].id}" and "${laneNodes[j].id}" are less than 8px apart in lane "${lane}" — move one to another col, adjust yOffset, or reduce width/height.`);
2342
- }
2343
- }
2344
- }
2345
- }
2346
-
2347
- for (const edge of workflow.edges) {
2348
- if (!nodes.has(edge.from)) problems.push(`Edge "${edge.label || edge.from}" references unknown source "${edge.from}".`);
2349
- if (!nodes.has(edge.to)) problems.push(`Edge "${edge.label || edge.to}" references unknown target "${edge.to}".`);
2350
- if (nodes.has(edge.from) && nodes.has(edge.to)) {
2351
- const routed = pathFor(edge);
2352
- if (routed.points.length === 2) {
2353
- const [start, end] = routed.points;
2354
- const segmentLength = Math.hypot(end[0] - start[0], end[1] - start[1]);
2355
- if (segmentLength < 28) {
2356
- problems.push(`Edge "${edge.from}" -> "${edge.to}" is too short (${Math.round(segmentLength)}px; minimum 28px) — move the nodes farther apart or use a verified orthogonal route with readable clearance.`);
2357
- }
2358
- }
2359
- }
2360
- }
2361
-
2362
- problems.push(...cleanEndpointSideProblems({
2363
- relations: workflow.edges,
2364
- endpointIds: new Set(nodes.keys()),
2365
- pathFor,
2366
- diagramType: 'workflow',
2367
- relationCollection: 'edges',
2368
- fromSideFor: (edge) => edgeSides(edge).fromSide,
2369
- toSideFor: (edge) => edgeSides(edge).toSide,
2370
- routeHint: 'keep automatic routing, or choose fromSide/toSide and via points whose first and final segments cross node borders perpendicularly',
2371
- }));
2372
- problems.push(...cleanFlowProblems({
2373
- relations: workflow.edges,
2374
- obstacles: nodes.values(),
2375
- pathFor,
2376
- diagramType: 'workflow',
2377
- relationCollection: 'edges',
2378
- obstacleKind: 'node',
2379
- routeHint: 'adjust fromSide/toSide, set route/via or channel coordinates, or move the node to a clearer lane/column'
2380
- }));
2381
- problems.push(...cleanCrossingProblems({
2382
- relations: workflow.edges,
2383
- endpointIds: new Set(nodes.keys()),
2384
- pathFor,
2385
- diagramType: 'workflow',
2386
- relationCollection: 'edges',
2387
- profile: workflow.meta?.quality_profile,
2388
- profileIsAuthoritative: true,
2389
- mergeForwardCollinearWaypoints: workflow.schema_version === 2,
2390
- routeHint: 'adjust route/via, bias, or channel coordinates so the edges use separate lane corridors'
2391
- }));
2392
- problems.push(...cleanAmbiguousCorridorProblems({
2393
- relations: workflow.edges,
2394
- endpointIds: new Set(nodes.keys()),
2395
- pathFor,
2396
- diagramType: 'workflow',
2397
- relationCollection: 'edges',
2398
- profile: workflow.meta?.quality_profile,
2399
- profileIsAuthoritative: true,
2400
- routeHint: 'adjust route/via, bias, or channel coordinates so unrelated edges do not visually merge'
2401
- }));
2402
- problems.push(...cleanBorderRunProblems({
2403
- relations: workflow.edges,
2404
- endpointIds: new Set(nodes.keys()),
2405
- frames: workflowCompositionFrames(),
2406
- pathFor,
2407
- diagramType: 'workflow',
2408
- relationCollection: 'edges',
2409
- profile: workflow.meta?.quality_profile,
2410
- profileIsAuthoritative: true,
2411
- routeHint: 'adjust route/via, bias, or channel coordinates so the edge crosses the lane or group perpendicularly instead of following its border'
2412
- }));
2413
- problems.push(...cleanRouteRhythmProblems({
2414
- relations: workflow.edges,
2415
- endpointIds: new Set(nodes.keys()),
2416
- pathFor,
2417
- diagramType: 'workflow',
2418
- relationCollection: 'edges',
2419
- profile: workflow.meta?.quality_profile,
2420
- profileIsAuthoritative: true,
2421
- routeHint: 'adjust route/via, bias, or channel coordinates so each turn has a readable run-up'
2422
- }));
2423
-
2424
- if (Array.isArray(workflow.mainPath)) {
2425
- for (const id of workflow.mainPath) {
2426
- if (!nodes.has(id)) {
2427
- problems.push(`mainPath references unknown node "${id}".`);
2428
- }
2429
- }
2430
- for (let i = 0; i < workflow.mainPath.length - 1; i += 1) {
2431
- const fromId = workflow.mainPath[i];
2432
- const toId = workflow.mainPath[i + 1];
2433
- const from = nodes.get(fromId);
2434
- const to = nodes.get(toId);
2435
- if (!from || !to) continue;
2436
- const linked = workflow.edges.some((edge) => edge.from === fromId && edge.to === toId);
2437
- if (!linked) {
2438
- problems.push(`mainPath step "${fromId}" -> "${toId}" has no matching edge — add the edge or remove the pair from mainPath.`);
2439
- }
2440
- if (to.col < from.col) {
2441
- problems.push(`mainPath step "${fromId}" -> "${toId}" moves backward from col ${from.col} to ${to.col} — use a return edge outside mainPath for loops.`);
2442
- }
2443
- }
2444
- }
2445
-
2446
- const labelRects = [];
2447
- for (const [edgeIndex, edge] of workflow.edges.entries()) {
2448
- const labelRect = labelRectFor(edge, edgeIndex);
2449
- if (labelRect) labelRects.push(labelRect);
2450
- }
2451
- for (const rect of labelRects) {
2452
- for (const node of nodes.values()) {
2453
- if (rectsOverlap(rect, node, -2)) {
2454
- problems.push(`Label "${rect.label}" overlaps node "${node.id}" — adjust labelDx/labelDy/labelSegment or set labelAt.\n${suggestLabelObstacleFix(rect, rect.lx, rect.ly, node, 'node')}`);
2455
- }
2456
- }
2457
- }
2458
- for (let i = 0; i < labelRects.length; i += 1) {
2459
- for (let j = i + 1; j < labelRects.length; j += 1) {
2460
- if (rectsOverlap(labelRects[i], labelRects[j], -2)) {
2461
- problems.push(`Labels "${labelRects[i].label}" and "${labelRects[j].label}" overlap — adjust labelDx/labelDy/labelSegment or route one relationship through a separate corridor.\n${suggestLabelPairFix(labelRects[i], labelRects[j])}`);
2462
- }
2463
- }
2464
- }
2465
- problems.push(...cleanLabelRouteClearanceProblems({
2466
- relations: workflow.edges,
2467
- labels: labelRects,
2468
- endpointIds: new Set(nodes.keys()),
2469
- pathFor,
2470
- diagramType: 'workflow',
2471
- relationCollection: 'edges',
2472
- profile: workflow.meta?.quality_profile,
2473
- profileIsAuthoritative: true,
2474
- }));
2475
-
2476
- if (workflow.schema_version === 1) {
2477
- if (viewBox[0] < layout.laneX + layout.laneW + 16) {
2478
- problems.push(`viewBox width ${viewBox[0]} clips the ${layout.laneW}px lanes — set meta.viewBox[0] to at least ${layout.laneX + layout.laneW + 16}.`);
2479
- }
2480
- if (legendY() + 18 > viewBox[1]) {
2481
- problems.push(`Legend exceeds viewBox height ${viewBox[1]} — set meta.viewBox[1] to at least ${legendY() + 18}.`);
2482
- }
2483
- }
2484
-
2485
- if (problems.length) {
2486
- throwDiagnosticProblems('Workflow layout validation failed', problems, {
2487
- subject: { diagramType: 'workflow' },
2488
- });
2489
- }
2490
- }
2491
-
2492
- function validateReadableInputsBeforeRouting() {
2493
- if (workflow.schema_version !== 2) return;
2494
- const fail = (diagnostic) => throwDiagnosticError(diagnostic.message, [diagnostic]);
2495
- const unusedId = (base, used) => {
2496
- for (let suffix = 2; ; suffix += 1) {
2497
- const candidate = `${base}-${suffix}`;
2498
- if (!used.has(candidate)) return candidate;
2499
- }
2500
- };
2501
- const authoredLanes = [...workflow.lanes].sort((left, right) => (
2502
- sourceIndexes.lanes.get(left) - sourceIndexes.lanes.get(right)
2503
- ));
2504
- const authoredNodes = [...workflow.nodes].sort((left, right) => (
2505
- sourceIndexes.nodes.get(left) - sourceIndexes.nodes.get(right)
2506
- ));
2507
- const authoredEdges = [...workflow.edges].sort((left, right) => (
2508
- sourceIndexes.edges.get(left) - sourceIndexes.edges.get(right)
2509
- ));
2510
-
2511
- const firstLaneIndex = new Map();
2512
- for (const lane of authoredLanes) {
2513
- const laneIndex = sourceIndexes.lanes.get(lane);
2514
- if (firstLaneIndex.has(lane.id)) {
2515
- const message = `Workflow lane id "${lane.id}" is duplicated.`;
2516
- const replacement = unusedId(lane.id, new Set(workflow.lanes.map(({ id }) => id)));
2517
- const canonicalLaneIndex = workflow.lanes.indexOf(lane);
2518
- const supportedFixes = acceptsFix((document) => {
2519
- document.lanes[canonicalLaneIndex].id = replacement;
2520
- }) ? [`rename /lanes/${laneIndex}/id to verified unique id "${replacement}"`] : [];
2521
- fail({
2522
- code: 'workflow/duplicate-lane-id',
2523
- severity: 'error',
2524
- message,
2525
- subject: { diagramType: 'workflow', lane: lane.id, path: `/lanes/${laneIndex}/id` },
2526
- evidence: {
2527
- duplicateLaneId: lane.id,
2528
- firstPath: `/lanes/${firstLaneIndex.get(lane.id)}/id`,
2529
- duplicatePath: `/lanes/${laneIndex}/id`,
2530
- },
2531
- supportedFixes,
2532
- });
2533
- }
2534
- firstLaneIndex.set(lane.id, laneIndex);
2535
- }
2536
-
2537
- const firstNodeIndex = new Map();
2538
- for (const node of authoredNodes) {
2539
- const nodeIndex = sourceIndexes.nodes.get(node);
2540
- if (firstNodeIndex.has(node.id)) {
2541
- const message = `Workflow node id "${node.id}" is duplicated.`;
2542
- const replacement = unusedId(node.id, new Set(workflow.nodes.map(({ id }) => id)));
2543
- const canonicalNodeIndex = workflow.nodes.indexOf(node);
2544
- const supportedFixes = acceptsFix((document) => {
2545
- document.nodes[canonicalNodeIndex].id = replacement;
2546
- }) ? [`rename /nodes/${nodeIndex}/id to verified unique id "${replacement}"`] : [];
2547
- fail({
2548
- code: 'workflow/duplicate-node-id',
2549
- severity: 'error',
2550
- message,
2551
- subject: { diagramType: 'workflow', node: node.id, path: `/nodes/${nodeIndex}/id` },
2552
- evidence: {
2553
- duplicateNodeId: node.id,
2554
- firstPath: `/nodes/${firstNodeIndex.get(node.id)}/id`,
2555
- duplicatePath: `/nodes/${nodeIndex}/id`,
2556
- },
2557
- supportedFixes,
2558
- });
2559
- }
2560
- firstNodeIndex.set(node.id, nodeIndex);
2561
- }
2562
-
2563
- const availableNodeIds = [...nodes.keys()].sort(stableCompare);
2564
- for (const edge of authoredEdges) {
2565
- const edgeIndex = sourceIndexes.edges.get(edge);
2566
- for (const [field, endpoint] of [['from', 'source'], ['to', 'target']]) {
2567
- if (nodes.has(edge[field])) continue;
2568
- const message = `Workflow edge "${workflowEdgeName(edge)}" references unknown ${endpoint} "${edge[field]}".`;
2569
- const canonicalEdgeIndex = workflow.edges.indexOf(edge);
2570
- const supportedFixes = availableNodeIds.flatMap((nodeId) => (
2571
- acceptsFix((document) => {
2572
- document.edges[canonicalEdgeIndex][field] = nodeId;
2573
- })
2574
- ? [`set /edges/${edgeIndex}/${field} to verified node id "${nodeId}"`]
2575
- : []
2576
- ));
2577
- fail({
2578
- code: 'workflow/unknown-edge-endpoint',
2579
- severity: 'error',
2580
- message,
2581
- subject: {
2582
- diagramType: 'workflow',
2583
- edge: edge.id ?? null,
2584
- path: `/edges/${edgeIndex}/${field}`,
2585
- from: edge.from,
2586
- to: edge.to,
2587
- },
2588
- evidence: {
2589
- endpoint,
2590
- unknownNodeId: edge[field],
2591
- availableNodeIds,
2592
- },
2593
- supportedFixes,
2594
- });
2595
- }
2596
- }
2597
- const laneIds = new Set(workflow.lanes.map((lane) => lane.id));
2598
- const availableLaneIds = [...laneIds].sort(stableCompare);
2599
- const nodeSourceIndexes = new Map(authoredNodes.map((node) => [
2600
- node.id,
2601
- sourceIndexes.nodes.get(node),
2602
- ]));
2603
-
2604
- const byLane = new Map();
2605
- for (const authoredNode of authoredNodes) {
2606
- const nodeIndex = sourceIndexes.nodes.get(authoredNode);
2607
- const node = nodes.get(authoredNode.id);
2608
- if (!laneIds.has(node.lane)) {
2609
- const message = `Workflow node "${node.id}" uses unknown lane "${node.lane}".`;
2610
- const canonicalNodeIndex = workflow.nodes.findIndex((candidate) => candidate.id === node.id);
2611
- const supportedFixes = availableLaneIds.flatMap((laneId) => (
2612
- acceptsFix((document) => {
2613
- document.nodes[canonicalNodeIndex].lane = laneId;
2614
- })
2615
- ? [`set /nodes/${nodeIndex}/lane to verified lane id "${laneId}"`]
2616
- : []
2617
- ));
2618
- fail({
2619
- code: 'workflow/unknown-node-lane',
2620
- severity: 'error',
2621
- message,
2622
- subject: { diagramType: 'workflow', node: node.id, path: `/nodes/${nodeIndex}/lane` },
2623
- evidence: { unknownLaneId: node.lane, availableLaneIds },
2624
- supportedFixes,
2625
- });
2626
- }
2627
- if (!Number.isInteger(node.col) || node.col < 0 || node.col >= layout.colXs.length) {
2628
- const message = `Workflow node "${node.id}" uses column ${node.col}, but valid columns are integers 0..${layout.colXs.length - 1}.`;
2629
- const canonicalNodeIndex = workflow.nodes.findIndex((candidate) => candidate.id === node.id);
2630
- const supportedFixes = layout.colXs.flatMap((_x, col) => (
2631
- acceptsFix((document) => {
2632
- document.nodes[canonicalNodeIndex].col = col;
2633
- })
2634
- ? [`set /nodes/${nodeIndex}/col to verified column ${col}`]
2635
- : []
2636
- ));
2637
- fail({
2638
- code: 'workflow/invalid-node-column',
2639
- severity: 'error',
2640
- message,
2641
- subject: { diagramType: 'workflow', node: node.id, path: `/nodes/${nodeIndex}/col` },
2642
- evidence: { actualColumn: node.col, minimumColumn: 0, maximumColumn: layout.colXs.length - 1 },
2643
- supportedFixes,
2644
- });
2645
- }
2646
- if (!isFinitePoint(node.x, node.y, node.cx, node.cy)) {
2647
- const message = `Workflow node "${node.id}" produced non-finite coordinates.`;
2648
- fail({
2649
- code: 'workflow/non-finite-node-geometry',
2650
- severity: 'error',
2651
- message,
2652
- subject: { diagramType: 'workflow', node: node.id, path: `/nodes/${nodeIndex}` },
2653
- evidence: {
2654
- measuredRect: { x: node.x, y: node.y, width: node.width, height: node.height },
2655
- authored: {
2656
- col: authoredNode.col,
2657
- width: authoredNode.width ?? null,
2658
- height: authoredNode.height ?? null,
2659
- yOffset: authoredNode.yOffset ?? null,
2660
- },
2661
- },
2662
- supportedFixes: [],
2663
- });
2664
- }
2665
- byLane.set(node.lane, [...(byLane.get(node.lane) || []), node]);
2666
- }
2667
- for (const [lane, laneNodes] of byLane) {
2668
- for (let left = 0; left < laneNodes.length; left += 1) {
2669
- for (let right = left + 1; right < laneNodes.length; right += 1) {
2670
- if (rectsOverlap(laneNodes[left], laneNodes[right], 8)) {
2671
- const leftNode = laneNodes[left];
2672
- const rightNode = laneNodes[right];
2673
- const rightIndex = nodeSourceIndexes.get(rightNode.id);
2674
- const canonicalNodeIndex = workflow.nodes.findIndex((candidate) => (
2675
- candidate.id === rightNode.id
2676
- ));
2677
- const supportedFixes = layout.colXs.flatMap((_x, col) => {
2678
- if (col === rightNode.col) return [];
2679
- return acceptsFix((document) => {
2680
- document.nodes[canonicalNodeIndex].col = col;
2681
- })
2682
- ? [`set /nodes/${rightIndex}/col to verified free column ${col}`]
2683
- : [];
2684
- });
2685
- const message = `Workflow nodes "${leftNode.id}" and "${rightNode.id}" are less than 8px apart in lane "${lane}".`;
2686
- fail({
2687
- code: 'workflow/node-overlap',
2688
- severity: 'error',
2689
- message,
2690
- subject: { diagramType: 'workflow', node: rightNode.id, path: `/nodes/${rightIndex}` },
2691
- evidence: {
2692
- lane,
2693
- minimumClearancePx: 8,
2694
- nodes: [
2695
- { id: leftNode.id, rect: { x: leftNode.x, y: leftNode.y, width: leftNode.width, height: leftNode.height } },
2696
- { id: rightNode.id, rect: { x: rightNode.x, y: rightNode.y, width: rightNode.width, height: rightNode.height } },
2697
- ],
2698
- },
2699
- supportedFixes,
2700
- });
2701
- }
2702
- }
2703
- }
2704
- }
2705
- }
2706
-
2707
- function gapYBetween(fromLane, toLane, bias = 0.5) {
2708
- const a = laneTop(fromLane) + laneHeight(fromLane);
2709
- const b = laneTop(toLane);
2710
- return a + (b - a) * bias;
2711
- }
2712
-
2713
- function spanForCols(fromCol, toCol, pad = 46, minimumWidth = 0) {
2714
- const start = layout.colXs[fromCol] - pad;
2715
- const end = layout.colXs[toCol] + pad;
2716
- const width = Math.max(end - start, minimumWidth);
2717
- if (fromCol === toCol && width > end - start) {
2718
- return { x: start, width, cx: start + width / 2 };
2719
- }
2720
- const cx = (start + end) / 2;
2721
- return { x: cx - width / 2, width, cx };
2722
- }
2723
-
2724
- function phaseSpan(phase) {
2725
- return spanForCols(
2726
- phase.fromCol,
2727
- phase.toCol,
2728
- 46,
2729
- workflow.schema_version === 2 ? textUnits(phase.label) * 5.6 + 8 : 0,
2730
- );
2731
- }
2732
-
2733
- function groupSpan(group) {
2734
- if (workflow.schema_version === 2) {
2735
- return readableGroupBounds(workflow, group, layout.colXs);
2736
- }
2737
- return spanForCols(
2738
- group.fromCol,
2739
- group.toCol,
2740
- 50,
2741
- 0,
2742
- );
2743
- }
2744
-
2745
- function sameLaneAutoVia(start, end) {
2746
- if (start[0] === end[0] || start[1] === end[1]) return [];
2747
- const midX = (start[0] + end[0]) / 2;
2748
- return [[midX, start[1]], [midX, end[1]]];
2749
- }
2750
-
2751
- function routeClearsUnrelatedNodes(edge, points, clearance = 2) {
2752
- const endpointIds = new Set([edge.from, edge.to]);
2753
- for (const node of nodes.values()) {
2754
- if (endpointIds.has(node.id)) continue;
2755
- for (let index = 0; index < points.length - 1; index += 1) {
2756
- if (segmentIntersectsRect({ start: points[index], end: points[index + 1] }, node, clearance)) {
2757
- return false;
2758
- }
2759
- }
2760
- }
2761
- return true;
2762
- }
2763
-
2764
- function firstRouteNodeCollision(edge, points) {
2765
- const lastSegment = points.length - 2;
2766
- for (const node of nodes.values()) {
2767
- const endpointRole = node.id === edge.from
2768
- ? 'source-endpoint'
2769
- : node.id === edge.to ? 'target-endpoint' : 'unrelated';
2770
- for (let segmentIndex = 0; segmentIndex <= lastSegment; segmentIndex += 1) {
2771
- if (endpointRole === 'source-endpoint' && segmentIndex === 0) continue;
2772
- if (endpointRole === 'target-endpoint' && segmentIndex === lastSegment) continue;
2773
- const clearancePx = endpointRole === 'unrelated' ? 2 : 0;
2774
- const from = points[segmentIndex];
2775
- const to = points[segmentIndex + 1];
2776
- if (segmentIntersectsRect({ start: from, end: to }, node, clearancePx)) {
2777
- return {
2778
- obstacleNode: node.id,
2779
- obstacleRole: endpointRole,
2780
- segmentIndex,
2781
- from: [...from],
2782
- to: [...to],
2783
- clearancePx,
2784
- };
2785
- }
2786
- }
2787
- }
2788
- return null;
2789
- }
2790
-
2791
- function oneBendCrossLaneVia(edge, start, end, fromSide, toSide) {
2792
- const fromVertical = fromSide === 'top' || fromSide === 'bottom';
2793
- const toVertical = toSide === 'top' || toSide === 'bottom';
2794
- if (fromVertical === toVertical) return null;
2795
-
2796
- const corner = fromVertical ? [start[0], end[1]] : [end[0], start[1]];
2797
- const points = normalizeRoutePoints([start, corner, end]);
2798
- if (points.length !== 3 || !routeHonorsEndpointSides(points, fromSide, toSide)) return null;
2799
-
2800
- const segmentsAreReadable = points.slice(0, -1).every((point, index) => (
2801
- Math.hypot(
2802
- points[index + 1][0] - point[0],
2803
- points[index + 1][1] - point[1],
2804
- ) >= 8
2805
- ));
2806
- if (!segmentsAreReadable || !routeClearsUnrelatedNodes(edge, points)) return null;
2807
- return points.slice(1, -1);
2808
- }
2809
-
2810
- const pathCache = new Map();
2811
- const readableSideCache = new Map();
2812
-
2813
- function legacyAutomaticOneBendSides(edge, from, to) {
2814
- const automaticRoute = !edge.via && (!edge.route || edge.route === 'auto');
2815
- const automaticFrom = !edge.fromSide || edge.fromSide === 'auto';
2816
- const automaticTo = !edge.toSide || edge.toSide === 'auto';
2817
- if (!automaticRoute || !automaticFrom || !automaticTo || from.lane === to.lane) return null;
2818
- if (from.cx === to.cx || from.cy === to.cy) return null;
2819
- const verticalFrom = to.cy < from.cy ? 'top' : 'bottom';
2820
- const horizontalTo = to.cx < from.cx ? 'right' : 'left';
2821
- const horizontalFrom = to.cx < from.cx ? 'left' : 'right';
2822
- const verticalTo = to.cy < from.cy ? 'bottom' : 'top';
2823
- const candidates = [
2824
- { fromSide: verticalFrom, toSide: horizontalTo },
2825
- { fromSide: horizontalFrom, toSide: verticalTo },
2826
- ];
2827
-
2828
- return candidates.find(({ fromSide, toSide }) => {
2829
- const start = anchor(from, fromSide);
2830
- const end = anchor(to, toSide);
2831
- return oneBendCrossLaneVia(edge, start, end, fromSide, toSide);
2832
- }) || null;
2833
- }
2834
-
2835
- function readableAutomaticSides(edge, from, to) {
2836
- const automaticRoute = !edge.via
2837
- && edge.channelX === undefined
2838
- && edge.channelY === undefined
2839
- && (!edge.route || edge.route === 'auto');
2840
- const authoredFrom = edge.fromSide && edge.fromSide !== 'auto' ? edge.fromSide : null;
2841
- const authoredTo = edge.toSide && edge.toSide !== 'auto' ? edge.toSide : null;
2842
- if (!automaticRoute || (authoredFrom && authoredTo)) return null;
2843
- if (readableSideCache.has(edge)) return readableSideCache.get(edge);
2844
-
2845
- const preferred = [];
2846
- const legacyPreferred = legacyAutomaticOneBendSides(edge, from, to);
2847
- if (legacyPreferred) preferred.push(legacyPreferred);
2848
- preferred.push({
2849
- fromSide: authoredFrom || defaultFromSide(from, to),
2850
- toSide: authoredTo || defaultToSide(from, to),
2851
- });
2852
- const sideOrder = ['right', 'bottom', 'left', 'top'];
2853
- for (const fromSide of authoredFrom ? [authoredFrom] : sideOrder) {
2854
- for (const toSide of authoredTo ? [authoredTo] : sideOrder) {
2855
- preferred.push({ fromSide, toSide });
2856
- }
2857
- }
2858
-
2859
- const seen = new Set();
2860
- const sidePairs = [];
2861
- for (const candidate of preferred) {
2862
- if (authoredFrom && candidate.fromSide !== authoredFrom) continue;
2863
- if (authoredTo && candidate.toSide !== authoredTo) continue;
2864
- const key = `${candidate.fromSide}:${candidate.toSide}`;
2865
- if (seen.has(key)) continue;
2866
- seen.add(key);
2867
- sidePairs.push(candidate);
2868
- }
2869
-
2870
- const naturalFromSide = authoredFrom || defaultFromSide(from, to);
2871
- const naturalToSide = authoredTo || defaultToSide(from, to);
2872
- const planFor = (candidate, pairOrdinal) => {
2873
- const start = anchor(from, candidate.fromSide);
2874
- const end = anchor(to, candidate.toSide);
2875
- return {
2876
- start,
2877
- end,
2878
- planned: readableAutomaticCandidateSet(
2879
- edge,
2880
- from,
2881
- to,
2882
- start,
2883
- end,
2884
- candidate.fromSide,
2885
- candidate.toSide,
2886
- {
2887
- ordinalOffset: pairOrdinal * 9,
2888
- naturalFromSide,
2889
- naturalToSide,
2890
- },
2891
- ),
2892
- };
2893
- };
2894
-
2895
- const primary = sidePairs[0];
2896
- if (primary) {
2897
- const { planned } = planFor(primary, 0);
2898
- if (planned.candidates.length) {
2899
- readableSideCache.set(edge, primary);
2900
- return primary;
2901
- }
2902
- }
2903
-
2904
- const candidates = [];
2905
- for (const [pairOrdinal, candidate] of sidePairs.entries()) {
2906
- const { planned } = planFor(candidate, pairOrdinal);
2907
- candidates.push(...planned.candidates.map((route) => ({ ...route, ...candidate })));
2908
- }
2909
- candidates.sort((left, right) => compareCost(left.cost, right.cost));
2910
- if (candidates.length) {
2911
- const selected = {
2912
- fromSide: candidates[0].fromSide,
2913
- toSide: candidates[0].toSide,
2914
- };
2915
- readableSideCache.set(edge, selected);
2916
- return selected;
2917
- }
2918
- readableSideCache.set(edge, null);
2919
- return null;
2920
- }
2921
-
2922
- function automaticOneBendSides(edge, from, to) {
2923
- return workflow.schema_version === 2
2924
- ? readableAutomaticSides(edge, from, to)
2925
- : legacyAutomaticOneBendSides(edge, from, to);
2926
- }
2927
-
2928
- const OUTWARD_SIDE_VECTOR = Object.freeze({
2929
- left: [-1, 0],
2930
- right: [1, 0],
2931
- top: [0, -1],
2932
- bottom: [0, 1],
2933
- });
2934
-
2935
- function outwardStub(point, side, distance = 16) {
2936
- const [dx, dy] = OUTWARD_SIDE_VECTOR[side] || [0, 0];
2937
- return [point[0] + dx * distance, point[1] + dy * distance];
2938
- }
2939
-
2940
- function orthogonalRoute(points) {
2941
- return points.every((point, index) => {
2942
- if (!Array.isArray(point) || point.length !== 2 || !isFinitePoint(...point)) return false;
2943
- if (index === 0) return true;
2944
- const previous = points[index - 1];
2945
- const dx = Math.abs(point[0] - previous[0]);
2946
- const dy = Math.abs(point[1] - previous[1]);
2947
- return (dx <= 0.0001) !== (dy <= 0.0001);
2948
- });
2949
- }
2950
-
2951
- function routeClearsEndpointNodes(points, from, to) {
2952
- const lastSegment = points.length - 2;
2953
- for (let index = 0; index <= lastSegment; index += 1) {
2954
- const segment = { start: points[index], end: points[index + 1] };
2955
- if (index > 0 && segmentIntersectsRect(segment, from)) return false;
2956
- if (index < lastSegment && segmentIntersectsRect(segment, to)) return false;
2957
- }
2958
- return true;
2959
- }
2960
-
2961
- function routeMeetsHardRhythm(points) {
2962
- if (points.length === 2) {
2963
- return Math.hypot(points[1][0] - points[0][0], points[1][1] - points[0][1]) + 0.0001 >= 28;
2964
- }
2965
- return points.slice(0, -1).every((point, index) => {
2966
- const length = Math.abs(points[index + 1][0] - point[0]) + Math.abs(points[index + 1][1] - point[1]);
2967
- const endpoint = index === 0 || index === points.length - 2;
2968
- return length + 0.0001 >= (endpoint ? 8 : 16);
2969
- });
2970
- }
2971
-
2972
- function routeLabelClearsNodes(edge, points) {
2973
- if (!edge.label || edge.labelAt) return true;
2974
- const [lx, ly] = workflowEdgeLabelPoint(edge, points);
2975
- const rect = {
2976
- x: lx - workflowLabelWidth(edge.label) / 2,
2977
- y: ly - 10,
2978
- width: workflowLabelWidth(edge.label),
2979
- height: 14,
2980
- };
2981
- return [...nodes.values()].every((node) => !rectsOverlap(rect, node, -2));
2982
- }
2983
-
2984
- function candidateLabelRect(edge, points) {
2985
- if (!edge.label) return null;
2986
- const [lx, ly] = workflowEdgeLabelPoint(edge, points);
2987
- const width = workflowLabelWidth(edge.label);
2988
- return { x: lx - width / 2, y: ly - 10, width, height: 14 };
2989
- }
2990
-
2991
- function labelRouteClearanceDeficit(edge, points, threshold = 8) {
2992
- const candidateLabel = candidateLabelRect(edge, points);
2993
- let deficit = 0;
2994
- for (const [otherEdge, routed] of pathCache) {
2995
- const otherIndex = workflow.edges.indexOf(otherEdge);
2996
- const otherLabel = labelRectFor(otherEdge, otherIndex);
2997
- if (candidateLabel) {
2998
- for (let index = 0; index < routed.points.length - 1; index += 1) {
2999
- const clearance = segmentRectClearance({
3000
- start: routed.points[index],
3001
- end: routed.points[index + 1],
3002
- }, candidateLabel);
3003
- if (clearance != null) deficit += Math.max(0, threshold - clearance);
3004
- }
3005
- }
3006
- if (otherLabel) {
3007
- for (let index = 0; index < points.length - 1; index += 1) {
3008
- const clearance = segmentRectClearance({
3009
- start: points[index],
3010
- end: points[index + 1],
3011
- }, otherLabel);
3012
- if (clearance != null) deficit += Math.max(0, threshold - clearance);
3013
- }
3014
- }
3015
- }
3016
- return deficit;
3017
- }
3018
-
3019
- function routeClearsPlacedLabels(edge, points) {
3020
- const candidateLabel = candidateLabelRect(edge, points);
3021
- for (const [otherEdge, routed] of pathCache) {
3022
- const otherIndex = workflow.edges.indexOf(otherEdge);
3023
- const otherLabel = labelRectFor(otherEdge, otherIndex);
3024
- if (candidateLabel && otherLabel && rectsOverlap(candidateLabel, otherLabel, -2)) return false;
3025
- if (candidateLabel) {
3026
- for (let index = 0; index < routed.points.length - 1; index += 1) {
3027
- const clearance = segmentRectClearance({
3028
- start: routed.points[index],
3029
- end: routed.points[index + 1],
3030
- }, candidateLabel);
3031
- if (clearance != null && clearance + 0.0001 < 4) return false;
3032
- }
3033
- }
3034
- if (otherLabel) {
3035
- for (let index = 0; index < points.length - 1; index += 1) {
3036
- const clearance = segmentRectClearance({
3037
- start: points[index],
3038
- end: points[index + 1],
3039
- }, otherLabel);
3040
- if (clearance != null && clearance + 0.0001 < 4) return false;
3041
- }
3042
- }
3043
- }
3044
- return true;
3045
- }
3046
-
3047
- function routeClearsLegend(edge, points) {
3048
- if (!workflowLegendEntries.length) return true;
3049
- const legendRects = workflowLegendRects();
3050
- for (const rect of legendRects) {
3051
- for (let index = 0; index < points.length - 1; index += 1) {
3052
- if (segmentIntersectsRect({ start: points[index], end: points[index + 1] }, rect)) return false;
3053
- }
3054
- const label = candidateLabelRect(edge, points);
3055
- if (label && rectsOverlap(label, rect)) return false;
3056
- }
3057
- return true;
3058
- }
3059
-
3060
- function routeClearsSceneLabelObstacles(edge, points) {
3061
- const label = candidateLabelRect(edge, points);
3062
- for (const obstacle of workflowSceneLabelObstacles()) {
3063
- for (let index = 0; index < points.length - 1; index += 1) {
3064
- if (segmentIntersectsRect({ start: points[index], end: points[index + 1] }, obstacle)) {
3065
- return false;
3066
- }
3067
- }
3068
- if (label && rectsOverlap(label, obstacle)) return false;
3069
- }
3070
- return true;
3071
- }
3072
-
3073
- function routeClearsFrameBorders(points) {
3074
- return collectBorderRuns({
3075
- routedRelations: [{ points }],
3076
- frames: workflowCompositionFrames(),
3077
- }).length === 0;
3078
- }
3079
-
3080
- function routeExtentCoordinates(edge, points) {
3081
- const coordinates = [...points];
3082
- if (!edge.labelAt) {
3083
- const label = candidateLabelRect(edge, points);
3084
- if (label) {
3085
- coordinates.push([label.x, label.y], [label.x + label.width, label.y + label.height]);
3086
- }
3087
- }
3088
- return coordinates;
3089
- }
3090
-
3091
- function routeFitsCanvasOrigin(edge, points) {
3092
- return routeExtentCoordinates(edge, points).every(([x, y]) => x >= 0 && y >= 0);
3093
- }
3094
-
3095
- function readableCandidateIsFeasible(edge, points, from, to, fromSide, toSide) {
3096
- return points.length >= 2
3097
- && orthogonalRoute(points)
3098
- && routeHonorsEndpointSides(points, fromSide, toSide)
3099
- && routeMeetsHardRhythm(points)
3100
- && routeClearsEndpointNodes(points, from, to)
3101
- && routeClearsUnrelatedNodes(edge, points)
3102
- && routeLabelClearsNodes(edge, points)
3103
- && routeClearsPlacedLabels(edge, points)
3104
- && routeClearsLegend(edge, points)
3105
- && routeClearsSceneLabelObstacles(edge, points)
3106
- && routeClearsFrameBorders(points)
3107
- && routeFitsCanvasOrigin(edge, points);
3108
- }
3109
-
3110
- function corridorViaY(start, end, fromSide, toSide, y) {
3111
- const startStub = outwardStub(start, fromSide);
3112
- const endStub = outwardStub(end, toSide);
3113
- return [startStub, [startStub[0], y], [endStub[0], y], endStub];
3114
- }
3115
-
3116
- function corridorViaX(start, end, fromSide, toSide, x) {
3117
- const startStub = outwardStub(start, fromSide);
3118
- const endStub = outwardStub(end, toSide);
3119
- return [startStub, [x, startStub[1]], [x, endStub[1]], endStub];
3120
- }
3121
-
3122
- function axisOverlapLength(a, b, c, d) {
3123
- const horizontal = Math.abs(a[1] - b[1]) <= 0.0001
3124
- && Math.abs(c[1] - d[1]) <= 0.0001
3125
- && Math.abs(a[1] - c[1]) <= 0.0001;
3126
- const vertical = Math.abs(a[0] - b[0]) <= 0.0001
3127
- && Math.abs(c[0] - d[0]) <= 0.0001
3128
- && Math.abs(a[0] - c[0]) <= 0.0001;
3129
- if (!horizontal && !vertical) return 0;
3130
- const axis = horizontal ? 0 : 1;
3131
- return Math.max(0, Math.min(Math.max(a[axis], b[axis]), Math.max(c[axis], d[axis]))
3132
- - Math.max(Math.min(a[axis], b[axis]), Math.min(c[axis], d[axis])));
3133
- }
3134
-
3135
- function properAxisCrossing(a, b, c, d) {
3136
- const firstHorizontal = Math.abs(a[1] - b[1]) <= 0.0001;
3137
- const secondHorizontal = Math.abs(c[1] - d[1]) <= 0.0001;
3138
- if (firstHorizontal === secondHorizontal) return false;
3139
- const horizontal = firstHorizontal ? [a, b] : [c, d];
3140
- const vertical = firstHorizontal ? [c, d] : [a, b];
3141
- const x = vertical[0][0];
3142
- const y = horizontal[0][1];
3143
- return x > Math.min(horizontal[0][0], horizontal[1][0]) + 0.0001
3144
- && x < Math.max(horizontal[0][0], horizontal[1][0]) - 0.0001
3145
- && y > Math.min(vertical[0][1], vertical[1][1]) + 0.0001
3146
- && y < Math.max(vertical[0][1], vertical[1][1]) - 0.0001;
3147
- }
3148
-
3149
- function routeInteractionMetrics(edge, points) {
3150
- let properCrossingCount = 0;
3151
- let sharedCorridorPx = 0;
3152
- for (const [otherEdge, routed] of pathCache) {
3153
- if ([edge.from, edge.to].some((id) => id === otherEdge.from || id === otherEdge.to)) continue;
3154
- for (let left = 0; left < points.length - 1; left += 1) {
3155
- for (let right = 0; right < routed.points.length - 1; right += 1) {
3156
- if (properAxisCrossing(points[left], points[left + 1], routed.points[right], routed.points[right + 1])) {
3157
- properCrossingCount += 1;
3158
- }
3159
- sharedCorridorPx += axisOverlapLength(
3160
- points[left], points[left + 1], routed.points[right], routed.points[right + 1],
3161
- );
3162
- }
3163
- }
3164
- }
3165
- return { properCrossingCount, sharedCorridorPx };
3166
- }
3167
-
3168
- function automaticForwardReversePx(edge, points) {
3169
- const from = nodes.get(edge.from);
3170
- const to = nodes.get(edge.to);
3171
- if (!from || !to || ['return', 'error'].includes(edge.role) || to.col <= from.col) return 0;
3172
- return points.slice(0, -1).reduce((total, point, index) => (
3173
- total + Math.max(0, point[0] - points[index + 1][0])
3174
- ), 0);
3175
- }
3176
-
3177
- function readableCandidateCost(
3178
- edge,
3179
- points,
3180
- ordinal,
3181
- naturalFromSide,
3182
- naturalToSide,
3183
- ) {
3184
- const interaction = routeInteractionMetrics(edge, points);
3185
- const segmentLengths = points.slice(0, -1).map((point, index) => (
3186
- Math.abs(points[index + 1][0] - point[0]) + Math.abs(points[index + 1][1] - point[1])
3187
- ));
3188
- const routeLength = segmentLengths.reduce((total, length) => total + length, 0);
3189
- const directLength = Math.abs(points.at(-1)[0] - points[0][0]) + Math.abs(points.at(-1)[1] - points[0][1]);
3190
- const interiorPreferred28Deficit = segmentLengths.slice(1, -1)
3191
- .reduce((total, length) => total + Math.max(0, 28 - length), 0);
3192
- const xs = points.map(([x]) => x);
3193
- const ys = points.map(([, y]) => y);
3194
- const canvasGrowthPx = Math.max(0, -Math.min(...xs))
3195
- + Math.max(0, Math.max(...xs) - minimumCanvasWidth)
3196
- + Math.max(0, -Math.min(...ys))
3197
- + Math.max(0, Math.max(...ys) - autoHeight);
3198
- const from = nodes.get(edge.from);
3199
- const to = nodes.get(edge.to);
3200
- const naturalStart = anchor(from, naturalFromSide);
3201
- const naturalEnd = anchor(to, naturalToSide);
3202
- const portDisplacementPx = Math.abs(points[0][0] - naturalStart[0])
3203
- + Math.abs(points[0][1] - naturalStart[1])
3204
- + Math.abs(points.at(-1)[0] - naturalEnd[0])
3205
- + Math.abs(points.at(-1)[1] - naturalEnd[1]);
3206
- const legacyCoordinateDisplacement = Math.abs(from.cx - LEGACY_COLUMN_CENTERS[from.col])
3207
- + Math.abs(to.cx - LEGACY_COLUMN_CENTERS[to.col]);
3208
- return {
3209
- automaticForwardReversePx: automaticForwardReversePx(edge, points),
3210
- properCrossingCount: interaction.properCrossingCount,
3211
- sharedCorridorPx: interaction.sharedCorridorPx,
3212
- labelRouteClearanceDeficit: labelRouteClearanceDeficit(edge, points),
3213
- interiorPreferred28Deficit,
3214
- bendCount: Math.max(0, points.length - 2),
3215
- stretchMilli: Math.round((directLength > 0 ? routeLength / directLength : 1) * 1000),
3216
- canvasGrowthPx,
3217
- portDisplacementMilli: Math.round(portDisplacementPx * 1000),
3218
- legacyCoordinateDisplacement,
3219
- stableCandidateOrdinal: ordinal,
3220
- };
3221
- }
3222
-
3223
- function compareCost(left, right) {
3224
- for (const dimension of READABLE_CANDIDATE_COST_PRIORITY) {
3225
- if ((left[dimension] || 0) !== (right[dimension] || 0)) {
3226
- return (left[dimension] || 0) - (right[dimension] || 0);
3227
- }
3228
- }
3229
- return 0;
3230
- }
3231
-
3232
- function readableAutomaticCandidateSet(
3233
- edge,
3234
- from,
3235
- to,
3236
- start,
3237
- end,
3238
- fromSide,
3239
- toSide,
3240
- {
3241
- ordinalOffset = 0,
3242
- naturalFromSide = fromSide,
3243
- naturalToSide = toSide,
3244
- } = {},
3245
- ) {
3246
- const midX = (start[0] + end[0]) / 2;
3247
- const laneGapY = from.lane === to.lane
3248
- ? laneTop(from.lane) - 16
3249
- : gapYBetween(from.lane, to.lane, edge.bias ?? 0.5);
3250
- const topY = Math.max(8, Math.min(laneTop(from.lane), laneTop(to.lane)) - 16);
3251
- const bottomY = Math.max(
3252
- laneTop(from.lane) + laneHeight(from.lane),
3253
- laneTop(to.lane) + laneHeight(to.lane),
3254
- ) + 16;
3255
- const outsideLeft = layout.laneX - 20;
3256
- const outsideRight = layout.laneX + layout.laneW + 12;
3257
- const rawCandidates = [
3258
- { family: 'facing-straight', via: [] },
3259
- { family: 'horizontal-then-vertical', via: [[end[0], start[1]]] },
3260
- { family: 'vertical-then-horizontal', via: [[start[0], end[1]]] },
3261
- { family: 'lane-gap-corridor', via: corridorViaY(start, end, fromSide, toSide, laneGapY) },
3262
- { family: 'column-gap-corridor', via: corridorViaX(start, end, fromSide, toSide, midX) },
3263
- { family: 'outside-left', via: corridorViaX(start, end, fromSide, toSide, outsideLeft) },
3264
- { family: 'outside-right', via: corridorViaX(start, end, fromSide, toSide, outsideRight) },
3265
- { family: 'top-corridor', via: corridorViaY(start, end, fromSide, toSide, topY) },
3266
- { family: 'bottom-corridor', via: corridorViaY(start, end, fromSide, toSide, bottomY) },
3267
- ];
3268
- const candidates = rawCandidates.map((candidate, ordinal) => ({
3269
- ...candidate,
3270
- ordinal: ordinalOffset + ordinal,
3271
- points: normalizeRoutePoints([start, ...candidate.via, end]),
3272
- })).filter(({ points }) => (
3273
- readableCandidateIsFeasible(edge, points, from, to, fromSide, toSide)
3274
- )).map((candidate) => ({
3275
- ...candidate,
3276
- cost: readableCandidateCost(
3277
- edge,
3278
- candidate.points,
3279
- candidate.ordinal,
3280
- naturalFromSide,
3281
- naturalToSide,
3282
- ),
3283
- })).sort((left, right) => compareCost(left.cost, right.cost));
3284
- return { rawCandidates, candidates, outsideRight };
3285
- }
3286
-
3287
- function readableAutomaticVia(edge, from, to, start, end, fromSide, toSide) {
3288
- const { rawCandidates, candidates, outsideRight } = readableAutomaticCandidateSet(
3289
- edge,
3290
- from,
3291
- to,
3292
- start,
3293
- end,
3294
- fromSide,
3295
- toSide,
3296
- );
3297
-
3298
- if (candidates.length) return candidates[0].points.slice(1, -1);
3299
- const outsideRightCandidate = rawCandidates.find(({ family }) => family === 'outside-right');
3300
- if (outsideRightCandidate) {
3301
- const currentPoints = normalizeRoutePoints([start, ...outsideRightCandidate.via, end]);
3302
- const labelRect = candidateLabelRect(edge, currentPoints);
3303
- let outsideRightMinX = outsideRight;
3304
- for (const node of nodes.values()) {
3305
- if (!labelRect || !rectsOverlap(labelRect, node, -2)) continue;
3306
- const rightwardLabelDeficit = node.x + node.width - 2 - labelRect.x;
3307
- if (rightwardLabelDeficit > 0) {
3308
- outsideRightMinX = Math.max(
3309
- outsideRightMinX,
3310
- outsideRight + rightwardLabelDeficit * 2,
3311
- );
3312
- }
3313
- }
3314
- for (const [otherEdge, routed] of pathCache) {
3315
- const otherIndex = workflow.edges.indexOf(otherEdge);
3316
- const otherLabel = labelRectFor(otherEdge, otherIndex);
3317
- if (labelRect && otherLabel && rectsOverlap(labelRect, otherLabel, -2)) {
3318
- const rightwardLabelDeficit = otherLabel.x + otherLabel.width - 2 - labelRect.x;
3319
- if (rightwardLabelDeficit > 0) {
3320
- outsideRightMinX = Math.max(
3321
- outsideRightMinX,
3322
- outsideRight + rightwardLabelDeficit * 2,
3323
- );
3324
- }
3325
- }
3326
- if (!labelRect) continue;
3327
- for (let index = 0; index < routed.points.length - 1; index += 1) {
3328
- const segment = {
3329
- start: routed.points[index],
3330
- end: routed.points[index + 1],
3331
- };
3332
- const clearance = segmentRectClearance(segment, labelRect);
3333
- if (clearance == null || clearance + 0.0001 >= 4) continue;
3334
- const rightwardLabelDeficit = Math.max(segment.start[0], segment.end[0])
3335
- + 4 - labelRect.x;
3336
- if (rightwardLabelDeficit > 0) {
3337
- outsideRightMinX = Math.max(
3338
- outsideRightMinX,
3339
- outsideRight + rightwardLabelDeficit * 2,
3340
- );
3341
- }
3342
- }
3343
- }
3344
- outsideRightMinX = Math.ceil(outsideRightMinX * 1000) / 1000;
3345
- let rightmostPlacedX = outsideRight;
3346
- for (const node of nodes.values()) {
3347
- rightmostPlacedX = Math.max(rightmostPlacedX, node.x + node.width);
3348
- }
3349
- for (const [otherEdge, routed] of pathCache) {
3350
- for (const [x] of routed.points) rightmostPlacedX = Math.max(rightmostPlacedX, x);
3351
- const otherLabel = labelRectFor(otherEdge, workflow.edges.indexOf(otherEdge));
3352
- if (otherLabel) {
3353
- rightmostPlacedX = Math.max(rightmostPlacedX, otherLabel.x + otherLabel.width);
3354
- }
3355
- }
3356
- let probeGrowth = Math.max(
3357
- 32,
3358
- labelRect?.width ?? 0,
3359
- rightmostPlacedX + 16 - outsideRightMinX,
3360
- );
3361
- let lastInfeasibleX = outsideRight;
3362
- for (let probe = 0; probe < 7; probe += 1) {
3363
- if (outsideRightMinX > outsideRight + 0.0001) {
3364
- const expandedPoints = normalizeRoutePoints([
3365
- start,
3366
- ...corridorViaX(start, end, fromSide, toSide, outsideRightMinX),
3367
- end,
3368
- ]);
3369
- if (readableCandidateIsFeasible(edge, expandedPoints, from, to, fromSide, toSide)) {
3370
- let feasibleX = outsideRightMinX;
3371
- let feasiblePoints = expandedPoints;
3372
- let infeasibleX = lastInfeasibleX;
3373
- for (let refinement = 0;
3374
- refinement < 53 && feasibleX - infeasibleX > 0.001;
3375
- refinement += 1) {
3376
- const midpointX = Math.ceil(((infeasibleX + feasibleX) / 2) * 1000) / 1000;
3377
- if (midpointX >= feasibleX - 0.0001) break;
3378
- const midpointPoints = normalizeRoutePoints([
3379
- start,
3380
- ...corridorViaX(start, end, fromSide, toSide, midpointX),
3381
- end,
3382
- ]);
3383
- if (readableCandidateIsFeasible(
3384
- edge,
3385
- midpointPoints,
3386
- from,
3387
- to,
3388
- fromSide,
3389
- toSide,
3390
- )) {
3391
- feasibleX = midpointX;
3392
- feasiblePoints = midpointPoints;
3393
- } else {
3394
- infeasibleX = midpointX;
3395
- }
3396
- }
3397
- return feasiblePoints.slice(1, -1);
3398
- }
3399
- lastInfeasibleX = outsideRightMinX;
3400
- }
3401
- outsideRightMinX = Math.ceil((outsideRightMinX + probeGrowth) * 1000) / 1000;
3402
- probeGrowth *= 2;
3403
- }
3404
- }
3405
- const hasRelevantAbsolutePin = Array.isArray(edge.labelAt)
3406
- || [...pathCache.keys()].some((otherEdge) => (
3407
- Array.isArray(otherEdge.labelAt) || hasAbsoluteRoutePins(otherEdge)
3408
- ));
3409
- if (hasRelevantAbsolutePin) classifyFailedAutomaticCandidatePins(edge, rawCandidates);
3410
- const horizontallyFacing = (
3411
- fromSide === 'right' && toSide === 'left' && end[0] > start[0]
3412
- ) || (
3413
- fromSide === 'left' && toSide === 'right' && start[0] > end[0]
3414
- );
3415
- if (horizontallyFacing && from.col !== to.col) {
3416
- const fromCol = Math.min(from.col, to.col);
3417
- const toCol = Math.max(from.col, to.col);
3418
- const requiredRankGap = from.width / 2 + 32 + to.width / 2;
3419
- const actualRankGap = layout.colXs[toCol] - layout.colXs[fromCol];
3420
- if (actualRankGap + 0.0001 < requiredRankGap) {
3421
- throw new WorkflowLayoutFeedback({
3422
- kind: 'rank-gap-minimum',
3423
- fromCol,
3424
- toCol,
3425
- minimum: Math.ceil(requiredRankGap * 1000) / 1000,
3426
- edge: edge.id ?? null,
3427
- from: edge.from,
3428
- to: edge.to,
3429
- attemptedCandidateFamilies: rawCandidates.map(({ family }) => family),
3430
- candidateCount: rawCandidates.length,
3431
- });
3432
- }
3433
- }
3434
- if (from.lane !== to.lane && layout.laneGap < 32) {
3435
- throw new WorkflowLayoutFeedback({
3436
- kind: 'lane-gap-minimum',
3437
- minimum: 32,
3438
- edge: edge.id ?? null,
3439
- from: edge.from,
3440
- to: edge.to,
3441
- attemptedCandidateFamilies: rawCandidates.map(({ family }) => family),
3442
- candidateCount: rawCandidates.length,
3443
- });
3444
- }
3445
- const message = `Workflow edge "${workflowEdgeName(edge)}" has no feasible readable-v2 automatic route.`;
3446
- throwDiagnosticError(message, [{
3447
- code: 'workflow/solver-budget-exhausted',
3448
- severity: 'error',
3449
- message,
3450
- subject: {
3451
- diagramType: 'workflow',
3452
- edge: edge.id ?? null,
3453
- from: edge.from,
3454
- to: edge.to,
3455
- },
3456
- evidence: {
3457
- attemptedCandidateFamilies: rawCandidates.map(({ family }) => family),
3458
- candidateCount: rawCandidates.length,
3459
- },
3460
- supportedFixes: [],
3461
- }]);
3462
- }
3463
-
3464
- function readablePresetVia(edge, from, to, start, end, fromSide, toSide) {
3465
- const preset = edge.route;
3466
- let via;
3467
- switch (preset) {
3468
- case 'straight':
3469
- via = [];
3470
- break;
3471
- case 'drop': {
3472
- const y = gapYBetween(from.lane, to.lane, edge.bias ?? 0.5);
3473
- via = [[start[0], y], [end[0], y]];
3474
- break;
3475
- }
3476
- case 'outside-right': {
3477
- const x = layout.laneX + layout.laneW + 12;
3478
- via = [[x, start[1]], [x, end[1]]];
3479
- break;
3480
- }
3481
- case 'return-left': {
3482
- const x = Math.min(from.x, to.x) - 28;
3483
- via = [[x, start[1]], [x, end[1]]];
3484
- break;
3485
- }
3486
- case 'bottom-channel': {
3487
- const y = Math.max(from.y + from.height, to.y + to.height) + 32;
3488
- via = [[start[0], y], [end[0], y]];
3489
- break;
3490
- }
3491
- case 'up-channel': {
3492
- const y = Math.min(from.y, to.y) - 28;
3493
- via = [[start[0], y], [end[0], y]];
3494
- break;
3495
- }
3496
- default:
3497
- return readableAutomaticVia(edge, from, to, start, end, fromSide, toSide);
3498
- }
3499
- const points = normalizeRoutePoints([start, ...via, end]);
3500
- if (readableCandidateIsFeasible(edge, points, from, to, fromSide, toSide)
3501
- && routeMatchesPresetFamily(preset, points, from, to)) {
3502
- return points.slice(1, -1);
3503
- }
3504
- const message = `Workflow edge "${workflowEdgeName(edge)}" cannot satisfy route preset "${preset}" under readable-v2 constraints (minimum 8px endpoint stubs, 16px interior turns, and 28px direct clearance).`;
3505
- const edgeIndex = workflow.edges.indexOf(edge);
3506
- const edgeName = workflowEdgeName(edge);
3507
- const supportedFixes = [];
3508
- for (const candidatePreset of ['straight', 'drop', 'outside-right', 'return-left', 'bottom-channel', 'up-channel']) {
3509
- if (candidatePreset === preset) continue;
3510
- if (acceptsFix((document) => {
3511
- document.edges[edgeIndex].route = candidatePreset;
3512
- })) {
3513
- supportedFixes.push(`set edge "${edgeName}" route to verified preset "${candidatePreset}"`);
3514
- }
3515
- }
3516
- if (acceptsFix((document) => {
3517
- delete document.edges[edgeIndex].route;
3518
- })) {
3519
- supportedFixes.push(`remove route from edge "${edgeName}" so readable-v2 can use its verified automatic candidate`);
3520
- }
3521
- throwDiagnosticError(message, [{
3522
- code: 'workflow/route-preset-conflict',
3523
- severity: 'error',
3524
- message,
3525
- subject: {
3526
- diagramType: 'workflow',
3527
- edge: edge.id ?? null,
3528
- from: edge.from,
3529
- to: edge.to,
3530
- route: preset,
3531
- },
3532
- evidence: {
3533
- attemptedCandidateFamily: preset,
3534
- points,
3535
- fromSide,
3536
- toSide,
3537
- requiredEndpointStubPx: 8,
3538
- requiredInteriorSegmentPx: 16,
3539
- requiredDirectClearancePx: 28,
3540
- },
3541
- supportedFixes,
3542
- }]);
3543
- }
3544
-
3545
- function routeVia(
3546
- edge,
3547
- from,
3548
- to,
3549
- start,
3550
- end,
3551
- fromSide,
3552
- toSide,
3553
- { validateReadablePreset = true } = {},
3554
- ) {
3555
- if (edge.via) return edge.via;
3556
- const hasCoordinatePins = edge.channelX !== undefined || edge.channelY !== undefined;
3557
- if (workflow.schema_version === 2
3558
- && edge.route
3559
- && edge.route !== 'auto'
3560
- && !hasCoordinatePins
3561
- && validateReadablePreset) {
3562
- return readablePresetVia(edge, from, to, start, end, fromSide, toSide);
3563
- }
3564
- switch (edge.route || 'auto') {
3565
- case 'straight':
3566
- return [];
3567
- case 'drop': {
3568
- const y = edge.channelY ?? gapYBetween(from.lane, to.lane, edge.bias ?? 0.5);
3569
- return [[start[0], y], [end[0], y]];
3570
- }
3571
- case 'outside-right': {
3572
- const x = edge.channelX ?? layout.laneX + layout.laneW + 12;
3573
- return [[x, start[1]], [x, end[1]]];
3574
- }
3575
- case 'return-left': {
3576
- const x = edge.channelX ?? Math.min(from.x, to.x) - 28;
3577
- return [[x, start[1]], [x, end[1]]];
3578
- }
3579
- case 'bottom-channel': {
3580
- const y = edge.channelY ?? Math.max(from.y + from.height, to.y + to.height) + 32;
3581
- return [[start[0], y], [end[0], y]];
3582
- }
3583
- case 'up-channel': {
3584
- const y = edge.channelY ?? Math.min(from.y, to.y) - 28;
3585
- return [[start[0], y], [end[0], y]];
3586
- }
3587
- case 'auto':
3588
- default: {
3589
- if (workflow.schema_version === 2) {
3590
- if (edge.channelX !== undefined && edge.channelY !== undefined) {
3591
- return [[edge.channelX, start[1]], [edge.channelX, edge.channelY], [end[0], edge.channelY]];
3592
- }
3593
- if (edge.channelX !== undefined) return [[edge.channelX, start[1]], [edge.channelX, end[1]]];
3594
- if (edge.channelY !== undefined) return [[start[0], edge.channelY], [end[0], edge.channelY]];
3595
- return readableAutomaticVia(edge, from, to, start, end, fromSide, toSide);
3596
- }
3597
- if (from.lane === to.lane) return sameLaneAutoVia(start, end);
3598
- const oneBendVia = oneBendCrossLaneVia(edge, start, end, fromSide, toSide);
3599
- if (oneBendVia) return oneBendVia;
3600
- const y = gapYBetween(from.lane, to.lane, edge.bias ?? 0.5);
3601
- return [[start[0], y], [end[0], y]];
3602
- }
3603
- }
3604
- }
3605
-
3606
- function workflowEdgeLabelPoint(edge, points) {
3607
- if (workflow.schema_version === 1) {
3608
- if (edge.labelAt || Number.isInteger(edge.labelSegment) || points.length !== 3) {
3609
- return labelPoint(edge, points);
3610
- }
3611
- const segmentLengths = [0, 1].map((index) => Math.hypot(
3612
- points[index + 1][0] - points[index][0],
3613
- points[index + 1][1] - points[index][1],
3614
- ));
3615
- const labelSegment = segmentLengths[0] >= segmentLengths[1] ? 0 : 1;
3616
- const point = labelPoint({ ...edge, labelSegment }, points);
3617
- if (points[labelSegment][0] === points[labelSegment + 1][0]) point[1] += 10;
3618
- return point;
3619
- }
3620
- if (edge.labelAt || Number.isInteger(edge.labelSegment) || points.length <= 2) {
3621
- return labelPoint(edge, points);
3622
- }
3623
- const segments = points.slice(0, -1).map((point, index) => ({
3624
- index,
3625
- horizontal: Math.abs(points[index + 1][1] - point[1]) <= 0.0001,
3626
- length: Math.hypot(
3627
- points[index + 1][0] - point[0],
3628
- points[index + 1][1] - point[1],
3629
- ),
3630
- })).sort((left, right) => (
3631
- Number(right.horizontal) - Number(left.horizontal)
3632
- || right.length - left.length
3633
- || left.index - right.index
3634
- ));
3635
- const labelSegment = segments[0]?.index ?? 0;
3636
- const point = labelPoint({ ...edge, labelSegment }, points);
3637
- if (points[labelSegment][0] === points[labelSegment + 1][0]) point[1] += 10;
3638
- return point;
3639
- }
3640
-
3641
- function edgeSides(edge) {
3642
- const from = nodes.get(edge.from);
3643
- const to = nodes.get(edge.to);
3644
- const resolved = workflow.schema_version === 2 ? readableSideCache.get(edge) : null;
3645
- if (resolved) return resolved;
3646
- const oneBendSides = automaticOneBendSides(edge, from, to);
3647
- if (oneBendSides) return oneBendSides;
3648
- if (workflow.schema_version === 2
3649
- && layout.channelLabelEdgeKeys?.has(stableValueKey(edge))
3650
- && !edge.fromSide
3651
- && !edge.toSide) {
3652
- return { fromSide: 'top', toSide: 'top' };
3653
- }
3654
- return {
3655
- fromSide: chosenSide(edge.fromSide, defaultFromSide(from, to)),
3656
- toSide: chosenSide(edge.toSide, defaultToSide(from, to)),
3657
- };
3658
- }
3659
-
3660
- const automaticPorts = automaticPortSpread(workflow.edges, nodes, {
3661
- sideFor: (edge, endpoint) => edgeSides(edge)[endpoint === 'source' ? 'fromSide' : 'toSide'],
3662
- });
3663
-
3664
- function readableAutomaticRoute(edge, from, to, primarySides, primaryPorts) {
3665
- const authoredFrom = edge.fromSide && edge.fromSide !== 'auto' ? edge.fromSide : null;
3666
- const authoredTo = edge.toSide && edge.toSide !== 'auto' ? edge.toSide : null;
3667
- const sideOrder = ['right', 'bottom', 'left', 'top'];
3668
- const sidePairs = [primarySides];
3669
- for (const fromSide of authoredFrom ? [authoredFrom] : sideOrder) {
3670
- for (const toSide of authoredTo ? [authoredTo] : sideOrder) {
3671
- sidePairs.push({ fromSide, toSide });
3672
- }
3673
- }
3674
-
3675
- const naturalFromSide = authoredFrom || defaultFromSide(from, to);
3676
- const naturalToSide = authoredTo || defaultToSide(from, to);
3677
- const seen = new Set();
3678
- const plans = [];
3679
- const feedback = [];
3680
- let firstFailure = null;
3681
- for (const candidateSides of sidePairs) {
3682
- if (authoredFrom && candidateSides.fromSide !== authoredFrom) continue;
3683
- if (authoredTo && candidateSides.toSide !== authoredTo) continue;
3684
- const key = `${candidateSides.fromSide}:${candidateSides.toSide}`;
3685
- if (seen.has(key)) continue;
3686
- const pairOrdinal = seen.size;
3687
- seen.add(key);
3688
- const primary = pairOrdinal === 0;
3689
- const start = primaryPorts?.from && primary
3690
- ? primaryPorts.from
3691
- : anchor(from, candidateSides.fromSide);
3692
- const end = primaryPorts?.to && primary
3693
- ? primaryPorts.to
3694
- : anchor(to, candidateSides.toSide);
3695
- const planned = readableAutomaticCandidateSet(
3696
- edge,
3697
- from,
3698
- to,
3699
- start,
3700
- end,
3701
- candidateSides.fromSide,
3702
- candidateSides.toSide,
3703
- {
3704
- ordinalOffset: pairOrdinal * 9,
3705
- naturalFromSide,
3706
- naturalToSide,
3707
- },
3708
- );
3709
- plans.push(...planned.candidates.map((candidate) => ({
3710
- ...candidate,
3711
- ...candidateSides,
3712
- })));
3713
- if (planned.candidates.length) continue;
3714
- try {
3715
- const expandedVia = withDiagnosticRecordingSuppressed(() => readableAutomaticVia(
3716
- edge,
3717
- from,
3718
- to,
3719
- start,
3720
- end,
3721
- candidateSides.fromSide,
3722
- candidateSides.toSide,
3723
- ));
3724
- const expandedPoints = normalizeRoutePoints([start, ...expandedVia, end]);
3725
- const outsideRightOrdinal = planned.rawCandidates.findIndex(({ family }) => (
3726
- family === 'outside-right'
3727
- ));
3728
- const ordinal = pairOrdinal * 9 + Math.max(0, outsideRightOrdinal);
3729
- plans.push({
3730
- family: 'outside-right',
3731
- ordinal,
3732
- points: expandedPoints,
3733
- cost: readableCandidateCost(
3734
- edge,
3735
- expandedPoints,
3736
- ordinal,
3737
- naturalFromSide,
3738
- naturalToSide,
3739
- ),
3740
- ...candidateSides,
3741
- });
3742
- } catch (error) {
3743
- if (error instanceof WorkflowLayoutFeedback) {
3744
- feedback.push({ error, pairOrdinal });
3745
- } else if (!firstFailure) {
3746
- firstFailure = error;
3747
- }
3748
- }
3749
- }
3750
-
3751
- plans.sort((left, right) => compareCost(left.cost, right.cost));
3752
- if (plans.length) {
3753
- const selected = plans[0];
3754
- return {
3755
- points: selected.points,
3756
- fromSide: selected.fromSide,
3757
- toSide: selected.toSide,
3758
- };
3759
- }
3760
-
3761
- const feedbackPriority = {
3762
- 'rank-gap-minimum': 0,
3763
- 'lane-gap-minimum': 1,
3764
- };
3765
- feedback.sort((left, right) => (
3766
- (feedbackPriority[left.error.request?.kind] ?? 99)
3767
- - (feedbackPriority[right.error.request?.kind] ?? 99)
3768
- || left.pairOrdinal - right.pairOrdinal
3769
- ));
3770
- if (feedback.length) throw feedback[0].error;
3771
- const authoredSideFields = [
3772
- ...(authoredFrom ? ['fromSide'] : []),
3773
- ...(authoredTo ? ['toSide'] : []),
3774
- ];
3775
- if (authoredSideFields.length) {
3776
- const alternatives = verifiedPinRemovalAlternatives(
3777
- edge,
3778
- authoredSideFields,
3779
- 'so readable-v2 can replan the remaining endpoint-side pins',
3780
- );
3781
- const sourceAnchor = primaryPorts?.from || anchor(from, primarySides.fromSide);
3782
- const targetAnchor = primaryPorts?.to || anchor(to, primarySides.toSide);
3783
- const attemptedEvidence = firstFailure?.archifyDiagnostics?.[0]?.evidence || {};
3784
- throwExplicitPinConflict(edge, 'readable route feasibility with authored endpoint sides', {
3785
- conflictingPins: conflictPinsFromRemovalSets(
3786
- edge,
3787
- alternatives.removalSets,
3788
- authoredSideFields,
3789
- ),
3790
- actualCoordinates: {
3791
- sourceAnchor: [...sourceAnchor],
3792
- targetAnchor: [...targetAnchor],
3793
- },
3794
- fromSide: primarySides.fromSide,
3795
- toSide: primarySides.toSide,
3796
- ...(attemptedEvidence.attemptedCandidateFamilies
3797
- ? { attemptedCandidateFamilies: attemptedEvidence.attemptedCandidateFamilies }
3798
- : {}),
3799
- ...(attemptedEvidence.candidateCount !== undefined
3800
- ? { candidateCount: attemptedEvidence.candidateCount }
3801
- : {}),
3802
- }, alternatives.supportedFixes);
3803
- }
3804
- if (firstFailure) throw firstFailure;
3805
- throw new Error('readable-v2 automatic route enumeration produced no result');
3806
- }
3807
-
3808
- function isReadableControlledRoute(edge) {
3809
- return workflow.schema_version === 2 && (
3810
- Array.isArray(edge.via)
3811
- || edge.channelX !== undefined
3812
- || edge.channelY !== undefined
3813
- || (edge.route && edge.route !== 'auto')
3814
- );
3815
- }
3816
-
3817
- function readableControlledRoute(edge, from, to) {
3818
- const authoredFrom = edge.fromSide && edge.fromSide !== 'auto' ? edge.fromSide : null;
3819
- const authoredTo = edge.toSide && edge.toSide !== 'auto' ? edge.toSide : null;
3820
- const naturalFromSide = authoredFrom || defaultFromSide(from, to);
3821
- const naturalToSide = authoredTo || defaultToSide(from, to);
3822
- const sideOrder = ['right', 'bottom', 'left', 'top'];
3823
- const preferredPairs = [{
3824
- fromSide: naturalFromSide,
3825
- toSide: naturalToSide,
3826
- }];
3827
- for (const fromSide of authoredFrom ? [authoredFrom] : sideOrder) {
3828
- for (const toSide of authoredTo ? [authoredTo] : sideOrder) {
3829
- preferredPairs.push({ fromSide, toSide });
3830
- }
3831
- }
3832
-
3833
- const seen = new Set();
3834
- const sidePairs = preferredPairs.filter(({ fromSide, toSide }) => {
3835
- if (authoredFrom && fromSide !== authoredFrom) return false;
3836
- if (authoredTo && toSide !== authoredTo) return false;
3837
- const key = `${fromSide}:${toSide}`;
3838
- if (seen.has(key)) return false;
3839
- seen.add(key);
3840
- return true;
3841
- });
3842
- const hasAbsoluteRoutePins = Array.isArray(edge.via)
3843
- || edge.channelX !== undefined
3844
- || edge.channelY !== undefined;
3845
- const candidates = [];
3846
- const diagnosticCandidates = [];
3847
- const materializedCandidates = [];
3848
- for (const [ordinal, { fromSide, toSide }] of sidePairs.entries()) {
3849
- const start = anchor(from, fromSide);
3850
- const end = anchor(to, toSide);
3851
- const via = routeVia(
3852
- edge,
3853
- from,
3854
- to,
3855
- start,
3856
- end,
3857
- fromSide,
3858
- toSide,
3859
- { validateReadablePreset: false },
3860
- );
3861
- const authoredPoints = [start, ...via, end];
3862
- const points = hasAbsoluteRoutePins
3863
- ? authoredPoints
3864
- : normalizeRoutePoints(authoredPoints);
3865
- const materialized = { points, fromSide, toSide, ordinal };
3866
- materializedCandidates.push(materialized);
3867
- if (points.length >= 2
3868
- && points.every((point) => (
3869
- Array.isArray(point) && point.length === 2 && isFinitePoint(...point)
3870
- ))
3871
- && routeHonorsEndpointSides(points, fromSide, toSide)) {
3872
- diagnosticCandidates.push(materialized);
3873
- }
3874
- if (!readableCandidateIsFeasible(edge, points, from, to, fromSide, toSide)) continue;
3875
- if (edge.route && edge.route !== 'auto' && !routeMatchesPresetFamily(
3876
- edge.route,
3877
- points,
3878
- from,
3879
- to,
3880
- )) continue;
3881
- if (presentChannelPins(edge).some((field) => (
3882
- !routeContainsChannelPin(points, field, edge[field])
3883
- ))) continue;
3884
- candidates.push({
3885
- points,
3886
- fromSide,
3887
- toSide,
3888
- cost: readableCandidateCost(
3889
- edge,
3890
- points,
3891
- ordinal,
3892
- naturalFromSide,
3893
- naturalToSide,
3894
- ),
3895
- });
3896
- }
3897
- candidates.sort((left, right) => compareCost(left.cost, right.cost));
3898
- if (candidates.length) return candidates[0];
3899
-
3900
- // Absolute geometry is authoritative even when it is invalid. Preserve the
3901
- // best endpoint-side inference so validation can diagnose the authored
3902
- // segment or preset that actually failed instead of silently falling back to
3903
- // default sides and changing the route's meaning.
3904
- if (hasAbsoluteRoutePins) {
3905
- return diagnosticCandidates[0] || materializedCandidates[0] || null;
3906
- }
3907
-
3908
- // Preset-only routes retain their dedicated typed conflict (and verified
3909
- // alternative search) when exhaustive side inference found no valid plan.
3910
- const fallback = materializedCandidates[0];
3911
- if (!fallback) return null;
3912
- const fallbackVia = readablePresetVia(
3913
- edge,
3914
- from,
3915
- to,
3916
- fallback.points[0],
3917
- fallback.points.at(-1),
3918
- fallback.fromSide,
3919
- fallback.toSide,
3920
- );
3921
- return {
3922
- ...fallback,
3923
- points: normalizeRoutePoints([
3924
- fallback.points[0],
3925
- ...fallbackVia,
3926
- fallback.points.at(-1),
3927
- ]),
3928
- };
3929
- }
3930
-
3931
- function pathFor(edge) {
3932
- if (pathCache.has(edge)) return pathCache.get(edge);
3933
- const from = nodes.get(edge.from);
3934
- const to = nodes.get(edge.to);
3935
- if (isReadableControlledRoute(edge)) {
3936
- const planned = readableControlledRoute(edge, from, to);
3937
- if (planned) {
3938
- readableSideCache.set(edge, {
3939
- fromSide: planned.fromSide,
3940
- toSide: planned.toSide,
3941
- });
3942
- const routed = { d: polylinePath(planned.points), points: planned.points };
3943
- pathCache.set(edge, routed);
3944
- return routed;
3945
- }
3946
- }
3947
- const ports = automaticPorts.get(edge);
3948
- const { fromSide, toSide } = edgeSides(edge);
3949
- const readableAutomatic = workflow.schema_version === 2
3950
- && !Array.isArray(edge.via)
3951
- && edge.channelX === undefined
3952
- && edge.channelY === undefined
3953
- && (!edge.route || edge.route === 'auto');
3954
- if (readableAutomatic) {
3955
- const planned = readableAutomaticRoute(
3956
- edge,
3957
- from,
3958
- to,
3959
- { fromSide, toSide },
3960
- ports,
3961
- );
3962
- readableSideCache.set(edge, {
3963
- fromSide: planned.fromSide,
3964
- toSide: planned.toSide,
3965
- });
3966
- const routed = { d: polylinePath(planned.points), points: planned.points };
3967
- pathCache.set(edge, routed);
3968
- return routed;
3969
- }
3970
- const start = ports?.from || anchor(from, fromSide);
3971
- const end = ports?.to || anchor(to, toSide);
3972
- const authoredPoints = [start, ...routeVia(edge, from, to, start, end, fromSide, toSide), end];
3973
- const hasAbsoluteRoutePins = Array.isArray(edge.via)
3974
- || edge.channelX !== undefined
3975
- || edge.channelY !== undefined;
3976
- const points = workflow.schema_version === 2 && !hasAbsoluteRoutePins
3977
- ? normalizeRoutePoints(authoredPoints)
3978
- : authoredPoints;
3979
- const routed = { d: polylinePath(points), points };
3980
- pathCache.set(edge, routed);
3981
- return routed;
3982
- }
3983
-
3984
- function labelRectFor(edge, relationIndex) {
3985
- if (!edge.label || !nodes.has(edge.from) || !nodes.has(edge.to)) return null;
3986
- const [lx, ly] = workflowEdgeLabelPoint(edge, pathFor(edge).points);
3987
- const width = workflowLabelWidth(edge.label);
3988
- return {
3989
- relation: edge,
3990
- relationIndex,
3991
- label: edge.label,
3992
- x: lx - width / 2,
3993
- y: ly - 10,
3994
- width,
3995
- height: 14,
3996
- lx,
3997
- ly,
3998
- };
3999
- }
4000
-
4001
- function measuredContentBounds() {
4002
- let left = layout.laneX;
4003
- let top = 27;
4004
- let right = layout.laneX + layout.laneW;
4005
- let bottom = legendY() + 18;
4006
- const owners = {
4007
- left: 'workflow lanes',
4008
- top: asArray(workflow.phases).length ? 'phase header band' : 'workflow top padding',
4009
- right: 'workflow lanes',
4010
- bottom: workflowLegendEntries.length ? 'legend' : 'workflow lanes and bottom padding',
4011
- };
4012
- const includePoint = ([x, y], contributor) => {
4013
- if (x < left) {
4014
- left = x;
4015
- owners.left = contributor;
4016
- }
4017
- if (y < top) {
4018
- top = y;
4019
- owners.top = contributor;
4020
- }
4021
- if (x > right) {
4022
- right = x;
4023
- owners.right = contributor;
4024
- }
4025
- if (y > bottom) {
4026
- bottom = y;
4027
- owners.bottom = contributor;
4028
- }
4029
- };
4030
- const includeRect = (rect, contributor) => {
4031
- includePoint([rect.x, rect.y], contributor);
4032
- includePoint([rect.x + rect.width, rect.y + rect.height], contributor);
4033
- };
4034
-
4035
- for (const node of nodes.values()) includeRect(node, `node ${node.id}`);
4036
- for (const [index, edge] of workflow.edges.entries()) {
4037
- if (!nodes.has(edge.from) || !nodes.has(edge.to)) continue;
4038
- for (const point of pathFor(edge).points) includePoint(point, `edge ${edge.id || index}`);
4039
- const label = labelRectFor(edge, index);
4040
- if (label) includeRect(label, `edge ${edge.id || index} label mask`);
4041
- }
4042
- for (const phase of asArray(workflow.phases)) {
4043
- if (!Number.isInteger(phase.fromCol) || !Number.isInteger(phase.toCol)
4044
- || phase.fromCol < 0 || phase.toCol >= layout.colXs.length || phase.fromCol > phase.toCol) continue;
4045
- const span = phaseSpan(phase);
4046
- includeRect({ x: span.x, y: 27, width: span.width, height: 16 }, `phase ${phase.id}`);
4047
- }
4048
- for (const group of asArray(workflow.groups)) {
4049
- if (!laneIndex.has(group.lane) || !Number.isInteger(group.fromCol) || !Number.isInteger(group.toCol)
4050
- || group.fromCol < 0 || group.toCol >= layout.colXs.length || group.fromCol > group.toCol) continue;
4051
- const span = groupSpan(group);
4052
- includeRect({
4053
- x: span.x,
4054
- y: laneTop(group.lane) + layout.laneTitleH + GROUP_FRAME_TOP_INSET,
4055
- width: span.width,
4056
- height: workflow.schema_version === 2
4057
- ? laneHeight(group.lane) - layout.laneTitleH
4058
- - GROUP_FRAME_TOP_INSET - GROUP_FRAME_BOTTOM_INSET
4059
- : layout.laneH - layout.laneTitleH - 16,
4060
- }, `group ${group.id}`);
4061
- if (workflow.schema_version === 2) {
4062
- const frameY = laneTop(group.lane) + layout.laneTitleH + GROUP_FRAME_TOP_INSET;
4063
- const labelBaseline = frameY + GROUP_LABEL_BASELINE_OFFSET;
4064
- includeRect({
4065
- x: span.x + 10,
4066
- y: labelBaseline - GROUP_LABEL_MASK_ASCENT,
4067
- width: textUnits(group.label) * 5.6,
4068
- height: GROUP_LABEL_MASK_H,
4069
- }, `group ${group.id} label`);
4070
- }
4071
- }
4072
- if (workflowLegendEntries.length) {
4073
- for (const rect of workflowLegendRects()) includeRect(rect, `legend ${rect.kind}`);
4074
- }
4075
- return {
4076
- left,
4077
- top,
4078
- right,
4079
- bottom,
4080
- contributors: [...new Set([
4081
- ...Object.values(owners),
4082
- ...asArray(layout.widthContributors),
4083
- ...asArray(layout.heightContributors),
4084
- ])],
4085
- };
4086
- }
4087
-
4088
- function finalizeReadableViewBox() {
4089
- if (workflow.schema_version !== 2) {
4090
- requiredViewBox = [...viewBox];
4091
- return;
4092
- }
4093
- const bounds = measuredContentBounds();
4094
- requiredViewBox = [
4095
- Math.max(minimumCanvasWidth, Math.ceil(bounds.right + 16)),
4096
- Math.max(autoHeight, Math.ceil(bounds.bottom + 18)),
4097
- ];
4098
- const outsideOrigin = bounds.left < 0 || bounds.top < 0;
4099
- if (outsideOrigin) {
4100
- const hasAbsolutePins = workflow.edges.some((edge) => (
4101
- Array.isArray(edge.via)
4102
- || Array.isArray(edge.labelAt)
4103
- || edge.channelX !== undefined
4104
- || edge.channelY !== undefined
4105
- ));
4106
- const message = `Workflow geometry extends above or left of the viewBox origin (${Math.round(bounds.left)}, ${Math.round(bounds.top)}).`;
4107
- throwDiagnosticError(message, [{
4108
- code: hasAbsolutePins ? 'workflow/explicit-pin-conflict' : 'workflow/solver-budget-exhausted',
4109
- severity: 'error',
4110
- message,
4111
- subject: { diagramType: 'workflow', path: '/meta/viewBox' },
4112
- evidence: {
4113
- actualViewBox: [...viewBox],
4114
- requiredViewBox: [...requiredViewBox],
4115
- contentBounds: [bounds.left, bounds.top, bounds.right, bounds.bottom],
4116
- contributors: bounds.contributors,
4117
- },
4118
- supportedFixes: [],
4119
- }]);
4120
- }
4121
- if (!workflow.meta?.viewBox) {
4122
- viewBox = [...requiredViewBox];
4123
- return;
4124
- }
4125
- const tooNarrow = viewBox[0] < requiredViewBox[0];
4126
- const tooShort = viewBox[1] < requiredViewBox[1];
4127
- if (!tooNarrow && !tooShort) return;
4128
- const message = `Workflow viewBox ${viewBox[0]}×${viewBox[1]} cannot contain the readable-v2 layout; minimum ${requiredViewBox[0]}×${requiredViewBox[1]}.`;
4129
- const supportedFixes = [];
4130
- if (acceptsFix((document) => {
4131
- document.meta.viewBox = [...requiredViewBox];
4132
- })) {
4133
- supportedFixes.push(`set meta.viewBox to at least [${requiredViewBox[0]}, ${requiredViewBox[1]}]`);
4134
- }
4135
- if (acceptsFix((document) => {
4136
- delete document.meta.viewBox;
4137
- })) {
4138
- supportedFixes.push('omit meta.viewBox so the compiler can use its measured intrinsic canvas');
4139
- }
4140
- throwDiagnosticError(message, [{
4141
- code: 'workflow/viewbox-capacity',
4142
- severity: 'error',
4143
- message,
4144
- subject: { diagramType: 'workflow', path: '/meta/viewBox' },
4145
- evidence: {
4146
- actualViewBox: [...viewBox],
4147
- requiredViewBox: [...requiredViewBox],
4148
- contentBounds: [bounds.left, bounds.top, bounds.right, bounds.bottom],
4149
- contributors: bounds.contributors,
4150
- },
4151
- supportedFixes,
4152
- }]);
4153
- }
4154
-
4155
- function renderLane(lane, index) {
4156
- const y = laneTop(lane.id);
4157
- const height = laneHeight(index);
4158
- const exception = lane.variant === 'exception'
4159
- ? `\n <rect data-graph-role="structural-frame" data-composition-frame-kind="exception-lane" data-composition-frame-id="lane-${index}-exception" x="${layout.laneX + 6}" y="${y + 6}" width="${layout.laneW - 12}" height="${height - 12}" rx="8" class="c-security-group" stroke-width="1"/>`
4160
- : '';
4161
- const labelClass = lane.variant === 'exception' ? 't-security' : 't-dim';
4162
- const prefix = lane.variant === 'exception' ? 'EX' : String(index + 1).padStart(2, '0');
4163
- return ` <rect data-graph-role="structural-frame" data-composition-frame-kind="lane" data-composition-frame-id="lane-${index}" x="${layout.laneX}" y="${y}" width="${layout.laneW}" height="${height}" rx="10" class="c-lane" stroke-width="1"/>${exception}
4164
- <text x="${layout.laneX + 14}" y="${y + 22}" class="${labelClass}" font-size="10" font-weight="600">${prefix} / ${esc(lane.label)}</text>`;
4165
- }
4166
-
4167
- function renderPhase(phase) {
4168
- const span = phaseSpan(phase);
4169
- const accent = variantAccent(phase.variant);
4170
- const [lineClass] = arrowClassMap[phase.variant || 'default'] || arrowClassMap.default;
4171
- return ` <line x1="${span.x}" y1="35" x2="${span.x + span.width}" y2="35" class="${lineClass}" stroke-width="1.1"/>
4172
- <rect x="${span.x}" y="27" width="${span.width}" height="16" rx="4" class="c-mask"/>
4173
- <text x="${span.cx}" y="39" class="${accent}" font-size="8" font-weight="600" text-anchor="middle">${esc(phase.label)}</text>`;
4174
- }
4175
-
4176
- function renderGroup(group, index) {
4177
- const span = groupSpan(group);
4178
- const y = laneTop(group.lane) + layout.laneTitleH + GROUP_FRAME_TOP_INSET;
4179
- const height = workflow.schema_version === 2
4180
- ? laneHeight(group.lane) - layout.laneTitleH
4181
- - GROUP_FRAME_TOP_INSET - GROUP_FRAME_BOTTOM_INSET
4182
- : layout.laneH - layout.laneTitleH - 16;
4183
- const cls = group.variant === 'security' ? 'c-security-group' : 'c-lane';
4184
- const textClass = variantAccent(group.variant);
4185
- const labelY = workflow.schema_version === 2 ? y + GROUP_LABEL_BASELINE_OFFSET : y + 14;
4186
- return ` <rect data-graph-role="structural-frame" data-composition-frame-kind="group" data-composition-frame-id="group-${index}" x="${span.x}" y="${y}" width="${span.width}" height="${height}" rx="9" class="${cls}" stroke-width="1"/>
4187
- <text x="${span.x + 10}" y="${labelY}" class="${textClass}" font-size="7" font-weight="600">${esc(group.label)}</text>`;
4188
- }
4189
-
4190
- function renderNode(node) {
4191
- const fill = componentFill[node.type] || 'c-external';
4192
- const accent = componentText[node.type] || 't-muted';
4193
- const hasSub = node.sublabel != null && node.sublabel !== '';
4194
- const labelFontSize = fittedNodeFontSize(node.label, brandLabelFitWidth(node, node.width), nodeTextFit.labelPreferred, nodeTextFit.labelMinimum);
4195
- const sublabelFontSize = hasSub
4196
- ? fittedNodeFontSize(node.sublabel, node.width, nodeTextFit.sublabelPreferred, nodeTextFit.sublabelMinimum)
4197
- : nodeTextFit.sublabelPreferred;
4198
- const sub = hasSub
4199
- ? `\n <text data-detail="context" x="${node.cx}" y="${node.y + 38}" class="t-muted" font-size="${sublabelFontSize}" text-anchor="middle">${esc(node.sublabel)}</text>`
4200
- : '';
4201
- const tag = node.tag
4202
- ? `\n <text data-detail="fine" x="${node.cx}" y="${node.y + node.height - 12}" class="${accent}" font-size="${fittedNodeFontSize(node.tag, node.width, nodeTextFit.tagPreferred, nodeTextFit.tagMinimum)}" text-anchor="middle">${esc(node.tag)}</text>`
4203
- : '';
4204
- const brand = renderBrandMark(node, { x: node.x + node.width - 22, y: node.y + 6 });
4205
- const passport = { kind: node.type, sublabel: node.sublabel, tag: node.tag, context: nodeContext(node), ...brandMetadataFor(node) };
4206
- return ` <g ${focusNodeAttrs(node.id, node.label, passport, workflow.meta.locale)}>
4207
- ${focusNodeTitle(node.label, passport)}
4208
- <rect x="${node.x}" y="${node.y}" width="${node.width}" height="${node.height}" rx="6" class="c-mask"/>
4209
- <rect x="${node.x}" y="${node.y}" width="${node.width}" height="${node.height}" rx="6" class="${fill}"${animateAttr(workflow.meta, 'node', nodeStep(node))} stroke-width="1.5"/>
4210
- ${renderSemanticSigil(node.type, { x: node.x + 6, y: node.y + 6 })}${brand ? `\n ${brand}` : ''}
4211
- <text data-node-label=""${hasSub ? ' data-detail-anchor=""' : ''} x="${node.cx}" y="${node.y + 21}" class="t-primary" font-size="${labelFontSize}" font-weight="600" text-anchor="middle">${esc(node.label)}</text>${sub}${tag}
4212
- </g>`;
4213
- }
4214
-
4215
- function renderEdgePath(edge, index) {
4216
- const [cls, marker] = arrowClassMap[edge.variant || 'default'] || arrowClassMap.default;
4217
- const routed = pathFor(edge);
4218
- const strokeWidth = edge.width || (edge.variant === 'emphasis' ? 1.8 : 1.4);
4219
- return ` <path ${focusEdgeAttrs(edge.from, edge.to, edge.label, index, edge.id)} data-composition-points="${routePointsValue(routed.points)}" d="${routed.d}" class="${cls}"${animateAttr(workflow.meta, 'edge', edgeSteps.get(edge))} stroke-width="${strokeWidth}" marker-end="url(#${marker})"/>`;
4220
- }
4221
-
4222
- function renderEdgeLabel(edge, index) {
4223
- if (!edge.label) return '';
4224
- const routed = pathFor(edge);
4225
- const [lx, ly] = workflowEdgeLabelPoint(edge, routed.points);
4226
- const labelW = workflowLabelWidth(edge.label);
4227
- return ` <g data-detail="context" ${focusEdgeAttrs(edge.from, edge.to, edge.label, index, edge.id)}>
4228
- <rect x="${lx - labelW / 2}" y="${ly - 10}" width="${labelW}" height="14" rx="3" class="c-mask"/>
4229
- <text x="${lx}" y="${ly}" class="${variantAccent(edge.variant, { dashed: 't-database' })}" font-size="8" text-anchor="middle">${esc(edge.label)}</text>
4230
- </g>`;
4231
- }
4232
-
4233
- function renderLegend() {
4234
- const obstacles = workflow.schema_version === 2
4235
- ? relationshipLegendObstacles(workflow.edges, {
4236
- pointsFor: (edge) => pathFor(edge).points,
4237
- labelRectFor,
4238
- })
4239
- : [];
4240
- return renderResolvedLegend({
4241
- entries: workflowLegendEntries,
4242
- locale: workflow.meta.locale,
4243
- layout: workflowLegendLayout(obstacles),
4244
- renderSwatch: (entry) => `<rect x="${entry.x}" y="${entry.baseline - 8}" width="14" height="9" rx="2" class="${componentFill[entry.kind] || 'c-external'}" stroke-width="1"/>`,
4245
- });
4246
- }
4247
-
4248
- function renderSvg() {
4249
- return ` <svg viewBox="0 0 ${viewBox[0]} ${viewBox[1]}" ${svgRootAttrs(workflow.meta, 'workflow diagram')}>
4250
- ${svgAccessibleText(workflow.meta, 'workflow')}
4251
- ${renderDefinitions()}
4252
-
4253
- <!-- Background Grid -->
4254
- <rect width="100%" height="100%" fill="url(#grid)" />
4255
-
4256
- <!-- Swimlanes -->
4257
- ${workflow.lanes.map(renderLane).join('\n\n')}
4258
-
4259
- <!-- Phase headers -->
4260
- ${asArray(workflow.phases).map(renderPhase).join('\n')}
4261
-
4262
- <!-- Workflow groups -->
4263
- ${asArray(workflow.groups).map(renderGroup).join('\n')}
4264
-
4265
- <!-- Edge paths -->
4266
- ${workflow.edges.map(renderEdgePath).join('\n')}
4267
-
4268
- <!-- Nodes -->
4269
- ${[...nodes.values()].map(renderNode).join('\n\n')}
4270
-
4271
- <!-- Edge labels -->
4272
- ${workflow.edges.map(renderEdgeLabel).join('\n')}
4273
-
4274
- <!-- Legend -->
4275
- ${renderLegend()}
4276
- </svg>`;
4277
- }
4278
-
4279
-
4280
- try {
4281
- validateReadableInputsBeforeRouting();
4282
- validateReadablePinnedGeometry();
4283
- validateWorkflow();
4284
- finalizeReadableViewBox();
4285
- const svg = renderSvg();
4286
- const receipt = {
4287
- contract: layout.contract,
4288
- viewBox: [...viewBox],
4289
- requiredViewBox: [...requiredViewBox],
4290
- columns: [...layout.colXs],
4291
- nodes: [...nodes.values()].map((node) => ({
4292
- id: node.id,
4293
- lane: node.lane,
4294
- col: node.col,
4295
- x: node.x,
4296
- y: node.y,
4297
- width: node.width,
4298
- height: node.height,
4299
- })),
4300
- edges: workflow.edges.map((edge) => ({
4301
- id: edge.id ?? null,
4302
- from: edge.from,
4303
- to: edge.to,
4304
- points: pathFor(edge).points.map((point) => [...point]),
4305
- })),
4306
- labels: workflow.edges.flatMap((edge) => {
4307
- if (!edge.label || !nodes.has(edge.from) || !nodes.has(edge.to)) return [];
4308
- const [x, y] = workflowEdgeLabelPoint(edge, pathFor(edge).points);
4309
- return [{ edge: edge.id ?? null, label: edge.label, x, y, width: workflowLabelWidth(edge.label), height: 14 }];
4310
- }),
4311
- diagnostics: [],
4312
- };
4313
- return { ok: true, svg, receipt };
4314
- } catch (error) {
4315
- if (!Array.isArray(error?.archifyDiagnostics)) throw error;
4316
- const diagnostics = error.archifyDiagnostics.map((diagnostic) => ({ ...diagnostic }));
4317
- return compilerFailure(layout.contract, diagnostics, error.message);
4318
- }
4319
- }
4320
-
4321
- function feedbackFailure(request) {
4322
- const message = `Workflow edge "${request.edge || `${request.from}->${request.to}`}" exhausted bounded readable-v2 layout feedback without a feasible automatic route.`;
4323
- const diagnostics = [{
4324
- code: 'workflow/solver-budget-exhausted',
4325
- severity: 'error',
4326
- message,
4327
- subject: {
4328
- diagramType: 'workflow',
4329
- edge: request.edge,
4330
- from: request.from,
4331
- to: request.to,
4332
- },
4333
- evidence: {
4334
- attemptedCandidateFamilies: request.attemptedCandidateFamilies,
4335
- candidateCount: request.candidateCount,
4336
- },
4337
- supportedFixes: [],
4338
- }];
4339
- return compilerFailure('readable-v2', diagnostics, message);
4340
- }
4341
-
4342
- function compileWorkflowWithFeedback({ workflow, qualityProfile, discoverFixes = true } = {}) {
4343
- let layoutFeedback = {};
4344
- for (let attempt = 0; attempt <= MAX_READABLE_LAYOUT_FEEDBACK_ROUNDS; attempt += 1) {
4345
- try {
4346
- return compileWorkflowInternal({
4347
- workflow,
4348
- qualityProfile,
4349
- discoverFixes,
4350
- layoutFeedback,
4351
- });
4352
- } catch (error) {
4353
- if (!(error instanceof WorkflowLayoutFeedback)) throw error;
4354
- const request = error.request;
4355
- let nextFeedback = null;
4356
- if (request.kind === 'rank-gap-minimum'
4357
- && Number.isInteger(request.fromCol)
4358
- && Number.isInteger(request.toCol)
4359
- && Number.isFinite(request.minimum)) {
4360
- const key = `${request.fromCol}:${request.toCol}`;
4361
- const current = layoutFeedback.rankGapMinimums?.[key] ?? -Infinity;
4362
- if (request.minimum > current + 0.0001) {
4363
- nextFeedback = {
4364
- ...layoutFeedback,
4365
- rankGapMinimums: {
4366
- ...(layoutFeedback.rankGapMinimums || {}),
4367
- [key]: request.minimum,
4368
- },
4369
- rankGapContributors: {
4370
- ...(layoutFeedback.rankGapContributors || {}),
4371
- [key]: [
4372
- `rank ${request.fromCol}→${request.toCol} route clearance`,
4373
- `edge ${request.edge || `${request.from}->${request.to}`} route`,
4374
- ],
4375
- },
4376
- };
4377
- }
4378
- } else if (request.kind === 'lane-gap-minimum'
4379
- && Number.isFinite(request.minimum)
4380
- && request.minimum > (layoutFeedback.laneGapMin ?? -Infinity) + 0.0001) {
4381
- nextFeedback = {
4382
- ...layoutFeedback,
4383
- laneGapMin: request.minimum,
4384
- laneGapContributors: [
4385
- `edge ${request.edge || `${request.from}->${request.to}`} lane-gap route clearance`,
4386
- ],
4387
- };
4388
- }
4389
- if (!nextFeedback || attempt === MAX_READABLE_LAYOUT_FEEDBACK_ROUNDS) {
4390
- return feedbackFailure(request);
4391
- }
4392
- layoutFeedback = nextFeedback;
4393
- }
4394
- }
4395
- throw new Error('unreachable readable-v2 layout feedback state');
4396
- }
4397
-
4398
- export function compileWorkflow({ workflow, qualityProfile } = {}) {
4399
- return compileWorkflowWithFeedback({ workflow, qualityProfile });
4400
- }