@transitrix/diagrams 1.0.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 (541) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +47 -0
  3. package/dist/__tests__/edge-path.test.d.ts +1 -0
  4. package/dist/__tests__/edge-path.test.js +39 -0
  5. package/dist/__tests__/scope.test.d.ts +1 -0
  6. package/dist/__tests__/scope.test.js +23 -0
  7. package/dist/__tests__/yaml-normalize.test.d.ts +1 -0
  8. package/dist/__tests__/yaml-normalize.test.js +148 -0
  9. package/dist/activities/__tests__/cpm.test.d.ts +1 -0
  10. package/dist/activities/__tests__/cpm.test.js +146 -0
  11. package/dist/activities/__tests__/gantt.test.d.ts +1 -0
  12. package/dist/activities/__tests__/gantt.test.js +224 -0
  13. package/dist/activities/__tests__/layout.test.d.ts +1 -0
  14. package/dist/activities/__tests__/layout.test.js +98 -0
  15. package/dist/activities/__tests__/validate.test.d.ts +1 -0
  16. package/dist/activities/__tests__/validate.test.js +363 -0
  17. package/dist/activities/cpm.d.ts +2 -0
  18. package/dist/activities/cpm.js +86 -0
  19. package/dist/activities/gantt.d.ts +6 -0
  20. package/dist/activities/gantt.js +250 -0
  21. package/dist/activities/index.d.ts +5 -0
  22. package/dist/activities/index.js +4 -0
  23. package/dist/activities/layout.d.ts +2 -0
  24. package/dist/activities/layout.js +103 -0
  25. package/dist/activities/types.d.ts +125 -0
  26. package/dist/activities/types.js +1 -0
  27. package/dist/activities/validate.d.ts +2 -0
  28. package/dist/activities/validate.js +326 -0
  29. package/dist/activity-card/__tests__/example.test.d.ts +1 -0
  30. package/dist/activity-card/__tests__/example.test.js +56 -0
  31. package/dist/activity-card/__tests__/layout.test.d.ts +1 -0
  32. package/dist/activity-card/__tests__/layout.test.js +57 -0
  33. package/dist/activity-card/__tests__/resolver.test.d.ts +1 -0
  34. package/dist/activity-card/__tests__/resolver.test.js +146 -0
  35. package/dist/activity-card/__tests__/validate.test.d.ts +1 -0
  36. package/dist/activity-card/__tests__/validate.test.js +116 -0
  37. package/dist/activity-card/index.d.ts +5 -0
  38. package/dist/activity-card/index.js +3 -0
  39. package/dist/activity-card/layout.d.ts +7 -0
  40. package/dist/activity-card/layout.js +167 -0
  41. package/dist/activity-card/resolver.d.ts +7 -0
  42. package/dist/activity-card/resolver.js +310 -0
  43. package/dist/activity-card/types.d.ts +175 -0
  44. package/dist/activity-card/types.js +20 -0
  45. package/dist/activity-card/validate.d.ts +3 -0
  46. package/dist/activity-card/validate.js +145 -0
  47. package/dist/actor/__tests__/validate.test.d.ts +1 -0
  48. package/dist/actor/__tests__/validate.test.js +57 -0
  49. package/dist/actor/index.d.ts +3 -0
  50. package/dist/actor/index.js +2 -0
  51. package/dist/actor/types.d.ts +20 -0
  52. package/dist/actor/types.js +4 -0
  53. package/dist/actor/validate.d.ts +2 -0
  54. package/dist/actor/validate.js +34 -0
  55. package/dist/applications/__tests__/validate.test.d.ts +1 -0
  56. package/dist/applications/__tests__/validate.test.js +223 -0
  57. package/dist/applications/index.d.ts +2 -0
  58. package/dist/applications/index.js +1 -0
  59. package/dist/applications/types.d.ts +39 -0
  60. package/dist/applications/types.js +1 -0
  61. package/dist/applications/validate.d.ts +3 -0
  62. package/dist/applications/validate.js +109 -0
  63. package/dist/assertion/__tests__/example.test.d.ts +1 -0
  64. package/dist/assertion/__tests__/example.test.js +32 -0
  65. package/dist/assertion/__tests__/validate.test.d.ts +1 -0
  66. package/dist/assertion/__tests__/validate.test.js +130 -0
  67. package/dist/assertion/index.d.ts +4 -0
  68. package/dist/assertion/index.js +2 -0
  69. package/dist/assertion/types.d.ts +43 -0
  70. package/dist/assertion/types.js +7 -0
  71. package/dist/assertion/validate.d.ts +9 -0
  72. package/dist/assertion/validate.js +137 -0
  73. package/dist/blocks/__tests__/layout.test.d.ts +1 -0
  74. package/dist/blocks/__tests__/layout.test.js +153 -0
  75. package/dist/blocks/__tests__/validate.test.d.ts +1 -0
  76. package/dist/blocks/__tests__/validate.test.js +235 -0
  77. package/dist/blocks/index.d.ts +4 -0
  78. package/dist/blocks/index.js +2 -0
  79. package/dist/blocks/layout.d.ts +4 -0
  80. package/dist/blocks/layout.js +145 -0
  81. package/dist/blocks/types.d.ts +56 -0
  82. package/dist/blocks/types.js +1 -0
  83. package/dist/blocks/validate.d.ts +9 -0
  84. package/dist/blocks/validate.js +186 -0
  85. package/dist/capability-map/__tests__/validate.test.d.ts +1 -0
  86. package/dist/capability-map/__tests__/validate.test.js +212 -0
  87. package/dist/capability-map/index.d.ts +2 -0
  88. package/dist/capability-map/index.js +1 -0
  89. package/dist/capability-map/types.d.ts +26 -0
  90. package/dist/capability-map/types.js +1 -0
  91. package/dist/capability-map/validate.d.ts +3 -0
  92. package/dist/capability-map/validate.js +103 -0
  93. package/dist/change/__tests__/validate.test.d.ts +1 -0
  94. package/dist/change/__tests__/validate.test.js +73 -0
  95. package/dist/change/index.d.ts +2 -0
  96. package/dist/change/index.js +1 -0
  97. package/dist/change/types.d.ts +17 -0
  98. package/dist/change/types.js +3 -0
  99. package/dist/change/validate.d.ts +2 -0
  100. package/dist/change/validate.js +57 -0
  101. package/dist/compliance/__tests__/classify.test.d.ts +1 -0
  102. package/dist/compliance/__tests__/classify.test.js +24 -0
  103. package/dist/compliance/__tests__/confidence.test.d.ts +1 -0
  104. package/dist/compliance/__tests__/confidence.test.js +78 -0
  105. package/dist/compliance/__tests__/coverage-metric.test.d.ts +1 -0
  106. package/dist/compliance/__tests__/coverage-metric.test.js +164 -0
  107. package/dist/compliance/__tests__/demo-scenario.test.d.ts +1 -0
  108. package/dist/compliance/__tests__/demo-scenario.test.js +226 -0
  109. package/dist/compliance/__tests__/example.test.d.ts +1 -0
  110. package/dist/compliance/__tests__/example.test.js +51 -0
  111. package/dist/compliance/__tests__/gap-report.test.d.ts +1 -0
  112. package/dist/compliance/__tests__/gap-report.test.js +113 -0
  113. package/dist/compliance/__tests__/html.test.d.ts +1 -0
  114. package/dist/compliance/__tests__/html.test.js +122 -0
  115. package/dist/compliance/__tests__/impact.test.d.ts +1 -0
  116. package/dist/compliance/__tests__/impact.test.js +410 -0
  117. package/dist/compliance/__tests__/markdown.test.d.ts +1 -0
  118. package/dist/compliance/__tests__/markdown.test.js +85 -0
  119. package/dist/compliance/__tests__/views.test.d.ts +1 -0
  120. package/dist/compliance/__tests__/views.test.js +59 -0
  121. package/dist/compliance/classify.d.ts +27 -0
  122. package/dist/compliance/classify.js +60 -0
  123. package/dist/compliance/confidence.d.ts +27 -0
  124. package/dist/compliance/confidence.js +43 -0
  125. package/dist/compliance/coverage-metric.d.ts +74 -0
  126. package/dist/compliance/coverage-metric.js +181 -0
  127. package/dist/compliance/gap-report.d.ts +20 -0
  128. package/dist/compliance/gap-report.js +64 -0
  129. package/dist/compliance/html.d.ts +22 -0
  130. package/dist/compliance/html.js +256 -0
  131. package/dist/compliance/impact.d.ts +251 -0
  132. package/dist/compliance/impact.js +464 -0
  133. package/dist/compliance/index.d.ts +16 -0
  134. package/dist/compliance/index.js +9 -0
  135. package/dist/compliance/markdown.d.ts +18 -0
  136. package/dist/compliance/markdown.js +129 -0
  137. package/dist/compliance/reverse-index.d.ts +8 -0
  138. package/dist/compliance/reverse-index.js +30 -0
  139. package/dist/compliance/types.d.ts +98 -0
  140. package/dist/compliance/types.js +5 -0
  141. package/dist/compliance/views.d.ts +14 -0
  142. package/dist/compliance/views.js +35 -0
  143. package/dist/compliance-matrix/__tests__/build.test.d.ts +1 -0
  144. package/dist/compliance-matrix/__tests__/build.test.js +183 -0
  145. package/dist/compliance-matrix/__tests__/example.test.d.ts +1 -0
  146. package/dist/compliance-matrix/__tests__/example.test.js +49 -0
  147. package/dist/compliance-matrix/build.d.ts +18 -0
  148. package/dist/compliance-matrix/build.js +0 -0
  149. package/dist/compliance-matrix/index.d.ts +2 -0
  150. package/dist/compliance-matrix/index.js +1 -0
  151. package/dist/compliance-matrix/types.d.ts +86 -0
  152. package/dist/compliance-matrix/types.js +8 -0
  153. package/dist/confidence/__tests__/score.test.d.ts +1 -0
  154. package/dist/confidence/__tests__/score.test.js +188 -0
  155. package/dist/confidence/index.d.ts +2 -0
  156. package/dist/confidence/index.js +1 -0
  157. package/dist/confidence/score.d.ts +62 -0
  158. package/dist/confidence/score.js +215 -0
  159. package/dist/confidence/types.d.ts +79 -0
  160. package/dist/confidence/types.js +6 -0
  161. package/dist/edge-path.d.ts +18 -0
  162. package/dist/edge-path.js +35 -0
  163. package/dist/element-envelope.d.ts +15 -0
  164. package/dist/element-envelope.js +55 -0
  165. package/dist/factor/__tests__/validate.test.d.ts +1 -0
  166. package/dist/factor/__tests__/validate.test.js +83 -0
  167. package/dist/factor/index.d.ts +3 -0
  168. package/dist/factor/index.js +2 -0
  169. package/dist/factor/types.d.ts +23 -0
  170. package/dist/factor/types.js +6 -0
  171. package/dist/factor/validate.d.ts +2 -0
  172. package/dist/factor/validate.js +69 -0
  173. package/dist/fgca/__tests__/chain-table.test.d.ts +1 -0
  174. package/dist/fgca/__tests__/chain-table.test.js +158 -0
  175. package/dist/fgca/__tests__/layout.test.d.ts +1 -0
  176. package/dist/fgca/__tests__/layout.test.js +140 -0
  177. package/dist/fgca/__tests__/parse-canonical.test.d.ts +1 -0
  178. package/dist/fgca/__tests__/parse-canonical.test.js +224 -0
  179. package/dist/fgca/__tests__/preview-layout.test.d.ts +1 -0
  180. package/dist/fgca/__tests__/preview-layout.test.js +106 -0
  181. package/dist/fgca/__tests__/validate.test.d.ts +1 -0
  182. package/dist/fgca/__tests__/validate.test.js +125 -0
  183. package/dist/fgca/chain-table.d.ts +36 -0
  184. package/dist/fgca/chain-table.js +177 -0
  185. package/dist/fgca/index.d.ts +16 -0
  186. package/dist/fgca/index.js +11 -0
  187. package/dist/fgca/layout.d.ts +27 -0
  188. package/dist/fgca/layout.js +156 -0
  189. package/dist/fgca/nodeTypes.d.ts +6 -0
  190. package/dist/fgca/nodeTypes.js +10 -0
  191. package/dist/fgca/nodes/FGCAActivityNode.d.ts +13 -0
  192. package/dist/fgca/nodes/FGCAActivityNode.js +35 -0
  193. package/dist/fgca/nodes/FGCAChangeNode.d.ts +12 -0
  194. package/dist/fgca/nodes/FGCAChangeNode.js +35 -0
  195. package/dist/fgca/nodes/FGCAFactorNode.d.ts +12 -0
  196. package/dist/fgca/nodes/FGCAFactorNode.js +35 -0
  197. package/dist/fgca/nodes/FGCAGoalNode.d.ts +14 -0
  198. package/dist/fgca/nodes/FGCAGoalNode.js +40 -0
  199. package/dist/fgca/parse-canonical.d.ts +58 -0
  200. package/dist/fgca/parse-canonical.js +339 -0
  201. package/dist/fgca/preview-layout.d.ts +87 -0
  202. package/dist/fgca/preview-layout.js +122 -0
  203. package/dist/fgca/types.d.ts +39 -0
  204. package/dist/fgca/types.js +7 -0
  205. package/dist/fgca/validate.d.ts +14 -0
  206. package/dist/fgca/validate.js +108 -0
  207. package/dist/geometry.d.ts +7 -0
  208. package/dist/geometry.js +2 -0
  209. package/dist/goals/__tests__/layout.test.d.ts +1 -0
  210. package/dist/goals/__tests__/layout.test.js +153 -0
  211. package/dist/goals/__tests__/mutations.test.d.ts +1 -0
  212. package/dist/goals/__tests__/mutations.test.js +95 -0
  213. package/dist/goals/__tests__/parse-canonical.test.d.ts +1 -0
  214. package/dist/goals/__tests__/parse-canonical.test.js +129 -0
  215. package/dist/goals/__tests__/validate.test.d.ts +1 -0
  216. package/dist/goals/__tests__/validate.test.js +183 -0
  217. package/dist/goals/index.d.ts +6 -0
  218. package/dist/goals/index.js +4 -0
  219. package/dist/goals/layout.d.ts +11 -0
  220. package/dist/goals/layout.js +147 -0
  221. package/dist/goals/mutations.d.ts +6 -0
  222. package/dist/goals/mutations.js +116 -0
  223. package/dist/goals/parse-canonical.d.ts +29 -0
  224. package/dist/goals/parse-canonical.js +257 -0
  225. package/dist/goals/types.d.ts +71 -0
  226. package/dist/goals/types.js +1 -0
  227. package/dist/goals/validate.d.ts +2 -0
  228. package/dist/goals/validate.js +122 -0
  229. package/dist/index.d.ts +23 -0
  230. package/dist/index.js +23 -0
  231. package/dist/issues/__tests__/layout.test.d.ts +1 -0
  232. package/dist/issues/__tests__/layout.test.js +62 -0
  233. package/dist/issues/__tests__/validate.test.d.ts +1 -0
  234. package/dist/issues/__tests__/validate.test.js +82 -0
  235. package/dist/issues/index.d.ts +4 -0
  236. package/dist/issues/index.js +2 -0
  237. package/dist/issues/layout.d.ts +10 -0
  238. package/dist/issues/layout.js +82 -0
  239. package/dist/issues/types.d.ts +61 -0
  240. package/dist/issues/types.js +6 -0
  241. package/dist/issues/validate.d.ts +3 -0
  242. package/dist/issues/validate.js +143 -0
  243. package/dist/process-blueprint/__tests__/compliance-lane.test.d.ts +1 -0
  244. package/dist/process-blueprint/__tests__/compliance-lane.test.js +272 -0
  245. package/dist/process-blueprint/__tests__/layout.test.d.ts +1 -0
  246. package/dist/process-blueprint/__tests__/layout.test.js +159 -0
  247. package/dist/process-blueprint/__tests__/validate.test.d.ts +1 -0
  248. package/dist/process-blueprint/__tests__/validate.test.js +280 -0
  249. package/dist/process-blueprint/index.d.ts +4 -0
  250. package/dist/process-blueprint/index.js +2 -0
  251. package/dist/process-blueprint/layout.d.ts +2 -0
  252. package/dist/process-blueprint/layout.js +416 -0
  253. package/dist/process-blueprint/types.d.ts +220 -0
  254. package/dist/process-blueprint/types.js +1 -0
  255. package/dist/process-blueprint/validate.d.ts +3 -0
  256. package/dist/process-blueprint/validate.js +165 -0
  257. package/dist/process-map/__tests__/validate.test.d.ts +1 -0
  258. package/dist/process-map/__tests__/validate.test.js +199 -0
  259. package/dist/process-map/index.d.ts +2 -0
  260. package/dist/process-map/index.js +1 -0
  261. package/dist/process-map/types.d.ts +32 -0
  262. package/dist/process-map/types.js +1 -0
  263. package/dist/process-map/validate.d.ts +3 -0
  264. package/dist/process-map/validate.js +115 -0
  265. package/dist/products/__tests__/validate.test.d.ts +1 -0
  266. package/dist/products/__tests__/validate.test.js +210 -0
  267. package/dist/products/index.d.ts +2 -0
  268. package/dist/products/index.js +1 -0
  269. package/dist/products/types.d.ts +28 -0
  270. package/dist/products/types.js +1 -0
  271. package/dist/products/validate.d.ts +3 -0
  272. package/dist/products/validate.js +93 -0
  273. package/dist/repo-validate/__tests__/validate-repo.test.d.ts +1 -0
  274. package/dist/repo-validate/__tests__/validate-repo.test.js +132 -0
  275. package/dist/repo-validate/index.d.ts +2 -0
  276. package/dist/repo-validate/index.js +1 -0
  277. package/dist/repo-validate/types.d.ts +34 -0
  278. package/dist/repo-validate/types.js +14 -0
  279. package/dist/repo-validate/validate-repo.d.ts +8 -0
  280. package/dist/repo-validate/validate-repo.js +189 -0
  281. package/dist/requirement/__tests__/example.test.d.ts +1 -0
  282. package/dist/requirement/__tests__/example.test.js +21 -0
  283. package/dist/requirement/__tests__/validate.test.d.ts +1 -0
  284. package/dist/requirement/__tests__/validate.test.js +80 -0
  285. package/dist/requirement/index.d.ts +4 -0
  286. package/dist/requirement/index.js +2 -0
  287. package/dist/requirement/types.d.ts +25 -0
  288. package/dist/requirement/types.js +4 -0
  289. package/dist/requirement/validate.d.ts +7 -0
  290. package/dist/requirement/validate.js +81 -0
  291. package/dist/scenarios/__tests__/validate.test.d.ts +1 -0
  292. package/dist/scenarios/__tests__/validate.test.js +183 -0
  293. package/dist/scenarios/index.d.ts +2 -0
  294. package/dist/scenarios/index.js +1 -0
  295. package/dist/scenarios/types.d.ts +45 -0
  296. package/dist/scenarios/types.js +1 -0
  297. package/dist/scenarios/validate.d.ts +3 -0
  298. package/dist/scenarios/validate.js +110 -0
  299. package/dist/schema-version.d.ts +16 -0
  300. package/dist/schema-version.js +16 -0
  301. package/dist/scope.d.ts +23 -0
  302. package/dist/scope.js +38 -0
  303. package/dist/stakeholder/__tests__/validate.test.d.ts +1 -0
  304. package/dist/stakeholder/__tests__/validate.test.js +86 -0
  305. package/dist/stakeholder/index.d.ts +3 -0
  306. package/dist/stakeholder/index.js +2 -0
  307. package/dist/stakeholder/types.d.ts +24 -0
  308. package/dist/stakeholder/types.js +5 -0
  309. package/dist/stakeholder/validate.d.ts +2 -0
  310. package/dist/stakeholder/validate.js +58 -0
  311. package/dist/target-state/__tests__/validate.test.d.ts +1 -0
  312. package/dist/target-state/__tests__/validate.test.js +62 -0
  313. package/dist/target-state/index.d.ts +2 -0
  314. package/dist/target-state/index.js +1 -0
  315. package/dist/target-state/types.d.ts +18 -0
  316. package/dist/target-state/types.js +7 -0
  317. package/dist/target-state/validate.d.ts +2 -0
  318. package/dist/target-state/validate.js +61 -0
  319. package/dist/theme/index.d.ts +4 -0
  320. package/dist/theme/index.js +2 -0
  321. package/dist/theme/themes.d.ts +16 -0
  322. package/dist/theme/themes.js +213 -0
  323. package/dist/theme/tokens.d.ts +158 -0
  324. package/dist/theme/tokens.js +105 -0
  325. package/dist/typed-id.d.ts +20 -0
  326. package/dist/typed-id.js +38 -0
  327. package/dist/validation-types.d.ts +34 -0
  328. package/dist/validation-types.js +1 -0
  329. package/dist/webview/__tests__/entry-notations.test.d.ts +1 -0
  330. package/dist/webview/__tests__/entry-notations.test.js +62 -0
  331. package/dist/webview/__tests__/entry.test.d.ts +1 -0
  332. package/dist/webview/__tests__/entry.test.js +56 -0
  333. package/dist/webview/__tests__/render-goals.test.d.ts +1 -0
  334. package/dist/webview/__tests__/render-goals.test.js +65 -0
  335. package/dist/webview/entry.d.ts +38 -0
  336. package/dist/webview/entry.js +182 -0
  337. package/dist/webview/render-activities.d.ts +24 -0
  338. package/dist/webview/render-activities.js +127 -0
  339. package/dist/webview/render-activity-card.d.ts +5 -0
  340. package/dist/webview/render-activity-card.js +168 -0
  341. package/dist/webview/render-applications.d.ts +11 -0
  342. package/dist/webview/render-applications.js +105 -0
  343. package/dist/webview/render-blocks.d.ts +5 -0
  344. package/dist/webview/render-blocks.js +71 -0
  345. package/dist/webview/render-capability-map.d.ts +7 -0
  346. package/dist/webview/render-capability-map.js +88 -0
  347. package/dist/webview/render-fgca.d.ts +8 -0
  348. package/dist/webview/render-fgca.js +94 -0
  349. package/dist/webview/render-goals.d.ts +6 -0
  350. package/dist/webview/render-goals.js +92 -0
  351. package/dist/webview/render-process-blueprint.d.ts +5 -0
  352. package/dist/webview/render-process-blueprint.js +135 -0
  353. package/dist/webview/render-process-map.d.ts +7 -0
  354. package/dist/webview/render-process-map.js +82 -0
  355. package/dist/webview/render-products.d.ts +7 -0
  356. package/dist/webview/render-products.js +81 -0
  357. package/dist/webview/render-scenarios.d.ts +7 -0
  358. package/dist/webview/render-scenarios.js +75 -0
  359. package/dist/webview/render-util.d.ts +16 -0
  360. package/dist/webview/render-util.js +31 -0
  361. package/dist/webview/transitrix-render.css +323 -0
  362. package/dist/webview/transitrix-render.js +6452 -0
  363. package/dist/webview/transitrix-render.js.map +7 -0
  364. package/dist/yaml-normalize.d.ts +20 -0
  365. package/dist/yaml-normalize.js +57 -0
  366. package/package.json +40 -0
  367. package/src/__tests__/edge-path.test.ts +46 -0
  368. package/src/__tests__/scope.test.ts +27 -0
  369. package/src/__tests__/yaml-normalize.test.ts +158 -0
  370. package/src/activities/__tests__/cpm.test.ts +164 -0
  371. package/src/activities/__tests__/gantt.test.ts +245 -0
  372. package/src/activities/__tests__/layout.test.ts +112 -0
  373. package/src/activities/__tests__/validate.test.ts +409 -0
  374. package/src/activities/cpm.ts +95 -0
  375. package/src/activities/gantt.ts +276 -0
  376. package/src/activities/index.ts +28 -0
  377. package/src/activities/layout.ts +112 -0
  378. package/src/activities/types.ts +148 -0
  379. package/src/activities/validate.ts +357 -0
  380. package/src/activity-card/__tests__/example.test.ts +66 -0
  381. package/src/activity-card/__tests__/layout.test.ts +63 -0
  382. package/src/activity-card/__tests__/resolver.test.ts +161 -0
  383. package/src/activity-card/__tests__/validate.test.ts +131 -0
  384. package/src/activity-card/index.ts +32 -0
  385. package/src/activity-card/layout.ts +194 -0
  386. package/src/activity-card/resolver.ts +337 -0
  387. package/src/activity-card/types.ts +237 -0
  388. package/src/activity-card/validate.ts +158 -0
  389. package/src/actor/__tests__/validate.test.ts +67 -0
  390. package/src/actor/index.ts +3 -0
  391. package/src/actor/types.ts +29 -0
  392. package/src/actor/validate.ts +38 -0
  393. package/src/applications/__tests__/validate.test.ts +256 -0
  394. package/src/applications/index.ts +11 -0
  395. package/src/applications/types.ts +43 -0
  396. package/src/applications/validate.ts +131 -0
  397. package/src/assertion/__tests__/example.test.ts +37 -0
  398. package/src/assertion/__tests__/validate.test.ts +142 -0
  399. package/src/assertion/index.ts +12 -0
  400. package/src/assertion/types.ts +58 -0
  401. package/src/assertion/validate.ts +145 -0
  402. package/src/blocks/__tests__/layout.test.ts +169 -0
  403. package/src/blocks/__tests__/validate.test.ts +260 -0
  404. package/src/blocks/index.ts +17 -0
  405. package/src/blocks/layout.ts +186 -0
  406. package/src/blocks/types.ts +62 -0
  407. package/src/blocks/validate.ts +206 -0
  408. package/src/capability-map/__tests__/validate.test.ts +238 -0
  409. package/src/capability-map/index.ts +8 -0
  410. package/src/capability-map/types.ts +29 -0
  411. package/src/capability-map/validate.ts +127 -0
  412. package/src/change/__tests__/validate.test.ts +88 -0
  413. package/src/change/index.ts +2 -0
  414. package/src/change/types.ts +23 -0
  415. package/src/change/validate.ts +61 -0
  416. package/src/compliance/__tests__/classify.test.ts +27 -0
  417. package/src/compliance/__tests__/confidence.test.ts +98 -0
  418. package/src/compliance/__tests__/coverage-metric.test.ts +188 -0
  419. package/src/compliance/__tests__/demo-scenario.test.ts +273 -0
  420. package/src/compliance/__tests__/example.test.ts +57 -0
  421. package/src/compliance/__tests__/gap-report.test.ts +129 -0
  422. package/src/compliance/__tests__/html.test.ts +142 -0
  423. package/src/compliance/__tests__/impact.test.ts +482 -0
  424. package/src/compliance/__tests__/markdown.test.ts +95 -0
  425. package/src/compliance/__tests__/views.test.ts +64 -0
  426. package/src/compliance/classify.ts +84 -0
  427. package/src/compliance/confidence.ts +69 -0
  428. package/src/compliance/coverage-metric.ts +263 -0
  429. package/src/compliance/gap-report.ts +94 -0
  430. package/src/compliance/html.ts +295 -0
  431. package/src/compliance/impact.ts +677 -0
  432. package/src/compliance/index.ts +56 -0
  433. package/src/compliance/markdown.ts +135 -0
  434. package/src/compliance/reverse-index.ts +33 -0
  435. package/src/compliance/types.ts +120 -0
  436. package/src/compliance/views.ts +46 -0
  437. package/src/compliance-matrix/__tests__/build.test.ts +200 -0
  438. package/src/compliance-matrix/__tests__/example.test.ts +57 -0
  439. package/src/compliance-matrix/build.ts +0 -0
  440. package/src/compliance-matrix/index.ts +11 -0
  441. package/src/compliance-matrix/types.ts +102 -0
  442. package/src/confidence/__tests__/score.test.ts +254 -0
  443. package/src/confidence/index.ts +21 -0
  444. package/src/confidence/score.ts +243 -0
  445. package/src/confidence/types.ts +96 -0
  446. package/src/edge-path.ts +44 -0
  447. package/src/element-envelope.ts +76 -0
  448. package/src/factor/__tests__/validate.test.ts +98 -0
  449. package/src/factor/index.ts +8 -0
  450. package/src/factor/types.ts +41 -0
  451. package/src/factor/validate.ts +74 -0
  452. package/src/fgca/__tests__/chain-table.test.ts +172 -0
  453. package/src/fgca/__tests__/layout.test.ts +179 -0
  454. package/src/fgca/__tests__/parse-canonical.test.ts +248 -0
  455. package/src/fgca/__tests__/preview-layout.test.ts +124 -0
  456. package/src/fgca/__tests__/validate.test.ts +142 -0
  457. package/src/fgca/chain-table.ts +225 -0
  458. package/src/fgca/index.ts +45 -0
  459. package/src/fgca/layout.ts +204 -0
  460. package/src/fgca/nodeTypes.ts +11 -0
  461. package/src/fgca/nodes/FGCAActivityNode.tsx +65 -0
  462. package/src/fgca/nodes/FGCAChangeNode.tsx +64 -0
  463. package/src/fgca/nodes/FGCAFactorNode.tsx +64 -0
  464. package/src/fgca/nodes/FGCAGoalNode.tsx +72 -0
  465. package/src/fgca/parse-canonical.ts +400 -0
  466. package/src/fgca/preview-layout.ts +217 -0
  467. package/src/fgca/types.ts +50 -0
  468. package/src/fgca/validate.ts +126 -0
  469. package/src/geometry.ts +9 -0
  470. package/src/goals/__tests__/layout.test.ts +175 -0
  471. package/src/goals/__tests__/mutations.test.ts +111 -0
  472. package/src/goals/__tests__/parse-canonical.test.ts +145 -0
  473. package/src/goals/__tests__/validate.test.ts +202 -0
  474. package/src/goals/index.ts +21 -0
  475. package/src/goals/layout.ts +172 -0
  476. package/src/goals/mutations.ts +123 -0
  477. package/src/goals/parse-canonical.ts +286 -0
  478. package/src/goals/types.ts +85 -0
  479. package/src/goals/validate.ts +136 -0
  480. package/src/index.ts +23 -0
  481. package/src/process-blueprint/__tests__/compliance-lane.test.ts +320 -0
  482. package/src/process-blueprint/__tests__/layout.test.ts +195 -0
  483. package/src/process-blueprint/__tests__/validate.test.ts +310 -0
  484. package/src/process-blueprint/index.ts +31 -0
  485. package/src/process-blueprint/layout.ts +531 -0
  486. package/src/process-blueprint/types.ts +242 -0
  487. package/src/process-blueprint/validate.ts +181 -0
  488. package/src/process-map/__tests__/validate.test.ts +223 -0
  489. package/src/process-map/index.ts +10 -0
  490. package/src/process-map/types.ts +36 -0
  491. package/src/process-map/validate.ts +135 -0
  492. package/src/products/__tests__/validate.test.ts +239 -0
  493. package/src/products/index.ts +9 -0
  494. package/src/products/types.ts +31 -0
  495. package/src/products/validate.ts +112 -0
  496. package/src/repo-validate/__tests__/validate-repo.test.ts +149 -0
  497. package/src/repo-validate/index.ts +2 -0
  498. package/src/repo-validate/types.ts +50 -0
  499. package/src/repo-validate/validate-repo.ts +196 -0
  500. package/src/requirement/__tests__/example.test.ts +24 -0
  501. package/src/requirement/__tests__/validate.test.ts +96 -0
  502. package/src/requirement/index.ts +4 -0
  503. package/src/requirement/types.ts +35 -0
  504. package/src/requirement/validate.ts +92 -0
  505. package/src/scenarios/__tests__/validate.test.ts +209 -0
  506. package/src/scenarios/index.ts +15 -0
  507. package/src/scenarios/types.ts +37 -0
  508. package/src/scenarios/validate.ts +122 -0
  509. package/src/schema-version.ts +16 -0
  510. package/src/scope.ts +46 -0
  511. package/src/stakeholder/__tests__/validate.test.ts +101 -0
  512. package/src/stakeholder/index.ts +3 -0
  513. package/src/stakeholder/types.ts +33 -0
  514. package/src/stakeholder/validate.ts +63 -0
  515. package/src/target-state/__tests__/validate.test.ts +74 -0
  516. package/src/target-state/index.ts +2 -0
  517. package/src/target-state/types.ts +28 -0
  518. package/src/target-state/validate.ts +67 -0
  519. package/src/theme/index.ts +4 -0
  520. package/src/theme/themes.ts +237 -0
  521. package/src/theme/tokens.ts +133 -0
  522. package/src/typed-id.ts +56 -0
  523. package/src/validation-types.ts +36 -0
  524. package/src/webview/__tests__/entry-notations.test.ts +77 -0
  525. package/src/webview/__tests__/entry.test.ts +64 -0
  526. package/src/webview/__tests__/render-goals.test.ts +72 -0
  527. package/src/webview/entry.ts +292 -0
  528. package/src/webview/render-activities.ts +156 -0
  529. package/src/webview/render-activity-card.ts +234 -0
  530. package/src/webview/render-applications.ts +123 -0
  531. package/src/webview/render-blocks.ts +91 -0
  532. package/src/webview/render-capability-map.ts +98 -0
  533. package/src/webview/render-fgca.ts +122 -0
  534. package/src/webview/render-goals.ts +110 -0
  535. package/src/webview/render-process-blueprint.ts +207 -0
  536. package/src/webview/render-process-map.ts +93 -0
  537. package/src/webview/render-products.ts +91 -0
  538. package/src/webview/render-scenarios.ts +90 -0
  539. package/src/webview/render-util.ts +34 -0
  540. package/src/webview/styles.css +323 -0
  541. package/src/yaml-normalize.ts +56 -0
