@stacksjs/defaults 0.75.361 → 0.75.366

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 (210) hide show
  1. package/ai/skills/stacks-ai/SKILL.md +22 -0
  2. package/ai/skills/stacks-native/CATALOG.md +5 -5
  3. package/ai/skills/stacks-payments/SKILL.md +10 -0
  4. package/ai/skills/stacks-technical-diagrams/LICENSE +202 -22
  5. package/ai/skills/stacks-technical-diagrams/LICENSE-MIT +22 -0
  6. package/ai/skills/stacks-technical-diagrams/NOTICE +26 -0
  7. package/ai/skills/stacks-technical-diagrams/SKILL.md +106 -266
  8. package/ai/skills/stacks-technical-diagrams/THIRD_PARTY_NOTICES.md +11 -2
  9. package/ai/skills/stacks-technical-diagrams/UPSTREAM.json +12 -0
  10. package/ai/skills/stacks-technical-diagrams/agents/openai.yaml +2 -2
  11. package/ai/skills/stacks-technical-diagrams/assets/template.html +3655 -3798
  12. package/ai/skills/stacks-technical-diagrams/bin/archify.mjs +7290 -0
  13. package/ai/skills/stacks-technical-diagrams/bin/delivery-update.mjs +7 -0
  14. package/ai/skills/stacks-technical-diagrams/bin/diagrams +1 -0
  15. package/ai/skills/stacks-technical-diagrams/bin/finalize.mjs +1056 -0
  16. package/ai/skills/stacks-technical-diagrams/bin/open-artifact.mjs +72 -12
  17. package/ai/skills/stacks-technical-diagrams/bin/preview.mjs +348 -31
  18. package/ai/skills/stacks-technical-diagrams/bin/recover-output.mjs +41 -0
  19. package/ai/skills/stacks-technical-diagrams/bin/technical-diagrams.mjs +3 -2097
  20. package/ai/skills/stacks-technical-diagrams/bin/visual-check.mjs +2142 -157
  21. package/ai/skills/stacks-technical-diagrams/brand-marks/README.md +3 -3
  22. package/ai/skills/stacks-technical-diagrams/delta/architecture-delta.mjs +130 -33
  23. package/ai/skills/stacks-technical-diagrams/examples/agent-run.lifecycle.json +25 -30
  24. package/ai/skills/stacks-technical-diagrams/examples/agent-tool-call.workflow.json +0 -20
  25. package/ai/skills/stacks-technical-diagrams/examples/archify-dev-activity.timeline.json +176 -0
  26. package/ai/skills/stacks-technical-diagrams/examples/archify-repository.tree.json +197 -0
  27. package/ai/skills/stacks-technical-diagrams/examples/async-job-roundtrip.sequence.json +1 -6
  28. package/ai/skills/stacks-technical-diagrams/examples/brand-aware-delivery.architecture.json +3 -16
  29. package/ai/skills/stacks-technical-diagrams/examples/cache-miss-request.sequence.json +2 -7
  30. package/ai/skills/stacks-technical-diagrams/examples/checkout-platform.base.architecture.json +2 -1
  31. package/ai/skills/stacks-technical-diagrams/examples/checkout-platform.head.architecture.json +2 -1
  32. package/ai/skills/stacks-technical-diagrams/examples/checkout-request.waterfall.json +20 -0
  33. package/ai/skills/stacks-technical-diagrams/examples/class-payment-processors-rendered.html +14987 -0
  34. package/ai/skills/stacks-technical-diagrams/examples/class-payments-rendered.html +14787 -0
  35. package/ai/skills/stacks-technical-diagrams/examples/dataflow-product-analytics.html +14880 -0
  36. package/ai/skills/stacks-technical-diagrams/examples/delivery.explainer.json +155 -0
  37. package/ai/skills/stacks-technical-diagrams/examples/deployment-release.lifecycle.json +57 -34
  38. package/ai/skills/stacks-technical-diagrams/examples/erd-orders-rendered.html +15112 -0
  39. package/ai/skills/stacks-technical-diagrams/examples/event-stream.dataflow.json +1 -6
  40. package/ai/skills/stacks-technical-diagrams/examples/example-rebuild.waterfall.json +212 -0
  41. package/ai/skills/stacks-technical-diagrams/examples/holiday-planning.workflow.json +143 -0
  42. package/ai/skills/stacks-technical-diagrams/examples/incident-response.workflow.json +1 -6
  43. package/ai/skills/stacks-technical-diagrams/examples/lifecycle-agent-run.html +14892 -0
  44. package/ai/skills/stacks-technical-diagrams/examples/locales/de.json +463 -0
  45. package/ai/skills/stacks-technical-diagrams/examples/locales/fr.json +463 -0
  46. package/ai/skills/stacks-technical-diagrams/examples/locales/fr.partial.json +22 -0
  47. package/ai/skills/stacks-technical-diagrams/examples/locales/it.json +463 -0
  48. package/ai/skills/stacks-technical-diagrams/examples/locales/ja.json +463 -0
  49. package/ai/skills/stacks-technical-diagrams/examples/locales/pt.json +463 -0
  50. package/ai/skills/stacks-technical-diagrams/examples/locales/ru.json +463 -0
  51. package/ai/skills/stacks-technical-diagrams/examples/orders.erd.json +337 -0
  52. package/ai/skills/stacks-technical-diagrams/examples/payment-incident.timeline.json +24 -0
  53. package/ai/skills/stacks-technical-diagrams/examples/payment-platform.tree.json +22 -0
  54. package/ai/skills/stacks-technical-diagrams/examples/payment-processors.class.json +177 -0
  55. package/ai/skills/stacks-technical-diagrams/examples/payments.class.json +85 -0
  56. package/ai/skills/stacks-technical-diagrams/examples/product-analytics.dataflow.json +1 -6
  57. package/ai/skills/stacks-technical-diagrams/examples/production-deployment.architecture.json +3 -23
  58. package/ai/skills/stacks-technical-diagrams/examples/release-delivery.workflow.json +1 -6
  59. package/ai/skills/stacks-technical-diagrams/examples/sequence-cache-miss-request.html +14895 -0
  60. package/ai/skills/stacks-technical-diagrams/examples/subscription-billing-rendered.html +15369 -0
  61. package/ai/skills/stacks-technical-diagrams/examples/subscription-billing.erd.json +548 -0
  62. package/ai/skills/stacks-technical-diagrams/examples/timeline-archify-dev-activity-rendered.html +15002 -0
  63. package/ai/skills/stacks-technical-diagrams/examples/timeline-payment-incident-rendered.html +14772 -0
  64. package/ai/skills/stacks-technical-diagrams/examples/tree-archify-repository-rendered.html +15071 -0
  65. package/ai/skills/stacks-technical-diagrams/examples/tree-payment-platform-rendered.html +14810 -0
  66. package/ai/skills/stacks-technical-diagrams/examples/waterfall-checkout-request-rendered.html +14754 -0
  67. package/ai/skills/stacks-technical-diagrams/examples/waterfall-example-rebuild-rendered.html +14940 -0
  68. package/ai/skills/stacks-technical-diagrams/examples/web-app-rendered.html +14889 -0
  69. package/ai/skills/stacks-technical-diagrams/examples/web-app.architecture.json +1 -6
  70. package/ai/skills/stacks-technical-diagrams/examples/workflow-agent-tool-call-rendered.html +14907 -0
  71. package/ai/skills/stacks-technical-diagrams/explainer/browser-check.mjs +208 -0
  72. package/ai/skills/stacks-technical-diagrams/explainer/charts.mjs +70 -0
  73. package/ai/skills/stacks-technical-diagrams/explainer/check.mjs +168 -0
  74. package/ai/skills/stacks-technical-diagrams/explainer/diagrams.mjs +518 -0
  75. package/ai/skills/stacks-technical-diagrams/explainer/diff.mjs +124 -0
  76. package/ai/skills/stacks-technical-diagrams/explainer/inline.mjs +155 -0
  77. package/ai/skills/stacks-technical-diagrams/explainer/layout.mjs +35 -0
  78. package/ai/skills/stacks-technical-diagrams/explainer/page-bundle.mjs +16 -0
  79. package/ai/skills/stacks-technical-diagrams/explainer/parse.mjs +300 -0
  80. package/ai/skills/stacks-technical-diagrams/explainer/patch.mjs +117 -0
  81. package/ai/skills/stacks-technical-diagrams/explainer/prepare.mjs +131 -0
  82. package/ai/skills/stacks-technical-diagrams/explainer/reader.css +472 -0
  83. package/ai/skills/stacks-technical-diagrams/explainer/reader.js +667 -0
  84. package/ai/skills/stacks-technical-diagrams/explainer/render.mjs +224 -0
  85. package/ai/skills/stacks-technical-diagrams/explainer/revision.mjs +20 -0
  86. package/ai/skills/stacks-technical-diagrams/explainer/sources.mjs +318 -0
  87. package/ai/skills/stacks-technical-diagrams/explainer/validate.mjs +138 -0
  88. package/ai/skills/stacks-technical-diagrams/explainer/vendor/pele/LICENSE +40 -0
  89. package/ai/skills/stacks-technical-diagrams/explainer/vendor/pele/README.md +5 -0
  90. package/ai/skills/stacks-technical-diagrams/explainer/vendor/pele/chunks/3DKXF73K.js +4 -0
  91. package/ai/skills/stacks-technical-diagrams/explainer/vendor/pele/chunks/42UTT654.js +3 -0
  92. package/ai/skills/stacks-technical-diagrams/explainer/vendor/pele/chunks/DKTLEL5E.js +1 -0
  93. package/ai/skills/stacks-technical-diagrams/explainer/vendor/pele/chunks/EEIX5ZYH.js +2 -0
  94. package/ai/skills/stacks-technical-diagrams/explainer/vendor/pele/chunks/EJ5KOXYD.js +25 -0
  95. package/ai/skills/stacks-technical-diagrams/explainer/vendor/pele/chunks/GUJTEFZK.js +1 -0
  96. package/ai/skills/stacks-technical-diagrams/explainer/vendor/pele/chunks/IZOKQ2GT.js +4 -0
  97. package/ai/skills/stacks-technical-diagrams/explainer/vendor/pele/chunks/L4LY553T.js +3 -0
  98. package/ai/skills/stacks-technical-diagrams/explainer/vendor/pele/chunks/MSKIJHB2.js +2 -0
  99. package/ai/skills/stacks-technical-diagrams/explainer/vendor/pele/chunks/RVARI57O.js +1 -0
  100. package/ai/skills/stacks-technical-diagrams/explainer/vendor/pele/chunks/UKSIWDDN.js +2 -0
  101. package/ai/skills/stacks-technical-diagrams/explainer/vendor/pele/chunks/UPTXNAXN.js +2 -0
  102. package/ai/skills/stacks-technical-diagrams/explainer/vendor/pele/chunks/XTDUIGUI.js +9 -0
  103. package/ai/skills/stacks-technical-diagrams/explainer/vendor/pele/chunks/YAYTP6L5.js +9 -0
  104. package/ai/skills/stacks-technical-diagrams/explainer/vendor/pele/core.js +1 -0
  105. package/ai/skills/stacks-technical-diagrams/explainer/vendor/pele/diagrams/pie.js +1 -0
  106. package/ai/skills/stacks-technical-diagrams/explainer/vendor/pele/diagrams/quadrantChart.js +1 -0
  107. package/ai/skills/stacks-technical-diagrams/explainer/vendor/pele/diagrams/radar.js +1 -0
  108. package/ai/skills/stacks-technical-diagrams/explainer/vendor/pele/diagrams/sankey.js +1 -0
  109. package/ai/skills/stacks-technical-diagrams/explainer/vendor/pele/diagrams/venn.js +1 -0
  110. package/ai/skills/stacks-technical-diagrams/explainer/vendor/pele/diagrams/xychart.js +1 -0
  111. package/ai/skills/stacks-technical-diagrams/explainer/writing.mjs +139 -0
  112. package/ai/skills/stacks-technical-diagrams/locales/README.md +40 -0
  113. package/ai/skills/stacks-technical-diagrams/locales/ar.json +488 -0
  114. package/ai/skills/stacks-technical-diagrams/locales/en.json +488 -0
  115. package/ai/skills/stacks-technical-diagrams/locales/es.json +488 -0
  116. package/ai/skills/stacks-technical-diagrams/locales/ko.json +488 -0
  117. package/ai/skills/stacks-technical-diagrams/locales/manifest.json +10 -0
  118. package/ai/skills/stacks-technical-diagrams/locales/zh-CN.json +488 -0
  119. package/ai/skills/stacks-technical-diagrams/locales/zh-TW.json +488 -0
  120. package/ai/skills/stacks-technical-diagrams/migrations/workflow-v2.mjs +1 -0
  121. package/ai/skills/stacks-technical-diagrams/recipes/scenarios.mjs +115 -51
  122. package/ai/skills/stacks-technical-diagrams/references/architecture-layout-repair.md +18 -0
  123. package/ai/skills/stacks-technical-diagrams/references/authoring-contract.md +453 -51
  124. package/ai/skills/stacks-technical-diagrams/references/authoring-defaults.md +57 -0
  125. package/ai/skills/stacks-technical-diagrams/references/brand-marks.md +57 -3
  126. package/ai/skills/stacks-technical-diagrams/references/delivery-contract.md +603 -58
  127. package/ai/skills/stacks-technical-diagrams/references/explainer-authoring.md +274 -0
  128. package/ai/skills/stacks-technical-diagrams/references/repository-authoring.md +126 -0
  129. package/ai/skills/stacks-technical-diagrams/references/update-awareness.md +13 -0
  130. package/ai/skills/stacks-technical-diagrams/references/viewer-runtime.md +18 -11
  131. package/ai/skills/stacks-technical-diagrams/renderers/architecture/grid.mjs +1 -1
  132. package/ai/skills/stacks-technical-diagrams/renderers/architecture/labels.mjs +2 -0
  133. package/ai/skills/stacks-technical-diagrams/renderers/architecture/render-architecture.mjs +550 -424
  134. package/ai/skills/stacks-technical-diagrams/renderers/architecture/routing.mjs +1469 -0
  135. package/ai/skills/stacks-technical-diagrams/renderers/class/README.md +129 -0
  136. package/ai/skills/stacks-technical-diagrams/renderers/class/render-class.mjs +1095 -0
  137. package/ai/skills/stacks-technical-diagrams/renderers/dataflow/README.md +89 -17
  138. package/ai/skills/stacks-technical-diagrams/renderers/dataflow/dataflow-compiler.mjs +1605 -0
  139. package/ai/skills/stacks-technical-diagrams/renderers/dataflow/joint-label-routing.mjs +165 -0
  140. package/ai/skills/stacks-technical-diagrams/renderers/dataflow/label-capacity.mjs +81 -0
  141. package/ai/skills/stacks-technical-diagrams/renderers/dataflow/render-dataflow.mjs +14 -474
  142. package/ai/skills/stacks-technical-diagrams/renderers/erd/README.md +246 -0
  143. package/ai/skills/stacks-technical-diagrams/renderers/erd/grid.mjs +150 -0
  144. package/ai/skills/stacks-technical-diagrams/renderers/erd/render-erd.mjs +1588 -0
  145. package/ai/skills/stacks-technical-diagrams/renderers/explainer/render-explainer.mjs +42 -0
  146. package/ai/skills/stacks-technical-diagrams/renderers/lifecycle/README.md +83 -94
  147. package/ai/skills/stacks-technical-diagrams/renderers/lifecycle/render-lifecycle.mjs +990 -417
  148. package/ai/skills/stacks-technical-diagrams/renderers/sequence/README.md +49 -17
  149. package/ai/skills/stacks-technical-diagrams/renderers/sequence/render-sequence.mjs +735 -94
  150. package/ai/skills/stacks-technical-diagrams/renderers/shared/atomic-output.mjs +1982 -0
  151. package/ai/skills/stacks-technical-diagrams/renderers/shared/automatic-labels.mjs +290 -0
  152. package/ai/skills/stacks-technical-diagrams/renderers/shared/brand-marks.mjs +169 -26
  153. package/ai/skills/stacks-technical-diagrams/renderers/shared/cli.mjs +266 -54
  154. package/ai/skills/stacks-technical-diagrams/renderers/shared/desktop-readability.mjs +106 -0
  155. package/ai/skills/stacks-technical-diagrams/renderers/shared/diagnostics.mjs +0 -0
  156. package/ai/skills/stacks-technical-diagrams/renderers/shared/generated-validators.mjs +268 -2
  157. package/ai/skills/stacks-technical-diagrams/renderers/shared/geometry.mjs +774 -124
  158. package/ai/skills/stacks-technical-diagrams/renderers/shared/i18n.mjs +289 -556
  159. package/ai/skills/stacks-technical-diagrams/renderers/shared/layout-report.mjs +18 -1
  160. package/ai/skills/stacks-technical-diagrams/renderers/shared/legend.mjs +16 -6
  161. package/ai/skills/stacks-technical-diagrams/renderers/shared/node-card-style.mjs +32 -0
  162. package/ai/skills/stacks-technical-diagrams/renderers/shared/output-path.mjs +329 -229
  163. package/ai/skills/stacks-technical-diagrams/renderers/shared/owned-temp-directory.mjs +82 -0
  164. package/ai/skills/stacks-technical-diagrams/renderers/shared/path-semantics.mjs +1017 -0
  165. package/ai/skills/stacks-technical-diagrams/renderers/shared/portable-path.mjs +408 -0
  166. package/ai/skills/stacks-technical-diagrams/renderers/shared/repository-evidence.mjs +235 -79
  167. package/ai/skills/stacks-technical-diagrams/renderers/shared/repository-location.mjs +17 -4
  168. package/ai/skills/stacks-technical-diagrams/renderers/shared/route-quality.mjs +670 -0
  169. package/ai/skills/stacks-technical-diagrams/renderers/shared/sidecar-path.mjs +38 -0
  170. package/ai/skills/stacks-technical-diagrams/renderers/shared/software-notices.mjs +6 -0
  171. package/ai/skills/stacks-technical-diagrams/renderers/shared/spatial-grid.mjs +66 -0
  172. package/ai/skills/stacks-technical-diagrams/renderers/shared/svg-path-analysis.mjs +135 -0
  173. package/ai/skills/stacks-technical-diagrams/renderers/shared/text-fit.mjs +59 -3
  174. package/ai/skills/stacks-technical-diagrams/renderers/shared/utils.mjs +63 -35
  175. package/ai/skills/stacks-technical-diagrams/renderers/shared/validator.mjs +2 -5
  176. package/ai/skills/stacks-technical-diagrams/renderers/timeline/README.md +76 -0
  177. package/ai/skills/stacks-technical-diagrams/renderers/timeline/render-timeline.mjs +576 -0
  178. package/ai/skills/stacks-technical-diagrams/renderers/tree/README.md +96 -0
  179. package/ai/skills/stacks-technical-diagrams/renderers/tree/render-tree.mjs +573 -0
  180. package/ai/skills/stacks-technical-diagrams/renderers/waterfall/README.md +73 -0
  181. package/ai/skills/stacks-technical-diagrams/renderers/waterfall/render-waterfall.mjs +413 -0
  182. package/ai/skills/stacks-technical-diagrams/renderers/workflow/README.md +137 -23
  183. package/ai/skills/stacks-technical-diagrams/renderers/workflow/render-workflow.mjs +18 -6
  184. package/ai/skills/stacks-technical-diagrams/renderers/workflow/workflow-compiler.mjs +2230 -710
  185. package/ai/skills/stacks-technical-diagrams/renderers/workflow/workflow-migration-geometry.mjs +17 -0
  186. package/ai/skills/stacks-technical-diagrams/renderers/workflow/workflow-placement-repair.mjs +94 -0
  187. package/ai/skills/stacks-technical-diagrams/schemas/README.md +87 -40
  188. package/ai/skills/stacks-technical-diagrams/schemas/architecture.schema.json +7 -33
  189. package/ai/skills/stacks-technical-diagrams/schemas/class.schema.json +345 -0
  190. package/ai/skills/stacks-technical-diagrams/schemas/common.schema.json +68 -2
  191. package/ai/skills/stacks-technical-diagrams/schemas/dataflow.schema.json +14 -3
  192. package/ai/skills/stacks-technical-diagrams/schemas/erd.schema.json +381 -0
  193. package/ai/skills/stacks-technical-diagrams/schemas/explainer.schema.json +927 -0
  194. package/ai/skills/stacks-technical-diagrams/schemas/lifecycle.schema.json +23 -110
  195. package/ai/skills/stacks-technical-diagrams/schemas/sequence.schema.json +15 -4
  196. package/ai/skills/stacks-technical-diagrams/schemas/timeline.schema.json +160 -0
  197. package/ai/skills/stacks-technical-diagrams/schemas/tree.schema.json +141 -0
  198. package/ai/skills/stacks-technical-diagrams/schemas/waterfall.schema.json +147 -0
  199. package/ai/skills/stacks-technical-diagrams/schemas/workflow.schema.json +14 -3
  200. package/ai/skills/stacks-technical-diagrams/scripts/check-render-output.mjs +876 -243
  201. package/ai/skills/stacks-technical-diagrams/scripts/check-update.mjs +1717 -0
  202. package/ai/skills/stacks-technical-diagrams/scripts/delivery-update-child.mjs +26 -0
  203. package/ai/skills/stacks-technical-diagrams/scripts/generate-brand-marks.mjs +141 -0
  204. package/ai/skills/stacks-technical-diagrams/scripts/generate-validators.mjs +105 -0
  205. package/ai/skills/stacks-technical-diagrams/scripts/render-examples.mjs +11 -1
  206. package/ai/skills/stacks-technical-diagrams/scripts/update-contract.mjs +187 -0
  207. package/ai/skills/stacks-technical-diagrams/skill-release.json +10 -0
  208. package/ai/skills/stacks-testing/SKILL.md +8 -1
  209. package/ide/vscode/package.json +1 -1
  210. package/package.json +2 -2
