@litfamily/litopencode 1.0.7 → 1.0.9

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 (723) hide show
  1. package/CHANGELOG.md +18 -0
  2. package/README-Ko-KR.md +314 -31
  3. package/README.md +312 -29
  4. package/dist/activation-primary-prompts.d.ts +1 -0
  5. package/dist/activation-primary-prompts.js +16 -0
  6. package/dist/activation-probe.js +4 -1
  7. package/dist/activation-prompt-utils.d.ts +1 -1
  8. package/dist/activation-routing.d.ts +6 -1
  9. package/dist/activation-routing.js +174 -16
  10. package/dist/activation-workflow-prompts.d.ts +1 -1
  11. package/dist/activation-workflow-prompts.js +18 -17
  12. package/dist/activation.d.ts +3 -2
  13. package/dist/activation.js +6 -6
  14. package/dist/agents/defaults.js +14 -6
  15. package/dist/cli/command-aliases.js +24 -22
  16. package/dist/cli/doctor.js +3 -0
  17. package/dist/cli/install-report.d.ts +1 -0
  18. package/dist/cli/install-report.js +4 -0
  19. package/dist/cli/install.js +7 -4
  20. package/dist/cli/managed-skill-assets.d.ts +1 -1
  21. package/dist/cli/managed-skill-assets.js +15 -5
  22. package/dist/cli/motion-runtime.d.ts +6 -0
  23. package/dist/cli/motion-runtime.js +46 -0
  24. package/dist/cli/native-skill-install.js +32 -9
  25. package/dist/cli/native-skill-integrity.js +1 -0
  26. package/dist/cli/native-skills.d.ts +2 -0
  27. package/dist/cli/native-skills.js +2 -1
  28. package/dist/cli/office-dependencies.d.ts +14 -0
  29. package/dist/cli/office-dependencies.js +24 -0
  30. package/dist/cli.js +13 -3
  31. package/dist/commands.d.ts +2 -11
  32. package/dist/commands.js +9 -17
  33. package/dist/deliverable-hedge-guard.d.ts +20 -21
  34. package/dist/deliverable-hedge-guard.js +234 -275
  35. package/dist/features.d.ts +81 -2
  36. package/dist/features.js +80 -13
  37. package/dist/hooks.d.ts +3 -2
  38. package/dist/hooks.js +4 -4
  39. package/dist/ignition.d.ts +1 -1
  40. package/dist/ignition.js +15 -4
  41. package/dist/index.d.ts +1 -1
  42. package/dist/index.js +1 -1
  43. package/dist/interface-handoff.d.ts +1 -0
  44. package/dist/interface-handoff.js +1 -0
  45. package/dist/motion-image-reads.d.ts +6 -0
  46. package/dist/motion-image-reads.js +46 -0
  47. package/dist/server.js +13 -11
  48. package/dist/skill-renames.d.ts +4 -2
  49. package/dist/skill-renames.js +12 -4
  50. package/dist/skills.d.ts +31 -3
  51. package/dist/skills.js +53 -9
  52. package/dist/tools.js +4 -4
  53. package/docs/ab/S11/baseline-desktop.webp +0 -0
  54. package/docs/ab/S11/baseline-phone.webp +0 -0
  55. package/docs/ab/S11/lit-desktop.webp +0 -0
  56. package/docs/ab/S11/lit-phone.webp +0 -0
  57. package/docs/ab/S3/baseline-desktop.webp +0 -0
  58. package/docs/ab/S3/baseline-phone.webp +0 -0
  59. package/docs/ab/S3/lit-desktop.webp +0 -0
  60. package/docs/ab/S3/lit-phone.webp +0 -0
  61. package/docs/ab/S4/baseline-desktop.webp +0 -0
  62. package/docs/ab/S4/baseline-phone.webp +0 -0
  63. package/docs/ab/S4/lit-desktop.webp +0 -0
  64. package/docs/ab/S4/lit-phone.webp +0 -0
  65. package/docs/ab/S5/lit-slides.webp +0 -0
  66. package/docs/ab/S7/lit-diagram.webp +0 -0
  67. package/docs/ab/S8/baseline-slides.webp +0 -0
  68. package/docs/ab/S8/lit-slides.webp +0 -0
  69. package/docs/ab/S9/lit-pages.webp +0 -0
  70. package/docs/assets/cover-motion-still.webp +0 -0
  71. package/docs/assets/cover-motion.webp +0 -0
  72. package/docs/assets/readme/badge-version.svg +1 -1
  73. package/docs/assets/skills/autoconference.webp +0 -0
  74. package/docs/assets/skills/automatic-guards.webp +0 -0
  75. package/docs/assets/skills/autoresearch.webp +0 -0
  76. package/docs/assets/skills/browser-drive.webp +0 -0
  77. package/docs/assets/skills/debugging.webp +0 -0
  78. package/docs/assets/skills/deep-interview.webp +0 -0
  79. package/docs/assets/skills/doctor-installer.webp +0 -0
  80. package/docs/assets/skills/durable-litgoal.webp +0 -0
  81. package/docs/assets/skills/frontend-ui-ux.webp +0 -0
  82. package/docs/assets/skills/lit-burnoff-file.webp +0 -0
  83. package/docs/assets/skills/lit-burnoff.webp +0 -0
  84. package/docs/assets/skills/lit-code.webp +0 -0
  85. package/docs/assets/skills/lit-commit.webp +0 -0
  86. package/docs/assets/skills/lit-comprehend.webp +0 -0
  87. package/docs/assets/skills/lit-crucible.webp +0 -0
  88. package/docs/assets/skills/lit-diagram-drawer.webp +0 -0
  89. package/docs/assets/skills/lit-docx.webp +0 -0
  90. package/docs/assets/skills/lit-fetch.webp +0 -0
  91. package/docs/assets/skills/lit-handoff.webp +0 -0
  92. package/docs/assets/skills/lit-humanizer.webp +0 -0
  93. package/docs/assets/skills/lit-init.webp +0 -0
  94. package/docs/assets/skills/lit-plan.webp +0 -0
  95. package/docs/assets/skills/lit-pptx.webp +0 -0
  96. package/docs/assets/skills/lit-recap.webp +0 -0
  97. package/docs/assets/skills/lit-scientific-visualization.webp +0 -0
  98. package/docs/assets/skills/lit-typographic-motion.webp +0 -0
  99. package/docs/assets/skills/litresearch.webp +0 -0
  100. package/docs/assets/skills/litwork.webp +0 -0
  101. package/docs/assets/skills/lsp-setup.webp +0 -0
  102. package/docs/assets/skills/lsp.webp +0 -0
  103. package/docs/assets/skills/readme-studio.webp +0 -0
  104. package/docs/assets/skills/refactor.webp +0 -0
  105. package/docs/assets/skills/review-work.webp +0 -0
  106. package/docs/assets/skills/rules.webp +0 -0
  107. package/docs/assets/skills/start-work.webp +0 -0
  108. package/docs/assets/skills/structural-search.webp +0 -0
  109. package/docs/assets/skills/visual-qa.webp +0 -0
  110. package/docs/assets/skills/wikify.webp +0 -0
  111. package/docs/reference-Ko-KR.md +5 -1
  112. package/docs/reference.md +6 -2
  113. package/package.json +1 -1
  114. package/rules/bundled-rules/lit-humanizer.md +12 -0
  115. package/skills/autoconference/SKILL.md +1 -1
  116. package/skills/autoconference/assets/report_template.md +1 -1
  117. package/skills/autoresearch/references/type-checklists.md +1 -1
  118. package/skills/browser-drive/SKILL.md +19 -5
  119. package/skills/browser-drive/scripts/capability-probe.mjs +26 -5
  120. package/skills/frontend-ui-ux/SKILL.md +10 -15
  121. package/skills/frontend-ui-ux/data/THIRD-PARTY-NOTICE.txt +10 -0
  122. package/skills/frontend-ui-ux/references/adaptive-layout.md +3 -11
  123. package/skills/frontend-ui-ux/references/brand-and-imagery.md +6 -11
  124. package/skills/frontend-ui-ux/references/complete-contract.md +10 -3
  125. package/skills/frontend-ui-ux/references/composition.md +1 -7
  126. package/skills/frontend-ui-ux/references/craft-floor.md +94 -0
  127. package/skills/frontend-ui-ux/references/creative-directions.md +1 -7
  128. package/skills/frontend-ui-ux/references/evidence-review.md +2 -12
  129. package/skills/frontend-ui-ux/references/implementation-platforms.md +1 -4
  130. package/skills/frontend-ui-ux/references/inclusive-interface.md +1 -3
  131. package/skills/frontend-ui-ux/references/interaction-motion.md +1 -7
  132. package/skills/frontend-ui-ux/references/motion-guide.md +125 -0
  133. package/skills/frontend-ui-ux/references/operating-lanes.md +2 -8
  134. package/skills/frontend-ui-ux/references/product-direction.md +1 -6
  135. package/skills/frontend-ui-ux/references/production.md +12 -5
  136. package/skills/frontend-ui-ux/references/redesign-playbook.md +1 -7
  137. package/skills/frontend-ui-ux/references/slop-register.md +103 -0
  138. package/skills/frontend-ui-ux/references/system-foundations.md +1 -8
  139. package/skills/frontend-ui-ux/references/taste-direction.md +4 -11
  140. package/skills/frontend-ui-ux/references/visual-language.md +1 -6
  141. package/skills/frontend-ui-ux/references/visual-reconstruction.md +2 -7
  142. package/skills/frontend-ui-ux/scripts/probe-page.mjs +326 -0
  143. package/skills/frontend-ui-ux/scripts/probe-server.mjs +24 -0
  144. package/skills/frontend-ui-ux/scripts/probe-static.mjs +42 -0
  145. package/skills/frontend-ui-ux/scripts/probe-thresholds.json +86 -0
  146. package/skills/frontend-ui-ux/scripts/probe.mjs +183 -0
  147. package/skills/lit-comprehend/SKILL.md +10 -11
  148. package/skills/lit-comprehend/references/artifact-template.md +2 -18
  149. package/skills/lit-comprehend/scripts/verify-explainer.ts +0 -14
  150. package/skills/lit-diagram-drawer/NOTICE.md +33 -0
  151. package/skills/lit-diagram-drawer/SKILL.md +101 -0
  152. package/skills/lit-diagram-drawer/assets/examples/type-architecture-dark.html +1 -0
  153. package/skills/lit-diagram-drawer/assets/examples/type-architecture-full.html +1 -0
  154. package/skills/lit-diagram-drawer/assets/examples/type-architecture-light.html +1 -0
  155. package/skills/lit-diagram-drawer/assets/examples/type-bar-dark.html +1 -0
  156. package/skills/lit-diagram-drawer/assets/examples/type-bar-full.html +1 -0
  157. package/skills/lit-diagram-drawer/assets/examples/type-bar-light.html +1 -0
  158. package/skills/lit-diagram-drawer/assets/examples/type-beeswarm-dark.html +1 -0
  159. package/skills/lit-diagram-drawer/assets/examples/type-beeswarm-full.html +1 -0
  160. package/skills/lit-diagram-drawer/assets/examples/type-beeswarm-light.html +1 -0
  161. package/skills/lit-diagram-drawer/assets/examples/type-bubble-dark.html +1 -0
  162. package/skills/lit-diagram-drawer/assets/examples/type-bubble-full.html +1 -0
  163. package/skills/lit-diagram-drawer/assets/examples/type-bubble-light.html +1 -0
  164. package/skills/lit-diagram-drawer/assets/examples/type-bump-dark.html +1 -0
  165. package/skills/lit-diagram-drawer/assets/examples/type-bump-full.html +1 -0
  166. package/skills/lit-diagram-drawer/assets/examples/type-bump-light.html +1 -0
  167. package/skills/lit-diagram-drawer/assets/examples/type-data-flow-dark.html +1 -0
  168. package/skills/lit-diagram-drawer/assets/examples/type-data-flow-full.html +1 -0
  169. package/skills/lit-diagram-drawer/assets/examples/type-data-flow-light.html +1 -0
  170. package/skills/lit-diagram-drawer/assets/examples/type-datalake-dark.html +1 -0
  171. package/skills/lit-diagram-drawer/assets/examples/type-datalake-full.html +1 -0
  172. package/skills/lit-diagram-drawer/assets/examples/type-datalake-light.html +1 -0
  173. package/skills/lit-diagram-drawer/assets/examples/type-db-schema-dark.html +1 -0
  174. package/skills/lit-diagram-drawer/assets/examples/type-db-schema-full.html +1 -0
  175. package/skills/lit-diagram-drawer/assets/examples/type-db-schema-light.html +1 -0
  176. package/skills/lit-diagram-drawer/assets/examples/type-dependency-dark.html +1 -0
  177. package/skills/lit-diagram-drawer/assets/examples/type-dependency-full.html +1 -0
  178. package/skills/lit-diagram-drawer/assets/examples/type-dependency-light.html +1 -0
  179. package/skills/lit-diagram-drawer/assets/examples/type-deployment-dark.html +1 -0
  180. package/skills/lit-diagram-drawer/assets/examples/type-deployment-full.html +1 -0
  181. package/skills/lit-diagram-drawer/assets/examples/type-deployment-light.html +1 -0
  182. package/skills/lit-diagram-drawer/assets/examples/type-dp-integration-dark.html +1 -0
  183. package/skills/lit-diagram-drawer/assets/examples/type-dp-integration-full.html +1 -0
  184. package/skills/lit-diagram-drawer/assets/examples/type-dp-integration-light.html +1 -0
  185. package/skills/lit-diagram-drawer/assets/examples/type-dp-security-matrix-dark.html +1 -0
  186. package/skills/lit-diagram-drawer/assets/examples/type-dp-security-matrix-full.html +1 -0
  187. package/skills/lit-diagram-drawer/assets/examples/type-dp-security-matrix-light.html +1 -0
  188. package/skills/lit-diagram-drawer/assets/examples/type-er-dark.html +1 -0
  189. package/skills/lit-diagram-drawer/assets/examples/type-er-full.html +1 -0
  190. package/skills/lit-diagram-drawer/assets/examples/type-er-light.html +1 -0
  191. package/skills/lit-diagram-drawer/assets/examples/type-fishbone-dark.html +1 -0
  192. package/skills/lit-diagram-drawer/assets/examples/type-fishbone-full.html +1 -0
  193. package/skills/lit-diagram-drawer/assets/examples/type-fishbone-light.html +1 -0
  194. package/skills/lit-diagram-drawer/assets/examples/type-flowchart-dark.html +1 -0
  195. package/skills/lit-diagram-drawer/assets/examples/type-flowchart-full.html +1 -0
  196. package/skills/lit-diagram-drawer/assets/examples/type-flowchart-light.html +1 -0
  197. package/skills/lit-diagram-drawer/assets/examples/type-gantt-dark.html +1 -0
  198. package/skills/lit-diagram-drawer/assets/examples/type-gantt-full.html +1 -0
  199. package/skills/lit-diagram-drawer/assets/examples/type-gantt-light.html +1 -0
  200. package/skills/lit-diagram-drawer/assets/examples/type-heatmap-dark.html +1 -0
  201. package/skills/lit-diagram-drawer/assets/examples/type-heatmap-full.html +1 -0
  202. package/skills/lit-diagram-drawer/assets/examples/type-heatmap-light.html +1 -0
  203. package/skills/lit-diagram-drawer/assets/examples/type-high-level-dark.html +1 -0
  204. package/skills/lit-diagram-drawer/assets/examples/type-high-level-full.html +1 -0
  205. package/skills/lit-diagram-drawer/assets/examples/type-high-level-light.html +1 -0
  206. package/skills/lit-diagram-drawer/assets/examples/type-high-level-vertical-dark.html +1 -0
  207. package/skills/lit-diagram-drawer/assets/examples/type-high-level-vertical-full.html +1 -0
  208. package/skills/lit-diagram-drawer/assets/examples/type-high-level-vertical-light.html +1 -0
  209. package/skills/lit-diagram-drawer/assets/examples/type-import-drawio-dark.html +1 -0
  210. package/skills/lit-diagram-drawer/assets/examples/type-import-drawio-full.html +1 -0
  211. package/skills/lit-diagram-drawer/assets/examples/type-import-drawio-light.html +1 -0
  212. package/skills/lit-diagram-drawer/assets/examples/type-import-excalidraw-dark.html +1 -0
  213. package/skills/lit-diagram-drawer/assets/examples/type-import-excalidraw-full.html +1 -0
  214. package/skills/lit-diagram-drawer/assets/examples/type-import-excalidraw-light.html +1 -0
  215. package/skills/lit-diagram-drawer/assets/examples/type-import-mermaid-dark.html +1 -0
  216. package/skills/lit-diagram-drawer/assets/examples/type-import-mermaid-full.html +1 -0
  217. package/skills/lit-diagram-drawer/assets/examples/type-import-mermaid-light.html +1 -0
  218. package/skills/lit-diagram-drawer/assets/examples/type-it-state-dark.html +1 -0
  219. package/skills/lit-diagram-drawer/assets/examples/type-it-state-full.html +1 -0
  220. package/skills/lit-diagram-drawer/assets/examples/type-it-state-light.html +1 -0
  221. package/skills/lit-diagram-drawer/assets/examples/type-journey-dark.html +1 -0
  222. package/skills/lit-diagram-drawer/assets/examples/type-journey-full.html +1 -0
  223. package/skills/lit-diagram-drawer/assets/examples/type-journey-light.html +1 -0
  224. package/skills/lit-diagram-drawer/assets/examples/type-kanban-dark.html +1 -0
  225. package/skills/lit-diagram-drawer/assets/examples/type-kanban-full.html +1 -0
  226. package/skills/lit-diagram-drawer/assets/examples/type-kanban-light.html +1 -0
  227. package/skills/lit-diagram-drawer/assets/examples/type-layers-dark.html +1 -0
  228. package/skills/lit-diagram-drawer/assets/examples/type-layers-full.html +1 -0
  229. package/skills/lit-diagram-drawer/assets/examples/type-layers-light.html +1 -0
  230. package/skills/lit-diagram-drawer/assets/examples/type-line-dark.html +1 -0
  231. package/skills/lit-diagram-drawer/assets/examples/type-line-full.html +1 -0
  232. package/skills/lit-diagram-drawer/assets/examples/type-line-light.html +1 -0
  233. package/skills/lit-diagram-drawer/assets/examples/type-loop-dark.html +1 -0
  234. package/skills/lit-diagram-drawer/assets/examples/type-loop-full.html +1 -0
  235. package/skills/lit-diagram-drawer/assets/examples/type-loop-light.html +1 -0
  236. package/skills/lit-diagram-drawer/assets/examples/type-loop-terminal-dark.html +1 -0
  237. package/skills/lit-diagram-drawer/assets/examples/type-loop-terminal-full.html +1 -0
  238. package/skills/lit-diagram-drawer/assets/examples/type-loop-terminal-light.html +1 -0
  239. package/skills/lit-diagram-drawer/assets/examples/type-marimekko-dark.html +1 -0
  240. package/skills/lit-diagram-drawer/assets/examples/type-marimekko-full.html +1 -0
  241. package/skills/lit-diagram-drawer/assets/examples/type-marimekko-light.html +1 -0
  242. package/skills/lit-diagram-drawer/assets/examples/type-medallion-dark.html +1 -0
  243. package/skills/lit-diagram-drawer/assets/examples/type-medallion-full.html +1 -0
  244. package/skills/lit-diagram-drawer/assets/examples/type-medallion-light.html +1 -0
  245. package/skills/lit-diagram-drawer/assets/examples/type-nested-dark.html +1 -0
  246. package/skills/lit-diagram-drawer/assets/examples/type-nested-full.html +1 -0
  247. package/skills/lit-diagram-drawer/assets/examples/type-nested-light.html +1 -0
  248. package/skills/lit-diagram-drawer/assets/examples/type-org-chart-dark.html +1 -0
  249. package/skills/lit-diagram-drawer/assets/examples/type-org-chart-full.html +1 -0
  250. package/skills/lit-diagram-drawer/assets/examples/type-org-chart-light.html +1 -0
  251. package/skills/lit-diagram-drawer/assets/examples/type-paved-road-animated-dark.html +1 -0
  252. package/skills/lit-diagram-drawer/assets/examples/type-paved-road-animated-full.html +1 -0
  253. package/skills/lit-diagram-drawer/assets/examples/type-paved-road-animated-light.html +1 -0
  254. package/skills/lit-diagram-drawer/assets/examples/type-polar-dark.html +1 -0
  255. package/skills/lit-diagram-drawer/assets/examples/type-polar-full.html +1 -0
  256. package/skills/lit-diagram-drawer/assets/examples/type-polar-light.html +1 -0
  257. package/skills/lit-diagram-drawer/assets/examples/type-policy-trace-animated-dark.html +1 -0
  258. package/skills/lit-diagram-drawer/assets/examples/type-policy-trace-animated-full.html +1 -0
  259. package/skills/lit-diagram-drawer/assets/examples/type-policy-trace-animated-light.html +1 -0
  260. package/skills/lit-diagram-drawer/assets/examples/type-process-dark.html +1 -0
  261. package/skills/lit-diagram-drawer/assets/examples/type-process-full.html +1 -0
  262. package/skills/lit-diagram-drawer/assets/examples/type-process-light.html +1 -0
  263. package/skills/lit-diagram-drawer/assets/examples/type-pyramid-dark.html +1 -0
  264. package/skills/lit-diagram-drawer/assets/examples/type-pyramid-full.html +1 -0
  265. package/skills/lit-diagram-drawer/assets/examples/type-pyramid-light.html +1 -0
  266. package/skills/lit-diagram-drawer/assets/examples/type-quadrant-consultant-dark.html +1 -0
  267. package/skills/lit-diagram-drawer/assets/examples/type-quadrant-consultant-full.html +1 -0
  268. package/skills/lit-diagram-drawer/assets/examples/type-quadrant-consultant-light.html +1 -0
  269. package/skills/lit-diagram-drawer/assets/examples/type-quadrant-dark.html +1 -0
  270. package/skills/lit-diagram-drawer/assets/examples/type-quadrant-full.html +1 -0
  271. package/skills/lit-diagram-drawer/assets/examples/type-quadrant-light.html +1 -0
  272. package/skills/lit-diagram-drawer/assets/examples/type-queue-animated-dark.html +1 -0
  273. package/skills/lit-diagram-drawer/assets/examples/type-queue-animated-full.html +1 -0
  274. package/skills/lit-diagram-drawer/assets/examples/type-queue-animated-light.html +1 -0
  275. package/skills/lit-diagram-drawer/assets/examples/type-radar-dark.html +1 -0
  276. package/skills/lit-diagram-drawer/assets/examples/type-radar-full.html +1 -0
  277. package/skills/lit-diagram-drawer/assets/examples/type-radar-light.html +1 -0
  278. package/skills/lit-diagram-drawer/assets/examples/type-ridgeline-dark.html +1 -0
  279. package/skills/lit-diagram-drawer/assets/examples/type-ridgeline-full.html +1 -0
  280. package/skills/lit-diagram-drawer/assets/examples/type-ridgeline-light.html +1 -0
  281. package/skills/lit-diagram-drawer/assets/examples/type-sankey-dark.html +1 -0
  282. package/skills/lit-diagram-drawer/assets/examples/type-sankey-full.html +1 -0
  283. package/skills/lit-diagram-drawer/assets/examples/type-sankey-light.html +1 -0
  284. package/skills/lit-diagram-drawer/assets/examples/type-scatter-dark.html +1 -0
  285. package/skills/lit-diagram-drawer/assets/examples/type-scatter-full.html +1 -0
  286. package/skills/lit-diagram-drawer/assets/examples/type-scatter-light.html +1 -0
  287. package/skills/lit-diagram-drawer/assets/examples/type-sequence-dark.html +1 -0
  288. package/skills/lit-diagram-drawer/assets/examples/type-sequence-full.html +1 -0
  289. package/skills/lit-diagram-drawer/assets/examples/type-sequence-light.html +1 -0
  290. package/skills/lit-diagram-drawer/assets/examples/type-sequence-oauth-dark.html +1 -0
  291. package/skills/lit-diagram-drawer/assets/examples/type-sequence-oauth-full.html +1 -0
  292. package/skills/lit-diagram-drawer/assets/examples/type-sequence-oauth-light.html +1 -0
  293. package/skills/lit-diagram-drawer/assets/examples/type-slopegraph-dark.html +1 -0
  294. package/skills/lit-diagram-drawer/assets/examples/type-slopegraph-full.html +1 -0
  295. package/skills/lit-diagram-drawer/assets/examples/type-slopegraph-light.html +1 -0
  296. package/skills/lit-diagram-drawer/assets/examples/type-state-dark.html +1 -0
  297. package/skills/lit-diagram-drawer/assets/examples/type-state-full.html +1 -0
  298. package/skills/lit-diagram-drawer/assets/examples/type-state-lifecycle-dark.html +1 -0
  299. package/skills/lit-diagram-drawer/assets/examples/type-state-lifecycle-full.html +1 -0
  300. package/skills/lit-diagram-drawer/assets/examples/type-state-lifecycle-light.html +1 -0
  301. package/skills/lit-diagram-drawer/assets/examples/type-state-light.html +1 -0
  302. package/skills/lit-diagram-drawer/assets/examples/type-story-map-dark.html +1 -0
  303. package/skills/lit-diagram-drawer/assets/examples/type-story-map-full.html +1 -0
  304. package/skills/lit-diagram-drawer/assets/examples/type-story-map-light.html +1 -0
  305. package/skills/lit-diagram-drawer/assets/examples/type-streamgraph-dark.html +1 -0
  306. package/skills/lit-diagram-drawer/assets/examples/type-streamgraph-full.html +1 -0
  307. package/skills/lit-diagram-drawer/assets/examples/type-streamgraph-light.html +1 -0
  308. package/skills/lit-diagram-drawer/assets/examples/type-swimlane-dark.html +1 -0
  309. package/skills/lit-diagram-drawer/assets/examples/type-swimlane-full.html +1 -0
  310. package/skills/lit-diagram-drawer/assets/examples/type-swimlane-light.html +1 -0
  311. package/skills/lit-diagram-drawer/assets/examples/type-timeline-dark.html +1 -0
  312. package/skills/lit-diagram-drawer/assets/examples/type-timeline-full.html +1 -0
  313. package/skills/lit-diagram-drawer/assets/examples/type-timeline-light.html +1 -0
  314. package/skills/lit-diagram-drawer/assets/examples/type-tree-block-decomposition-dark.html +1 -0
  315. package/skills/lit-diagram-drawer/assets/examples/type-tree-block-decomposition-full.html +1 -0
  316. package/skills/lit-diagram-drawer/assets/examples/type-tree-block-decomposition-light.html +1 -0
  317. package/skills/lit-diagram-drawer/assets/examples/type-tree-dark.html +1 -0
  318. package/skills/lit-diagram-drawer/assets/examples/type-tree-full.html +1 -0
  319. package/skills/lit-diagram-drawer/assets/examples/type-tree-light.html +1 -0
  320. package/skills/lit-diagram-drawer/assets/examples/type-treemap-dark.html +1 -0
  321. package/skills/lit-diagram-drawer/assets/examples/type-treemap-full.html +1 -0
  322. package/skills/lit-diagram-drawer/assets/examples/type-treemap-light.html +1 -0
  323. package/skills/lit-diagram-drawer/assets/examples/type-uml-class-dark.html +1 -0
  324. package/skills/lit-diagram-drawer/assets/examples/type-uml-class-full.html +1 -0
  325. package/skills/lit-diagram-drawer/assets/examples/type-uml-class-light.html +1 -0
  326. package/skills/lit-diagram-drawer/assets/examples/type-venn-dark.html +1 -0
  327. package/skills/lit-diagram-drawer/assets/examples/type-venn-full.html +1 -0
  328. package/skills/lit-diagram-drawer/assets/examples/type-venn-light.html +1 -0
  329. package/skills/lit-diagram-drawer/assets/examples/type-wardley-dark.html +1 -0
  330. package/skills/lit-diagram-drawer/assets/examples/type-wardley-full.html +1 -0
  331. package/skills/lit-diagram-drawer/assets/examples/type-wardley-light.html +1 -0
  332. package/skills/lit-diagram-drawer/assets/examples/type-waterfall-dark.html +1 -0
  333. package/skills/lit-diagram-drawer/assets/examples/type-waterfall-full.html +1 -0
  334. package/skills/lit-diagram-drawer/assets/examples/type-waterfall-light.html +1 -0
  335. package/skills/lit-diagram-drawer/assets/fonts/OFL.txt +94 -0
  336. package/skills/lit-diagram-drawer/assets/fonts/PretendardVariable.woff2 +0 -0
  337. package/skills/lit-diagram-drawer/assets/fonts/provenance.json +23 -0
  338. package/skills/lit-diagram-drawer/assets/icons.html +231 -0
  339. package/skills/lit-diagram-drawer/assets/licenses/devicon-MIT.txt +20 -0
  340. package/skills/lit-diagram-drawer/assets/licenses/diagram-design-MIT.txt +21 -0
  341. package/skills/lit-diagram-drawer/assets/licenses/log-z-MIT.txt +21 -0
  342. package/skills/lit-diagram-drawer/assets/licenses/simple-icons-CC0.md +30 -0
  343. package/skills/lit-diagram-drawer/assets/licenses/tabler-MIT.txt +21 -0
  344. package/skills/lit-diagram-drawer/examples/01-service-architecture/after.html +1 -0
  345. package/skills/lit-diagram-drawer/examples/01-service-architecture/brief.md +33 -0
  346. package/skills/lit-diagram-drawer/examples/02-release-decision/after.html +1 -0
  347. package/skills/lit-diagram-drawer/examples/02-release-decision/brief.md +18 -0
  348. package/skills/lit-diagram-drawer/examples/03-data-retention/after.html +1 -0
  349. package/skills/lit-diagram-drawer/examples/03-data-retention/brief.md +19 -0
  350. package/skills/lit-diagram-drawer/examples/04-oauth-sequence/after.html +1 -0
  351. package/skills/lit-diagram-drawer/examples/04-oauth-sequence/brief.md +17 -0
  352. package/skills/lit-diagram-drawer/examples/05-review-lanes/after.html +1 -0
  353. package/skills/lit-diagram-drawer/examples/05-review-lanes/brief.md +17 -0
  354. package/skills/lit-diagram-drawer/examples/06-rollout-gates/after.html +1 -0
  355. package/skills/lit-diagram-drawer/examples/06-rollout-gates/brief.md +17 -0
  356. package/skills/lit-diagram-drawer/examples/07-deployment-boundary/after.html +1 -0
  357. package/skills/lit-diagram-drawer/examples/07-deployment-boundary/brief.md +19 -0
  358. package/skills/lit-diagram-drawer/examples/08-policy-traces/after.html +1 -0
  359. package/skills/lit-diagram-drawer/examples/08-policy-traces/brief.md +20 -0
  360. package/skills/lit-diagram-drawer/references/accessibility.md +37 -0
  361. package/skills/lit-diagram-drawer/references/export.md +17 -0
  362. package/skills/lit-diagram-drawer/references/import-drawio.md +13 -0
  363. package/skills/lit-diagram-drawer/references/import-excalidraw.md +11 -0
  364. package/skills/lit-diagram-drawer/references/import-mermaid.md +12 -0
  365. package/skills/lit-diagram-drawer/references/import-schema.md +28 -0
  366. package/skills/lit-diagram-drawer/references/korean-typography.md +34 -0
  367. package/skills/lit-diagram-drawer/references/motion.md +29 -0
  368. package/skills/lit-diagram-drawer/references/office-pptx-docx.md +28 -0
  369. package/skills/lit-diagram-drawer/references/output-spec.md +48 -0
  370. package/skills/lit-diagram-drawer/references/primitive-annotation.md +12 -0
  371. package/skills/lit-diagram-drawer/references/primitive-icons.md +21 -0
  372. package/skills/lit-diagram-drawer/references/primitive-sketchy.md +11 -0
  373. package/skills/lit-diagram-drawer/references/primitive-terminal.md +11 -0
  374. package/skills/lit-diagram-drawer/references/profiles.md +24 -0
  375. package/skills/lit-diagram-drawer/references/semantic-patterns.md +27 -0
  376. package/skills/lit-diagram-drawer/references/style-guide.md +67 -0
  377. package/skills/lit-diagram-drawer/references/type-architecture.md +51 -0
  378. package/skills/lit-diagram-drawer/references/type-bar.md +51 -0
  379. package/skills/lit-diagram-drawer/references/type-beeswarm.md +49 -0
  380. package/skills/lit-diagram-drawer/references/type-bubble.md +49 -0
  381. package/skills/lit-diagram-drawer/references/type-bump.md +49 -0
  382. package/skills/lit-diagram-drawer/references/type-catalog.json +1433 -0
  383. package/skills/lit-diagram-drawer/references/type-data-flow.md +51 -0
  384. package/skills/lit-diagram-drawer/references/type-datalake.md +49 -0
  385. package/skills/lit-diagram-drawer/references/type-db-schema.md +49 -0
  386. package/skills/lit-diagram-drawer/references/type-dependency.md +49 -0
  387. package/skills/lit-diagram-drawer/references/type-deployment.md +49 -0
  388. package/skills/lit-diagram-drawer/references/type-dp-integration.md +49 -0
  389. package/skills/lit-diagram-drawer/references/type-dp-security-matrix.md +49 -0
  390. package/skills/lit-diagram-drawer/references/type-er.md +49 -0
  391. package/skills/lit-diagram-drawer/references/type-fishbone.md +49 -0
  392. package/skills/lit-diagram-drawer/references/type-flowchart.md +49 -0
  393. package/skills/lit-diagram-drawer/references/type-gantt.md +49 -0
  394. package/skills/lit-diagram-drawer/references/type-heatmap.md +53 -0
  395. package/skills/lit-diagram-drawer/references/type-high-level-vertical.md +53 -0
  396. package/skills/lit-diagram-drawer/references/type-high-level.md +53 -0
  397. package/skills/lit-diagram-drawer/references/type-import-drawio.md +53 -0
  398. package/skills/lit-diagram-drawer/references/type-import-excalidraw.md +53 -0
  399. package/skills/lit-diagram-drawer/references/type-import-mermaid.md +53 -0
  400. package/skills/lit-diagram-drawer/references/type-it-state.md +54 -0
  401. package/skills/lit-diagram-drawer/references/type-journey.md +54 -0
  402. package/skills/lit-diagram-drawer/references/type-kanban.md +54 -0
  403. package/skills/lit-diagram-drawer/references/type-layers.md +54 -0
  404. package/skills/lit-diagram-drawer/references/type-line.md +54 -0
  405. package/skills/lit-diagram-drawer/references/type-loop-terminal.md +53 -0
  406. package/skills/lit-diagram-drawer/references/type-loop.md +54 -0
  407. package/skills/lit-diagram-drawer/references/type-marimekko.md +54 -0
  408. package/skills/lit-diagram-drawer/references/type-medallion.md +54 -0
  409. package/skills/lit-diagram-drawer/references/type-nested.md +59 -0
  410. package/skills/lit-diagram-drawer/references/type-org-chart.md +58 -0
  411. package/skills/lit-diagram-drawer/references/type-paved-road-animated.md +72 -0
  412. package/skills/lit-diagram-drawer/references/type-polar.md +67 -0
  413. package/skills/lit-diagram-drawer/references/type-policy-trace-animated.md +69 -0
  414. package/skills/lit-diagram-drawer/references/type-process.md +58 -0
  415. package/skills/lit-diagram-drawer/references/type-pyramid.md +59 -0
  416. package/skills/lit-diagram-drawer/references/type-quadrant-consultant.md +60 -0
  417. package/skills/lit-diagram-drawer/references/type-quadrant.md +57 -0
  418. package/skills/lit-diagram-drawer/references/type-queue-animated.md +63 -0
  419. package/skills/lit-diagram-drawer/references/type-radar.md +57 -0
  420. package/skills/lit-diagram-drawer/references/type-ridgeline.md +63 -0
  421. package/skills/lit-diagram-drawer/references/type-sankey.md +68 -0
  422. package/skills/lit-diagram-drawer/references/type-scatter.md +60 -0
  423. package/skills/lit-diagram-drawer/references/type-sequence-oauth.md +66 -0
  424. package/skills/lit-diagram-drawer/references/type-sequence.md +63 -0
  425. package/skills/lit-diagram-drawer/references/type-slopegraph.md +65 -0
  426. package/skills/lit-diagram-drawer/references/type-state-lifecycle.md +53 -0
  427. package/skills/lit-diagram-drawer/references/type-state.md +59 -0
  428. package/skills/lit-diagram-drawer/references/type-story-map.md +52 -0
  429. package/skills/lit-diagram-drawer/references/type-streamgraph.md +53 -0
  430. package/skills/lit-diagram-drawer/references/type-swimlane.md +52 -0
  431. package/skills/lit-diagram-drawer/references/type-timeline.md +52 -0
  432. package/skills/lit-diagram-drawer/references/type-tree-block-decomposition.md +57 -0
  433. package/skills/lit-diagram-drawer/references/type-tree.md +54 -0
  434. package/skills/lit-diagram-drawer/references/type-treemap.md +54 -0
  435. package/skills/lit-diagram-drawer/references/type-uml-class.md +52 -0
  436. package/skills/lit-diagram-drawer/references/type-venn.md +51 -0
  437. package/skills/lit-diagram-drawer/references/type-wardley.md +52 -0
  438. package/skills/lit-diagram-drawer/references/type-waterfall.md +54 -0
  439. package/skills/lit-diagram-drawer/references/verifier-guide.md +59 -0
  440. package/skills/lit-diagram-drawer/scripts/block-registry.mjs +43 -0
  441. package/skills/lit-diagram-drawer/scripts/brief-contract.mjs +94 -0
  442. package/skills/lit-diagram-drawer/scripts/capability-probe.mjs +132 -0
  443. package/skills/lit-diagram-drawer/scripts/check-visible-text.mjs +15 -0
  444. package/skills/lit-diagram-drawer/scripts/craft-thresholds.json +15 -0
  445. package/skills/lit-diagram-drawer/scripts/diagram-metrics.mjs +216 -0
  446. package/skills/lit-diagram-drawer/scripts/doctor.mjs +8 -0
  447. package/skills/lit-diagram-drawer/scripts/drawio-extract.mjs +214 -0
  448. package/skills/lit-diagram-drawer/scripts/excalidraw-extract.mjs +151 -0
  449. package/skills/lit-diagram-drawer/scripts/export.mjs +133 -0
  450. package/skills/lit-diagram-drawer/scripts/import-shared.mjs +130 -0
  451. package/skills/lit-diagram-drawer/scripts/mermaid-extract.mjs +173 -0
  452. package/skills/lit-diagram-drawer/scripts/office-safety.mjs +120 -0
  453. package/skills/lit-diagram-drawer/scripts/renderer-safety.mjs +46 -0
  454. package/skills/lit-diagram-drawer/scripts/test-block-registry.mjs +20 -0
  455. package/skills/lit-diagram-drawer/scripts/test-brief-contract.mjs +27 -0
  456. package/skills/lit-diagram-drawer/scripts/test-importers.mjs +119 -0
  457. package/skills/lit-diagram-drawer/scripts/test-office-safety.mjs +67 -0
  458. package/skills/lit-diagram-drawer/scripts/test-sequence-verifier.mjs +28 -0
  459. package/skills/lit-diagram-drawer/scripts/test-visual-quality.mjs +68 -0
  460. package/skills/lit-diagram-drawer/scripts/verify-all.mjs +74 -0
  461. package/skills/lit-diagram-drawer/scripts/verify-brief.mjs +47 -0
  462. package/skills/lit-diagram-drawer/scripts/verify-coverage.mjs +56 -0
  463. package/skills/lit-diagram-drawer/scripts/verify-diagram.mjs +26 -0
  464. package/skills/lit-diagram-drawer/scripts/verify-motion.mjs +12 -0
  465. package/skills/lit-diagram-drawer/scripts/verify-type.mjs +48 -0
  466. package/skills/lit-diagram-drawer/scripts/visual-quality.mjs +363 -0
  467. package/skills/lit-docx/LICENSE-MIT.txt +21 -0
  468. package/skills/lit-docx/SKILL.md +78 -0
  469. package/skills/lit-docx/references/frontmatter_schema.md +42 -0
  470. package/skills/lit-docx/references/journal_style_spec.md +17 -0
  471. package/skills/lit-docx/references/markdown_quality_checklist.md +37 -0
  472. package/skills/lit-docx/references/slop_phrase_list.yaml +58 -0
  473. package/skills/lit-docx/references/slop_rules.md +35 -0
  474. package/skills/lit-docx/requirements.in +5 -0
  475. package/skills/lit-docx/requirements.lock +289 -0
  476. package/skills/lit-docx/run.py +64 -0
  477. package/skills/lit-docx/scripts/clean_markdown.py +95 -0
  478. package/skills/lit-docx/scripts/convert_md_to_docx.py +1047 -0
  479. package/skills/lit-docx/scripts/convert_md_to_pdf.py +281 -0
  480. package/skills/lit-docx/scripts/convert_pdf.py +130 -0
  481. package/skills/lit-docx/scripts/craft-thresholds.json +11 -0
  482. package/skills/lit-docx/scripts/craft_docx.py +83 -0
  483. package/skills/lit-docx/scripts/edit_docx.py +297 -0
  484. package/skills/lit-docx/scripts/embed_images.py +78 -0
  485. package/skills/lit-docx/scripts/generate_docx_templates.py +491 -0
  486. package/skills/lit-docx/scripts/slop_lint.py +485 -0
  487. package/skills/lit-docx/scripts/visual_audit.py +41 -0
  488. package/skills/lit-docx/templates/docx/acs.docx +0 -0
  489. package/skills/lit-docx/templates/docx/elsevier.docx +0 -0
  490. package/skills/lit-docx/templates/docx/ieee.docx +0 -0
  491. package/skills/lit-docx/templates/docx/korean-generic.docx +0 -0
  492. package/skills/lit-docx/templates/docx/nature.docx +0 -0
  493. package/skills/lit-docx/templates/latex/acs/README.md +5 -0
  494. package/skills/lit-docx/templates/latex/acs/template.tex +37 -0
  495. package/skills/lit-docx/templates/latex/elsevier/README.md +5 -0
  496. package/skills/lit-docx/templates/latex/elsevier/template.tex +38 -0
  497. package/skills/lit-docx/templates/latex/ieee/README.md +5 -0
  498. package/skills/lit-docx/templates/latex/ieee/template.tex +37 -0
  499. package/skills/lit-docx/templates/latex/korean-generic/README.md +5 -0
  500. package/skills/lit-docx/templates/latex/korean-generic/template.tex +37 -0
  501. package/skills/lit-docx/templates/latex/nature/README.md +5 -0
  502. package/skills/lit-docx/templates/latex/nature/template.tex +37 -0
  503. package/skills/lit-docx/templates/registry.yaml +1366 -0
  504. package/skills/lit-humanizer/NOTICE +160 -0
  505. package/skills/lit-humanizer/SKILL.md +122 -0
  506. package/skills/lit-humanizer/assets/always-on-rule.md +9 -0
  507. package/skills/lit-humanizer/assets/report-skeleton.md +25 -0
  508. package/skills/lit-humanizer/assets/slide-text-skeleton.md +28 -0
  509. package/skills/lit-humanizer/examples/accessibility-note/after.md +7 -0
  510. package/skills/lit-humanizer/examples/accessibility-note/before.md +7 -0
  511. package/skills/lit-humanizer/examples/api-reference/after.md +9 -0
  512. package/skills/lit-humanizer/examples/api-reference/before.md +15 -0
  513. package/skills/lit-humanizer/examples/changelog/after.md +5 -0
  514. package/skills/lit-humanizer/examples/changelog/before.md +12 -0
  515. package/skills/lit-humanizer/examples/code-comments/after.md +10 -0
  516. package/skills/lit-humanizer/examples/code-comments/before.md +19 -0
  517. package/skills/lit-humanizer/examples/commit/after.md +5 -0
  518. package/skills/lit-humanizer/examples/commit/before.md +7 -0
  519. package/skills/lit-humanizer/examples/data-release/after.md +7 -0
  520. package/skills/lit-humanizer/examples/data-release/before.md +9 -0
  521. package/skills/lit-humanizer/examples/english-essay/after.md +5 -0
  522. package/skills/lit-humanizer/examples/english-essay/before.md +5 -0
  523. package/skills/lit-humanizer/examples/incident-update/after.md +7 -0
  524. package/skills/lit-humanizer/examples/incident-update/before.md +7 -0
  525. package/skills/lit-humanizer/examples/ko-essay/after.md +7 -0
  526. package/skills/lit-humanizer/examples/ko-essay/before.md +9 -0
  527. package/skills/lit-humanizer/examples/ko-report/after.md +9 -0
  528. package/skills/lit-humanizer/examples/ko-report/before.md +13 -0
  529. package/skills/lit-humanizer/examples/ko-slide/after.md +19 -0
  530. package/skills/lit-humanizer/examples/ko-slide/before.md +21 -0
  531. package/skills/lit-humanizer/examples/meeting-brief/after.md +9 -0
  532. package/skills/lit-humanizer/examples/meeting-brief/before.md +11 -0
  533. package/skills/lit-humanizer/examples/policy-faq/after.md +9 -0
  534. package/skills/lit-humanizer/examples/policy-faq/before.md +9 -0
  535. package/skills/lit-humanizer/examples/pr/after.md +15 -0
  536. package/skills/lit-humanizer/examples/pr/before.md +17 -0
  537. package/skills/lit-humanizer/examples/project-update/after.md +7 -0
  538. package/skills/lit-humanizer/examples/project-update/before.md +9 -0
  539. package/skills/lit-humanizer/examples/readme/after.md +12 -0
  540. package/skills/lit-humanizer/examples/readme/before.md +14 -0
  541. package/skills/lit-humanizer/examples/report/after.md +13 -0
  542. package/skills/lit-humanizer/examples/report/before.md +11 -0
  543. package/skills/lit-humanizer/examples/research-abstract/after.md +5 -0
  544. package/skills/lit-humanizer/examples/research-abstract/before.md +5 -0
  545. package/skills/lit-humanizer/examples/slides/after.md +19 -0
  546. package/skills/lit-humanizer/examples/slides/before.md +19 -0
  547. package/skills/lit-humanizer/examples/troubleshooting/after.md +11 -0
  548. package/skills/lit-humanizer/examples/troubleshooting/before.md +11 -0
  549. package/skills/lit-humanizer/fixtures/ko-metrics-golden.json +49 -0
  550. package/skills/lit-humanizer/fixtures/office/minimal.docx +0 -0
  551. package/skills/lit-humanizer/fixtures/office/minimal.pptx +0 -0
  552. package/skills/lit-humanizer/fixtures/pos-real.txt +26 -0
  553. package/skills/lit-humanizer/fixtures/rule-cases.json +306 -0
  554. package/skills/lit-humanizer/references/code-patterns.md +468 -0
  555. package/skills/lit-humanizer/references/deliverable-channels.md +111 -0
  556. package/skills/lit-humanizer/references/en-patterns-checklist.md +43 -0
  557. package/skills/lit-humanizer/references/en-patterns-content.md +243 -0
  558. package/skills/lit-humanizer/references/en-patterns-structure.md +375 -0
  559. package/skills/lit-humanizer/references/en-patterns.md +57 -0
  560. package/skills/lit-humanizer/references/ko-metrics.md +33 -0
  561. package/skills/lit-humanizer/references/ko-patterns-a-d.md +659 -0
  562. package/skills/lit-humanizer/references/ko-patterns-e-j.md +387 -0
  563. package/skills/lit-humanizer/references/ko-patterns.md +31 -0
  564. package/skills/lit-humanizer/references/rewrite-playbook.md +54 -0
  565. package/skills/lit-humanizer/references/taxonomy.md +153 -0
  566. package/skills/lit-humanizer/rules.json +884 -0
  567. package/skills/lit-humanizer/scripts/core.mjs +208 -0
  568. package/skills/lit-humanizer/scripts/detect.mjs +91 -0
  569. package/skills/lit-humanizer/scripts/extract_office_text.py +89 -0
  570. package/skills/lit-humanizer/scripts/guard-scan.mjs +36 -0
  571. package/skills/lit-humanizer/scripts/ko-metrics.mjs +124 -0
  572. package/skills/lit-humanizer/scripts/test-fixtures.mjs +54 -0
  573. package/skills/lit-humanizer/scripts/test-ko-metrics.mjs +27 -0
  574. package/skills/lit-pptx/FORBIDDEN_TERMS.json +55 -0
  575. package/skills/lit-pptx/NOTICE.md +3 -0
  576. package/skills/lit-pptx/SKILL.md +76 -0
  577. package/skills/lit-pptx/agents/analyst.md +49 -0
  578. package/skills/lit-pptx/agents/antithesis.md +59 -0
  579. package/skills/lit-pptx/agents/architect.md +44 -0
  580. package/skills/lit-pptx/agents/critic.md +42 -0
  581. package/skills/lit-pptx/agents/synthesizer.md +47 -0
  582. package/skills/lit-pptx/agents/thesis.md +33 -0
  583. package/skills/lit-pptx/assets/azure/circle-lg.png +0 -0
  584. package/skills/lit-pptx/assets/azure/circle-md.png +0 -0
  585. package/skills/lit-pptx/assets/azure/circle-sm.png +0 -0
  586. package/skills/lit-pptx/fonts/a2z-font/A2Z-Black.otf +0 -0
  587. package/skills/lit-pptx/fonts/a2z-font/A2Z-Bold.otf +0 -0
  588. package/skills/lit-pptx/fonts/a2z-font/A2Z-Light.otf +0 -0
  589. package/skills/lit-pptx/fonts/a2z-font/A2Z-Medium.otf +0 -0
  590. package/skills/lit-pptx/fonts/a2z-font/A2Z-Regular.otf +0 -0
  591. package/skills/lit-pptx/fonts/a2z-font/OFL.txt +94 -0
  592. package/skills/lit-pptx/fonts/a2z-font/SOURCE.md +29 -0
  593. package/skills/lit-pptx/package-lock.json +747 -0
  594. package/skills/lit-pptx/package.json +13 -0
  595. package/skills/lit-pptx/pretendard-font/LICENSE.txt +94 -0
  596. package/skills/lit-pptx/pretendard-font/public/static/LitOpenCodeSans-Bold.otf +0 -0
  597. package/skills/lit-pptx/pretendard-font/public/static/LitOpenCodeSans-Regular.otf +0 -0
  598. package/skills/lit-pptx/requirements.in +2 -0
  599. package/skills/lit-pptx/requirements.lock +285 -0
  600. package/skills/lit-pptx/run.mjs +71 -0
  601. package/skills/lit-pptx/scripts/check_ooxml.py +47 -0
  602. package/skills/lit-pptx/scripts/compile-deck.js +447 -0
  603. package/skills/lit-pptx/scripts/craft-thresholds.json +26 -0
  604. package/skills/lit-pptx/scripts/craft_extras.py +224 -0
  605. package/skills/lit-pptx/scripts/embed_fonts.py +204 -0
  606. package/skills/lit-pptx/scripts/layout_inventory.py +70 -0
  607. package/skills/lit-pptx/scripts/learn_template.py +433 -0
  608. package/skills/lit-pptx/scripts/lib/derive-palette.js +176 -0
  609. package/skills/lit-pptx/scripts/lib/directive-parser.js +244 -0
  610. package/skills/lit-pptx/scripts/lib/font-map.js +79 -0
  611. package/skills/lit-pptx/scripts/lib/gen-bg.js +85 -0
  612. package/skills/lit-pptx/scripts/lib/gen-gradient-assets.js +36 -0
  613. package/skills/lit-pptx/scripts/lib/layout-resolver.js +737 -0
  614. package/skills/lit-pptx/scripts/lib/markdown-loader.js +136 -0
  615. package/skills/lit-pptx/scripts/lib/render-adapter-html.js +364 -0
  616. package/skills/lit-pptx/scripts/lib/render-adapter-pptx.js +1848 -0
  617. package/skills/lit-pptx/scripts/lib/slide-ast.js +534 -0
  618. package/skills/lit-pptx/scripts/lib/spec-validator.js +94 -0
  619. package/skills/lit-pptx/scripts/lib/template-registry.js +355 -0
  620. package/skills/lit-pptx/scripts/qa_deck.py +773 -0
  621. package/skills/lit-pptx/scripts/validate_pptx.py +206 -0
  622. package/skills/lit-pptx/specs/markdown-slide-spec-v1.md +251 -0
  623. package/skills/lit-pptx/specs/markdown-slide-spec-v2.md +223 -0
  624. package/skills/lit-pptx/specs/slide-ast-v1.schema.json +229 -0
  625. package/skills/lit-pptx/specs/slide-ast-v2.schema.json +144 -0
  626. package/skills/lit-pptx/specs/template-enrollment-contract.md +379 -0
  627. package/skills/lit-pptx/templates/bauhaus_light.css +4 -0
  628. package/skills/lit-pptx/templates/boilerplate_professional.css +508 -0
  629. package/skills/lit-pptx/templates/enrolled/AZURE-A2Z/capabilities.yaml +146 -0
  630. package/skills/lit-pptx/templates/enrolled/AZURE-A2Z/layout-mapping.yaml +454 -0
  631. package/skills/lit-pptx/templates/enrolled/AZURE-A2Z/template.yaml +37 -0
  632. package/skills/lit-pptx/templates/enrolled/AZURE-PRO/capabilities.yaml +154 -0
  633. package/skills/lit-pptx/templates/enrolled/AZURE-PRO/layout-mapping.yaml +483 -0
  634. package/skills/lit-pptx/templates/enrolled/AZURE-PRO/template.yaml +37 -0
  635. package/skills/lit-pptx/templates/enrolled/BOILERPLATE-A2Z/capabilities.yaml +179 -0
  636. package/skills/lit-pptx/templates/enrolled/BOILERPLATE-A2Z/layout-mapping.yaml +299 -0
  637. package/skills/lit-pptx/templates/enrolled/BOILERPLATE-A2Z/template.yaml +45 -0
  638. package/skills/lit-pptx/templates/enrolled/BOILERPLATE-PRETENDARD/capabilities.yaml +181 -0
  639. package/skills/lit-pptx/templates/enrolled/BOILERPLATE-PRETENDARD/layout-mapping.yaml +299 -0
  640. package/skills/lit-pptx/templates/enrolled/BOILERPLATE-PRETENDARD/template.yaml +44 -0
  641. package/skills/lit-scientific-visualization/SKILL.md +2 -0
  642. package/skills/lit-typographic-motion/NOTICE +23 -0
  643. package/skills/lit-typographic-motion/SKILL.md +77 -0
  644. package/skills/lit-typographic-motion/THIRD_PARTY_NOTICES +25 -0
  645. package/skills/lit-typographic-motion/audio-analysis.py +52 -0
  646. package/skills/lit-typographic-motion/engine/browser.mjs +83 -0
  647. package/skills/lit-typographic-motion/engine/constants.mjs +177 -0
  648. package/skills/lit-typographic-motion/engine/contrast.mjs +101 -0
  649. package/skills/lit-typographic-motion/engine/encode.mjs +46 -0
  650. package/skills/lit-typographic-motion/engine/flash.mjs +216 -0
  651. package/skills/lit-typographic-motion/engine/look.mjs +166 -0
  652. package/skills/lit-typographic-motion/engine/page/common.js +105 -0
  653. package/skills/lit-typographic-motion/engine/page/engine.js +451 -0
  654. package/skills/lit-typographic-motion/engine/page/gl.js +213 -0
  655. package/skills/lit-typographic-motion/engine/page/lines.js +88 -0
  656. package/skills/lit-typographic-motion/engine/page/passes.js +144 -0
  657. package/skills/lit-typographic-motion/engine/page/post.js +119 -0
  658. package/skills/lit-typographic-motion/engine/page/scenes.js +187 -0
  659. package/skills/lit-typographic-motion/engine/page/type.js +321 -0
  660. package/skills/lit-typographic-motion/engine/png.mjs +139 -0
  661. package/skills/lit-typographic-motion/engine/sound.mjs +291 -0
  662. package/skills/lit-typographic-motion/engine/stage/capture.mjs +133 -0
  663. package/skills/lit-typographic-motion/engine/stage/clock.js +171 -0
  664. package/skills/lit-typographic-motion/engine/stage/frame-worker.mjs +47 -0
  665. package/skills/lit-typographic-motion/engine/stage/gate.mjs +119 -0
  666. package/skills/lit-typographic-motion/engine/stage/qa-page.js +158 -0
  667. package/skills/lit-typographic-motion/engine/stage/qa.mjs +208 -0
  668. package/skills/lit-typographic-motion/engine/stage/render.mjs +418 -0
  669. package/skills/lit-typographic-motion/engine/stage/scan.mjs +162 -0
  670. package/skills/lit-typographic-motion/engine/stage/stage-kit.js +310 -0
  671. package/skills/lit-typographic-motion/engine/stills.mjs +60 -0
  672. package/skills/lit-typographic-motion/engine/text.mjs +126 -0
  673. package/skills/lit-typographic-motion/engine/timing.mjs +289 -0
  674. package/skills/lit-typographic-motion/engine/treatment.mjs +254 -0
  675. package/skills/lit-typographic-motion/fonts/Archivo-100-400.ttf +0 -0
  676. package/skills/lit-typographic-motion/fonts/Archivo-100-700.ttf +0 -0
  677. package/skills/lit-typographic-motion/fonts/Archivo-100-900.ttf +0 -0
  678. package/skills/lit-typographic-motion/fonts/Archivo-125-400.ttf +0 -0
  679. package/skills/lit-typographic-motion/fonts/Archivo-125-700.ttf +0 -0
  680. package/skills/lit-typographic-motion/fonts/Archivo-125-900.ttf +0 -0
  681. package/skills/lit-typographic-motion/fonts/Archivo-75-400.ttf +0 -0
  682. package/skills/lit-typographic-motion/fonts/Archivo-75-700.ttf +0 -0
  683. package/skills/lit-typographic-motion/fonts/Archivo-75-900.ttf +0 -0
  684. package/skills/lit-typographic-motion/fonts/Archivo-OFL.txt +93 -0
  685. package/skills/lit-typographic-motion/fonts/Silkscreen-Bold.ttf +0 -0
  686. package/skills/lit-typographic-motion/fonts/Silkscreen-OFL.txt +93 -0
  687. package/skills/lit-typographic-motion/fonts/Silkscreen-Regular.ttf +0 -0
  688. package/skills/lit-typographic-motion/fonts/VT323-OFL.txt +93 -0
  689. package/skills/lit-typographic-motion/fonts/VT323-Regular.ttf +0 -0
  690. package/skills/lit-typographic-motion/fonts/pins.json +44 -0
  691. package/skills/lit-typographic-motion/fonts/stroke/CREDITS +52 -0
  692. package/skills/lit-typographic-motion/fonts/stroke/EMSAllure.svg +216 -0
  693. package/skills/lit-typographic-motion/fonts/stroke/EMSFelix.svg +216 -0
  694. package/skills/lit-typographic-motion/fonts/stroke/EMSOsmotron.svg +216 -0
  695. package/skills/lit-typographic-motion/fonts/stroke/EMSReadability.svg +216 -0
  696. package/skills/lit-typographic-motion/fonts/stroke/EMSTech.svg +217 -0
  697. package/skills/lit-typographic-motion/fonts/stroke/OFL.txt +85 -0
  698. package/skills/lit-typographic-motion/gate.mjs +593 -0
  699. package/skills/lit-typographic-motion/package-lock.json +78 -0
  700. package/skills/lit-typographic-motion/package.json +11 -0
  701. package/skills/lit-typographic-motion/probe.mjs +74 -0
  702. package/skills/lit-typographic-motion/references/authoring.md +110 -0
  703. package/skills/lit-typographic-motion/references/craft-loop.md +110 -0
  704. package/skills/lit-typographic-motion/references/runtime.md +88 -0
  705. package/skills/lit-typographic-motion/references/stage.md +164 -0
  706. package/skills/lit-typographic-motion/references/style-bibles.md +88 -0
  707. package/skills/lit-typographic-motion/references/treatment.md +143 -0
  708. package/skills/lit-typographic-motion/references/type-craft.md +55 -0
  709. package/skills/lit-typographic-motion/render.mjs +654 -0
  710. package/skills/lit-typographic-motion/requirements-audio.in +1 -0
  711. package/skills/lit-typographic-motion/requirements-audio.txt +790 -0
  712. package/skills/lit-typographic-motion/runtime.mjs +259 -0
  713. package/skills/lit-typographic-motion/word-timing-models.json +25 -0
  714. package/skills/litresearch/SKILL.md +41 -12
  715. package/skills/managed-skill-manifest.json +2367 -63
  716. package/skills/skill-rename-aliases.json +6 -1
  717. package/tools/check-pack-payload.mjs +22 -1
  718. package/tools/check-payload-substance.mjs +2 -2
  719. package/tools/payload-reference-exemptions.json +4 -0
  720. package/tools/payload-substance-allowlist.json +2 -3
  721. package/tools/payload-substance-parity.json +7 -7
  722. package/tools/version-manifests.json +4 -4
  723. package/skills/lit-korean/SKILL.md +0 -231