@@ -0,0 +1,234 @@
1
+ /**
2
+ * Host-neutral SVG renderer for the Activity Card notation.
3
+ *
4
+ * Step 4 of the IntelliJ epic (ADR 0001): the webview bundle must turn a
5
+ * validated Activity Card document into renderable SVG so JCEF can drop it into
6
+ * the preview panel. The VS Code path lives in
7
+ * `extension/src/activity-card-preview.ts` and pulls in VS Code-specific
8
+ * concerns (themes, title block, save dialogs, sibling-document discovery on
9
+ * the filesystem); this module is the host-neutral subset — pure layout → SVG
10
+ * with no VS Code APIs, no `node:fs`, no `node:path`.
11
+ *
12
+ * CROSS-DOCUMENT RESOLUTION CAVEAT
13
+ * The Activity Card is the only MULTI-DOCUMENT Studio notation: the card YAML
14
+ * names a project Activity, and the project's name, dates, motivation chain
15
+ * (Factors → Goals → Changes) and child activities are pulled BY REFERENCE from
16
+ * the canonical element + relation store (`canon/elements/**`,
17
+ * `canon/relations/**`; see `../activity-card/resolver.ts`). That resolution
18
+ * requires reading those files from disk, which is NOT available inside the
19
+ * JCEF host. We therefore resolve from the single in-memory card document
20
+ * ONLY: we synthesise
21
+ * a minimal `ResolvedActivityCard` whose project carries just the referenced
22
+ * project id (no resolved name/dates), whose milestones come straight from the
23
+ * card's own `milestones[]`, and whose motivation chain + child activities are
24
+ * empty (those cannot resolve without the siblings). The SVG layout is shared
25
+ * with the VS Code path via `layoutActivityCard`, so a single-document card
26
+ * still renders its title, dates band and milestone timeline.
27
+ */
28
+ import { layoutActivityCard, ARCHIMATE_CLASS } from '../activity-card/layout.js';
29
+ import type {
30
+ ActivityCardDoc,
31
+ ActivityCardLayout,
32
+ ResolvedActivityCard,
33
+ ResolvedMilestone,
34
+ } from '../activity-card/types.js';
35
+ import { generateSvgEmbedCss } from '../theme/index.js';
36
+ import { escXml } from './render-util.js';
37
+
38
+ const PAD = 24;
39
+
40
+ const EMPTY_SVG = `<svg xmlns="http://www.w3.org/2000/svg" width="0" height="0" viewBox="0 0 0 0"></svg>`;
41
+
42
+ export interface RenderActivityCardOptions {
43
+ title?: string;
44
+ }
45
+
46
+ function truncate(text: string, maxChars: number): string {
47
+ if (text.length <= maxChars) return text;
48
+ return text.slice(0, Math.max(0, maxChars - 1)) + '…';
49
+ }
50
+
51
+ /**
52
+ * Build a single-document resolution of the card: everything that can be read
53
+ * straight off the card YAML, with the cross-document fields left empty. This
54
+ * mirrors what `resolveActivityCard` produces, minus the parts that need the
55
+ * canon element + relation store (project name/dates, motivation chain, child
56
+ * activities).
57
+ */
58
+ function resolveSingleDoc(doc: ActivityCardDoc): ResolvedActivityCard {
59
+ const card = doc.activity_card;
60
+ const rawMilestones = Array.isArray(card?.milestones) ? card.milestones : [];
61
+
62
+ const milestones: ResolvedMilestone[] = rawMilestones
63
+ .filter((m): m is NonNullable<typeof m> => !!m && typeof m === 'object')
64
+ .map((m) => ({
65
+ id: m.id,
66
+ name: m.name,
67
+ date: m.date,
68
+ description: m.description,
69
+ deliversChanges: Array.isArray(m.delivers_changes) ? m.delivers_changes : [],
70
+ }))
71
+ .sort((a, b) => (a.date < b.date ? -1 : a.date > b.date ? 1 : 0));
72
+
73
+ return {
74
+ cardId: card?.id ?? '',
75
+ cardDescription: card?.description,
76
+ // No sibling docs in the host-neutral path: the project resolves to its id
77
+ // only. The layout falls back to '—' for the unknown date fields.
78
+ project: { id: card?.project ?? '', name: card?.project ?? '' },
79
+ milestones,
80
+ motivation: { factors: [], goals: [], changes: [] },
81
+ childActivities: [],
82
+ };
83
+ }
84
+
85
+ function buildBody(layout: ActivityCardLayout, ox: number, oy: number): string {
86
+ const parts: string[] = [];
87
+
88
+ // Outer card.
89
+ parts.push(
90
+ `<rect class="diagram-node level-0" x="${ox}" y="${oy}" width="${layout.bounds.width}" height="${layout.bounds.height}" rx="8"/>`,
91
+ );
92
+
93
+ // Title (project name / id).
94
+ parts.push(
95
+ `<text class="text-header" x="${layout.title.x + ox}" y="${layout.title.y + oy}" dominant-baseline="central" font-size="18">${escXml(truncate(layout.title.name, 70))}</text>`,
96
+ );
97
+
98
+ // Dates band.
99
+ for (const d of layout.dateFields) {
100
+ parts.push(
101
+ `<rect class="diagram-node level-2" x="${d.x + ox}" y="${d.y + oy}" width="${d.width}" height="${d.height}" rx="6"/>`,
102
+ );
103
+ parts.push(
104
+ `<text class="text-secondary" x="${d.x + ox + 12}" y="${d.y + oy + 18}" dominant-baseline="central">${escXml(d.label)}</text>`,
105
+ );
106
+ parts.push(
107
+ `<text class="text-primary" x="${d.x + ox + 12}" y="${d.y + oy + 40}" dominant-baseline="central">${escXml(d.value)}</text>`,
108
+ );
109
+ }
110
+
111
+ // Section headers.
112
+ for (const s of layout.sectionHeaders) {
113
+ parts.push(
114
+ `<text class="text-header" x="${s.x + ox}" y="${s.y + oy + s.height / 2}" dominant-baseline="central">${escXml(s.label)}</text>`,
115
+ );
116
+ }
117
+
118
+ // Milestones.
119
+ for (const m of layout.milestones) {
120
+ parts.push(
121
+ `<rect class="diagram-node level-3" x="${m.x + ox}" y="${m.y + oy}" width="${m.width}" height="${m.height}" rx="6"/>`,
122
+ );
123
+ parts.push(
124
+ `<text class="text-secondary" x="${m.x + ox + 10}" y="${m.y + oy + 16}" dominant-baseline="central">${escXml(m.date)}</text>`,
125
+ );
126
+ parts.push(
127
+ `<text class="text-primary" x="${m.x + ox + 10}" y="${m.y + oy + 36}" dominant-baseline="central">${escXml(truncate(m.name, 22))}</text>`,
128
+ );
129
+ parts.push(
130
+ `<text class="text-secondary" x="${m.x + ox + 10}" y="${m.y + oy + 52}" dominant-baseline="central" font-style="italic">(${escXml(m.archimateClass)})</text>`,
131
+ );
132
+ }
133
+
134
+ // Motivation chain — edges first (under nodes).
135
+ const nodeById = new Map<string, { x: number; y: number; width: number; height: number }>();
136
+ for (const col of [
137
+ layout.chainColumns.factors,
138
+ layout.chainColumns.goals,
139
+ layout.chainColumns.changes,
140
+ ]) {
141
+ for (const n of col) nodeById.set(n.id, n);
142
+ }
143
+ for (const e of layout.chainEdges) {
144
+ const s = nodeById.get(e.sourceId);
145
+ const t = nodeById.get(e.targetId);
146
+ if (!s || !t) continue;
147
+ const x1 = s.x + s.width + ox;
148
+ const y1 = s.y + s.height / 2 + oy;
149
+ const x2 = t.x + ox;
150
+ const y2 = t.y + t.height / 2 + oy;
151
+ const mx = (x1 + x2) / 2;
152
+ parts.push(
153
+ `<path class="diagram-edge" d="M${x1},${y1} C${mx},${y1} ${mx},${y2} ${x2},${y2}" fill="none" marker-end="url(#ac-arrow)"/>`,
154
+ );
155
+ }
156
+ const chainLevels: Array<[typeof layout.chainColumns.factors, number]> = [
157
+ [layout.chainColumns.factors, 4],
158
+ [layout.chainColumns.goals, 5],
159
+ [layout.chainColumns.changes, 6],
160
+ ];
161
+ for (const [col, level] of chainLevels) {
162
+ for (const n of col) {
163
+ parts.push(
164
+ `<rect class="diagram-node level-${level}" x="${n.x + ox}" y="${n.y + oy}" width="${n.width}" height="${n.height}" rx="6"/>`,
165
+ );
166
+ parts.push(
167
+ `<text class="text-pill" x="${n.x + ox + n.width / 2}" y="${n.y + oy + n.height / 2}" text-anchor="middle" dominant-baseline="central">${escXml(truncate(n.name, Math.floor(n.width / 7)))}</text>`,
168
+ );
169
+ }
170
+ }
171
+
172
+ // Child activities.
173
+ for (const a of layout.childActivities) {
174
+ parts.push(
175
+ `<rect class="diagram-node level-1" x="${a.x + ox}" y="${a.y + oy}" width="${a.width}" height="${a.height}" rx="6"/>`,
176
+ );
177
+ parts.push(
178
+ `<text class="text-primary" x="${a.x + ox + 12}" y="${a.y + oy + a.height / 2}" dominant-baseline="central">${escXml(truncate(a.name, 48))} <tspan class="text-secondary" font-style="italic">(${escXml(a.archimateClass)})</tspan></text>`,
179
+ );
180
+ if (a.meta) {
181
+ parts.push(
182
+ `<text class="text-secondary" x="${a.x + a.width + ox - 12}" y="${a.y + oy + a.height / 2}" text-anchor="end" dominant-baseline="central">${escXml(truncate(a.meta, 40))}</text>`,
183
+ );
184
+ }
185
+ }
186
+
187
+ return parts.join('\n');
188
+ }
189
+
190
+ export function renderActivityCardSvg(
191
+ doc: ActivityCardDoc,
192
+ options: RenderActivityCardOptions = {},
193
+ ): string {
194
+ // `ARCHIMATE_CLASS` is referenced so the host-neutral module pins the same
195
+ // §5.1 class convention the layout applies; keeps the import meaningful.
196
+ void ARCHIMATE_CLASS;
197
+
198
+ const { title = '' } = options;
199
+
200
+ const resolved = resolveSingleDoc(doc);
201
+ const layout = layoutActivityCard(resolved);
202
+
203
+ if (layout.bounds.width <= 0 || layout.bounds.height <= 0) {
204
+ return EMPTY_SVG;
205
+ }
206
+
207
+ const titleH = title ? 28 : 0;
208
+ const w = layout.bounds.width + PAD * 2;
209
+ const h = layout.bounds.height + PAD * 2 + titleH;
210
+ const ox = PAD;
211
+ const oy = PAD + titleH;
212
+
213
+ const body = buildBody(layout, ox, oy);
214
+
215
+ const titleSvg = title
216
+ ? `<text class="text-header" x="${PAD}" y="${PAD + 14}">${escXml(`Activity Card — ${title}`)}</text>`
217
+ : '';
218
+
219
+ // Embed the shared theme CSS inside the SVG so the rendered output is
220
+ // self-contained — the JCEF host page only needs to drop the SVG into the
221
+ // DOM and styling resolves without any cooperation from the host stylesheet.
222
+ const embedCss = generateSvgEmbedCss('transitrix');
223
+
224
+ return `<svg xmlns="http://www.w3.org/2000/svg" width="${w}" height="${h}" viewBox="0 0 ${w} ${h}">
225
+ <style>${embedCss}</style>
226
+ <defs>
227
+ <marker id="ac-arrow" markerWidth="8" markerHeight="8" refX="8" refY="3" orient="auto">
228
+ <path d="M0,0 L0,6 L8,3 z" class="arrow-fill"/>
229
+ </marker>
230
+ </defs>
231
+ ${titleSvg}
232
+ ${body}
233
+ </svg>`;
234
+ }
@@ -0,0 +1,123 @@
1
+ /**
2
+ * Host-neutral renderer for the Applications catalogue notation.
3
+ *
4
+ * Mirrors the VS Code preview (`extension/src/applications-preview.ts`) but
5
+ * strips the VS Code-specific concerns (theme lookup, command URIs, fix-prompt
6
+ * scaffolding). The output is a self-contained HTML fragment — a `<section>`
7
+ * carrying its own `<style>` block — that the JCEF host can drop into
8
+ * `#transitrix-root` exactly the way it drops the goals SVG (Step 3 contract).
9
+ */
10
+ import type {
11
+ Application,
12
+ ApplicationIntegration,
13
+ ApplicationsCatalogueHeader,
14
+ } from '../applications/types.js';
15
+ import { escHtml } from './render-util.js';
16
+
17
+ const TYPE_LABEL: Record<string, string> = {
18
+ application: 'Application',
19
+ integration: 'Integration',
20
+ platform: 'Platform',
21
+ data_store: 'Data Store',
22
+ };
23
+
24
+ const STATUS_BADGE: Record<string, string> = {
25
+ Active: 'badge-active',
26
+ Draft: 'badge-draft',
27
+ Deprecated: 'badge-deprecated',
28
+ Decommissioning: 'badge-decommissioning',
29
+ };
30
+
31
+ function maturityDots(m: number | undefined): string {
32
+ if (m === undefined) return '<span class="cell-empty">—</span>';
33
+ const filled = '●'.repeat(Math.max(0, Math.min(5, m)));
34
+ const empty = '○'.repeat(5 - Math.max(0, Math.min(5, m)));
35
+ return `<span class="maturity-dots">${filled}${empty}</span>`;
36
+ }
37
+
38
+ function disclosureList(label: string, items: string[] | undefined): string {
39
+ if (!items || items.length === 0) return '';
40
+ const lis = items.map((i) => `<li>${escHtml(i)}</li>`).join('');
41
+ return `<details><summary>${escHtml(label)} (${items.length})</summary><ul>${lis}</ul></details>`;
42
+ }
43
+
44
+ function renderIntegrations(integrations: ApplicationIntegration[] | undefined): string {
45
+ if (!integrations || integrations.length === 0) return '';
46
+ const items = integrations
47
+ .map((intg) => {
48
+ const parts = [
49
+ intg.target ? escHtml(intg.target) : '?',
50
+ intg.direction ? `<span class="intg-dir">${escHtml(intg.direction)}</span>` : '',
51
+ intg.protocol ? `<span class="intg-proto">${escHtml(intg.protocol)}</span>` : '',
52
+ ]
53
+ .filter(Boolean)
54
+ .join(' ');
55
+ const desc = intg.description ? `<span class="intg-desc">${escHtml(intg.description)}</span>` : '';
56
+ return `<li>${parts}${desc ? ' — ' + desc : ''}</li>`;
57
+ })
58
+ .join('');
59
+ return `<details><summary>Integrations (${integrations.length})</summary><ul>${items}</ul></details>`;
60
+ }
61
+
62
+ function renderRow(a: Application): string {
63
+ const extras = [
64
+ renderIntegrations(a.integrations),
65
+ disclosureList('Capabilities', a.capabilities),
66
+ disclosureList('Products', a.products),
67
+ ]
68
+ .filter(Boolean)
69
+ .join('');
70
+ const vendorCell = a.vendor
71
+ ? `<span class="${a.vendor === 'Internal' ? 'vendor-internal' : 'vendor-external'}">${escHtml(a.vendor)}</span>`
72
+ : '<span class="cell-empty">—</span>';
73
+ return `<tr>
74
+ <td class="col-name">
75
+ <div class="catalogue-name">${escHtml(a.name)}</div>
76
+ <div class="catalogue-id">${escHtml(a.app_id)}</div>
77
+ ${a.description ? `<div class="catalogue-desc">${escHtml(a.description)}</div>` : ''}
78
+ ${extras}
79
+ </td>
80
+ <td class="col-type"><span class="type-tag">${escHtml(TYPE_LABEL[a.type] ?? a.type)}</span></td>
81
+ <td class="col-status"><span class="tx-badge ${escHtml(STATUS_BADGE[a.status] ?? '')}">${escHtml(a.status)}</span></td>
82
+ <td class="col-maturity">${maturityDots(a.maturity)}</td>
83
+ <td class="col-domain">${a.domain ? escHtml(a.domain) : '<span class="cell-empty">—</span>'}</td>
84
+ <td class="col-vendor">${vendorCell}</td>
85
+ <td class="col-owner">${a.owner_role ? escHtml(a.owner_role) : '<span class="cell-empty">—</span>'}</td>
86
+ </tr>`;
87
+ }
88
+
89
+ export function renderApplicationsHtml(catalogue: ApplicationsCatalogueHeader): string {
90
+ const rows = catalogue.applications.map(renderRow).join('\n');
91
+ const emptyRow = catalogue.applications.length === 0
92
+ ? `<tr><td colspan="7" class="empty-catalogue">No applications defined.</td></tr>`
93
+ : '';
94
+ const header = `<header class="catalogue-header">
95
+ <div class="catalogue-title">${escHtml(catalogue.name)}</div>
96
+ <div class="catalogue-meta">
97
+ <span class="catalogue-id-tag">${escHtml(catalogue.id)}</span>
98
+ <span class="catalogue-updated">Updated ${escHtml(catalogue.updated_at)}</span>
99
+ ${catalogue.version ? `<span class="catalogue-version">v${escHtml(catalogue.version)}</span>` : ''}
100
+ </div>
101
+ ${catalogue.description ? `<div class="catalogue-subtitle">${escHtml(catalogue.description)}</div>` : ''}
102
+ </header>`;
103
+ return `<section class="tx-catalogue tx-applications">
104
+ ${header}
105
+ <table class="catalogue-table">
106
+ <thead>
107
+ <tr>
108
+ <th>Name / ID</th>
109
+ <th>Type</th>
110
+ <th>Status</th>
111
+ <th>Maturity</th>
112
+ <th>Domain</th>
113
+ <th>Vendor</th>
114
+ <th>Owner Role</th>
115
+ </tr>
116
+ </thead>
117
+ <tbody>
118
+ ${rows}
119
+ ${emptyRow}
120
+ </tbody>
121
+ </table>
122
+ </section>`;
123
+ }
@@ -0,0 +1,91 @@
1
+ /**
2
+ * Browser-safe SVG renderer for the Nested Blocks notation.
3
+ *
4
+ * Step 4 of the IntelliJ epic (ADR 0001): the webview bundle must turn a
5
+ * validated BlocksFile into renderable SVG so JCEF can drop it into the
6
+ * preview panel. The VS Code path lives in `extension/src/blocks-preview.ts`
7
+ * and pulls in VS Code-specific concerns (themes, title block, save dialogs);
8
+ * this module is the host-neutral subset — pure `layoutNestedBlocks` → SVG
9
+ * with no VS Code APIs, no `node:*`, and no svgbob subprocess.
10
+ *
11
+ * Follows the same shape as `render-goals.ts`: a self-contained `<svg>` with
12
+ * the shared theme CSS embedded in a `<style>` element and a simple optional
13
+ * title `<text>`.
14
+ */
15
+ import { layoutNestedBlocks } from '../blocks/layout.js';
16
+ import type { BlocksFile, BlocksLayout, LaidOutBlock } from '../blocks/types.js';
17
+ import { generateSvgEmbedCss } from '../theme/index.js';
18
+ import { escXml } from './render-util.js';
19
+
20
+ const PAD = 24;
21
+
22
+ export interface RenderBlocksOptions {
23
+ title?: string;
24
+ }
25
+
26
+ /**
27
+ * Pick the diagram-frame level class for a block at the given depth.
28
+ *
29
+ * `level-0` is the lightest fill in the brand colour ramp; deeper levels are
30
+ * progressively darker. The methodology spec mandates "outermost lightest"
31
+ * (08-blocks.md §7), so depth 1 (top-level) maps to `level-0`. The theme CSS
32
+ * defines `level-0` … `level-6`; deeper blocks reuse `level-6`.
33
+ */
34
+ function levelClassForDepth(depth: number): string {
35
+ const idx = Math.min(Math.max(depth - 1, 0), 6);
36
+ return `level-${idx}`;
37
+ }
38
+
39
+ function truncate(text: string, maxChars: number): string {
40
+ if (text.length <= maxChars) return text;
41
+ return text.slice(0, Math.max(0, maxChars - 1)) + '…';
42
+ }
43
+
44
+ function emitBlockSvg(b: LaidOutBlock, ox: number, oy: number, parts: string[]): void {
45
+ const cls = levelClassForDepth(b.depth);
46
+ parts.push(
47
+ `<rect class="diagram-node ${cls}" x="${b.x + ox}" y="${b.y + oy}" width="${b.width}" height="${b.height}" rx="6"/>`,
48
+ );
49
+
50
+ // Header label, centred horizontally within the block's header strip.
51
+ const headerY = b.y + oy + b.headerHeight / 2;
52
+ const maxChars = Math.max(4, Math.floor(b.width / 8));
53
+ parts.push(
54
+ `<text class="text-header" x="${b.x + ox + b.width / 2}" y="${headerY}" text-anchor="middle" dominant-baseline="central">${escXml(truncate(b.name, maxChars))}</text>`,
55
+ );
56
+
57
+ for (const c of b.children) emitBlockSvg(c, ox, oy, parts);
58
+ }
59
+
60
+ export function renderBlocksSvg(doc: BlocksFile, options: RenderBlocksOptions = {}): string {
61
+ const { title = '' } = options;
62
+
63
+ const layout: BlocksLayout = layoutNestedBlocks(doc);
64
+
65
+ if (layout.blocks.length === 0) {
66
+ return `<svg xmlns="http://www.w3.org/2000/svg" width="0" height="0" viewBox="0 0 0 0"></svg>`;
67
+ }
68
+
69
+ const w = layout.bounds.width + PAD * 2;
70
+ const h = layout.bounds.height + PAD * 2;
71
+ const ox = -layout.bounds.x + PAD;
72
+ const oy = -layout.bounds.y + PAD;
73
+
74
+ const parts: string[] = [];
75
+ for (const top of layout.blocks) emitBlockSvg(top, ox, oy, parts);
76
+
77
+ const titleSvg = title
78
+ ? `<text class="text-header" x="${PAD}" y="${PAD - 6}">${escXml(`Nested Blocks — ${title}`)}</text>`
79
+ : '';
80
+
81
+ // Embed the shared theme CSS inside the SVG so the rendered output is
82
+ // self-contained — the JCEF host page only needs to drop the SVG into the
83
+ // DOM and styling resolves without any cooperation from the host stylesheet.
84
+ const embedCss = generateSvgEmbedCss('transitrix');
85
+
86
+ return `<svg xmlns="http://www.w3.org/2000/svg" width="${w}" height="${h}" viewBox="0 0 ${w} ${h}">
87
+ <style>${embedCss}</style>
88
+ ${titleSvg}
89
+ ${parts.join('\n')}
90
+ </svg>`;
91
+ }
@@ -0,0 +1,98 @@
1
+ /**
2
+ * Host-neutral renderer for the Capability Map notation.
3
+ * Mirrors `extension/src/capability-map-preview.ts`; emits a self-contained
4
+ * HTML fragment for the JCEF host (Step 4 of ADR 0001).
5
+ */
6
+ import type { CapabilityMapHeader, CapabilityNode } from '../capability-map/types.js';
7
+ import { escHtml } from './render-util.js';
8
+
9
+ const MATURITY_LABEL: Record<number, string> = {
10
+ 1: 'Initial',
11
+ 2: 'Managed',
12
+ 3: 'Defined',
13
+ 4: 'Quantitatively Managed',
14
+ 5: 'Optimising',
15
+ };
16
+
17
+ function maturityBadge(level: number, kind: 'current' | 'target'): string {
18
+ const safe = Math.max(1, Math.min(5, level | 0));
19
+ const label = kind === 'current' ? 'Current' : 'Target';
20
+ return `<span class="maturity-pill maturity-${safe}" title="${label}: Level ${safe} — ${escHtml(MATURITY_LABEL[safe] ?? '')}">L${safe}</span>`;
21
+ }
22
+
23
+ function isHorizontal(id: string): boolean {
24
+ return id.startsWith('H');
25
+ }
26
+
27
+ function renderCapabilityCard(node: CapabilityNode, depth: number): string {
28
+ const cls = ['capability-card', `depth-${Math.min(depth, 3)}`];
29
+ if (node.type) cls.push(`cap-type-${node.type}`);
30
+ if (isHorizontal(node.id)) cls.push('cap-horizontal');
31
+
32
+ const current = maturityBadge(node.current_maturity, 'current');
33
+ const target = node.target_maturity !== undefined ? maturityBadge(node.target_maturity, 'target') : '';
34
+ const arrow = target ? '<span class="maturity-arrow">→</span>' : '';
35
+
36
+ const meta: string[] = [];
37
+ if (node.type) meta.push(`<span class="cap-tag cap-tag-${escHtml(node.type)}">${escHtml(node.type)}</span>`);
38
+ if (node.owner_role) meta.push(`<span class="cap-meta">Owner: ${escHtml(node.owner_role)}</span>`);
39
+ if (node.business_process) meta.push(`<span class="cap-meta">Process: ${escHtml(node.business_process)}</span>`);
40
+ if (node.target_date) meta.push(`<span class="cap-meta">By ${escHtml(node.target_date)}</span>`);
41
+
42
+ const apps = node.applications && node.applications.length > 0
43
+ ? `<div class="cap-apps"><span class="cap-apps-label">Apps:</span> ${node.applications.map((a) => `<code>${escHtml(a)}</code>`).join(' ')}</div>`
44
+ : '';
45
+
46
+ const childBlock = node.children && node.children.length > 0
47
+ ? `<div class="cap-children">${node.children.map((c) => renderCapabilityCard(c, depth + 1)).join('')}</div>`
48
+ : '';
49
+
50
+ return `<div class="${cls.join(' ')}">
51
+ <div class="capability-head">
52
+ <div class="capability-maturity">${current}${arrow}${target}</div>
53
+ <div class="capability-titles">
54
+ <div class="capability-name">${escHtml(node.name)}</div>
55
+ <div class="capability-id">${escHtml(node.id)}</div>
56
+ </div>
57
+ </div>
58
+ ${meta.length > 0 ? `<div class="cap-meta-row">${meta.join('')}</div>` : ''}
59
+ ${node.description ? `<div class="cap-desc">${escHtml(node.description)}</div>` : ''}
60
+ ${apps}
61
+ ${childBlock}
62
+ </div>`;
63
+ }
64
+
65
+ export function renderCapabilityMapHtml(map: CapabilityMapHeader): string {
66
+ const header = `<header class="catalogue-header">
67
+ <div class="catalogue-title">${escHtml(map.name)}</div>
68
+ <div class="catalogue-meta">
69
+ <span class="catalogue-id-tag">${escHtml(map.id)}</span>
70
+ <span class="catalogue-updated">Assessed ${escHtml(map.assessment_date)}</span>
71
+ </div>
72
+ ${map.description ? `<div class="catalogue-subtitle">${escHtml(map.description)}</div>` : ''}
73
+ </header>`;
74
+ if (map.capabilities.length === 0) {
75
+ return `<section class="tx-catalogue tx-capability-map">
76
+ ${header}
77
+ <div class="empty-map">No capabilities defined.</div>
78
+ </section>`;
79
+ }
80
+ const verticals = map.capabilities.filter((c) => !isHorizontal(c.id));
81
+ const horizontals = map.capabilities.filter((c) => isHorizontal(c.id));
82
+ const vBlock = verticals.length > 0
83
+ ? `<section class="cap-axis cap-axis-v">
84
+ <h2 class="cap-axis-title">Vertical capabilities (domains)</h2>
85
+ <div class="cap-axis-list">${verticals.map((c) => renderCapabilityCard(c, 0)).join('')}</div>
86
+ </section>`
87
+ : '';
88
+ const hBlock = horizontals.length > 0
89
+ ? `<section class="cap-axis cap-axis-h">
90
+ <h2 class="cap-axis-title">Horizontal capabilities (cross-cutting)</h2>
91
+ <div class="cap-axis-list">${horizontals.map((c) => renderCapabilityCard(c, 0)).join('')}</div>
92
+ </section>`
93
+ : '';
94
+ return `<section class="tx-catalogue tx-capability-map">
95
+ ${header}
96
+ ${vBlock}${hBlock}
97
+ </section>`;
98
+ }
@@ -0,0 +1,122 @@
1
+ /**
2
+ * Browser-safe SVG renderer for the canonical FGCA and FGA notations.
3
+ *
4
+ * Step 4 of the IntelliJ epic (ADR 0001): the webview bundle must turn a
5
+ * validated FGCA/FGA document into renderable SVG so JCEF can drop it into the
6
+ * preview panel. The VS Code path lives in `extension/src/fgca-preview.ts` and
7
+ * pulls in VS Code-specific concerns (themes, title block, save dialogs,
8
+ * spacing/scope controls); this module is the host-neutral subset — pure
9
+ * column layout → SVG with no VS Code APIs, no `node:fs`, no `node:path`.
10
+ *
11
+ * FGCA and FGA share the same renderer; FGA only differs by hiding the
12
+ * `change` column (`hideChanges` / the layout's Goal → Activity collapse),
13
+ * exactly as the extension preview does.
14
+ */
15
+ import {
16
+ layoutFGCAPreview,
17
+ FGCA_NODE_W as NODE_W,
18
+ FGCA_NODE_H as NODE_H,
19
+ FGCA_HEADER_H as HEADER_H,
20
+ FGCA_PAD as PAD,
21
+ type FGCAPreviewColumn,
22
+ } from '../fgca/preview-layout.js';
23
+ import type { FGCADoc } from '../fgca/validate.js';
24
+ import { horizontalCubicEdgePath, DEFAULT_EDGE_CURVATURE } from '../edge-path.js';
25
+ import { generateSvgEmbedCss } from '../theme/index.js';
26
+ import { escXml } from './render-util.js';
27
+
28
+ const COL_LABELS: Record<FGCAPreviewColumn, string> = {
29
+ factor: 'Factors (F)',
30
+ goal: 'Goals (G)',
31
+ change: 'Changes (C)',
32
+ activity: 'Activities (A)',
33
+ };
34
+
35
+ export interface RenderFgcaOptions {
36
+ /** `'fga'` hides the Changes column; defaults to `'fgca'`. */
37
+ variant?: 'fgca' | 'fga';
38
+ /** Optional heading rendered as a left-anchored `text-header` line. */
39
+ title?: string;
40
+ }
41
+
42
+ export function renderFgcaSvg(doc: FGCADoc, options: RenderFgcaOptions = {}): string {
43
+ const { variant = 'fgca', title = '' } = options;
44
+ const hideChanges = variant === 'fga';
45
+
46
+ const { nodes, edges, columns, width, height } = layoutFGCAPreview(doc, { hideChanges });
47
+
48
+ if (nodes.length === 0) {
49
+ return `<svg xmlns="http://www.w3.org/2000/svg" width="0" height="0" viewBox="0 0 0 0"></svg>`;
50
+ }
51
+
52
+ const headerSvg = columns
53
+ .map(({ col, x }) =>
54
+ [
55
+ `<rect class="diagram-node layer-${col}" x="${x}" y="${PAD}" width="${NODE_W}" height="${HEADER_H}" rx="6"/>`,
56
+ `<text class="text-header" x="${x + NODE_W / 2}" y="${PAD + HEADER_H / 2}" text-anchor="middle" dominant-baseline="central">${escXml(COL_LABELS[col])}</text>`,
57
+ ].join('\n'),
58
+ )
59
+ .join('\n');
60
+
61
+ // Cubic bezier with horizontal control handles (shared geometry in
62
+ // @transitrix/diagrams). Uses the package default curvature — the
63
+ // interactive curvature control is a VS Code-only concern.
64
+ const edgeSvg = edges
65
+ .map(
66
+ (e) =>
67
+ `<path d="${horizontalCubicEdgePath(e.sx, e.sy, e.tx, e.ty, DEFAULT_EDGE_CURVATURE)}" class="diagram-edge" marker-end="url(#arrow)"/>`,
68
+ )
69
+ .join('\n');
70
+
71
+ const nodeSvg = nodes
72
+ .map((n) => {
73
+ const words = n.label.split(' ');
74
+ let line1 = '';
75
+ let line2 = '';
76
+ for (const w of words) {
77
+ if ((line1 + ' ' + w).trim().length <= 26) {
78
+ line1 = (line1 + ' ' + w).trim();
79
+ } else if ((line2 + ' ' + w).trim().length <= 26) {
80
+ line2 = (line2 + ' ' + w).trim();
81
+ } else if (!line2) {
82
+ line2 = w.slice(0, 24) + '…';
83
+ break;
84
+ }
85
+ }
86
+ const twoLines = line2.length > 0;
87
+ const y1 = twoLines ? n.y + NODE_H / 2 - 8 : n.y + NODE_H / 2 + 5;
88
+ const y2 = y1 + 18;
89
+ return [
90
+ `<rect class="diagram-node layer-${n.col}" x="${n.x}" y="${n.y}" width="${NODE_W}" height="${NODE_H}" rx="8"/>`,
91
+ `<text class="text-primary" x="${n.x + NODE_W / 2}" y="${y1}" text-anchor="middle">${escXml(line1)}</text>`,
92
+ twoLines
93
+ ? `<text class="text-secondary" x="${n.x + NODE_W / 2}" y="${y2}" text-anchor="middle">${escXml(line2)}</text>`
94
+ : '',
95
+ ]
96
+ .filter(Boolean)
97
+ .join('\n');
98
+ })
99
+ .join('\n');
100
+
101
+ const titleSvg = title
102
+ ? `<text class="text-header" x="${PAD}" y="${PAD - 6}">${escXml(title)}</text>`
103
+ : '';
104
+
105
+ // Embed the shared theme CSS inside the SVG so the rendered output is
106
+ // self-contained — the JCEF host page only needs to drop the SVG into the
107
+ // DOM and styling resolves without any cooperation from the host stylesheet.
108
+ const embedCss = generateSvgEmbedCss('transitrix');
109
+
110
+ return `<svg xmlns="http://www.w3.org/2000/svg" width="${width}" height="${height}" viewBox="0 0 ${width} ${height}">
111
+ <style>${embedCss}</style>
112
+ <defs>
113
+ <marker id="arrow" markerWidth="8" markerHeight="8" refX="8" refY="3" orient="auto">
114
+ <path d="M0,0 L0,6 L8,3 z" class="arrow-fill"/>
115
+ </marker>
116
+ </defs>
117
+ ${titleSvg}
118
+ ${headerSvg}
119
+ ${nodeSvg}
120
+ ${edgeSvg}
121
+ </svg>`;
122
+ }