@@ -1,5 +1,17 @@
1
1
  const TARGET_SCHEMA_VERSION = 2;
2
2
 
3
+ // Planning removes absolute route assertions, but must keep the same rank
4
+ // policy as the document whose coordinates will be mapped into that plan.
5
+ // An authored canvas likewise keeps its established plan: draft-only optional
6
+ // corridor growth must not consume space that a valid fixed canvas lacks.
7
+ const absoluteGeometryPolicy = Symbol('workflow absolute geometry policy');
8
+ export function preservesWorkflowAbsoluteGeometry(workflow) {
9
+ return workflow[absoluteGeometryPolicy] ?? (Array.isArray(workflow.meta?.viewBox) || (workflow.edges || []).some((edge) => (
10
+ Array.isArray(edge.via) || Array.isArray(edge.labelAt)
11
+ || edge.channelX !== undefined || edge.channelY !== undefined
12
+ )));
13
+ }
14
+
3
15
  function clone(value) {
4
16
  return JSON.parse(JSON.stringify(value));
5
17
  }
@@ -12,6 +24,7 @@ function clone(value) {
12
24
  export function intrinsicWorkflow(workflow) {
13
25
  const intrinsic = clone(workflow);
14
26
  intrinsic.schema_version = TARGET_SCHEMA_VERSION;
27
+ intrinsic[absoluteGeometryPolicy] = preservesWorkflowAbsoluteGeometry(workflow);
15
28
  intrinsic.meta = { ...intrinsic.meta };
16
29
  delete intrinsic.meta.viewBox;
17
30
  return intrinsic;
@@ -40,6 +53,10 @@ export function planningWorkflow(workflow) {
40
53
  return [automatic];
41
54
  });
42
55
 
56
+ // Full-topology contracts cannot be checked against a layout-only subgraph.
57
+ // The source and final mapped candidate retain and validate these contracts.
58
+ if (planned.edges.length !== workflow.edges.length) delete planned.semanticChecks;
59
+
43
60
  if (Array.isArray(planned.mainPath)) {
44
61
  const projectedPairs = new Set(planned.edges.map((edge) => `${edge.from}\u0000${edge.to}`));
45
62
  const projectionBreaksMainPath = planned.mainPath.some((from, index) => (
@@ -0,0 +1,94 @@
1
+ // One optional placement proposal for a failed readable workflow.
2
+ // Never applied to the authored input; the compiler verifies the complete result.
3
+ export function proposeWorkflowPlacement(input) {
4
+ if (input.schema_version !== 2 || input.meta?.viewBox
5
+ || input.groups?.length || input.phases?.length
6
+ || !input.mainPath?.length || input.nodes.length > 64
7
+ || input.edges.some(e => ['via', 'channelX', 'channelY', 'labelAt'].some(k => e[k] !== undefined))) {
8
+ return { eligible: false, reason: 'Needs unpinned v2, complete mainPath, no authored regions, <=64 nodes.' };
9
+ }
10
+ const main = input.mainPath;
11
+ const mainIndex = new Map(main.map((id, i) => [id, i]));
12
+ const nodes = new Map(input.nodes.map(n => [n.id, n]));
13
+ const laneIndex = new Map(input.lanes.map((l, i) => [l.id, i]));
14
+ if (main.some(id => !nodes.has(id)) || new Set(main).size !== main.length)
15
+ return { eligible: false, reason: 'Invalid mainPath.' };
16
+ const out = new Map(input.nodes.map(n => [n.id, input.edges.filter(e => e.from === n.id).map(e => e.to)]));
17
+ function reachable(id) {
18
+ const found = new Set(), todo = [...out.get(id)];
19
+ while (todo.length) {
20
+ const next = todo.pop();
21
+ if (found.has(next) || !nodes.has(next)) continue;
22
+ found.add(next); todo.push(...out.get(next));
23
+ }
24
+ return found;
25
+ }
26
+ const reach = new Map(input.nodes.map(n => [n.id, reachable(n.id)]));
27
+ const offMain = input.nodes.filter(n => !mainIndex.has(n.id));
28
+ const offIds = new Set(offMain.map(n => n.id));
29
+ const components = [], assigned = new Set();
30
+ for (const n of offMain) {
31
+ if (assigned.has(n.id)) continue;
32
+ const component = [], todo = [n.id];
33
+ while (todo.length) {
34
+ const id = todo.pop();
35
+ if (assigned.has(id)) continue;
36
+ assigned.add(id); component.push(id);
37
+ for (const e of input.edges) {
38
+ if (e.from === id && offIds.has(e.to)) todo.push(e.to);
39
+ if (e.to === id && offIds.has(e.from)) todo.push(e.from);
40
+ }
41
+ }
42
+ const cyclic = component.some(id => main.some(m => reach.get(id).has(m) && reach.get(m).has(id)));
43
+ components.push({ ids: component, cyclic });
44
+ }
45
+ const leftRail = components.some(c => c.cyclic);
46
+ if (!leftRail) return { eligible: false, reason: 'No return cycle connected to the main path.' };
47
+ const rightRail = components.some(c => !c.cyclic && c.ids.length > 1);
48
+ const start = leftRail ? 1 : 0, end = rightRail ? 4 : 5;
49
+ const proposed = structuredClone(input), moved = new Map(proposed.nodes.map(n => [n.id, n]));
50
+ let col = start;
51
+ for (let i = 0; i < main.length; i++) {
52
+ const current = moved.get(main[i]), previous = moved.get(main[i - 1]);
53
+ if (previous && laneIndex.get(current.lane) <= laneIndex.get(previous.lane)) col = Math.min(col + 1, end);
54
+ current.col = col;
55
+ }
56
+ for (const component of components) {
57
+ for (const id of component.ids) {
58
+ const n = moved.get(id);
59
+ const parents = input.edges.filter(e => e.to === id && mainIndex.has(e.from)).map(e => moved.get(e.from));
60
+ n.col = component.cyclic ? 0 : component.ids.length > 1 ? 5
61
+ : Math.min(end, Math.max(start, ...parents.map(p => p.col + 1)));
62
+ // Place same-lane failure branches below their main-path source row.
63
+ if (component.cyclic && parents.some(p => p.lane === n.lane)) {
64
+ const sameLane = main.map(m => moved.get(m)).filter(m => m.lane === n.lane);
65
+ n.yOffset = Math.max(...sameLane.map(m => (m.yOffset || 0) + (m.height || 52) / 2)) + (n.height || 52) / 2 + 40;
66
+ }
67
+ }
68
+ }
69
+ const groups = new Map();
70
+ for (const n of proposed.nodes) {
71
+ const key = n.lane + ':' + n.col;
72
+ groups.set(key, [...groups.get(key) || [], n]);
73
+ }
74
+ function order(n) {
75
+ if (mainIndex.has(n.id)) return mainIndex.get(n.id);
76
+ const incoming = input.edges.filter(e => e.to === n.id && mainIndex.has(e.from)).map(e => mainIndex.get(e.from));
77
+ return incoming.length ? Math.min(...incoming) + 0.5 : main.length;
78
+ }
79
+ for (const group of groups.values()) {
80
+ if (group.length < 2) continue;
81
+ group.sort((a, b) => order(a) - order(b) || a.id.localeCompare(b.id));
82
+ const total = group.reduce((sum, n) => sum + (n.height || 52), 0) + 40 * (group.length - 1);
83
+ let top = -total / 2;
84
+ for (const n of group) {
85
+ n.yOffset = top + (n.height || 52) / 2;
86
+ top += (n.height || 52) + 40;
87
+ }
88
+ }
89
+ const changes = [];
90
+ for (let i = 0; i < input.nodes.length; i++) for (const field of ['col', 'yOffset']) {
91
+ if (input.nodes[i][field] !== proposed.nodes[i][field]) changes.push({op: field in input.nodes[i] ? 'replace' : 'add', path: `/nodes/${i}/${field}`, value: proposed.nodes[i][field]});
92
+ }
93
+ return {eligible: true, proposed, changes, components, rails: {left: leftRail, right: rightRail}};
94
+ }
@@ -1,4 +1,4 @@
1
- # Technical Diagram JSON IR Schemas
1
+ # Archify JSON IR Schemas
2
2
 
3
3
  Each typed renderer consumes a JSON intermediate representation (IR) validated
4
4
  against one of the schemas in this folder before any layout work happens.
@@ -10,37 +10,54 @@ against one of the schemas in this folder before any layout work happens.
10
10
  | `workflow.schema.json` | `diagram_type: "workflow"` | `lanes`, `phases`, `groups`, `mainPath`, `nodes`, `edges` |
11
11
  | `sequence.schema.json` | `diagram_type: "sequence"` | `participants`, `segments`, `messages`, `activations` |
12
12
  | `dataflow.schema.json` | `diagram_type: "dataflow"` | `stages`, `nodes`, `flows` |
13
- | `lifecycle.schema.json` | `diagram_type: "lifecycle"` | `lanes`, `states`, `transitions` |
13
+ | `lifecycle.schema.json` | `diagram_type: "lifecycle"` | `mainPath`, `states`, `transitions` |
14
14
  | `architecture.schema.json` | `diagram_type: "architecture"` | `components`, `boundaries`, `connections` |
15
- | `common.schema.json` | shared `$defs` only (no top-level document) | - |
15
+ | `erd.schema.json` | `diagram_type: "erd"` | `entities`, `relationships` |
16
+ | `tree.schema.json` | `diagram_type: "tree"` | `nodes` (each with one `parent`) |
17
+ | `class.schema.json` | `diagram_type: "class"` | `types`, `relationships` |
18
+ | `timeline.schema.json` | `diagram_type: "timeline"` | `events` (`lanes` optional) |
19
+ | `waterfall.schema.json` | `diagram_type: "waterfall"` | `spans` (each with optional `parent`) |
20
+ | `common.schema.json` | shared `$defs` only (no top-level document) | — |
16
21
 
17
22
  Every diagram schema requires `schema_version`, `diagram_type`, `meta` (with
18
- `title`), and its structural arrays - except `segments`, `activations`, and
19
- `cards`, which are optional - and sets `additionalProperties: false` at every
23
+ `title` and a durable portable `output`), and its structural arrays — except `segments`, `activations`, ERD and class
24
+ `relationships`, and `cards`, which are optional — and sets `additionalProperties: false` at every
20
25
  level, so unknown fields are rejected rather than silently ignored.
21
26
 
22
27
  Every `meta` object also accepts `animation: "trace"` for opt-in SVG/CSS motion
23
28
  in generated HTML. Omit it, or set `"none"`, for the default static output.
24
- It also accepts `locale: "en" | "zh-CN"`. The field selects the fixed Viewer
25
- UI, renderer-owned default legend and accessibility copy, document-title
26
- suffix, and `<html lang>` value; it does not translate authored strings.
27
- Omitting it preserves legacy behavior and resolves to English. Unsupported
28
- locale values fail schema validation instead of being guessed or silently
29
- rewritten.
29
+ It also accepts `locale`, any well-formed language tag (schema pattern
30
+ `^[a-z]{2,3}(-[A-Za-z0-9]{2,8})*$`). The field selects the fixed Viewer UI,
31
+ renderer-owned default legend and accessibility copy, document-title suffix,
32
+ and `<html lang>` value; it does not translate authored strings. The bundled
33
+ catalogs enrolled in `locales/manifest.json` (`en`, `zh-CN`, `zh-TW`, `es`, `ko`, `ar`) are
34
+ selected by tag, case-insensitively; region and script variants are distinct
35
+ tags. Any other tag needs a matching `translations` object (see below) or the
36
+ renderer falls back to English and discloses it.
37
+ Omitting `locale` preserves legacy behavior and resolves to English.
38
+ Malformed locale tags fail schema validation instead of being guessed or
39
+ silently rewritten.
40
+
41
+ `meta.translations` is an optional per-key override, as data: an object mapping
42
+ canonical message keys (`locales/en.json`) to translated strings whose
43
+ `{placeholder}` tokens match the English source. Each message resolves as:
44
+ valid `translations` value → bundled catalog for `locale` → English. An
45
+ unrecognized key or mismatched placeholders never replaces a valid
46
+ lower-priority message and fails no render; `validate`/`render`/`deliver`
47
+ report rejected entries and the final resolved coverage to stderr.
30
48
  `visual_preset` accepts `classic` (the stable default), `signal-flow` (luminous
31
49
  motion-forward presentation), `blueprint` (high-contrast engineering review),
32
50
  or `editorial` (warm publication-style design review and documentation).
33
51
  Presets change only viewer styling; they do not alter semantic IDs or geometry.
34
- Sequence `meta` additionally accepts `column_fit`. The default `fixed` keeps
35
- the historical 108px column gap and 86px participant boxes, so an authored
36
- diagram renders at the same coordinates no matter how wide its viewBox is.
37
- `spread` derives the gap and box width from the viewBox instead, which turns a
52
+ Sequence `meta` additionally accepts `column_fit`. The default `spread` applies whether or not `meta.viewBox` is supplied.
53
+ Explicit `fixed` keeps the historical 108px column gap and 86px participant
54
+ boxes. `spread` derives column distance and box width from the viewBox, with
55
+ at least a 16px gutter between participant cards, which turns a
38
56
  wide canvas into column distance and label room rather than empty space on the
39
57
  right. Lane order, IDs, and message semantics are unchanged either way.
40
58
 
41
- It may also include up to five guided `views`. Each view has a unique `id`, a
42
- reader-facing `label`, a non-empty `focus` list of existing semantic node IDs,
43
- and an optional short `note`.
59
+ `meta.views` is retired. The schemas still accept the old guided-view shape so
60
+ existing files keep validating, but renderers ignore it; do not author it.
44
61
 
45
62
  ### Legend presentation contract
46
63
 
@@ -63,7 +80,7 @@ Architecture documents that omit an explicit `viewBox` size that automatic
63
80
  viewBox from the same measured resolved legend footprint used for final SVG
64
81
  layout. Across all renderers, legacy documents that omit `meta.legend` use a
65
82
  compatibility-safe implicit `auto`: if the resolved legend cannot fit an
66
- explicit authored viewBox without overlap, the renderer omits the complete legend
83
+ explicit authored viewBox without overlap, Archify omits the complete legend
67
84
  instead of turning a previously valid schema-v1 document into a hard failure.
68
85
  Once an author adds `meta.legend` (including explicit `mode: "auto"`), the
69
86
  layout is intentional and unfit labels or bands fail with a path-prefixed
@@ -82,6 +99,8 @@ Supported keys are renderer-owned:
82
99
  | Sequence | `emphasis`, `return`, `security`, `dashed`, `default` |
83
100
  | Dataflow | `emphasis`, `security`, `dashed`, `database`, `default` |
84
101
  | Lifecycle | `start`, `active`, `waiting`, `decision`, `success`, `failure`, `neutral`, `external` |
102
+ | ERD | `pk`, `fk`, `uk`, `one`, `many`, `optional` |
103
+ | Class | `dependency`, `association`, `inheritance`, `realization`, `composition`, `aggregation` |
85
104
 
86
105
  Labels are presentation only: they do not rename the stable kind, change
87
106
  nodes/relationships, or create Semantic Lens edge facts. Sequence message and
@@ -99,8 +118,8 @@ local to the current page.
99
118
 
100
119
  Every semantic node collection (`components`, `nodes`, `participants`, and
101
120
  `states`) also accepts one optional `brand`: either a canonical string returned
102
- by `.claude/skills/stacks-technical-diagrams/bin/diagrams brands --json`, or a digest-pinned `{ "url", "sha256" }` object
103
- returned by `.claude/skills/stacks-technical-diagrams/bin/diagrams brands capture <url> --json`. Known IDs and known-brand
121
+ by `archify brands --json`, or a digest-pinned `{ "url", "sha256" }` object
122
+ returned by `archify brands capture <url> --json`. Known IDs and known-brand
104
123
  domains use the bundled vector catalogue. Unknown URLs must be captured in that
105
124
  explicit command before authoring; render and validate never perform an
106
125
  unpinned network capture. Unsafe, unavailable, changed, or unsupported content
@@ -111,8 +130,15 @@ output.
111
130
 
112
131
  Workflow supports schema versions 1 and 2. Version 1 remains the fixed-layout
113
132
  compatibility contract; version 2 opts into the readable workflow compiler and
114
- can be produced explicitly with `.claude/skills/stacks-technical-diagrams/bin/diagrams migrate workflow ... --to-schema 2`.
115
- The other four diagram schemas keep `schema_version` pinned to `1`.
133
+ can be produced explicitly with `archify migrate workflow ... --to-schema 2`.
134
+ Lifecycle accepts only version 3, an automatic main-path layout (see the
135
+ [lifecycle renderer](../renderers/lifecycle/README.md)).
136
+ The other three diagram schemas keep `schema_version` pinned to `1`; they have
137
+ no schema-version migration command. For any of the five diagram types, repair
138
+ a legacy missing or nonportable `meta.output` in the source and run `validate`.
139
+ For a workflow v1-to-v2 migration specifically, `migrate workflow` also accepts
140
+ `--output reports/diagram.html` to put that portable value in the separate v2
141
+ destination without changing the legacy source.
116
142
 
117
143
  Workflow also accepts optional `semanticChecks`. `allowedRoots` and
118
144
  `allowedTerminals` close the set of intentional graph sources and sinks;
@@ -124,7 +150,13 @@ workflow behavior and including a satisfied contract does not change SVG or
124
150
  layout-receipt bytes.
125
151
 
126
152
  A file that validates today must keep validating and rendering within its
127
- declared version throughout the 2.x release line. Additive viewer,
153
+ declared version throughout the 2.x release line. The explicitly reviewed
154
+ portable-output hardening is the one exception: older v1 documents that omit
155
+ `meta.output` must add a portable POSIX-relative `.html` path (for example,
156
+ `reports/diagram.html`); ordinary explicit CLI output arguments do not replace
157
+ this durable authored value. The workflow-only v1-to-v2 migration command may
158
+ instead receive that value explicitly as `--output reports/diagram.html`; it
159
+ writes the value only to its separate validated destination. Additive viewer,
128
160
  accessibility, and presentation improvements may enhance generated HTML, but
129
161
  they must not reinterpret authored IR or turn a previously valid profile-less
130
162
  v1 file into a new hard layout failure. Breaking IR changes require a new
@@ -134,22 +166,33 @@ version; additive, backwards-compatible fields do not.
134
166
 
135
167
  The five diagram schemas reference `common.schema.json#/$defs/...`:
136
168
 
137
- - `id` - element identifiers, pattern `^[a-zA-Z][a-zA-Z0-9_-]*$`
138
- - `point` - an `[x, y]` pair of numbers (used by `via` and `labelAt`)
139
- - `componentType` - `frontend`, `backend`, `database`, `cloud`, `security`,
169
+ - `id` — element identifiers, pattern `^[a-zA-Z][a-zA-Z0-9_-]*$`
170
+ - `point` — an `[x, y]` pair of numbers (used by `via` and `labelAt`)
171
+ - `componentType` — `frontend`, `backend`, `database`, `cloud`, `security`,
140
172
  `messagebus`, `external`
141
- - `locale` - the bounded renderer locale, `en` or `zh-CN`
142
- - `brandMark` - one optional built-in brand ID or explicit HTTP(S) site URL
143
- - `variant` - `default`, `emphasis`, `security`, `dashed` (sequence messages
173
+ - `locale` — a well-formed renderer locale tag (bundled catalogs are listed in
174
+ `locales/manifest.json`; any other tag needs a matching `translations` object)
175
+ - `translations` — canonical message key → translated string, layered over the
176
+ bundled catalog for `locale`, then English
177
+ - `portableOutputPath` — the portable POSIX-relative `.html` path used by
178
+ `meta.output`; see the two output-path boundaries in the
179
+ [delivery contract](../references/delivery-contract.md#output-path-contracts)
180
+ - `brandMark` — one optional built-in brand ID or explicit HTTP(S) site URL
181
+ - `variant` — `default`, `emphasis`, `security`, `dashed` (sequence messages
144
182
  extend this list locally with `return`)
145
- - `legendMode` and `legendEntry` - the shared strict mode and label/visibility
183
+ - `legendMode` and `legendEntry` — the shared strict mode and label/visibility
146
184
  override shapes used by each renderer-owned key map
147
- - `guidedViews` - the bounded, read-only reader paths accepted by `meta.views`
148
- - `cards` - the summary-card blocks rendered below the SVG
185
+ - `guidedViews` — the retired `meta.views` shape, still accepted and ignored
186
+ - `cards` — the summary-card blocks rendered below the SVG
149
187
 
150
188
  Lifecycle state `type` is mode-specific (`start`/`active`/`waiting`/...) and
151
189
  stays in `lifecycle.schema.json`.
152
190
 
191
+ The JSON Schema definition is the portable contract's structurally expressible
192
+ preflight. The shipped generated validator wrapper and CLI additionally enforce
193
+ byte-based component limits and the complete runtime path contract; consumers
194
+ that need the same cross-platform acceptance boundary should use that wrapper.
195
+
153
196
  ## Runtime validation
154
197
 
155
198
  At development time, `scripts/generate-validators.mjs` compiles all five
@@ -163,10 +206,14 @@ express cleanly here: duplicate view IDs, duplicate focus IDs, focus IDs that do
163
206
  not exist in the diagram's semantic collection, and duplicate authored
164
207
  relationship IDs within the mode's relationship collection.
165
208
 
166
- Architecture additionally supports opt-in, revision-pinned repository evidence.
167
- `meta.repository` names a public GitHub URL and full commit SHA; a component may
168
- carry one to three `sources` with repo-relative POSIX paths, optional line
169
- ranges, and optional labels. Shape is schema-checked, then the renderer requires
209
+ All five modes support opt-in, revision-pinned repository evidence.
210
+ `meta.repository` names the repository URL and full commit SHA, with optional
211
+ `provider` (`github`, `gitee`, or `gitlab`) and `link_mode` (`web` or `local-only`; see the
212
+ authoring contract); a node may carry one to three `sources` with repo-relative POSIX paths, optional line
213
+ ranges, and optional labels. Sources are authored on the mode's own node
214
+ collection — Architecture `components`, Workflow and Data Flow `nodes`,
215
+ Sequence `participants`, Lifecycle `states` — and the verified payload is keyed
216
+ by node id. Shape is schema-checked, then the renderer requires
170
217
  `--repo-root`: the local Git origin must match, and Git must prove the commit,
171
218
  blobs, and requested lines. Verified evidence is embedded outside the canonical
172
219
  SVG for the Semantic Passport and Node Finder; ordinary documents and visual
@@ -176,7 +223,7 @@ exports carry no repository evidence.
176
223
 
177
224
  `meta.quality_profile` and `meta.engineering_profile` answer different
178
225
  questions. `quality_profile` is available in all five modes and controls how
179
- strictly the renderer judges composition. `engineering_profile` is an optional
226
+ strictly Archify judges composition. `engineering_profile` is an optional
180
227
  Architecture-only semantic contract; omitting it preserves the ordinary v1
181
228
  behavior.
182
229
 
@@ -199,8 +246,8 @@ validators drift from their schemas.
199
246
  ## Error format
200
247
 
201
248
  Schema violations exit non-zero. Each ajv error is reported on its own line as
202
- the instance path - annotated with the nearest enclosing element's `id` or
203
- `label` - followed by the message and parameters:
249
+ the instance path — annotated with the nearest enclosing element's `id` or
250
+ `label` — followed by the message and parameters:
204
251
 
205
252
  ```text
206
253
  workflow schema validation failed:
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "$schema": "https://json-schema.org/draft/2020-12/schema",
3
3
  "$id": "https://github.com/tt-a1i/archify/schemas/architecture.schema.json",
4
- "title": "Technical Architecture Diagram",
4
+ "title": "Archify Architecture Diagram",
5
5
  "type": "object",
6
6
  "additionalProperties": false,
7
7
  "required": ["schema_version", "diagram_type", "meta", "components"],
@@ -11,30 +11,18 @@
11
11
  "meta": {
12
12
  "type": "object",
13
13
  "additionalProperties": false,
14
- "required": ["title"],
14
+ "required": ["title", "output"],
15
15
  "properties": {
16
16
  "title": { "type": "string", "minLength": 1 },
17
17
  "locale": { "$ref": "common.schema.json#/$defs/locale" },
18
+ "translations": { "$ref": "common.schema.json#/$defs/translations" },
18
19
  "subtitle": { "type": "string" },
19
- "output": { "type": "string" },
20
+ "output": { "$ref": "common.schema.json#/$defs/portableOutputPath" },
20
21
  "animation": { "$ref": "common.schema.json#/$defs/animation" },
21
22
  "visual_preset": { "$ref": "common.schema.json#/$defs/visualPreset" },
22
23
  "quality_profile": { "$ref": "common.schema.json#/$defs/qualityProfile" },
23
24
  "engineering_profile": { "enum": ["deployment-ownership"] },
24
- "repository": {
25
- "type": "object",
26
- "additionalProperties": false,
27
- "required": ["url", "revision"],
28
- "properties": {
29
- "url": {
30
- "type": "string",
31
- "minLength": 1
32
- },
33
- "provider": { "enum": ["github", "gitee"] },
34
- "link_mode": { "enum": ["web", "local-only"] },
35
- "revision": { "type": "string", "pattern": "^[a-fA-F0-9]{40}$" }
36
- }
37
- },
25
+ "repository": { "$ref": "common.schema.json#/$defs/repository" },
38
26
  "views": { "$ref": "common.schema.json#/$defs/guidedViews" },
39
27
  "legend": {
40
28
  "type": "object",
@@ -95,23 +83,9 @@
95
83
  "label": { "type": "string", "minLength": 1 },
96
84
  "sublabel": { "type": "string" },
97
85
  "tag": { "type": "string" },
86
+ "icon": { "$ref": "common.schema.json#/$defs/nodeIcon" },
98
87
  "brand": { "$ref": "common.schema.json#/$defs/brandMark" },
99
- "sources": {
100
- "type": "array",
101
- "minItems": 1,
102
- "maxItems": 3,
103
- "items": {
104
- "type": "object",
105
- "additionalProperties": false,
106
- "required": ["path"],
107
- "properties": {
108
- "path": { "type": "string", "minLength": 1, "maxLength": 240 },
109
- "line": { "type": "integer", "minimum": 1 },
110
- "end_line": { "type": "integer", "minimum": 1 },
111
- "label": { "type": "string", "minLength": 1, "maxLength": 48 }
112
- }
113
- }
114
- },
88
+ "sources": { "$ref": "common.schema.json#/$defs/sourceReferences" },
115
89
  "row": { "type": "integer", "minimum": 0 },
116
90
  "col": { "type": "integer", "minimum": 0 },
117
91
  "pos": { "$ref": "common.schema.json#/$defs/point" },