@@ -0,0 +1,47 @@
1
+ #!/usr/bin/env node
2
+ import fs from 'node:fs';
3
+ import path from 'node:path';
4
+ import { root } from './diagram-metrics.mjs';
5
+ import { checkBrief, readBrief } from './brief-contract.mjs';
6
+
7
+ const args = process.argv.slice(2);
8
+ function option(name) {
9
+ const index = args.indexOf(name);
10
+ return index === -1 ? undefined : args[index + 1];
11
+ }
12
+
13
+ const briefPath = option('--brief');
14
+ const diagramPath = option('--diagram');
15
+ if (args.includes('--brief') || args.includes('--diagram')) {
16
+ if (!briefPath || !diagramPath || args.some((arg, index) => ['--brief', '--diagram'].includes(arg) && !args[index + 1])) {
17
+ console.error('Usage: node scripts/verify-brief.mjs [--brief <brief.md> --diagram <diagram.html>]');
18
+ process.exit(2);
19
+ }
20
+ try {
21
+ const result = checkBrief(fs.readFileSync(path.resolve(diagramPath), 'utf8'), readBrief(path.resolve(briefPath)));
22
+ const failed = result.missingNodes?.length || result.missingLabels?.length || result.missingEdges?.length
23
+ || result.unpairedLabels?.length || result.languageMismatches?.length || result.boundaryMembership?.issues?.length;
24
+ process.stdout.write(`${JSON.stringify({ mode: 'brief', brief: path.resolve(briefPath), diagram: path.resolve(diagramPath), result }, null, 2)}\n`);
25
+ if (failed) process.exitCode = 1;
26
+ } catch (error) {
27
+ console.error(`BRIEF_VERIFY_ERROR ${error instanceof Error ? error.message : String(error)}`);
28
+ process.exit(2);
29
+ }
30
+ } else {
31
+ const folders = fs.readdirSync(path.join(root, 'examples'), { withFileTypes: true })
32
+ .filter((entry) => entry.isDirectory()).map((entry) => entry.name).sort();
33
+ const results = [];
34
+ for (const folder of folders) {
35
+ const brief = path.join(root, 'examples', folder, 'brief.md');
36
+ const after = path.join(root, 'examples', folder, 'after.html');
37
+ if (!fs.existsSync(brief) || !fs.existsSync(after)) {
38
+ results.push({ example: folder, missingFiles: [!fs.existsSync(brief) ? 'brief.md' : null, !fs.existsSync(after) ? 'after.html' : null].filter(Boolean) });
39
+ continue;
40
+ }
41
+ results.push({ example: folder, ...checkBrief(fs.readFileSync(after, 'utf8'), readBrief(brief)) });
42
+ }
43
+ const failures = results.filter((result) => result.missingFiles || result.missingNodes?.length || result.missingLabels?.length
44
+ || result.missingEdges?.length || result.unpairedLabels?.length || result.languageMismatches?.length || result.boundaryMembership?.issues?.length);
45
+ process.stdout.write(`${JSON.stringify({ mode: 'examples', checked: results.length, failures, results }, null, 2)}\n`);
46
+ if (failures.length) process.exitCode = 1;
47
+ }
@@ -0,0 +1,56 @@
1
+ #!/usr/bin/env node
2
+ import fs from 'node:fs';
3
+ import path from 'node:path';
4
+ import { fileURLToPath } from 'node:url';
5
+
6
+ const root = path.resolve(path.dirname(fileURLToPath(import.meta.url)), '..');
7
+ const catalogPath = path.join(root, 'references/type-catalog.json');
8
+ const catalog = JSON.parse(fs.readFileSync(catalogPath, 'utf8'));
9
+ const refs = fs.existsSync(path.join(root, 'references')) ? fs.readdirSync(path.join(root, 'references')) : [];
10
+ const examplesDir = path.join(root, 'assets/examples');
11
+ const exampleFiles = fs.existsSync(examplesDir) ? fs.readdirSync(examplesDir).filter((name) => name.endsWith('.html')) : [];
12
+ const issues = [];
13
+
14
+ function audit(c, refNames, names) {
15
+ const problems = [];
16
+ const ids = c.entries.map((entry) => entry.id);
17
+ if (c.source?.coreTypeCount !== 41 || c.source?.galleryEntryCount !== 61) problems.push('SOURCE_COUNTS');
18
+ if (ids.length !== 61) problems.push('ENTRY_COUNT expected=61 actual=' + ids.length);
19
+ if (new Set(ids).size !== ids.length) problems.push('DUPLICATE_ID');
20
+ const expected = new Set();
21
+ const refSet = new Set(refNames);
22
+ for (const entry of c.entries) {
23
+ if (!/^[a-z0-9]+(?:-[a-z0-9]+)*$/.test(entry.id)) problems.push('INVALID_ID ' + entry.id);
24
+ if (entry.reference !== 'type-' + entry.id + '.md') problems.push('BAD_REFERENCE ' + entry.id + ' ' + entry.reference);
25
+ if (!refSet.has(entry.reference)) problems.push('MISSING_REFERENCE ' + entry.reference);
26
+ if (JSON.stringify(entry.variants) !== JSON.stringify(['light', 'dark', 'full'])) problems.push('BAD_VARIANTS ' + entry.id);
27
+ for (const variant of ['light', 'dark', 'full']) expected.add('type-' + entry.id + '-' + variant + '.html');
28
+ }
29
+ const actual = new Set(names);
30
+ for (const name of expected) if (!actual.has(name)) problems.push('MISSING_EXAMPLE ' + name);
31
+ for (const name of actual) if (!expected.has(name)) problems.push('ORPHAN_EXAMPLE ' + name);
32
+ if (expected.size !== 183) problems.push('EXPECTED_VARIANT_COUNT ' + expected.size);
33
+ return problems;
34
+ }
35
+ issues.push(...audit(catalog, refs, exampleFiles));
36
+ if (process.argv.includes('--self-test')) {
37
+ const clone = JSON.parse(JSON.stringify(catalog));
38
+ const good = audit(clone, refs, exampleFiles);
39
+ const duplicate = JSON.parse(JSON.stringify(clone));
40
+ duplicate.entries[1].id = duplicate.entries[0].id;
41
+ const duplicateResult = audit(duplicate, refs, exampleFiles);
42
+ const missing = audit(clone, refs, exampleFiles.filter((name) => name !== 'type-architecture-light.html'));
43
+ const orphan = audit(clone, refs, [...exampleFiles, 'type-orphan-light.html']);
44
+ if (good.length || !duplicateResult.some((x) => x.startsWith('DUPLICATE_ID')) || !missing.some((x) => x.startsWith('MISSING_EXAMPLE')) || !orphan.some((x) => x.startsWith('ORPHAN_EXAMPLE'))) {
45
+ console.error('SELF_TEST_FAIL', { good, duplicateResult, missing, orphan });
46
+ process.exit(1);
47
+ }
48
+ console.log('SELF_TEST_PASS duplicate, missing, and orphan cases fail as expected');
49
+ }
50
+ if (issues.length) {
51
+ console.error('COVERAGE_FAIL');
52
+ for (const issue of issues) console.error('- ' + issue);
53
+ process.exitCode = 1;
54
+ } else {
55
+ console.log('COVERAGE_PASS core=41 gallery=61 variants=183 references=61');
56
+ }
@@ -0,0 +1,26 @@
1
+ #!/usr/bin/env node
2
+ import { analyzeFile } from './diagram-metrics.mjs';
3
+ import { visualQuality } from './visual-quality.mjs';
4
+ import { readFileSync } from 'node:fs';
5
+
6
+ const file=process.argv.slice(2).find((x)=>!x.startsWith('--'));
7
+ if(!file){console.error('Usage: node scripts/verify-diagram.mjs <file.html|file.svg>');process.exit(2);}
8
+ let result;
9
+ try{result=analyzeFile(file);}catch(e){console.error('VERIFY_ERROR '+e.message);process.exit(2);}
10
+ const failures=[];
11
+ if(!result.hasSvg) failures.push('SVG_MISSING');
12
+ if(!result.viewBox||result.viewBox.w<=0||result.viewBox.h<=0) failures.push('VIEWBOX_INVALID');
13
+ if(!result.title||!result.desc||!result.roleImage||!result.ariaLinked) failures.push('A11Y_TITLE_DESC_ROLE_LINK');
14
+ if(result.textCount===0) failures.push('TEXT_MISSING');
15
+ if(result.offCanvas) failures.push('OFF_CANVAS '+result.offCanvas);
16
+ if(result.textOverlaps) failures.push('TEXT_OVERLAP '+result.textOverlaps);
17
+ if(result.objectOverlaps) failures.push('SHAPE_OVERLAP '+result.objectOverlaps);
18
+ if(result.contrastFailures.length) failures.push('CONTRAST '+result.contrastFailures.length);
19
+ if(result.humanizer.summary?.block) failures.push('HUMANIZER_BLOCK '+result.humanizer.summary.block);
20
+ if(result.humanizer.errors?.length) failures.push('HUMANIZER_ERROR');
21
+ if(!result.fontFamilyPresent||!result.localFont||!result.fontFileValid) failures.push('PRETENDARD_FONT_NOT_LOADED_FROM_LOCAL_ASSET');
22
+ if(/<script\b|\bon[a-z]+\s*=|https?:\/\//i.test(result.visibleText)) failures.push('UNSAFE_VISIBLE_TEXT');
23
+ const craft = visualQuality(readFileSync(file, 'utf8'));
24
+ for (const issue of craft.issues.filter((item) => /^(?:CLUSTER_GAP_RATIO|ACCENT_COUNT|LABEL_OVERFLOW)\b/u.test(item))) failures.push(issue);
25
+ if(failures.length){console.error('DIAGRAM_FAIL '+file);for(const f of failures)console.error('- '+f);process.exitCode=1;}
26
+ else console.log('DIAGRAM_PASS '+file+' text='+result.textCount+' overlap=0 contrast=pass humanizer-block=0'+(craft.advisories.length?' advisories='+craft.advisories.join(' | '):''));
@@ -0,0 +1,12 @@
1
+ #!/usr/bin/env node
2
+ import fs from 'node:fs';
3
+ const file=process.argv.slice(2).find((x)=>!x.startsWith('--'));
4
+ if(!file){console.error('Usage: node scripts/verify-motion.mjs <file.html|file.svg>');process.exit(2);}
5
+ const source=fs.readFileSync(file,'utf8');
6
+ const issues=[];
7
+ if(/<animate\b|<set\b/i.test(source)) issues.push('SVG_ANIMATION_NOT_STATIC');
8
+ if(/animation\s*:\s*(?!none\b)[^;}]+/i.test(source)&&!/@media\s*\(prefers-reduced-motion\s*:\s*reduce\)[\s\S]*?animation\s*:\s*none/i.test(source)) issues.push('REDUCED_MOTION_RULE_MISSING');
9
+ if(/autoplay|infinite/i.test(source)) issues.push('UNBOUNDED_MOTION');
10
+ if(/<script\b/i.test(source)&&!/(prefers-reduced-motion|matchMedia)/i.test(source)) issues.push('MOTION_CONTROLLER_REDUCED_MOTION_MISSING');
11
+ if(issues.length){console.error('MOTION_FAIL '+file);for(const issue of issues)console.error('- '+issue);process.exitCode=1;}
12
+ else console.log('MOTION_PASS '+file+' static-first=reduced-motion-ready');
@@ -0,0 +1,48 @@
1
+ #!/usr/bin/env node
2
+ import fs from 'node:fs';
3
+ import path from 'node:path';
4
+ import { analyzeFile, root } from './diagram-metrics.mjs';
5
+ import { buildBlockRegistry } from './block-registry.mjs';
6
+ import { sequenceQuality } from './visual-quality.mjs';
7
+
8
+ const args=process.argv.slice(2);
9
+ const typeArg=args.find((x)=>x.startsWith('--type='));
10
+ const type=typeArg?.slice('--type='.length);
11
+ const file=args.find((x)=>!x.startsWith('--'));
12
+ if(!type||!file){console.error('Usage: node scripts/verify-type.mjs --type=<catalog-id> <file.html|file.svg>');process.exit(2);}
13
+ const catalog=JSON.parse(fs.readFileSync(path.join(root,'references/type-catalog.json'),'utf8'));
14
+ const entry=catalog.entries.find((x)=>x.id===type);
15
+ if(!entry){console.error('TYPE_UNKNOWN '+type);process.exit(2);}
16
+ const source=fs.readFileSync(file,'utf8');
17
+ const result=analyzeFile(file);
18
+ const issues=[];
19
+ if(!source.includes('data-type="'+type+'"')&&!source.includes('id="diagram-'+type+'-')) issues.push('TYPE_ID_MISMATCH');
20
+ if(!fs.existsSync(path.join(root,'references',entry.reference))) issues.push('TYPE_GUIDE_MISSING');
21
+ if(!/data-variant\s*=\s*["'](?:light|dark|full)["']/i.test(source)&&!/id="diagram-[a-z0-9-]+-(?:light|dark|full)"/i.test(source)) issues.push('VARIANT_MISSING');
22
+ if(entry.family==='quantitative'&&result.textCount<3) issues.push('QUANTITATIVE_LABELS_MISSING');
23
+ if(type==='heatmap'&&(source.match(/<rect\b/gi)||[]).length<16) issues.push('HEATMAP_GRID_TOO_SMALL');
24
+ if(type==='treemap'&&(source.match(/<rect\b/gi)||[]).length<6) issues.push('TREEMAP_TILES_TOO_FEW');
25
+ if(type==='sankey'&&!/<path\b[^>]*stroke-width\s*=\s*["'][1-9]/i.test(source)) issues.push('SANKEY_RIBBON_WIDTH_MISSING');
26
+ if(type==='waterfall'&&(source.match(/<rect\b/gi)||[]).length<5) issues.push('WATERFALL_STEPS_TOO_FEW');
27
+ if(type==='beeswarm'&&(source.match(/<circle\b/gi)||[]).length<20) issues.push('BEESWARM_MARKS_TOO_FEW');
28
+ if(type==='bubble'&&(source.match(/<circle\b/gi)||[]).length<6) issues.push('BUBBLE_MARKS_TOO_FEW');
29
+ if(type==='polar'&&!/<polygon\b/i.test(source)) issues.push('POLAR_SHAPE_MISSING');
30
+ if(type==='radar'&&!/<polygon\b/i.test(source)) issues.push('RADAR_SHAPE_MISSING');
31
+ if(type==='sequence'||type==='sequence-oauth')issues.push(...sequenceQuality(source).map((issue)=>'SEQUENCE '+issue));
32
+ if(type==='tree-block-decomposition'){
33
+ try{
34
+ const svg=source.match(/<svg\b[^>]*>[\s\S]*?<\/svg>/i)?.[0]||'';
35
+ const registry=buildBlockRegistry(svg,path.basename(file));
36
+ const visible=[...svg.matchAll(/<text\b[^>]*>([\s\S]*?)<\/text>/gi)].map((match)=>match[1].replace(/<[^>]*>/g,'').trim());
37
+ for(const block of registry.blocks){
38
+ for(const field of ['name','input','output','constraint','assumption','impl']) if(!block[field])issues.push('BLOCK_FIELD_MISSING '+block.id+'.'+field);
39
+ if(!visible.includes(block.id))issues.push('BLOCK_BADGE_MISSING '+block.id);
40
+ if(block.name&&!visible.includes(block.name))issues.push('BLOCK_NAME_MISSING '+block.id);
41
+ }
42
+ }catch(error){issues.push('BLOCK_REGISTRY_INVALID '+error.message);}
43
+ }
44
+ if(type==='policy-trace-animated'&&!/(rule|policy|allow|deny)/i.test(source)) issues.push('POLICY_TRACE_SEMANTIC_MISSING');
45
+ if(type==='queue-animated'&&!/(queue|buffer|drain|fan-in)/i.test(source)) issues.push('QUEUE_SEMANTIC_MISSING');
46
+ if(type==='paved-road-animated'&&!/(boundary|guardrail|secure|policy)/i.test(source)) issues.push('PAVED_ROAD_SEMANTIC_MISSING');
47
+ if(issues.length){console.error('TYPE_FAIL '+type+' '+file);for(const issue of issues)console.error('- '+issue);process.exitCode=1;}
48
+ else console.log('TYPE_PASS '+type+' family='+entry.family);
@@ -0,0 +1,363 @@
1
+ import { sourceMetrics } from './diagram-metrics.mjs';
2
+ import { readFileSync } from 'node:fs';
3
+
4
+ const craft = JSON.parse(readFileSync(new URL('./craft-thresholds.json', import.meta.url), 'utf8'));
5
+
6
+ const MAX_EDGE_LABEL_ANCHOR_DISTANCE=24;
7
+ const BOUNDARY_EDGE_PADDING=4;
8
+ const BOUNDARY_EDGE_MIN_OVERLAP=12;
9
+ const ARROWHEAD_CANVAS_FLOOR=12/1080;
10
+ const ARROWHEAD_STROKE_MULTIPLE=5;
11
+ const ARROWHEAD_TARGET_TOLERANCE=2;
12
+
13
+ const decode=(s)=>s.replaceAll('&amp;','&').replaceAll('&lt;','<').replaceAll('&gt;','>').replaceAll('&quot;','"').replaceAll('&apos;',"'").replaceAll('&#39;',"'");
14
+ const attributes=(s)=>Object.fromEntries([...s.matchAll(/([\w:-]+)\s*=\s*(?:"([^"]*)"|'([^']*)')/g)].map((m)=>[m[1],decode(m[2]??m[3]??'')]));
15
+ const clean=(s)=>decode(s.replace(/<[^>]*>/g,' ').replace(/\s+/g,' ').trim());
16
+ const widthOf=(text,size)=>[...text].reduce((n,c)=>n+(/\s/.test(c)?.28:/[\u1100-\u11ff\u3130-\u318f\uac00-\ud7af]/.test(c)?.98:/[ilI.,:;!|]/.test(c)?.32:/[MW@#%]/.test(c)?.82:.56),0)*size;
17
+ const contamination=[
18
+ /\blitfamily\b/i, /\b(?:generator|generated by|template|prototype)\b/i,
19
+ /\bsource\s*:/i, /\bnotes?\s*:/i, /\bstatic\s+first\b/i,
20
+ /\baccessible\s+labels\b/i, /\bone\s+accent\b/i, /\bfocal\b/i,
21
+ /\b(?:light|dark|full)\s*[·|/]\s*static\b/i, /\bdesign\s+rules?\b/i,
22
+ /^\s*show\b/i,
23
+ ];
24
+
25
+ function visibleSvgText(svg){
26
+ return [...svg.matchAll(/<text\b([^>]*)>([\s\S]*?)<\/text>/gi)].map((m)=>{
27
+ const a=attributes(m[1]),label=clean(m[2]),size=Number(a['font-size']||16),textAnchor=a['text-anchor']||'start',anchor={x:Number(a.x||0),y:Number(a.y||0)},w=widthOf(label,size),x=anchor.x-(textAnchor==='middle'?w/2:textAnchor==='end'?w:0),y=anchor.y-size*.82;
28
+ return {label,size,role:a['data-role']||'',anchor,nodeFor:a['data-node-for']||a['data-node-id']||'',edgeFor:a['data-edge-for']||'',boundaryFor:a['data-boundary-for']||a['data-group-for']||'',x,y,w,h:size*1.22};
29
+ }).filter((t)=>t.label);
30
+ }
31
+ function svgContent(source){return [...source.matchAll(/<svg\b[^>]*>[\s\S]*?<\/svg>/gi)].map((m)=>m[0]).join('\n');}
32
+ function parseRoutes(svg){
33
+ const routes=[];
34
+ for(const m of svg.matchAll(/<(line|path)\b([^>]*)>/gi)){
35
+ const a=attributes(m[2]); if(!a['data-from']||!a['data-to'])continue;
36
+ let segments=[];
37
+ if(m[1].toLowerCase()==='line'){
38
+ const v=['x1','y1','x2','y2'].map((k)=>Number(a[k])); if(v.every(Number.isFinite))segments=[[v[0],v[1],v[2],v[3]]];
39
+ }else if(a.d){
40
+ const parts=a.d.match(/[a-zA-Z]|[-+]?(?:\d*\.\d+|\d+\.?\d*)(?:e[-+]?\d+)?/gi)||[];let i=0,cmd='',x=0,y=0,px=0,py=0;
41
+ while(i<parts.length){if(/^[a-z]$/i.test(parts[i]))cmd=parts[i++];if(!cmd)break;const rel=cmd===cmd.toLowerCase(),up=cmd.toUpperCase();
42
+ if(up==='M'||up==='L'){if(i+1>=parts.length||/^[a-z]$/i.test(parts[i])){cmd='';continue;}const nx=Number(parts[i++])+(rel?x:0),ny=Number(parts[i++])+(rel?y:0);if(up==='L')segments.push([x,y,nx,ny]);x=nx;y=ny;}
43
+ else if(up==='H'){if(i>=parts.length||/^[a-z]$/i.test(parts[i])){cmd='';continue;}const nx=Number(parts[i++])+(rel?x:0);segments.push([x,y,nx,y]);x=nx;}
44
+ else if(up==='V'){if(i>=parts.length||/^[a-z]$/i.test(parts[i])){cmd='';continue;}const ny=Number(parts[i++])+(rel?y:0);segments.push([x,y,x,ny]);y=ny;}
45
+ else if(up==='C'){if(i+5>=parts.length||/^[a-z]$/i.test(parts[i])){cmd='';continue;}const p=(n)=>[Number(parts[n])+(rel?x:0),Number(parts[n+1])+(rel?y:0)],start=[x,y],c1=p(i),c2=p(i+2),end=p(i+4);i+=6;let previous=start;for(let step=1;step<=16;step++){const t=step/16,u=1-t,next=[u*u*u*start[0]+3*u*u*t*c1[0]+3*u*t*t*c2[0]+t*t*t*end[0],u*u*u*start[1]+3*u*u*t*c1[1]+3*u*t*t*c2[1]+t*t*t*end[1]];segments.push([previous[0],previous[1],next[0],next[1]]);previous=next;}x=end[0];y=end[1];}
46
+ else {cmd='';while(i<parts.length&&!/^[a-z]$/i.test(parts[i]))i++;}
47
+ }
48
+ }
49
+ if(segments.length)routes.push({from:a['data-from'],to:a['data-to'],label:a['data-label']||'',segments,markerStart:a['marker-start']||'',markerEnd:a['marker-end']||'',strokeWidth:Number(a['stroke-width']||1)});
50
+ }
51
+ return routes;
52
+ }
53
+ function rectangles(svg){
54
+ const nodes=[];
55
+ for(const m of svg.matchAll(/<rect\b([^>]*)\/?\s*>/gi)){
56
+ const a=attributes(m[1]);if(!a['data-node-id'])continue;
57
+ const box={id:a['data-node-id'],type:a['data-node-type']||'',fill:a.fill||'',outcomes:(a['data-outcomes']||'').split('|').map((value)=>value.trim()).filter(Boolean),x:Number(a.x||0),y:Number(a.y||0),w:Number(a.width||0),h:Number(a.height||0)};
58
+ if(box.w>0&&box.h>0)nodes.push(box);
59
+ }
60
+ return nodes;
61
+ }
62
+ function segmentHitsBox(s,b,pad=0){
63
+ const [x1,y1,x2,y2]=s,loX=Math.min(x1,x2),hiX=Math.max(x1,x2),loY=Math.min(y1,y2),hiY=Math.max(y1,y2),left=b.x-pad,right=b.x+b.w+pad,top=b.y-pad,bottom=b.y+b.h+pad;
64
+ if(x1===x2)return x1>=left&&x1<=right&&hiY>=top&&loY<=bottom;
65
+ if(y1===y2)return y1>=top&&y1<=bottom&&hiX>=left&&loX<=right;
66
+ const steps=24;for(let i=0;i<=steps;i++){const t=i/steps,x=x1+(x2-x1)*t,y=y1+(y2-y1)*t;if(x>=left&&x<=right&&y>=top&&y<=bottom)return true;}return false;
67
+ }
68
+ function segmentHitsText(s,t,pad=1){
69
+ const b={x:t.x-pad,y:t.y-pad,w:t.w+pad*2,h:t.h+pad*2};return segmentHitsBox(s,b,0);
70
+ }
71
+ function textOverlapsNode(text,node,pad=1){return text.x<node.x+node.w+pad&&text.x+text.w>node.x-pad&&text.y<node.y+node.h+pad&&text.y+text.h>node.y-pad;}
72
+ function gap(a,b){const dx=Math.max(0,a.x-(b.x+b.w),b.x-(a.x+a.w)),dy=Math.max(0,a.y-(b.y+b.h),b.y-(a.y+a.h));return Math.hypot(dx,dy);}
73
+
74
+ function accentHue(value){
75
+ const hex=value.match(/^#([0-9a-f]{6}|[0-9a-f]{3})$/i);if(!hex)return null;
76
+ const raw=hex[1].length===3?[...hex[1]].map((digit)=>digit+digit).join(''):hex[1];
77
+ const [r,g,b]=[0,2,4].map((index)=>parseInt(raw.slice(index,index+2),16)/255),hi=Math.max(r,g,b),lo=Math.min(r,g,b),d=hi-lo,l=(hi+lo)/2,s=d/(1-Math.abs(2*l-1))||0;
78
+ if(s<craft.accentSaturationMin||l<craft.accentLightnessMin||l>craft.accentLightnessMax)return null;
79
+ const h=d===0?0:hi===r?((g-b)/d)%6:hi===g?(b-r)/d+2:(r-g)/d+4;
80
+ return (h*60+360)%360;
81
+ }
82
+
83
+ function officeCraft(texts,nodes,outlines,view){
84
+ const issues=[],advisories=[];
85
+ if(outlines.length>=2){
86
+ const membership=(node)=>outlines.filter((outline)=>node.x+node.w/2>=outline.x&&node.x+node.w/2<=outline.x+outline.w&&node.y+node.h/2>=outline.y&&node.y+node.h/2<=outline.y+outline.h).sort((a,b)=>a.w*a.h-b.w*b.h)[0]?.id||'<outside>';
87
+ const inside=[],outside=[];
88
+ for(let i=0;i<nodes.length;i++)for(let j=i+1;j<nodes.length;j++)(membership(nodes[i])===membership(nodes[j])?inside:outside).push(gap(nodes[i],nodes[j]));
89
+ if(inside.length&&outside.length){const intra=Math.max(...inside),inter=Math.min(...outside);if(intra>0&&inter<craft.groupRatioMin*intra)issues.push('CLUSTER_GAP_RATIO OF-201 '+(inter/intra).toFixed(2)+' minimum='+craft.groupRatioMin);}
90
+ }
91
+ const hues=[];
92
+ for(const node of nodes){
93
+ if(view&&node.w*node.h>=craft.fullBleedFraction*view.w*view.h)continue;
94
+ const hue=accentHue(node.fill);if(hue!==null&&!hues.some((other)=>Math.min(Math.abs(hue-other),360-Math.abs(hue-other))<=craft.accentHueBucketDegrees))hues.push(hue);
95
+ }
96
+ if(hues.length>=craft.accentHigh)issues.push('ACCENT_COUNT OF-202 '+hues.length+' maximum='+(craft.accentHigh-1));
97
+ else if(hues.length>=craft.accentMedium)advisories.push('ACCENT_COUNT OF-202 '+hues.length+' preferred<'+craft.accentMedium);
98
+ for(const text of texts){
99
+ const label=text.label,latin=[...label].filter((char)=>/[A-Za-z0-9]/.test(char)).length/Math.max(1,[...label].filter((char)=>!(/\s/.test(char))).length);
100
+ if(latin>=craft.latinFractionMin&&label!==label.toUpperCase()){
101
+ const words=label.match(/[A-Za-z]+/g)||[],long=words.filter((word)=>word.length>=craft.titleWordMinLetters),capped=long.filter((word)=>/^[A-Z][a-z]+$/.test(word));
102
+ if(capped.length>=craft.titleWordMinCount&&capped.length/Math.max(1,long.length)>craft.titleWordFractionMin&&/\b(?:Of|And|The|To|For|In)\b/.test(label))advisories.push('LABEL_CASE OF-203 '+label);
103
+ }
104
+ const target=text.nodeFor?nodes.find((node)=>node.id===text.nodeFor):text.boundaryFor?outlines.find((outline)=>outline.id===text.boundaryFor||outline.labels.includes(text.boundaryFor)):null;
105
+ if(target&&text.w>target.w-2*craft.labelInsetPx)issues.push('LABEL_OVERFLOW OF-204 '+label+' width='+text.w.toFixed(1)+'px available='+(target.w-2*craft.labelInsetPx).toFixed(1)+'px');
106
+ }
107
+ return {issues,advisories};
108
+ }
109
+
110
+ function boundaryOutlines(svg){
111
+ const outlines=[];
112
+ const add=(a)=>{
113
+ const markers=['data-trust-boundary','data-boundary','data-boundary-name','data-group-boundary','data-group-name','data-group-label','data-group-id'];
114
+ const classMarker=/\b(?:boundary|group)(?:[-_][\w-]+)?\b/i.test(a.class||'');
115
+ if(!markers.some((key)=>Object.hasOwn(a,key))&&!classMarker)return;
116
+ const labels=[a['data-trust-boundary'],a['data-boundary-name'],a['data-group-boundary'],a['data-group-name'],a['data-group-label']].filter((value)=>value&&value!=='true');
117
+ const x=Number(a.x||0),y=Number(a.y||0),w=Number(a.width||0),h=Number(a.height||0);
118
+ if(w>0&&h>0)outlines.push({id:a['data-group-id']||a.id||labels[0]||'outline',labels,x,y,w,h,strokeWidth:Number(a['stroke-width']||1)});
119
+ };
120
+ for(const match of svg.matchAll(/<rect\b([^>]*)\/?\s*>/gi))add(attributes(match[1]));
121
+ for(const match of svg.matchAll(/<g\b([^>]*)>([\s\S]*?)<\/g>/gi)){
122
+ const group=attributes(match[1]);
123
+ if(!['data-trust-boundary','data-boundary','data-boundary-name','data-group-boundary','data-group-name','data-group-label','data-group-id'].some((key)=>Object.hasOwn(group,key)))continue;
124
+ const rect=match[2].match(/<rect\b([^>]*)\/?\s*>/i);
125
+ if(rect)add({...attributes(rect[1]),...group});
126
+ }
127
+ return outlines;
128
+ }
129
+
130
+ function pointSegmentDistance(point,segment){
131
+ const [x1,y1,x2,y2]=segment,dx=x2-x1,dy=y2-y1,length=dx*dx+dy*dy;
132
+ const t=length?Math.max(0,Math.min(1,((point.x-x1)*dx+(point.y-y1)*dy)/length)):0;
133
+ return Math.hypot(point.x-(x1+t*dx),point.y-(y1+t*dy));
134
+ }
135
+ function routeDistance(point,route){return Math.min(...route.segments.map((segment)=>pointSegmentDistance(point,segment)));}
136
+ function isBoundaryLabel(text,outlines){return text.role==='boundary'||text.boundaryFor||outlines.some((outline)=>outline.labels.includes(text.label)||outline.id===text.boundaryFor);}
137
+ function outlineEdges(outline){return [[outline.x,outline.y,outline.x+outline.w,outline.y],[outline.x+outline.w,outline.y,outline.x+outline.w,outline.y+outline.h],[outline.x+outline.w,outline.y+outline.h,outline.x,outline.y+outline.h],[outline.x,outline.y+outline.h,outline.x,outline.y]];}
138
+ function textHitsOutline(text,outline){return outlineEdges(outline).some((edge)=>segmentHitsText(edge,text,outline.strokeWidth/2+.5));}
139
+ function segmentAlongOutline(segment,outline){
140
+ const [x1,y1,x2,y2]=segment,loX=Math.min(x1,x2),hiX=Math.max(x1,x2),loY=Math.min(y1,y2),hiY=Math.max(y1,y2),right=outline.x+outline.w,bottom=outline.y+outline.h;
141
+ if(Math.abs(y1-y2)<=1){const overlap=Math.min(hiX,right)-Math.max(loX,outline.x);return overlap>BOUNDARY_EDGE_MIN_OVERLAP&&(Math.abs(y1-outline.y)<=BOUNDARY_EDGE_PADDING||Math.abs(y1-bottom)<=BOUNDARY_EDGE_PADDING);}
142
+ if(Math.abs(x1-x2)<=1){const overlap=Math.min(hiY,bottom)-Math.max(loY,outline.y);return overlap>BOUNDARY_EDGE_MIN_OVERLAP&&(Math.abs(x1-outline.x)<=BOUNDARY_EDGE_PADDING||Math.abs(x1-right)<=BOUNDARY_EDGE_PADDING);}
143
+ return false;
144
+ }
145
+ function markerPathPoints(d){
146
+ const parts=d.match(/[a-zA-Z]|[-+]?(?:\d*\.\d+|\d+\.?\d*)(?:e[-+]?\d+)?/gi)||[],points=[];let i=0,cmd='',x=0,y=0;
147
+ while(i<parts.length){if(/^[a-z]$/i.test(parts[i]))cmd=parts[i++];if(!cmd)break;const upper=cmd.toUpperCase(),relative=cmd===cmd.toLowerCase();
148
+ if(upper==='M'||upper==='L'){if(i+1>=parts.length||/^[a-z]$/i.test(parts[i]))break;let nx=Number(parts[i++]),ny=Number(parts[i++]);if(relative){nx+=x;ny+=y;}x=nx;y=ny;points.push([x,y]);}
149
+ else if(upper==='H'){if(i>=parts.length||/^[a-z]$/i.test(parts[i]))break;x=Number(parts[i++])+(relative?x:0);points.push([x,y]);}
150
+ else if(upper==='V'){if(i>=parts.length||/^[a-z]$/i.test(parts[i]))break;y=Number(parts[i++])+(relative?y:0);points.push([x,y]);}
151
+ else if(upper==='Z')cmd='';
152
+ else {while(i<parts.length&&!/^[a-z]$/i.test(parts[i]))i++;cmd='';}
153
+ }
154
+ return points;
155
+ }
156
+ function markerDefinitions(svg){
157
+ const markers=new Map();
158
+ for(const match of svg.matchAll(/<marker\b([^>]*)>([\s\S]*?)<\/marker>/gi)){
159
+ const a=attributes(match[1]),id=a.id;if(!id)continue;
160
+ const points=[];
161
+ for(const shape of match[2].matchAll(/<(path|polygon)\b([^>]*)>/gi)){
162
+ const attrsForShape=attributes(shape[2]);
163
+ if(shape[1].toLowerCase()==='polygon'){
164
+ const values=(attrsForShape.points||'').match(/[-+]?(?:\d*\.\d+|\d+\.?\d*)(?:e[-+]?\d+)?/gi)||[];
165
+ for(let i=0;i+1<values.length;i+=2)points.push([Number(values[i]),Number(values[i+1])]);
166
+ }else if(attrsForShape.d){
167
+ points.push(...markerPathPoints(attrsForShape.d));
168
+ }
169
+ }
170
+ markers.set(id,{refX:Number(a.refX||0),refY:Number(a.refY||0),units:a.markerUnits||'strokeWidth',width:Number(a.markerWidth||0),height:Number(a.markerHeight||0),points,closed:/\bz\b/i.test(match[2])||/<polygon\b/i.test(match[2])});
171
+ }
172
+ return markers;
173
+ }
174
+ function markerOverlapsTarget(route,target,markers){
175
+ const match=route.markerEnd.match(/url\(\s*["']?#([^\s)'"`]+)["']?\s*\)/i),marker=match&&markers.get(match[1]),segment=route.segments.at(-1);
176
+ if(!segment)return false;
177
+ const [x1,y1,x2,y2]=segment,length=Math.hypot(x2-x1,y2-y1)||1,ux=(x2-x1)/length,uy=(y2-y1)/length,nx=-uy,ny=ux;
178
+ if(!marker?.points.length){const reach=route.strokeWidth;return segmentHitsBox([x2+ux*reach,y2+uy*reach,x2+ux*reach,y2+uy*reach],target,-1);}
179
+ const scale=marker.units==='userSpaceOnUse'?1:route.strokeWidth;
180
+ const points=marker.points.map(([x,y])=>[x2+ux*(x-marker.refX)*scale+nx*(y-marker.refY)*scale,y2+uy*(x-marker.refX)*scale+ny*(y-marker.refY)*scale]);
181
+ if(points.some(([x,y])=>x>target.x+1&&x<target.x+target.w-1&&y>target.y+1&&y<target.y+target.h-1))return true;
182
+ const segments=points.slice(1).map((point,index)=>[points[index][0],points[index][1],point[0],point[1]]);
183
+ if(marker.closed&&points.length>2)segments.push([points.at(-1)[0],points.at(-1)[1],points[0][0],points[0][1]]);
184
+ return segments.some((line)=>segmentHitsBox(line,target,-1));
185
+ }
186
+ function markerFor(route,edge,markers){
187
+ const value=edge==='end'?route.markerEnd:route.markerStart,match=value.match(/url\(\s*["']?#([^\s)'"`]+)["']?\s*\)/i);
188
+ return match?markers.get(match[1]):null;
189
+ }
190
+ function markerScale(marker,route){return marker.units==='userSpaceOnUse'?1:route.strokeWidth;}
191
+ function markerHeadLength(marker){
192
+ if(!marker?.points.length)return 0;
193
+ const xs=marker.points.map(([x])=>x);
194
+ return Math.max(...xs)-Math.min(...xs);
195
+ }
196
+ function markerTip(route,marker,edge){
197
+ const segment=edge==='end'?route.segments.at(-1):route.segments[0];
198
+ if(!segment)return null;
199
+ const [x1,y1,x2,y2]=segment,dx=x2-x1,dy=y2-y1,length=Math.hypot(dx,dy)||1,ux=dx/length,uy=dy/length;
200
+ const anchor=edge==='end'?[x2,y2]:[x1,y1],direction=edge==='end'?1:-1;
201
+ const forward=marker?.points.length?Math.max(...marker.points.map(([x])=>direction*(x-marker.refX)))*markerScale(marker,route):0;
202
+ return [anchor[0]+direction*ux*forward,anchor[1]+direction*uy*forward];
203
+ }
204
+ function distanceToBoxBoundary(point,box){
205
+ const [x,y]=point,candidates=[];
206
+ if(y>=box.y-ARROWHEAD_TARGET_TOLERANCE&&y<=box.y+box.h+ARROWHEAD_TARGET_TOLERANCE)candidates.push(Math.abs(x-box.x),Math.abs(x-(box.x+box.w)));
207
+ if(x>=box.x-ARROWHEAD_TARGET_TOLERANCE&&x<=box.x+box.w+ARROWHEAD_TARGET_TOLERANCE)candidates.push(Math.abs(y-box.y),Math.abs(y-(box.y+box.h)));
208
+ if(candidates.length)return Math.min(...candidates);
209
+ return Math.hypot(Math.max(box.x-x,0,x-(box.x+box.w)),Math.max(box.y-y,0,y-(box.y+box.h)));
210
+ }
211
+ function decisionBranchQuality(nodes,routes){
212
+ const issues=[];
213
+ for(const node of nodes.filter((item)=>item.type==='decision')){
214
+ if(node.outcomes.length<2){issues.push('DECISION_OUTCOMES_MISSING '+node.id+' must name at least two outcomes');continue;}
215
+ const labels=new Set(routes.filter((route)=>route.from===node.id).map((route)=>route.label).filter(Boolean));
216
+ for(const outcome of node.outcomes)if(!labels.has(outcome))issues.push('DECISION_OUTCOME_MISSING '+node.id+' '+outcome);
217
+ for(const label of labels)if(!node.outcomes.includes(label))issues.push('DECISION_OUTCOME_UNDECLARED '+node.id+' '+label);
218
+ }
219
+ return issues;
220
+ }
221
+
222
+ function routeLength(route){return route.segments.reduce((sum,[x1,y1,x2,y2])=>sum+Math.hypot(x2-x1,y2-y1),0);}
223
+ function routeBends(route){
224
+ const directions=route.segments.map(([x1,y1,x2,y2])=>{const dx=x2-x1,dy=y2-y1,length=Math.hypot(dx,dy);return length?{x:dx/length,y:dy/length}:null;}).filter(Boolean);
225
+ let bends=0;
226
+ for(let i=1;i<directions.length;i++)if(directions[i-1].x*directions[i].x+directions[i-1].y*directions[i].y<Math.SQRT1_2)bends++;
227
+ return bends;
228
+ }
229
+ function routeManhattanDistance(route){
230
+ const start=route.segments[0]?.slice(0,2),end=route.segments.at(-1)?.slice(2,4);
231
+ return start&&end?Math.abs(start[0]-end[0])+Math.abs(start[1]-end[1])||null:null;
232
+ }
233
+ function alignedRouteKind(route,nodes){
234
+ const from=nodes.find((node)=>node.id===route.from),to=nodes.find((node)=>node.id===route.to);
235
+ if(!from||!to)return null;
236
+ const sameRow=Math.abs(from.y+from.h/2-(to.y+to.h/2))<=1,sameColumn=Math.abs(from.x+from.w/2-(to.x+to.w/2))<=1;
237
+ const horizontal=route.segments.every(([x1,y1,x2,y2])=>Math.abs(y1-y2)<=1),vertical=route.segments.every(([x1,y1,x2,y2])=>Math.abs(x1-x2)<=1);
238
+ if(sameRow&&nodes.every((node)=>node===from||node===to||Math.abs(node.y+node.h/2-(from.y+from.h/2))>1||node.x+node.w/2<=Math.min(from.x+from.w/2,to.x+to.w/2)||node.x+node.w/2>=Math.max(from.x+from.w/2,to.x+to.w/2))&&!horizontal)return 'same-row';
239
+ if(sameColumn&&nodes.every((node)=>node===from||node===to||Math.abs(node.x+node.w/2-(from.x+from.w/2))>1||node.y+node.h/2<=Math.min(from.y+from.h/2,to.y+to.h/2)||node.y+node.h/2>=Math.max(from.y+from.h/2,to.y+to.h/2))&&!vertical)return 'same-column';
240
+ return null;
241
+ }
242
+ function routeCrossesBoundary(route,outline){
243
+ const points=route.segments.flatMap(([x1,y1,x2,y2])=>[[x1,y1],[x2,y2],[(x1+x2)/2,(y1+y2)/2]]);
244
+ const inside=points.some(([x,y])=>x>outline.x&&x<outline.x+outline.w&&y>outline.y&&y<outline.y+outline.h);
245
+ const outside=points.some(([x,y])=>x<outline.x||x>outline.x+outline.w||y<outline.y||y>outline.y+outline.h);
246
+ return inside&&outside;
247
+ }
248
+ function collinearOverlap(a,b){
249
+ for(const [ax1,ay1,ax2,ay2] of a.segments)for(const [bx1,by1,bx2,by2] of b.segments){
250
+ if(Math.abs(ay1-ay2)<=.5&&Math.abs(by1-by2)<=.5&&Math.abs(ay1-by1)<12){if(Math.min(Math.max(ax1,ax2),Math.max(bx1,bx2))-Math.max(Math.min(ax1,ax2),Math.min(bx1,bx2))>=12)return true;}
251
+ if(Math.abs(ax1-ax2)<=.5&&Math.abs(bx1-bx2)<=.5&&Math.abs(ax1-bx1)<12){if(Math.min(Math.max(ay1,ay2),Math.max(by1,by2))-Math.max(Math.min(ay1,ay2),Math.min(by1,by2))>=12)return true;}
252
+ }
253
+ return false;
254
+ }
255
+ function segmentIntersectionPoint(a,b){
256
+ const rx=a[2]-a[0],ry=a[3]-a[1],sx=b[2]-b[0],sy=b[3]-b[1],denominator=rx*sy-ry*sx;
257
+ if(Math.abs(denominator)<1e-8)return null;
258
+ const qx=b[0]-a[0],qy=b[1]-a[1],t=(qx*sy-qy*sx)/denominator,u=(qx*ry-qy*rx)/denominator;
259
+ if(t< -1e-8||t>1+1e-8||u< -1e-8||u>1+1e-8)return null;
260
+ return [a[0]+t*rx,a[1]+t*ry];
261
+ }
262
+ function routeEndpoints(route){
263
+ return [{id:route.from,point:route.segments[0].slice(0,2)},{id:route.to,point:route.segments.at(-1).slice(2,4)}];
264
+ }
265
+ function routeCrossingPoints(a,b){
266
+ const aEnds=routeEndpoints(a),bEnds=routeEndpoints(b),points=[];
267
+ for(const first of a.segments)for(const second of b.segments){
268
+ const point=segmentIntersectionPoint(first,second);
269
+ if(!point)continue;
270
+ const sharedNodeEndpoint=aEnds.some((left)=>bEnds.some((right)=>left.id===right.id&&Math.hypot(left.point[0]-right.point[0],left.point[1]-right.point[1])<=.5&&Math.hypot(left.point[0]-point[0],left.point[1]-point[1])<=.5));
271
+ if(sharedNodeEndpoint||points.some((prior)=>Math.hypot(prior[0]-point[0],prior[1]-point[1])<=.5))continue;
272
+ points.push(point);
273
+ }
274
+ return points;
275
+ }
276
+ function sequenceQuality(source,svg=svgContent(source),nodes=rectangles(svg),routes=parseRoutes(svg)){
277
+ if(!/\bdata-type\s*=\s*["']sequence(?:-oauth)?["']/i.test(source)&&!/\bid\s*=\s*["']diagram-sequence(?:-oauth)?-[^"']+["']/i.test(svg))return [];
278
+ const lifelines=new Map();
279
+ for(const match of svg.matchAll(/<line\b([^>]*)>/gi)){
280
+ const a=attributes(match[1]),name=a['data-lifeline-for'];
281
+ if(name&&a['stroke-dasharray']&&Number(a.x1)===Number(a.x2)&&Number(a.y2)>Number(a.y1))lifelines.set(name,{x:Number(a.x1),top:Number(a.y1),bottom:Number(a.y2)});
282
+ }
283
+ const issues=[],messages=routes.map((route)=>({route,start:route.segments[0].slice(0,2),end:route.segments.at(-1).slice(2,4),y:(route.segments[0][1]+route.segments.at(-1)[3])/2}));
284
+ const lastMessageY=Math.max(0,...messages.map((message)=>message.y));
285
+ for(const node of nodes){
286
+ const line=lifelines.get(node.id);
287
+ if(!line){issues.push('SEQUENCE_LIFELINE_MISSING '+node.id);continue;}
288
+ if(Math.abs(line.x-(node.x+node.w/2))>1||Math.abs(line.top-(node.y+node.h))>1)issues.push('SEQUENCE_LIFELINE_ALIGNMENT '+node.id);
289
+ if(line.bottom+1<lastMessageY)issues.push('SEQUENCE_LIFELINE_SHORT '+node.id+' ends before last message');
290
+ }
291
+ let previousY=-Infinity;
292
+ for(const message of messages){
293
+ const from=lifelines.get(message.route.from),to=lifelines.get(message.route.to);
294
+ if(!from||!to)continue;
295
+ if(Math.abs(message.start[0]-from.x)>1||Math.abs(message.end[0]-to.x)>1)issues.push('SEQUENCE_MESSAGE_OFF_LIFELINE '+message.route.from+'->'+message.route.to);
296
+ if(message.y<=previousY)issues.push('SEQUENCE_MESSAGE_ORDER '+message.route.from+'->'+message.route.to+' is not top-to-bottom');
297
+ previousY=message.y;
298
+ }
299
+ return issues;
300
+ }
301
+
302
+ function visualQuality(source,{enforceCanvas=false,scale=null}={}){
303
+ const svg=svgContent(source),texts=visibleSvgText(svg),nodes=rectangles(svg),routes=parseRoutes(svg),outlines=boundaryOutlines(svg),markers=markerDefinitions(svg),metrics=sourceMetrics(source),issues=[],sequenceDiagram=/\bdata-type\s*=\s*["']sequence(?:-oauth)?["']/i.test(source);
304
+ const contaminated=texts.filter((t)=>contamination.some((rule)=>rule.test(t.label))).map((t)=>t.label);
305
+ const office=officeCraft(texts,nodes,outlines,metrics.viewBox);
306
+ issues.push(...office.issues);
307
+ if(contaminated.length)issues.push('PROCESS_TEXT '+[...new Set(contaminated)].join(' | '));
308
+ for(const text of texts.filter((item)=>item.role==='edge'||item.edgeFor)){
309
+ const matches=routes.filter((route)=>route.from+'|'+route.to===text.edgeFor&&(!route.label||route.label===text.label));
310
+ if(!text.edgeFor||matches.length!==1){issues.push('EDGE_LABEL_UNBOUND '+(text.edgeFor||text.label));continue;}
311
+ const own=matches[0],distance=routeDistance(text.anchor,own),nearestOther=Math.min(Infinity,...routes.filter((route)=>route!==own).map((route)=>routeDistance(text.anchor,route)));
312
+ if(distance>MAX_EDGE_LABEL_ANCHOR_DISTANCE)issues.push('EDGE_LABEL_TOO_FAR '+text.label+' own='+distance.toFixed(1)+'px max='+MAX_EDGE_LABEL_ANCHOR_DISTANCE+'px');
313
+ if(Number.isFinite(nearestOther)&&distance>=nearestOther)issues.push('EDGE_LABEL_NEAREST_PATH '+text.label+' own='+distance.toFixed(1)+'px other='+nearestOther.toFixed(1)+'px');
314
+ for(const node of nodes)if(textOverlapsNode(text,node))issues.push('EDGE_LABEL_NODE_COLLISION '+text.label+' overlaps '+node.id);
315
+ }
316
+ for(const route of routes){
317
+ const facing=routeManhattanDistance(route),ratio=facing?routeLength(route)/facing:null,aligned=alignedRouteKind(route,nodes);
318
+ if(ratio>1.4)issues.push('ROUTE_DETOUR '+route.from+'->'+route.to+' ratio='+ratio.toFixed(2)+' max=1.40');
319
+ if(aligned)issues.push('ROUTE_ALIGNED_PATH '+route.from+'->'+route.to+' '+aligned+' neighbors require one straight segment');
320
+ const crossesBoundary=outlines.some((outline)=>routeCrossesBoundary(route,outline)),bendLimit=crossesBoundary?3:2,bends=routeBends(route);
321
+ if(bends>bendLimit)issues.push('ROUTE_BENDS '+route.from+'->'+route.to+' bends='+bends+' max='+bendLimit);
322
+ if(route.markerStart&&route.markerEnd)issues.push('ROUTE_OPPOSED_HEADS '+route.from+'->'+route.to);
323
+ for(const text of texts)for(const segment of route.segments)if(segmentHitsText(segment,text)){issues.push('EDGE_TEXT_COLLISION '+route.from+'->'+route.to+': '+text.label);break;}
324
+ for(const node of nodes)if(node.id!==route.from&&node.id!==route.to&&route.segments.some((s)=>segmentHitsBox(s,node,8)))issues.push('ROUTE_THROUGH_NODE '+route.from+'->'+route.to+' via '+node.id);
325
+ for(const outline of outlines)if(route.segments.some((segment)=>segmentAlongOutline(segment,outline))){issues.push('ROUTE_ALONG_BOUNDARY '+route.from+'->'+route.to+' along '+outline.id);break;}
326
+ const target=nodes.find((node)=>node.id===route.to);
327
+ for(const edge of ['start','end'])if(edge==='end'?route.markerEnd:route.markerStart){
328
+ const marker=markerFor(route,edge,markers),minimum=Math.max(ARROWHEAD_STROKE_MULTIPLE*route.strokeWidth,ARROWHEAD_CANVAS_FLOOR*(metrics.viewBox?.w||1080));
329
+ const length=markerHeadLength(marker)*markerScale(marker||{units:'userSpaceOnUse'},route);
330
+ if(!marker)issues.push('ARROWHEAD_GEOMETRY_MISSING '+route.from+'->'+route.to+' '+edge);
331
+ else if(length+0.01<minimum)issues.push('ARROWHEAD_SIZE_FLOOR '+route.from+'->'+route.to+' '+edge+'='+length.toFixed(1)+'px min='+minimum.toFixed(1)+'px (12/1080 canvas, 5x stroke)');
332
+ }
333
+ if(route.markerEnd&&target&&!sequenceDiagram){
334
+ const marker=markerFor(route,'end',markers),tip=markerTip(route,marker,'end');
335
+ if(tip&&distanceToBoxBoundary(tip,target)>ARROWHEAD_TARGET_TOLERANCE)issues.push('ARROWHEAD_TIP_MISSED_TARGET '+route.from+'->'+route.to+' gap='+distanceToBoxBoundary(tip,target).toFixed(1)+'px max='+ARROWHEAD_TARGET_TOLERANCE+'px');
336
+ }
337
+ if(route.markerEnd&&target&&markerOverlapsTarget(route,target,markers))issues.push('ARROWHEAD_TARGET_OVERLAP '+route.from+'->'+route.to+' marker intersects target '+target.id);
338
+ }
339
+ issues.push(...decisionBranchQuality(nodes,routes));
340
+ for(let i=0;i<routes.length;i++)for(let j=i+1;j<routes.length;j++){
341
+ if(collinearOverlap(routes[i],routes[j]))issues.push('ROUTE_COLLINEAR_OVERLAP '+routes[i].from+'->'+routes[i].to+' / '+routes[j].from+'->'+routes[j].to+' shared within 12px');
342
+ for(const point of routeCrossingPoints(routes[i],routes[j]))issues.push('ROUTE_CROSSING '+routes[i].from+'->'+routes[i].to+' / '+routes[j].from+'->'+routes[j].to+' at '+point[0].toFixed(1)+','+point[1].toFixed(1));
343
+ }
344
+ issues.push(...sequenceQuality(source,svg,nodes,routes));
345
+ for(const text of texts)for(const outline of outlines)if(textHitsOutline(text,outline)){issues.push('OUTLINE_TEXT_COLLISION '+text.label+' crosses '+outline.id);break;}
346
+ const boundaryTexts=texts.filter((text)=>isBoundaryLabel(text,outlines));
347
+ const boundaryContrastFailures=boundaryTexts.filter((text)=>metrics.contrastFailures.some((failure)=>failure.text===text.label));
348
+ for(const text of boundaryContrastFailures)issues.push('BOUNDARY_CONTRAST_FLOOR '+text.label+' below 4.5:1');
349
+ for(let i=0;i<nodes.length;i++)for(let j=i+1;j<nodes.length;j++)if(gap(nodes[i],nodes[j])<12)issues.push('NODE_GAP '+nodes[i].id+'/'+nodes[j].id+' below 12px');
350
+ const fontFailures=[];
351
+ if(enforceCanvas){
352
+ const ratio=scale??(metrics.viewBox?Math.min(metrics.viewBox.w/1080,metrics.viewBox.h/640):1);
353
+ if(!texts.some((t)=>t.role==='title'))issues.push('TITLE_ROLE_MISSING visible title must use data-role="title"');
354
+ for(const t of texts){const boundary=isBoundaryLabel(t,outlines),minimum=t.role==='title'?28:t.role==='edge'||boundary?13:t.role==='node'?15:0;if(minimum&&t.size+0.01<minimum*ratio){const failure=(boundary?'boundary':t.role)+':'+t.label+'='+t.size+'px (min '+(minimum*ratio).toFixed(1)+'px)';if(boundary)issues.push('BOUNDARY_FONT_FLOOR '+failure);else fontFailures.push(failure);}}
355
+ if(fontFailures.length)issues.push('FONT_FLOOR '+fontFailures.join(' | '));
356
+ const points=nodes.flatMap((n)=>[[n.x,n.y],[n.x+n.w,n.y+n.h]]).concat(routes.flatMap((r)=>r.segments.flatMap((s)=>[[s[0],s[1]],[s[2],s[3]]])));
357
+ const box=points.reduce((b,p)=>({left:Math.min(b.left,p[0]),top:Math.min(b.top,p[1]),right:Math.max(b.right,p[0]),bottom:Math.max(b.bottom,p[1])}),{left:Infinity,top:Infinity,right:-Infinity,bottom:-Infinity});
358
+ if(nodes.length&&metrics.viewBox){const safeWidth=metrics.viewBox.w*.90,safeHeight=metrics.viewBox.h*.74,width=(box.right-box.left)/safeWidth,height=(box.bottom-box.top)/safeHeight;if(width<.75||height<.54)issues.push('CONTENT_FILL safe-area-width='+width.toFixed(3)+' safe-area-height='+height.toFixed(3)+' minimum=.75/.54');}
359
+ if(!nodes.length)issues.push('CONTENT_NODES_MISSING');
360
+ }
361
+ return {issues,advisories:office.advisories,contaminated,fonts:fontFailures,nodes:nodes.length,edges:routes.length,edgeLabelMaxAnchorDistance:MAX_EDGE_LABEL_ANCHOR_DISTANCE,arrowheadFloor:{canvas:ARROWHEAD_CANVAS_FLOOR,strokeMultiple:ARROWHEAD_STROKE_MULTIPLE,targetTolerance:ARROWHEAD_TARGET_TOLERANCE},boundaryTexts:boundaryTexts.length};
362
+ }
363
+ export { visualQuality, officeCraft, visibleSvgText, parseRoutes, rectangles, boundaryOutlines, sequenceQuality };
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) Woojin Go (wjgoarxiv)
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.