@litfamily/lithermes 1.0.8 → 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 (652) hide show
  1. package/README.md +299 -13
  2. package/README_Ko-KR.md +300 -14
  3. package/assets/lithermes-plugin/README.md +17 -6
  4. package/assets/lithermes-plugin/__init__.py +96 -21
  5. package/assets/lithermes-plugin/core.py +15 -6
  6. package/assets/lithermes-plugin/core_commands.py +140 -28
  7. package/assets/lithermes-plugin/core_contexts.py +88 -15
  8. package/assets/lithermes-plugin/core_contract.py +118 -9
  9. package/assets/lithermes-plugin/core_routing.py +197 -8
  10. package/assets/lithermes-plugin/deliverable_hedge_guard.py +378 -357
  11. package/assets/lithermes-plugin/diagnostics.py +53 -2
  12. package/assets/lithermes-plugin/humanizer_detector.py +348 -0
  13. package/assets/lithermes-plugin/humanizer_ko_metrics.py +108 -0
  14. package/assets/lithermes-plugin/humanizer_office.py +18 -0
  15. package/assets/lithermes-plugin/lit_mark.py +1 -1
  16. package/assets/lithermes-plugin/motion_receipts.py +80 -0
  17. package/assets/lithermes-plugin/payload-version.json +2240 -64
  18. package/assets/lithermes-plugin/plugin.yaml +1 -1
  19. package/assets/lithermes-plugin/rules/bundled-rules/lit-humanizer.md +14 -0
  20. package/assets/lithermes-plugin/skills/autoconference/assets/report_template.md +2 -1
  21. package/assets/lithermes-plugin/skills/autoconference/modes/ship/SKILL.md +11 -8
  22. package/assets/lithermes-plugin/skills/autoresearch/modes/ship/type-checklists.md +2 -2
  23. package/assets/lithermes-plugin/skills/browser-drive/ORIGIN.json +17 -0
  24. package/assets/lithermes-plugin/skills/browser-drive/SKILL.md +41 -16
  25. package/assets/lithermes-plugin/skills/browser-drive/scripts/capability_probe.py +122 -10
  26. package/assets/lithermes-plugin/skills/frontend-ui-ux/SKILL.md +45 -13
  27. package/assets/lithermes-plugin/skills/frontend-ui-ux/examples/phase-3-readme-ab/README.md +51 -0
  28. package/assets/lithermes-plugin/skills/frontend-ui-ux/references/README.md +44 -0
  29. package/assets/lithermes-plugin/skills/frontend-ui-ux/references/adaptive-layout.md +34 -62
  30. package/assets/lithermes-plugin/skills/frontend-ui-ux/references/brand-and-imagery.md +22 -70
  31. package/assets/lithermes-plugin/skills/frontend-ui-ux/references/complete-contract.md +18 -4
  32. package/assets/lithermes-plugin/skills/frontend-ui-ux/references/composition.md +27 -78
  33. package/assets/lithermes-plugin/skills/frontend-ui-ux/references/craft-floor.md +74 -0
  34. package/assets/lithermes-plugin/skills/frontend-ui-ux/references/creative-directions.md +25 -69
  35. package/assets/lithermes-plugin/skills/frontend-ui-ux/references/evidence-review.md +18 -97
  36. package/assets/lithermes-plugin/skills/frontend-ui-ux/references/implementation-platforms.md +23 -83
  37. package/assets/lithermes-plugin/skills/frontend-ui-ux/references/inclusive-interface.md +22 -70
  38. package/assets/lithermes-plugin/skills/frontend-ui-ux/references/interaction-motion.md +34 -68
  39. package/assets/lithermes-plugin/skills/frontend-ui-ux/references/motion-guide.md +62 -0
  40. package/assets/lithermes-plugin/skills/frontend-ui-ux/references/operating-lanes.md +14 -78
  41. package/assets/lithermes-plugin/skills/frontend-ui-ux/references/performance-delivery.md +22 -71
  42. package/assets/lithermes-plugin/skills/frontend-ui-ux/references/product-direction.md +17 -70
  43. package/assets/lithermes-plugin/skills/frontend-ui-ux/references/production.md +19 -7
  44. package/assets/lithermes-plugin/skills/frontend-ui-ux/references/redesign-playbook.md +23 -76
  45. package/assets/lithermes-plugin/skills/frontend-ui-ux/references/slop-register.md +69 -0
  46. package/assets/lithermes-plugin/skills/frontend-ui-ux/references/system-foundations.md +22 -67
  47. package/assets/lithermes-plugin/skills/frontend-ui-ux/references/visual-language.md +16 -72
  48. package/assets/lithermes-plugin/skills/frontend-ui-ux/references/visual-reconstruction.md +16 -81
  49. package/assets/lithermes-plugin/skills/frontend-ui-ux/resources/THIRD-PARTY-NOTICE.txt +15 -0
  50. package/assets/lithermes-plugin/skills/frontend-ui-ux/scripts/probe-page.js +311 -0
  51. package/assets/lithermes-plugin/skills/frontend-ui-ux/scripts/probe-rules.json +46 -0
  52. package/assets/lithermes-plugin/skills/frontend-ui-ux/scripts/probe.mjs +231 -0
  53. package/assets/lithermes-plugin/skills/lit-comprehend/SKILL.md +36 -25
  54. package/assets/lithermes-plugin/skills/lit-comprehend/references/artifact-template.md +45 -87
  55. package/assets/lithermes-plugin/skills/lit-comprehend/scripts/verify-explainer.py +3 -27
  56. package/assets/lithermes-plugin/skills/lit-diagram-drawer/NOTICE +33 -0
  57. package/assets/lithermes-plugin/skills/lit-diagram-drawer/SKILL.md +308 -0
  58. package/assets/lithermes-plugin/skills/lit-diagram-drawer/assets/examples/type-architecture-dark.html +1 -0
  59. package/assets/lithermes-plugin/skills/lit-diagram-drawer/assets/examples/type-architecture-full.html +1 -0
  60. package/assets/lithermes-plugin/skills/lit-diagram-drawer/assets/examples/type-architecture-light.html +1 -0
  61. package/assets/lithermes-plugin/skills/lit-diagram-drawer/assets/examples/type-bar-dark.html +1 -0
  62. package/assets/lithermes-plugin/skills/lit-diagram-drawer/assets/examples/type-bar-full.html +1 -0
  63. package/assets/lithermes-plugin/skills/lit-diagram-drawer/assets/examples/type-bar-light.html +1 -0
  64. package/assets/lithermes-plugin/skills/lit-diagram-drawer/assets/examples/type-beeswarm-dark.html +1 -0
  65. package/assets/lithermes-plugin/skills/lit-diagram-drawer/assets/examples/type-beeswarm-full.html +1 -0
  66. package/assets/lithermes-plugin/skills/lit-diagram-drawer/assets/examples/type-beeswarm-light.html +1 -0
  67. package/assets/lithermes-plugin/skills/lit-diagram-drawer/assets/examples/type-bubble-dark.html +1 -0
  68. package/assets/lithermes-plugin/skills/lit-diagram-drawer/assets/examples/type-bubble-full.html +1 -0
  69. package/assets/lithermes-plugin/skills/lit-diagram-drawer/assets/examples/type-bubble-light.html +1 -0
  70. package/assets/lithermes-plugin/skills/lit-diagram-drawer/assets/examples/type-bump-dark.html +1 -0
  71. package/assets/lithermes-plugin/skills/lit-diagram-drawer/assets/examples/type-bump-full.html +1 -0
  72. package/assets/lithermes-plugin/skills/lit-diagram-drawer/assets/examples/type-bump-light.html +1 -0
  73. package/assets/lithermes-plugin/skills/lit-diagram-drawer/assets/examples/type-data-flow-dark.html +1 -0
  74. package/assets/lithermes-plugin/skills/lit-diagram-drawer/assets/examples/type-data-flow-full.html +1 -0
  75. package/assets/lithermes-plugin/skills/lit-diagram-drawer/assets/examples/type-data-flow-light.html +1 -0
  76. package/assets/lithermes-plugin/skills/lit-diagram-drawer/assets/examples/type-datalake-dark.html +1 -0
  77. package/assets/lithermes-plugin/skills/lit-diagram-drawer/assets/examples/type-datalake-full.html +1 -0
  78. package/assets/lithermes-plugin/skills/lit-diagram-drawer/assets/examples/type-datalake-light.html +1 -0
  79. package/assets/lithermes-plugin/skills/lit-diagram-drawer/assets/examples/type-db-schema-dark.html +1 -0
  80. package/assets/lithermes-plugin/skills/lit-diagram-drawer/assets/examples/type-db-schema-full.html +1 -0
  81. package/assets/lithermes-plugin/skills/lit-diagram-drawer/assets/examples/type-db-schema-light.html +1 -0
  82. package/assets/lithermes-plugin/skills/lit-diagram-drawer/assets/examples/type-dependency-dark.html +1 -0
  83. package/assets/lithermes-plugin/skills/lit-diagram-drawer/assets/examples/type-dependency-full.html +1 -0
  84. package/assets/lithermes-plugin/skills/lit-diagram-drawer/assets/examples/type-dependency-light.html +1 -0
  85. package/assets/lithermes-plugin/skills/lit-diagram-drawer/assets/examples/type-deployment-dark.html +1 -0
  86. package/assets/lithermes-plugin/skills/lit-diagram-drawer/assets/examples/type-deployment-full.html +1 -0
  87. package/assets/lithermes-plugin/skills/lit-diagram-drawer/assets/examples/type-deployment-light.html +1 -0
  88. package/assets/lithermes-plugin/skills/lit-diagram-drawer/assets/examples/type-dp-integration-dark.html +1 -0
  89. package/assets/lithermes-plugin/skills/lit-diagram-drawer/assets/examples/type-dp-integration-full.html +1 -0
  90. package/assets/lithermes-plugin/skills/lit-diagram-drawer/assets/examples/type-dp-integration-light.html +1 -0
  91. package/assets/lithermes-plugin/skills/lit-diagram-drawer/assets/examples/type-dp-security-matrix-dark.html +1 -0
  92. package/assets/lithermes-plugin/skills/lit-diagram-drawer/assets/examples/type-dp-security-matrix-full.html +1 -0
  93. package/assets/lithermes-plugin/skills/lit-diagram-drawer/assets/examples/type-dp-security-matrix-light.html +1 -0
  94. package/assets/lithermes-plugin/skills/lit-diagram-drawer/assets/examples/type-er-dark.html +1 -0
  95. package/assets/lithermes-plugin/skills/lit-diagram-drawer/assets/examples/type-er-full.html +1 -0
  96. package/assets/lithermes-plugin/skills/lit-diagram-drawer/assets/examples/type-er-light.html +1 -0
  97. package/assets/lithermes-plugin/skills/lit-diagram-drawer/assets/examples/type-fishbone-dark.html +1 -0
  98. package/assets/lithermes-plugin/skills/lit-diagram-drawer/assets/examples/type-fishbone-full.html +1 -0
  99. package/assets/lithermes-plugin/skills/lit-diagram-drawer/assets/examples/type-fishbone-light.html +1 -0
  100. package/assets/lithermes-plugin/skills/lit-diagram-drawer/assets/examples/type-flowchart-dark.html +1 -0
  101. package/assets/lithermes-plugin/skills/lit-diagram-drawer/assets/examples/type-flowchart-full.html +1 -0
  102. package/assets/lithermes-plugin/skills/lit-diagram-drawer/assets/examples/type-flowchart-light.html +1 -0
  103. package/assets/lithermes-plugin/skills/lit-diagram-drawer/assets/examples/type-gantt-dark.html +1 -0
  104. package/assets/lithermes-plugin/skills/lit-diagram-drawer/assets/examples/type-gantt-full.html +1 -0
  105. package/assets/lithermes-plugin/skills/lit-diagram-drawer/assets/examples/type-gantt-light.html +1 -0
  106. package/assets/lithermes-plugin/skills/lit-diagram-drawer/assets/examples/type-heatmap-dark.html +1 -0
  107. package/assets/lithermes-plugin/skills/lit-diagram-drawer/assets/examples/type-heatmap-full.html +1 -0
  108. package/assets/lithermes-plugin/skills/lit-diagram-drawer/assets/examples/type-heatmap-light.html +1 -0
  109. package/assets/lithermes-plugin/skills/lit-diagram-drawer/assets/examples/type-high-level-dark.html +1 -0
  110. package/assets/lithermes-plugin/skills/lit-diagram-drawer/assets/examples/type-high-level-full.html +1 -0
  111. package/assets/lithermes-plugin/skills/lit-diagram-drawer/assets/examples/type-high-level-light.html +1 -0
  112. package/assets/lithermes-plugin/skills/lit-diagram-drawer/assets/examples/type-high-level-vertical-dark.html +1 -0
  113. package/assets/lithermes-plugin/skills/lit-diagram-drawer/assets/examples/type-high-level-vertical-full.html +1 -0
  114. package/assets/lithermes-plugin/skills/lit-diagram-drawer/assets/examples/type-high-level-vertical-light.html +1 -0
  115. package/assets/lithermes-plugin/skills/lit-diagram-drawer/assets/examples/type-import-drawio-dark.html +1 -0
  116. package/assets/lithermes-plugin/skills/lit-diagram-drawer/assets/examples/type-import-drawio-full.html +1 -0
  117. package/assets/lithermes-plugin/skills/lit-diagram-drawer/assets/examples/type-import-drawio-light.html +1 -0
  118. package/assets/lithermes-plugin/skills/lit-diagram-drawer/assets/examples/type-import-excalidraw-dark.html +1 -0
  119. package/assets/lithermes-plugin/skills/lit-diagram-drawer/assets/examples/type-import-excalidraw-full.html +1 -0
  120. package/assets/lithermes-plugin/skills/lit-diagram-drawer/assets/examples/type-import-excalidraw-light.html +1 -0
  121. package/assets/lithermes-plugin/skills/lit-diagram-drawer/assets/examples/type-import-mermaid-dark.html +1 -0
  122. package/assets/lithermes-plugin/skills/lit-diagram-drawer/assets/examples/type-import-mermaid-full.html +1 -0
  123. package/assets/lithermes-plugin/skills/lit-diagram-drawer/assets/examples/type-import-mermaid-light.html +1 -0
  124. package/assets/lithermes-plugin/skills/lit-diagram-drawer/assets/examples/type-it-state-dark.html +1 -0
  125. package/assets/lithermes-plugin/skills/lit-diagram-drawer/assets/examples/type-it-state-full.html +1 -0
  126. package/assets/lithermes-plugin/skills/lit-diagram-drawer/assets/examples/type-it-state-light.html +1 -0
  127. package/assets/lithermes-plugin/skills/lit-diagram-drawer/assets/examples/type-journey-dark.html +1 -0
  128. package/assets/lithermes-plugin/skills/lit-diagram-drawer/assets/examples/type-journey-full.html +1 -0
  129. package/assets/lithermes-plugin/skills/lit-diagram-drawer/assets/examples/type-journey-light.html +1 -0
  130. package/assets/lithermes-plugin/skills/lit-diagram-drawer/assets/examples/type-kanban-dark.html +1 -0
  131. package/assets/lithermes-plugin/skills/lit-diagram-drawer/assets/examples/type-kanban-full.html +1 -0
  132. package/assets/lithermes-plugin/skills/lit-diagram-drawer/assets/examples/type-kanban-light.html +1 -0
  133. package/assets/lithermes-plugin/skills/lit-diagram-drawer/assets/examples/type-layers-dark.html +1 -0
  134. package/assets/lithermes-plugin/skills/lit-diagram-drawer/assets/examples/type-layers-full.html +1 -0
  135. package/assets/lithermes-plugin/skills/lit-diagram-drawer/assets/examples/type-layers-light.html +1 -0
  136. package/assets/lithermes-plugin/skills/lit-diagram-drawer/assets/examples/type-line-dark.html +1 -0
  137. package/assets/lithermes-plugin/skills/lit-diagram-drawer/assets/examples/type-line-full.html +1 -0
  138. package/assets/lithermes-plugin/skills/lit-diagram-drawer/assets/examples/type-line-light.html +1 -0
  139. package/assets/lithermes-plugin/skills/lit-diagram-drawer/assets/examples/type-loop-dark.html +1 -0
  140. package/assets/lithermes-plugin/skills/lit-diagram-drawer/assets/examples/type-loop-full.html +1 -0
  141. package/assets/lithermes-plugin/skills/lit-diagram-drawer/assets/examples/type-loop-light.html +1 -0
  142. package/assets/lithermes-plugin/skills/lit-diagram-drawer/assets/examples/type-loop-terminal-dark.html +1 -0
  143. package/assets/lithermes-plugin/skills/lit-diagram-drawer/assets/examples/type-loop-terminal-full.html +1 -0
  144. package/assets/lithermes-plugin/skills/lit-diagram-drawer/assets/examples/type-loop-terminal-light.html +1 -0
  145. package/assets/lithermes-plugin/skills/lit-diagram-drawer/assets/examples/type-marimekko-dark.html +1 -0
  146. package/assets/lithermes-plugin/skills/lit-diagram-drawer/assets/examples/type-marimekko-full.html +1 -0
  147. package/assets/lithermes-plugin/skills/lit-diagram-drawer/assets/examples/type-marimekko-light.html +1 -0
  148. package/assets/lithermes-plugin/skills/lit-diagram-drawer/assets/examples/type-medallion-dark.html +1 -0
  149. package/assets/lithermes-plugin/skills/lit-diagram-drawer/assets/examples/type-medallion-full.html +1 -0
  150. package/assets/lithermes-plugin/skills/lit-diagram-drawer/assets/examples/type-medallion-light.html +1 -0
  151. package/assets/lithermes-plugin/skills/lit-diagram-drawer/assets/examples/type-nested-dark.html +1 -0
  152. package/assets/lithermes-plugin/skills/lit-diagram-drawer/assets/examples/type-nested-full.html +1 -0
  153. package/assets/lithermes-plugin/skills/lit-diagram-drawer/assets/examples/type-nested-light.html +1 -0
  154. package/assets/lithermes-plugin/skills/lit-diagram-drawer/assets/examples/type-org-chart-dark.html +1 -0
  155. package/assets/lithermes-plugin/skills/lit-diagram-drawer/assets/examples/type-org-chart-full.html +1 -0
  156. package/assets/lithermes-plugin/skills/lit-diagram-drawer/assets/examples/type-org-chart-light.html +1 -0
  157. package/assets/lithermes-plugin/skills/lit-diagram-drawer/assets/examples/type-paved-road-animated-dark.html +1 -0
  158. package/assets/lithermes-plugin/skills/lit-diagram-drawer/assets/examples/type-paved-road-animated-full.html +1 -0
  159. package/assets/lithermes-plugin/skills/lit-diagram-drawer/assets/examples/type-paved-road-animated-light.html +1 -0
  160. package/assets/lithermes-plugin/skills/lit-diagram-drawer/assets/examples/type-polar-dark.html +1 -0
  161. package/assets/lithermes-plugin/skills/lit-diagram-drawer/assets/examples/type-polar-full.html +1 -0
  162. package/assets/lithermes-plugin/skills/lit-diagram-drawer/assets/examples/type-polar-light.html +1 -0
  163. package/assets/lithermes-plugin/skills/lit-diagram-drawer/assets/examples/type-policy-trace-animated-dark.html +1 -0
  164. package/assets/lithermes-plugin/skills/lit-diagram-drawer/assets/examples/type-policy-trace-animated-full.html +1 -0
  165. package/assets/lithermes-plugin/skills/lit-diagram-drawer/assets/examples/type-policy-trace-animated-light.html +1 -0
  166. package/assets/lithermes-plugin/skills/lit-diagram-drawer/assets/examples/type-process-dark.html +1 -0
  167. package/assets/lithermes-plugin/skills/lit-diagram-drawer/assets/examples/type-process-full.html +1 -0
  168. package/assets/lithermes-plugin/skills/lit-diagram-drawer/assets/examples/type-process-light.html +1 -0
  169. package/assets/lithermes-plugin/skills/lit-diagram-drawer/assets/examples/type-pyramid-dark.html +1 -0
  170. package/assets/lithermes-plugin/skills/lit-diagram-drawer/assets/examples/type-pyramid-full.html +1 -0
  171. package/assets/lithermes-plugin/skills/lit-diagram-drawer/assets/examples/type-pyramid-light.html +1 -0
  172. package/assets/lithermes-plugin/skills/lit-diagram-drawer/assets/examples/type-quadrant-consultant-dark.html +1 -0
  173. package/assets/lithermes-plugin/skills/lit-diagram-drawer/assets/examples/type-quadrant-consultant-full.html +1 -0
  174. package/assets/lithermes-plugin/skills/lit-diagram-drawer/assets/examples/type-quadrant-consultant-light.html +1 -0
  175. package/assets/lithermes-plugin/skills/lit-diagram-drawer/assets/examples/type-quadrant-dark.html +1 -0
  176. package/assets/lithermes-plugin/skills/lit-diagram-drawer/assets/examples/type-quadrant-full.html +1 -0
  177. package/assets/lithermes-plugin/skills/lit-diagram-drawer/assets/examples/type-quadrant-light.html +1 -0
  178. package/assets/lithermes-plugin/skills/lit-diagram-drawer/assets/examples/type-queue-animated-dark.html +1 -0
  179. package/assets/lithermes-plugin/skills/lit-diagram-drawer/assets/examples/type-queue-animated-full.html +1 -0
  180. package/assets/lithermes-plugin/skills/lit-diagram-drawer/assets/examples/type-queue-animated-light.html +1 -0
  181. package/assets/lithermes-plugin/skills/lit-diagram-drawer/assets/examples/type-radar-dark.html +1 -0
  182. package/assets/lithermes-plugin/skills/lit-diagram-drawer/assets/examples/type-radar-full.html +1 -0
  183. package/assets/lithermes-plugin/skills/lit-diagram-drawer/assets/examples/type-radar-light.html +1 -0
  184. package/assets/lithermes-plugin/skills/lit-diagram-drawer/assets/examples/type-ridgeline-dark.html +1 -0
  185. package/assets/lithermes-plugin/skills/lit-diagram-drawer/assets/examples/type-ridgeline-full.html +1 -0
  186. package/assets/lithermes-plugin/skills/lit-diagram-drawer/assets/examples/type-ridgeline-light.html +1 -0
  187. package/assets/lithermes-plugin/skills/lit-diagram-drawer/assets/examples/type-sankey-dark.html +1 -0
  188. package/assets/lithermes-plugin/skills/lit-diagram-drawer/assets/examples/type-sankey-full.html +1 -0
  189. package/assets/lithermes-plugin/skills/lit-diagram-drawer/assets/examples/type-sankey-light.html +1 -0
  190. package/assets/lithermes-plugin/skills/lit-diagram-drawer/assets/examples/type-scatter-dark.html +1 -0
  191. package/assets/lithermes-plugin/skills/lit-diagram-drawer/assets/examples/type-scatter-full.html +1 -0
  192. package/assets/lithermes-plugin/skills/lit-diagram-drawer/assets/examples/type-scatter-light.html +1 -0
  193. package/assets/lithermes-plugin/skills/lit-diagram-drawer/assets/examples/type-sequence-dark.html +1 -0
  194. package/assets/lithermes-plugin/skills/lit-diagram-drawer/assets/examples/type-sequence-full.html +1 -0
  195. package/assets/lithermes-plugin/skills/lit-diagram-drawer/assets/examples/type-sequence-light.html +1 -0
  196. package/assets/lithermes-plugin/skills/lit-diagram-drawer/assets/examples/type-sequence-oauth-dark.html +1 -0
  197. package/assets/lithermes-plugin/skills/lit-diagram-drawer/assets/examples/type-sequence-oauth-full.html +1 -0
  198. package/assets/lithermes-plugin/skills/lit-diagram-drawer/assets/examples/type-sequence-oauth-light.html +1 -0
  199. package/assets/lithermes-plugin/skills/lit-diagram-drawer/assets/examples/type-slopegraph-dark.html +1 -0
  200. package/assets/lithermes-plugin/skills/lit-diagram-drawer/assets/examples/type-slopegraph-full.html +1 -0
  201. package/assets/lithermes-plugin/skills/lit-diagram-drawer/assets/examples/type-slopegraph-light.html +1 -0
  202. package/assets/lithermes-plugin/skills/lit-diagram-drawer/assets/examples/type-state-dark.html +1 -0
  203. package/assets/lithermes-plugin/skills/lit-diagram-drawer/assets/examples/type-state-full.html +1 -0
  204. package/assets/lithermes-plugin/skills/lit-diagram-drawer/assets/examples/type-state-lifecycle-dark.html +1 -0
  205. package/assets/lithermes-plugin/skills/lit-diagram-drawer/assets/examples/type-state-lifecycle-full.html +1 -0
  206. package/assets/lithermes-plugin/skills/lit-diagram-drawer/assets/examples/type-state-lifecycle-light.html +1 -0
  207. package/assets/lithermes-plugin/skills/lit-diagram-drawer/assets/examples/type-state-light.html +1 -0
  208. package/assets/lithermes-plugin/skills/lit-diagram-drawer/assets/examples/type-story-map-dark.html +1 -0
  209. package/assets/lithermes-plugin/skills/lit-diagram-drawer/assets/examples/type-story-map-full.html +1 -0
  210. package/assets/lithermes-plugin/skills/lit-diagram-drawer/assets/examples/type-story-map-light.html +1 -0
  211. package/assets/lithermes-plugin/skills/lit-diagram-drawer/assets/examples/type-streamgraph-dark.html +1 -0
  212. package/assets/lithermes-plugin/skills/lit-diagram-drawer/assets/examples/type-streamgraph-full.html +1 -0
  213. package/assets/lithermes-plugin/skills/lit-diagram-drawer/assets/examples/type-streamgraph-light.html +1 -0
  214. package/assets/lithermes-plugin/skills/lit-diagram-drawer/assets/examples/type-swimlane-dark.html +1 -0
  215. package/assets/lithermes-plugin/skills/lit-diagram-drawer/assets/examples/type-swimlane-full.html +1 -0
  216. package/assets/lithermes-plugin/skills/lit-diagram-drawer/assets/examples/type-swimlane-light.html +1 -0
  217. package/assets/lithermes-plugin/skills/lit-diagram-drawer/assets/examples/type-timeline-dark.html +1 -0
  218. package/assets/lithermes-plugin/skills/lit-diagram-drawer/assets/examples/type-timeline-full.html +1 -0
  219. package/assets/lithermes-plugin/skills/lit-diagram-drawer/assets/examples/type-timeline-light.html +1 -0
  220. package/assets/lithermes-plugin/skills/lit-diagram-drawer/assets/examples/type-tree-block-decomposition-dark.html +1 -0
  221. package/assets/lithermes-plugin/skills/lit-diagram-drawer/assets/examples/type-tree-block-decomposition-full.html +1 -0
  222. package/assets/lithermes-plugin/skills/lit-diagram-drawer/assets/examples/type-tree-block-decomposition-light.html +1 -0
  223. package/assets/lithermes-plugin/skills/lit-diagram-drawer/assets/examples/type-tree-dark.html +1 -0
  224. package/assets/lithermes-plugin/skills/lit-diagram-drawer/assets/examples/type-tree-full.html +1 -0
  225. package/assets/lithermes-plugin/skills/lit-diagram-drawer/assets/examples/type-tree-light.html +1 -0
  226. package/assets/lithermes-plugin/skills/lit-diagram-drawer/assets/examples/type-treemap-dark.html +1 -0
  227. package/assets/lithermes-plugin/skills/lit-diagram-drawer/assets/examples/type-treemap-full.html +1 -0
  228. package/assets/lithermes-plugin/skills/lit-diagram-drawer/assets/examples/type-treemap-light.html +1 -0
  229. package/assets/lithermes-plugin/skills/lit-diagram-drawer/assets/examples/type-uml-class-dark.html +1 -0
  230. package/assets/lithermes-plugin/skills/lit-diagram-drawer/assets/examples/type-uml-class-full.html +1 -0
  231. package/assets/lithermes-plugin/skills/lit-diagram-drawer/assets/examples/type-uml-class-light.html +1 -0
  232. package/assets/lithermes-plugin/skills/lit-diagram-drawer/assets/examples/type-venn-dark.html +1 -0
  233. package/assets/lithermes-plugin/skills/lit-diagram-drawer/assets/examples/type-venn-full.html +1 -0
  234. package/assets/lithermes-plugin/skills/lit-diagram-drawer/assets/examples/type-venn-light.html +1 -0
  235. package/assets/lithermes-plugin/skills/lit-diagram-drawer/assets/examples/type-wardley-dark.html +1 -0
  236. package/assets/lithermes-plugin/skills/lit-diagram-drawer/assets/examples/type-wardley-full.html +1 -0
  237. package/assets/lithermes-plugin/skills/lit-diagram-drawer/assets/examples/type-wardley-light.html +1 -0
  238. package/assets/lithermes-plugin/skills/lit-diagram-drawer/assets/examples/type-waterfall-dark.html +1 -0
  239. package/assets/lithermes-plugin/skills/lit-diagram-drawer/assets/examples/type-waterfall-full.html +1 -0
  240. package/assets/lithermes-plugin/skills/lit-diagram-drawer/assets/examples/type-waterfall-light.html +1 -0
  241. package/assets/lithermes-plugin/skills/lit-diagram-drawer/assets/fonts/OFL.txt +94 -0
  242. package/assets/lithermes-plugin/skills/lit-diagram-drawer/assets/fonts/PretendardVariable.woff2 +0 -0
  243. package/assets/lithermes-plugin/skills/lit-diagram-drawer/assets/fonts/provenance.json +22 -0
  244. package/assets/lithermes-plugin/skills/lit-diagram-drawer/assets/icons.html +231 -0
  245. package/assets/lithermes-plugin/skills/lit-diagram-drawer/assets/index.html +1 -0
  246. package/assets/lithermes-plugin/skills/lit-diagram-drawer/assets/licenses/devicon-MIT.txt +20 -0
  247. package/assets/lithermes-plugin/skills/lit-diagram-drawer/assets/licenses/diagram-design-MIT.txt +21 -0
  248. package/assets/lithermes-plugin/skills/lit-diagram-drawer/assets/licenses/log-z-MIT.txt +21 -0
  249. package/assets/lithermes-plugin/skills/lit-diagram-drawer/assets/licenses/simple-icons-CC0.md +30 -0
  250. package/assets/lithermes-plugin/skills/lit-diagram-drawer/assets/licenses/tabler-MIT.txt +21 -0
  251. package/assets/lithermes-plugin/skills/lit-diagram-drawer/examples/01-service-architecture/after.html +1 -0
  252. package/assets/lithermes-plugin/skills/lit-diagram-drawer/examples/01-service-architecture/brief.md +33 -0
  253. package/assets/lithermes-plugin/skills/lit-diagram-drawer/examples/02-release-decision/after.html +1 -0
  254. package/assets/lithermes-plugin/skills/lit-diagram-drawer/examples/02-release-decision/brief.md +18 -0
  255. package/assets/lithermes-plugin/skills/lit-diagram-drawer/examples/03-data-retention/after.html +1 -0
  256. package/assets/lithermes-plugin/skills/lit-diagram-drawer/examples/03-data-retention/brief.md +19 -0
  257. package/assets/lithermes-plugin/skills/lit-diagram-drawer/examples/04-oauth-sequence/after.html +1 -0
  258. package/assets/lithermes-plugin/skills/lit-diagram-drawer/examples/04-oauth-sequence/brief.md +17 -0
  259. package/assets/lithermes-plugin/skills/lit-diagram-drawer/examples/05-review-lanes/after.html +1 -0
  260. package/assets/lithermes-plugin/skills/lit-diagram-drawer/examples/05-review-lanes/brief.md +17 -0
  261. package/assets/lithermes-plugin/skills/lit-diagram-drawer/examples/06-rollout-gates/after.html +1 -0
  262. package/assets/lithermes-plugin/skills/lit-diagram-drawer/examples/06-rollout-gates/brief.md +17 -0
  263. package/assets/lithermes-plugin/skills/lit-diagram-drawer/examples/07-deployment-boundary/after.html +1 -0
  264. package/assets/lithermes-plugin/skills/lit-diagram-drawer/examples/07-deployment-boundary/brief.md +19 -0
  265. package/assets/lithermes-plugin/skills/lit-diagram-drawer/examples/08-policy-traces/after.html +1 -0
  266. package/assets/lithermes-plugin/skills/lit-diagram-drawer/examples/08-policy-traces/brief.md +20 -0
  267. package/assets/lithermes-plugin/skills/lit-diagram-drawer/references/accessibility.md +37 -0
  268. package/assets/lithermes-plugin/skills/lit-diagram-drawer/references/export.md +29 -0
  269. package/assets/lithermes-plugin/skills/lit-diagram-drawer/references/import-drawio.md +21 -0
  270. package/assets/lithermes-plugin/skills/lit-diagram-drawer/references/import-excalidraw.md +14 -0
  271. package/assets/lithermes-plugin/skills/lit-diagram-drawer/references/import-mermaid.md +18 -0
  272. package/assets/lithermes-plugin/skills/lit-diagram-drawer/references/import-schema.md +28 -0
  273. package/assets/lithermes-plugin/skills/lit-diagram-drawer/references/korean-typography.md +34 -0
  274. package/assets/lithermes-plugin/skills/lit-diagram-drawer/references/motion.md +29 -0
  275. package/assets/lithermes-plugin/skills/lit-diagram-drawer/references/office-pptx-docx.md +40 -0
  276. package/assets/lithermes-plugin/skills/lit-diagram-drawer/references/output-spec.md +48 -0
  277. package/assets/lithermes-plugin/skills/lit-diagram-drawer/references/primitive-annotation.md +12 -0
  278. package/assets/lithermes-plugin/skills/lit-diagram-drawer/references/primitive-icons.md +21 -0
  279. package/assets/lithermes-plugin/skills/lit-diagram-drawer/references/primitive-sketchy.md +11 -0
  280. package/assets/lithermes-plugin/skills/lit-diagram-drawer/references/primitive-terminal.md +11 -0
  281. package/assets/lithermes-plugin/skills/lit-diagram-drawer/references/profiles.md +24 -0
  282. package/assets/lithermes-plugin/skills/lit-diagram-drawer/references/semantic-patterns.md +27 -0
  283. package/assets/lithermes-plugin/skills/lit-diagram-drawer/references/style-guide.md +67 -0
  284. package/assets/lithermes-plugin/skills/lit-diagram-drawer/references/type-architecture.md +51 -0
  285. package/assets/lithermes-plugin/skills/lit-diagram-drawer/references/type-bar.md +51 -0
  286. package/assets/lithermes-plugin/skills/lit-diagram-drawer/references/type-beeswarm.md +49 -0
  287. package/assets/lithermes-plugin/skills/lit-diagram-drawer/references/type-bubble.md +49 -0
  288. package/assets/lithermes-plugin/skills/lit-diagram-drawer/references/type-bump.md +49 -0
  289. package/assets/lithermes-plugin/skills/lit-diagram-drawer/references/type-catalog.json +1433 -0
  290. package/assets/lithermes-plugin/skills/lit-diagram-drawer/references/type-data-flow.md +51 -0
  291. package/assets/lithermes-plugin/skills/lit-diagram-drawer/references/type-datalake.md +49 -0
  292. package/assets/lithermes-plugin/skills/lit-diagram-drawer/references/type-db-schema.md +49 -0
  293. package/assets/lithermes-plugin/skills/lit-diagram-drawer/references/type-dependency.md +49 -0
  294. package/assets/lithermes-plugin/skills/lit-diagram-drawer/references/type-deployment.md +49 -0
  295. package/assets/lithermes-plugin/skills/lit-diagram-drawer/references/type-dp-integration.md +49 -0
  296. package/assets/lithermes-plugin/skills/lit-diagram-drawer/references/type-dp-security-matrix.md +49 -0
  297. package/assets/lithermes-plugin/skills/lit-diagram-drawer/references/type-er.md +49 -0
  298. package/assets/lithermes-plugin/skills/lit-diagram-drawer/references/type-fishbone.md +49 -0
  299. package/assets/lithermes-plugin/skills/lit-diagram-drawer/references/type-flowchart.md +49 -0
  300. package/assets/lithermes-plugin/skills/lit-diagram-drawer/references/type-gantt.md +49 -0
  301. package/assets/lithermes-plugin/skills/lit-diagram-drawer/references/type-heatmap.md +53 -0
  302. package/assets/lithermes-plugin/skills/lit-diagram-drawer/references/type-high-level-vertical.md +53 -0
  303. package/assets/lithermes-plugin/skills/lit-diagram-drawer/references/type-high-level.md +53 -0
  304. package/assets/lithermes-plugin/skills/lit-diagram-drawer/references/type-import-drawio.md +53 -0
  305. package/assets/lithermes-plugin/skills/lit-diagram-drawer/references/type-import-excalidraw.md +53 -0
  306. package/assets/lithermes-plugin/skills/lit-diagram-drawer/references/type-import-mermaid.md +53 -0
  307. package/assets/lithermes-plugin/skills/lit-diagram-drawer/references/type-it-state.md +54 -0
  308. package/assets/lithermes-plugin/skills/lit-diagram-drawer/references/type-journey.md +54 -0
  309. package/assets/lithermes-plugin/skills/lit-diagram-drawer/references/type-kanban.md +54 -0
  310. package/assets/lithermes-plugin/skills/lit-diagram-drawer/references/type-layers.md +54 -0
  311. package/assets/lithermes-plugin/skills/lit-diagram-drawer/references/type-line.md +54 -0
  312. package/assets/lithermes-plugin/skills/lit-diagram-drawer/references/type-loop-terminal.md +53 -0
  313. package/assets/lithermes-plugin/skills/lit-diagram-drawer/references/type-loop.md +54 -0
  314. package/assets/lithermes-plugin/skills/lit-diagram-drawer/references/type-marimekko.md +54 -0
  315. package/assets/lithermes-plugin/skills/lit-diagram-drawer/references/type-medallion.md +54 -0
  316. package/assets/lithermes-plugin/skills/lit-diagram-drawer/references/type-nested.md +59 -0
  317. package/assets/lithermes-plugin/skills/lit-diagram-drawer/references/type-org-chart.md +58 -0
  318. package/assets/lithermes-plugin/skills/lit-diagram-drawer/references/type-paved-road-animated.md +72 -0
  319. package/assets/lithermes-plugin/skills/lit-diagram-drawer/references/type-polar.md +67 -0
  320. package/assets/lithermes-plugin/skills/lit-diagram-drawer/references/type-policy-trace-animated.md +69 -0
  321. package/assets/lithermes-plugin/skills/lit-diagram-drawer/references/type-process.md +58 -0
  322. package/assets/lithermes-plugin/skills/lit-diagram-drawer/references/type-pyramid.md +59 -0
  323. package/assets/lithermes-plugin/skills/lit-diagram-drawer/references/type-quadrant-consultant.md +60 -0
  324. package/assets/lithermes-plugin/skills/lit-diagram-drawer/references/type-quadrant.md +57 -0
  325. package/assets/lithermes-plugin/skills/lit-diagram-drawer/references/type-queue-animated.md +63 -0
  326. package/assets/lithermes-plugin/skills/lit-diagram-drawer/references/type-radar.md +57 -0
  327. package/assets/lithermes-plugin/skills/lit-diagram-drawer/references/type-ridgeline.md +63 -0
  328. package/assets/lithermes-plugin/skills/lit-diagram-drawer/references/type-sankey.md +68 -0
  329. package/assets/lithermes-plugin/skills/lit-diagram-drawer/references/type-scatter.md +60 -0
  330. package/assets/lithermes-plugin/skills/lit-diagram-drawer/references/type-sequence-oauth.md +66 -0
  331. package/assets/lithermes-plugin/skills/lit-diagram-drawer/references/type-sequence.md +63 -0
  332. package/assets/lithermes-plugin/skills/lit-diagram-drawer/references/type-slopegraph.md +65 -0
  333. package/assets/lithermes-plugin/skills/lit-diagram-drawer/references/type-state-lifecycle.md +53 -0
  334. package/assets/lithermes-plugin/skills/lit-diagram-drawer/references/type-state.md +59 -0
  335. package/assets/lithermes-plugin/skills/lit-diagram-drawer/references/type-story-map.md +52 -0
  336. package/assets/lithermes-plugin/skills/lit-diagram-drawer/references/type-streamgraph.md +53 -0
  337. package/assets/lithermes-plugin/skills/lit-diagram-drawer/references/type-swimlane.md +52 -0
  338. package/assets/lithermes-plugin/skills/lit-diagram-drawer/references/type-timeline.md +52 -0
  339. package/assets/lithermes-plugin/skills/lit-diagram-drawer/references/type-tree-block-decomposition.md +57 -0
  340. package/assets/lithermes-plugin/skills/lit-diagram-drawer/references/type-tree.md +54 -0
  341. package/assets/lithermes-plugin/skills/lit-diagram-drawer/references/type-treemap.md +54 -0
  342. package/assets/lithermes-plugin/skills/lit-diagram-drawer/references/type-uml-class.md +52 -0
  343. package/assets/lithermes-plugin/skills/lit-diagram-drawer/references/type-venn.md +51 -0
  344. package/assets/lithermes-plugin/skills/lit-diagram-drawer/references/type-wardley.md +52 -0
  345. package/assets/lithermes-plugin/skills/lit-diagram-drawer/references/type-waterfall.md +54 -0
  346. package/assets/lithermes-plugin/skills/lit-diagram-drawer/references/verifier-guide.md +31 -0
  347. package/assets/lithermes-plugin/skills/lit-diagram-drawer/scripts/block-registry.mjs +43 -0
  348. package/assets/lithermes-plugin/skills/lit-diagram-drawer/scripts/browser-version.mjs +12 -0
  349. package/assets/lithermes-plugin/skills/lit-diagram-drawer/scripts/check-visible-text.py +12 -0
  350. package/assets/lithermes-plugin/skills/lit-diagram-drawer/scripts/diagram_brief.py +192 -0
  351. package/assets/lithermes-plugin/skills/lit-diagram-drawer/scripts/diagram_catalog.py +135 -0
  352. package/assets/lithermes-plugin/skills/lit-diagram-drawer/scripts/diagram_checks.py +123 -0
  353. package/assets/lithermes-plugin/skills/lit-diagram-drawer/scripts/diagram_cli.py +94 -0
  354. package/assets/lithermes-plugin/skills/lit-diagram-drawer/scripts/diagram_geometry.py +130 -0
  355. package/assets/lithermes-plugin/skills/lit-diagram-drawer/scripts/diagram_metrics.py +166 -0
  356. package/assets/lithermes-plugin/skills/lit-diagram-drawer/scripts/diagram_quality.py +293 -0
  357. package/assets/lithermes-plugin/skills/lit-diagram-drawer/scripts/diagram_quality_geometry.py +200 -0
  358. package/assets/lithermes-plugin/skills/lit-diagram-drawer/scripts/diagram_records.py +205 -0
  359. package/assets/lithermes-plugin/skills/lit-diagram-drawer/scripts/diagram_sequence.py +55 -0
  360. package/assets/lithermes-plugin/skills/lit-diagram-drawer/scripts/doctor.mjs +24 -0
  361. package/assets/lithermes-plugin/skills/lit-diagram-drawer/scripts/drawio_extract.py +209 -0
  362. package/assets/lithermes-plugin/skills/lit-diagram-drawer/scripts/drawio_source.py +188 -0
  363. package/assets/lithermes-plugin/skills/lit-diagram-drawer/scripts/excalidraw_extract.py +233 -0
  364. package/assets/lithermes-plugin/skills/lit-diagram-drawer/scripts/excalidraw_support.py +64 -0
  365. package/assets/lithermes-plugin/skills/lit-diagram-drawer/scripts/export.mjs +125 -0
  366. package/assets/lithermes-plugin/skills/lit-diagram-drawer/scripts/mermaid_extract.py +240 -0
  367. package/assets/lithermes-plugin/skills/lit-diagram-drawer/scripts/mermaid_source.py +39 -0
  368. package/assets/lithermes-plugin/skills/lit-diagram-drawer/scripts/office-safety.mjs +54 -0
  369. package/assets/lithermes-plugin/skills/lit-diagram-drawer/scripts/verify-all.py +12 -0
  370. package/assets/lithermes-plugin/skills/lit-diagram-drawer/scripts/verify-brief.py +12 -0
  371. package/assets/lithermes-plugin/skills/lit-diagram-drawer/scripts/verify-diagram.py +12 -0
  372. package/assets/lithermes-plugin/skills/lit-diagram-drawer/scripts/verify-motion.py +12 -0
  373. package/assets/lithermes-plugin/skills/lit-diagram-drawer/scripts/verify-type.py +12 -0
  374. package/assets/lithermes-plugin/skills/lit-docx/NOTICE +1 -0
  375. package/assets/lithermes-plugin/skills/lit-docx/SKILL.md +97 -0
  376. package/assets/lithermes-plugin/skills/lit-docx/references/frontmatter_schema.md +42 -0
  377. package/assets/lithermes-plugin/skills/lit-docx/references/journal_style_spec.md +17 -0
  378. package/assets/lithermes-plugin/skills/lit-docx/references/markdown_quality_checklist.md +37 -0
  379. package/assets/lithermes-plugin/skills/lit-docx/references/slop_phrase_list.yaml +58 -0
  380. package/assets/lithermes-plugin/skills/lit-docx/references/slop_rules.md +35 -0
  381. package/assets/lithermes-plugin/skills/lit-docx/scripts/clean_markdown.py +95 -0
  382. package/assets/lithermes-plugin/skills/lit-docx/scripts/convert_md_to_docx.py +1041 -0
  383. package/assets/lithermes-plugin/skills/lit-docx/scripts/convert_md_to_pdf.py +281 -0
  384. package/assets/lithermes-plugin/skills/lit-docx/scripts/convert_pdf.py +130 -0
  385. package/assets/lithermes-plugin/skills/lit-docx/scripts/edit_docx.py +297 -0
  386. package/assets/lithermes-plugin/skills/lit-docx/scripts/embed_images.py +78 -0
  387. package/assets/lithermes-plugin/skills/lit-docx/scripts/generate_docx_templates.py +491 -0
  388. package/assets/lithermes-plugin/skills/lit-docx/scripts/slop_lint.py +536 -0
  389. package/assets/lithermes-plugin/skills/lit-docx/scripts/visual_audit.py +41 -0
  390. package/assets/lithermes-plugin/skills/lit-docx/templates/docx/acs.docx +0 -0
  391. package/assets/lithermes-plugin/skills/lit-docx/templates/docx/elsevier.docx +0 -0
  392. package/assets/lithermes-plugin/skills/lit-docx/templates/docx/ieee.docx +0 -0
  393. package/assets/lithermes-plugin/skills/lit-docx/templates/docx/korean-generic.docx +0 -0
  394. package/assets/lithermes-plugin/skills/lit-docx/templates/docx/nature.docx +0 -0
  395. package/assets/lithermes-plugin/skills/lit-docx/templates/latex/acs/README.md +5 -0
  396. package/assets/lithermes-plugin/skills/lit-docx/templates/latex/acs/template.tex +37 -0
  397. package/assets/lithermes-plugin/skills/lit-docx/templates/latex/elsevier/README.md +5 -0
  398. package/assets/lithermes-plugin/skills/lit-docx/templates/latex/elsevier/template.tex +38 -0
  399. package/assets/lithermes-plugin/skills/lit-docx/templates/latex/ieee/README.md +5 -0
  400. package/assets/lithermes-plugin/skills/lit-docx/templates/latex/ieee/template.tex +37 -0
  401. package/assets/lithermes-plugin/skills/lit-docx/templates/latex/korean-generic/README.md +5 -0
  402. package/assets/lithermes-plugin/skills/lit-docx/templates/latex/korean-generic/template.tex +37 -0
  403. package/assets/lithermes-plugin/skills/lit-docx/templates/latex/nature/README.md +5 -0
  404. package/assets/lithermes-plugin/skills/lit-docx/templates/latex/nature/template.tex +37 -0
  405. package/assets/lithermes-plugin/skills/lit-docx/templates/registry.yaml +1366 -0
  406. package/assets/lithermes-plugin/skills/lit-humanizer/NOTICE +170 -0
  407. package/assets/lithermes-plugin/skills/lit-humanizer/SKILL.md +125 -0
  408. package/assets/lithermes-plugin/skills/lit-humanizer/assets/report-skeleton.md +26 -0
  409. package/assets/lithermes-plugin/skills/lit-humanizer/assets/slide-text-skeleton.md +30 -0
  410. package/assets/lithermes-plugin/skills/lit-humanizer/examples/accessibility-note/after.md +7 -0
  411. package/assets/lithermes-plugin/skills/lit-humanizer/examples/accessibility-note/before.md +7 -0
  412. package/assets/lithermes-plugin/skills/lit-humanizer/examples/api-reference/after.md +9 -0
  413. package/assets/lithermes-plugin/skills/lit-humanizer/examples/api-reference/before.md +15 -0
  414. package/assets/lithermes-plugin/skills/lit-humanizer/examples/changelog/after.md +5 -0
  415. package/assets/lithermes-plugin/skills/lit-humanizer/examples/changelog/before.md +12 -0
  416. package/assets/lithermes-plugin/skills/lit-humanizer/examples/code-comments/after.md +10 -0
  417. package/assets/lithermes-plugin/skills/lit-humanizer/examples/code-comments/before.md +19 -0
  418. package/assets/lithermes-plugin/skills/lit-humanizer/examples/commit/after.md +5 -0
  419. package/assets/lithermes-plugin/skills/lit-humanizer/examples/commit/before.md +7 -0
  420. package/assets/lithermes-plugin/skills/lit-humanizer/examples/data-release/after.md +7 -0
  421. package/assets/lithermes-plugin/skills/lit-humanizer/examples/data-release/before.md +9 -0
  422. package/assets/lithermes-plugin/skills/lit-humanizer/examples/detector-validation/ko-metrics-golden.json +49 -0
  423. package/assets/lithermes-plugin/skills/lit-humanizer/examples/detector-validation/pos-real.txt +26 -0
  424. package/assets/lithermes-plugin/skills/lit-humanizer/examples/detector-validation/rule-cases.json +306 -0
  425. package/assets/lithermes-plugin/skills/lit-humanizer/examples/english-essay/after.md +5 -0
  426. package/assets/lithermes-plugin/skills/lit-humanizer/examples/english-essay/before.md +5 -0
  427. package/assets/lithermes-plugin/skills/lit-humanizer/examples/incident-update/after.md +7 -0
  428. package/assets/lithermes-plugin/skills/lit-humanizer/examples/incident-update/before.md +7 -0
  429. package/assets/lithermes-plugin/skills/lit-humanizer/examples/ko-essay/after.md +7 -0
  430. package/assets/lithermes-plugin/skills/lit-humanizer/examples/ko-essay/before.md +9 -0
  431. package/assets/lithermes-plugin/skills/lit-humanizer/examples/ko-report/after.md +9 -0
  432. package/assets/lithermes-plugin/skills/lit-humanizer/examples/ko-report/before.md +13 -0
  433. package/assets/lithermes-plugin/skills/lit-humanizer/examples/ko-slide/after.md +19 -0
  434. package/assets/lithermes-plugin/skills/lit-humanizer/examples/ko-slide/before.md +21 -0
  435. package/assets/lithermes-plugin/skills/lit-humanizer/examples/meeting-brief/after.md +9 -0
  436. package/assets/lithermes-plugin/skills/lit-humanizer/examples/meeting-brief/before.md +11 -0
  437. package/assets/lithermes-plugin/skills/lit-humanizer/examples/policy-faq/after.md +9 -0
  438. package/assets/lithermes-plugin/skills/lit-humanizer/examples/policy-faq/before.md +9 -0
  439. package/assets/lithermes-plugin/skills/lit-humanizer/examples/pr/after.md +15 -0
  440. package/assets/lithermes-plugin/skills/lit-humanizer/examples/pr/before.md +17 -0
  441. package/assets/lithermes-plugin/skills/lit-humanizer/examples/project-update/after.md +7 -0
  442. package/assets/lithermes-plugin/skills/lit-humanizer/examples/project-update/before.md +9 -0
  443. package/assets/lithermes-plugin/skills/lit-humanizer/examples/readme/after.md +12 -0
  444. package/assets/lithermes-plugin/skills/lit-humanizer/examples/readme/before.md +14 -0
  445. package/assets/lithermes-plugin/skills/lit-humanizer/examples/report/after.md +13 -0
  446. package/assets/lithermes-plugin/skills/lit-humanizer/examples/report/before.md +11 -0
  447. package/assets/lithermes-plugin/skills/lit-humanizer/examples/research-abstract/after.md +5 -0
  448. package/assets/lithermes-plugin/skills/lit-humanizer/examples/research-abstract/before.md +5 -0
  449. package/assets/lithermes-plugin/skills/lit-humanizer/examples/slides/after.md +19 -0
  450. package/assets/lithermes-plugin/skills/lit-humanizer/examples/slides/before.md +19 -0
  451. package/assets/lithermes-plugin/skills/lit-humanizer/examples/troubleshooting/after.md +11 -0
  452. package/assets/lithermes-plugin/skills/lit-humanizer/examples/troubleshooting/before.md +11 -0
  453. package/assets/lithermes-plugin/skills/lit-humanizer/references/README.md +16 -0
  454. package/assets/lithermes-plugin/skills/lit-humanizer/references/always-on-rule.md +9 -0
  455. package/assets/lithermes-plugin/skills/lit-humanizer/references/code-patterns.md +468 -0
  456. package/assets/lithermes-plugin/skills/lit-humanizer/references/deliverable-channels.md +111 -0
  457. package/assets/lithermes-plugin/skills/lit-humanizer/references/en-patterns-checklist.md +43 -0
  458. package/assets/lithermes-plugin/skills/lit-humanizer/references/en-patterns-content.md +243 -0
  459. package/assets/lithermes-plugin/skills/lit-humanizer/references/en-patterns-structure.md +375 -0
  460. package/assets/lithermes-plugin/skills/lit-humanizer/references/en-patterns.md +57 -0
  461. package/assets/lithermes-plugin/skills/lit-humanizer/references/ko-metrics.md +33 -0
  462. package/assets/lithermes-plugin/skills/lit-humanizer/references/ko-patterns-a-d.md +659 -0
  463. package/assets/lithermes-plugin/skills/lit-humanizer/references/ko-patterns-e-j.md +387 -0
  464. package/assets/lithermes-plugin/skills/lit-humanizer/references/ko-patterns.md +31 -0
  465. package/assets/lithermes-plugin/skills/lit-humanizer/references/rewrite-playbook.md +54 -0
  466. package/assets/lithermes-plugin/skills/lit-humanizer/references/taxonomy.md +153 -0
  467. package/assets/lithermes-plugin/skills/lit-humanizer/rules.json +884 -0
  468. package/assets/lithermes-plugin/skills/lit-humanizer/scripts/detect.py +17 -0
  469. package/assets/lithermes-plugin/skills/lit-humanizer/scripts/extract_office_text.py +114 -0
  470. package/assets/lithermes-plugin/skills/lit-humanizer/scripts/ko_metrics.py +35 -0
  471. package/assets/lithermes-plugin/skills/lit-pptx/NOTICE +1 -0
  472. package/assets/lithermes-plugin/skills/lit-pptx/SKILL.md +109 -0
  473. package/assets/lithermes-plugin/skills/lit-pptx/agents/analyst.md +49 -0
  474. package/assets/lithermes-plugin/skills/lit-pptx/agents/antithesis.md +65 -0
  475. package/assets/lithermes-plugin/skills/lit-pptx/agents/architect.md +44 -0
  476. package/assets/lithermes-plugin/skills/lit-pptx/agents/critic.md +42 -0
  477. package/assets/lithermes-plugin/skills/lit-pptx/agents/synthesizer.md +47 -0
  478. package/assets/lithermes-plugin/skills/lit-pptx/agents/thesis.md +33 -0
  479. package/assets/lithermes-plugin/skills/lit-pptx/assets/azure/circle-lg.png +0 -0
  480. package/assets/lithermes-plugin/skills/lit-pptx/assets/azure/circle-md.png +0 -0
  481. package/assets/lithermes-plugin/skills/lit-pptx/assets/azure/circle-sm.png +0 -0
  482. package/assets/lithermes-plugin/skills/lit-pptx/bin/office.mjs +77 -0
  483. package/assets/lithermes-plugin/skills/lit-pptx/fonts/PRETENDARD-OFL.txt +94 -0
  484. package/assets/lithermes-plugin/skills/lit-pptx/fonts/a2z-font/A2Z-Black.otf +0 -0
  485. package/assets/lithermes-plugin/skills/lit-pptx/fonts/a2z-font/A2Z-Bold.otf +0 -0
  486. package/assets/lithermes-plugin/skills/lit-pptx/fonts/a2z-font/A2Z-ExtraBold.otf +0 -0
  487. package/assets/lithermes-plugin/skills/lit-pptx/fonts/a2z-font/A2Z-ExtraLight.otf +0 -0
  488. package/assets/lithermes-plugin/skills/lit-pptx/fonts/a2z-font/A2Z-Light.otf +0 -0
  489. package/assets/lithermes-plugin/skills/lit-pptx/fonts/a2z-font/A2Z-Medium.otf +0 -0
  490. package/assets/lithermes-plugin/skills/lit-pptx/fonts/a2z-font/A2Z-Regular.otf +0 -0
  491. package/assets/lithermes-plugin/skills/lit-pptx/fonts/a2z-font/A2Z-SemiBold.otf +0 -0
  492. package/assets/lithermes-plugin/skills/lit-pptx/fonts/a2z-font/A2Z-Thin.otf +0 -0
  493. package/assets/lithermes-plugin/skills/lit-pptx/fonts/a2z-font/OFL.txt +94 -0
  494. package/assets/lithermes-plugin/skills/lit-pptx/fonts/a2z-font/SOURCE.md +29 -0
  495. package/assets/lithermes-plugin/skills/lit-pptx/pretendard-font/public/static/PretendardGOV-Bold.otf +0 -0
  496. package/assets/lithermes-plugin/skills/lit-pptx/pretendard-font/public/static/PretendardGOV-Regular.otf +0 -0
  497. package/assets/lithermes-plugin/skills/lit-pptx/references/anti-slop-checklist.md +71 -0
  498. package/assets/lithermes-plugin/skills/lit-pptx/references/authoring-guide.md +139 -0
  499. package/assets/lithermes-plugin/skills/lit-pptx/references/consensus-protocol.md +125 -0
  500. package/assets/lithermes-plugin/skills/lit-pptx/references/data-display-cookbook.md +45 -0
  501. package/assets/lithermes-plugin/skills/lit-pptx/references/design-system-azure.md +58 -0
  502. package/assets/lithermes-plugin/skills/lit-pptx/runtime/package-lock.json +750 -0
  503. package/assets/lithermes-plugin/skills/lit-pptx/runtime/package.json +15 -0
  504. package/assets/lithermes-plugin/skills/lit-pptx/runtime/requirements.in +7 -0
  505. package/assets/lithermes-plugin/skills/lit-pptx/runtime/requirements.lock +391 -0
  506. package/assets/lithermes-plugin/skills/lit-pptx/scripts/compile-deck.js +447 -0
  507. package/assets/lithermes-plugin/skills/lit-pptx/scripts/craft_extras.py +215 -0
  508. package/assets/lithermes-plugin/skills/lit-pptx/scripts/embed_fonts.py +199 -0
  509. package/assets/lithermes-plugin/skills/lit-pptx/scripts/integrity.py +60 -0
  510. package/assets/lithermes-plugin/skills/lit-pptx/scripts/inventory.py +64 -0
  511. package/assets/lithermes-plugin/skills/lit-pptx/scripts/learn_template.py +433 -0
  512. package/assets/lithermes-plugin/skills/lit-pptx/scripts/lib/derive-palette.js +176 -0
  513. package/assets/lithermes-plugin/skills/lit-pptx/scripts/lib/directive-parser.js +244 -0
  514. package/assets/lithermes-plugin/skills/lit-pptx/scripts/lib/font-map.js +79 -0
  515. package/assets/lithermes-plugin/skills/lit-pptx/scripts/lib/gen-bg.js +85 -0
  516. package/assets/lithermes-plugin/skills/lit-pptx/scripts/lib/gen-gradient-assets.js +36 -0
  517. package/assets/lithermes-plugin/skills/lit-pptx/scripts/lib/layout-resolver.js +736 -0
  518. package/assets/lithermes-plugin/skills/lit-pptx/scripts/lib/markdown-loader.js +136 -0
  519. package/assets/lithermes-plugin/skills/lit-pptx/scripts/lib/render-adapter-html.js +357 -0
  520. package/assets/lithermes-plugin/skills/lit-pptx/scripts/lib/render-adapter-pptx.js +1864 -0
  521. package/assets/lithermes-plugin/skills/lit-pptx/scripts/lib/slide-ast.js +539 -0
  522. package/assets/lithermes-plugin/skills/lit-pptx/scripts/lib/spec-validator.js +94 -0
  523. package/assets/lithermes-plugin/skills/lit-pptx/scripts/lib/template-registry.js +355 -0
  524. package/assets/lithermes-plugin/skills/lit-pptx/scripts/qa_deck.py +791 -0
  525. package/assets/lithermes-plugin/skills/lit-pptx/scripts/validate_pptx.py +206 -0
  526. package/assets/lithermes-plugin/skills/lit-pptx/slide-formats/markdown-slide-spec-v1.md +251 -0
  527. package/assets/lithermes-plugin/skills/lit-pptx/slide-formats/markdown-slide-spec-v2.md +221 -0
  528. package/assets/lithermes-plugin/skills/lit-pptx/slide-formats/slide-ast-v1.schema.json +229 -0
  529. package/assets/lithermes-plugin/skills/lit-pptx/slide-formats/slide-ast-v2.schema.json +144 -0
  530. package/assets/lithermes-plugin/skills/lit-pptx/slide-formats/template-enrollment-contract.md +228 -0
  531. package/assets/lithermes-plugin/skills/lit-pptx/templates/enrolled/AZURE-A2Z/capabilities.yaml +146 -0
  532. package/assets/lithermes-plugin/skills/lit-pptx/templates/enrolled/AZURE-A2Z/layout-mapping.yaml +384 -0
  533. package/assets/lithermes-plugin/skills/lit-pptx/templates/enrolled/AZURE-A2Z/template.yaml +37 -0
  534. package/assets/lithermes-plugin/skills/lit-pptx/templates/enrolled/AZURE-PRO/capabilities.yaml +154 -0
  535. package/assets/lithermes-plugin/skills/lit-pptx/templates/enrolled/AZURE-PRO/layout-mapping.yaml +405 -0
  536. package/assets/lithermes-plugin/skills/lit-pptx/templates/enrolled/AZURE-PRO/template.yaml +37 -0
  537. package/assets/lithermes-plugin/skills/lit-pptx/templates/enrolled/BOILERPLATE-A2Z/capabilities.yaml +179 -0
  538. package/assets/lithermes-plugin/skills/lit-pptx/templates/enrolled/BOILERPLATE-A2Z/layout-mapping.yaml +299 -0
  539. package/assets/lithermes-plugin/skills/lit-pptx/templates/enrolled/BOILERPLATE-A2Z/template.yaml +45 -0
  540. package/assets/lithermes-plugin/skills/lit-pptx/templates/enrolled/BOILERPLATE-PRETENDARD/capabilities.yaml +181 -0
  541. package/assets/lithermes-plugin/skills/lit-pptx/templates/enrolled/BOILERPLATE-PRETENDARD/layout-mapping.yaml +299 -0
  542. package/assets/lithermes-plugin/skills/lit-pptx/templates/enrolled/BOILERPLATE-PRETENDARD/template.yaml +44 -0
  543. package/assets/lithermes-plugin/skills/lit-scientific-visualization/SKILL.md +2 -0
  544. package/assets/lithermes-plugin/skills/lit-typographic-motion/SKILL.md +71 -0
  545. package/assets/lithermes-plugin/skills/lit-typographic-motion/bin/audio.py +45 -0
  546. package/assets/lithermes-plugin/skills/lit-typographic-motion/bin/motion.mjs +690 -0
  547. package/assets/lithermes-plugin/skills/lit-typographic-motion/bin/runtime.mjs +299 -0
  548. package/assets/lithermes-plugin/skills/lit-typographic-motion/engine/NOTICE +23 -0
  549. package/assets/lithermes-plugin/skills/lit-typographic-motion/engine/THIRD_PARTY_NOTICES +55 -0
  550. package/assets/lithermes-plugin/skills/lit-typographic-motion/engine/browser.mjs +169 -0
  551. package/assets/lithermes-plugin/skills/lit-typographic-motion/engine/completion.mjs +52 -0
  552. package/assets/lithermes-plugin/skills/lit-typographic-motion/engine/constants.mjs +162 -0
  553. package/assets/lithermes-plugin/skills/lit-typographic-motion/engine/director.mjs +33 -0
  554. package/assets/lithermes-plugin/skills/lit-typographic-motion/engine/encode.mjs +191 -0
  555. package/assets/lithermes-plugin/skills/lit-typographic-motion/engine/flash.mjs +163 -0
  556. package/assets/lithermes-plugin/skills/lit-typographic-motion/engine/frame.mjs +428 -0
  557. package/assets/lithermes-plugin/skills/lit-typographic-motion/engine/gate.mjs +483 -0
  558. package/assets/lithermes-plugin/skills/lit-typographic-motion/engine/look.mjs +223 -0
  559. package/assets/lithermes-plugin/skills/lit-typographic-motion/engine/page.js +622 -0
  560. package/assets/lithermes-plugin/skills/lit-typographic-motion/engine/presets.mjs +170 -0
  561. package/assets/lithermes-plugin/skills/lit-typographic-motion/engine/scenes.mjs +242 -0
  562. package/assets/lithermes-plugin/skills/lit-typographic-motion/engine/sound.mjs +382 -0
  563. package/assets/lithermes-plugin/skills/lit-typographic-motion/engine/stage-gate.mjs +97 -0
  564. package/assets/lithermes-plugin/skills/lit-typographic-motion/engine/stage-init.js +186 -0
  565. package/assets/lithermes-plugin/skills/lit-typographic-motion/engine/stage-kit.js +389 -0
  566. package/assets/lithermes-plugin/skills/lit-typographic-motion/engine/stage-qa.mjs +358 -0
  567. package/assets/lithermes-plugin/skills/lit-typographic-motion/engine/stage-worker.mjs +33 -0
  568. package/assets/lithermes-plugin/skills/lit-typographic-motion/engine/stage.mjs +691 -0
  569. package/assets/lithermes-plugin/skills/lit-typographic-motion/engine/stills.mjs +71 -0
  570. package/assets/lithermes-plugin/skills/lit-typographic-motion/engine/stroke.mjs +231 -0
  571. package/assets/lithermes-plugin/skills/lit-typographic-motion/engine/timeline.mjs +177 -0
  572. package/assets/lithermes-plugin/skills/lit-typographic-motion/engine/treatment.mjs +244 -0
  573. package/assets/lithermes-plugin/skills/lit-typographic-motion/engine/type.mjs +183 -0
  574. package/assets/lithermes-plugin/skills/lit-typographic-motion/engine/util.mjs +152 -0
  575. package/assets/lithermes-plugin/skills/lit-typographic-motion/references/craft-loop.md +175 -0
  576. package/assets/lithermes-plugin/skills/lit-typographic-motion/references/engine-contract.md +166 -0
  577. package/assets/lithermes-plugin/skills/lit-typographic-motion/references/runtime.md +122 -0
  578. package/assets/lithermes-plugin/skills/lit-typographic-motion/references/stage.md +261 -0
  579. package/assets/lithermes-plugin/skills/lit-typographic-motion/references/style-bibles.md +122 -0
  580. package/assets/lithermes-plugin/skills/lit-typographic-motion/references/treatment.md +164 -0
  581. package/assets/lithermes-plugin/skills/lit-typographic-motion/references/type-craft.md +92 -0
  582. package/assets/lithermes-plugin/skills/lit-typographic-motion/runtime/fonts.json +154 -0
  583. package/assets/lithermes-plugin/skills/lit-typographic-motion/runtime/licenses/CREDITS +20 -0
  584. package/assets/lithermes-plugin/skills/lit-typographic-motion/runtime/licenses/EMS-OFL.txt +91 -0
  585. package/assets/lithermes-plugin/skills/lit-typographic-motion/runtime/package-lock.json +88 -0
  586. package/assets/lithermes-plugin/skills/lit-typographic-motion/runtime/package.json +12 -0
  587. package/assets/lithermes-plugin/skills/lit-typographic-motion/runtime/requirements.in +1 -0
  588. package/assets/lithermes-plugin/skills/lit-typographic-motion/runtime/requirements.lock +727 -0
  589. package/assets/lithermes-plugin/skills/lit-typographic-motion/runtime/word-timing.json +9 -0
  590. package/assets/lithermes-plugin/skills/litresearch/SKILL.md +19 -18
  591. package/assets/lithermes-plugin/skills/litwork/SKILL.md +28 -0
  592. package/assets/lithermes-plugin/skills/visual-qa/references/complete-contract.md +3 -3
  593. package/package.json +1 -1
  594. package/readme-assets/ab-simple/s11-ui-baseline-desktop.webp +0 -0
  595. package/readme-assets/ab-simple/s11-ui-lithermes-desktop.webp +0 -0
  596. package/readme-assets/ab-simple/s3-ui-baseline-desktop.webp +0 -0
  597. package/readme-assets/ab-simple/s3-ui-lithermes-desktop.webp +0 -0
  598. package/readme-assets/ab-simple/s4-ui-baseline-desktop.webp +0 -0
  599. package/readme-assets/ab-simple/s4-ui-lithermes-desktop.webp +0 -0
  600. package/readme-assets/ab-simple/s5-office-baseline-slides.webp +0 -0
  601. package/readme-assets/ab-simple/s5-office-lithermes-slides.webp +0 -0
  602. package/readme-assets/ab-simple/s7-lithermes-diagram.webp +0 -0
  603. package/readme-assets/ab-simple/s8-office-baseline-slides.webp +0 -0
  604. package/readme-assets/ab-simple/s8-office-lithermes-slides.webp +0 -0
  605. package/readme-assets/ab-simple/s9-office-lithermes-pages.webp +0 -0
  606. package/readme-assets/badge-version.svg +1 -1
  607. package/readme-assets/cover-motion-still.webp +0 -0
  608. package/readme-assets/cover-motion.webp +0 -0
  609. package/readme-assets/skills/autoconference.webp +0 -0
  610. package/readme-assets/skills/autoresearch.webp +0 -0
  611. package/readme-assets/skills/browser-drive.webp +0 -0
  612. package/readme-assets/skills/comment-checker.webp +0 -0
  613. package/readme-assets/skills/debugging.webp +0 -0
  614. package/readme-assets/skills/deep-interview.webp +0 -0
  615. package/readme-assets/skills/frontend-ui-ux.webp +0 -0
  616. package/readme-assets/skills/lit-burnoff-file.webp +0 -0
  617. package/readme-assets/skills/lit-burnoff.webp +0 -0
  618. package/readme-assets/skills/lit-code.webp +0 -0
  619. package/readme-assets/skills/lit-commit.webp +0 -0
  620. package/readme-assets/skills/lit-comprehend.webp +0 -0
  621. package/readme-assets/skills/lit-crucible.webp +0 -0
  622. package/readme-assets/skills/lit-diagram-drawer.webp +0 -0
  623. package/readme-assets/skills/lit-docx.webp +0 -0
  624. package/readme-assets/skills/lit-handoff.webp +0 -0
  625. package/readme-assets/skills/lit-humanizer.webp +0 -0
  626. package/readme-assets/skills/lit-init.webp +0 -0
  627. package/readme-assets/skills/lit-plan.webp +0 -0
  628. package/readme-assets/skills/lit-pptx.webp +0 -0
  629. package/readme-assets/skills/lit-recap.webp +0 -0
  630. package/readme-assets/skills/lit-scientific-visualization.webp +0 -0
  631. package/readme-assets/skills/lit-typographic-motion.webp +0 -0
  632. package/readme-assets/skills/litgoal.webp +0 -0
  633. package/readme-assets/skills/litresearch.webp +0 -0
  634. package/readme-assets/skills/litwork.webp +0 -0
  635. package/readme-assets/skills/lsp-setup.webp +0 -0
  636. package/readme-assets/skills/lsp.webp +0 -0
  637. package/readme-assets/skills/readme-studio.webp +0 -0
  638. package/readme-assets/skills/refactor.webp +0 -0
  639. package/readme-assets/skills/review-work.webp +0 -0
  640. package/readme-assets/skills/rules.webp +0 -0
  641. package/readme-assets/skills/start-work.webp +0 -0
  642. package/readme-assets/skills/structural-search.webp +0 -0
  643. package/readme-assets/skills/visual-qa.webp +0 -0
  644. package/readme-assets/skills/wikify.webp +0 -0
  645. package/src/cli.js +40 -1
  646. package/src/lib/check.js +21 -0
  647. package/src/lib/install.js +262 -7
  648. package/src/lib/skillPayload.js +3 -3
  649. package/assets/lithermes-plugin/skills/lit-korean/SKILL.md +0 -237
  650. package/assets/lithermes-plugin/skills/lit-korean/references/quick-rules.md +0 -24
  651. package/assets/lithermes-plugin/skills/lit-korean/references/safety-checklist.md +0 -23
  652. package/readme-assets/cover.webp +0 -0
@@ -0,0 +1,690 @@
1
+ #!/usr/bin/env node
2
+ // lit-typographic-motion render CLI for LitHermes. The mode set and flags
3
+ // follow pdoom's scripts/render.ts (stills, sheet, perf, video; --samples,
4
+ // --shutter, --scale), MIT, see NOTICE; `run` is the one end-to-end command
5
+ // and `gate`/`complete` re-check an existing output directory. The render only
6
+ // reads the pre-warmed cache and writes inside --out (MO-A-43).
7
+ import { createHash } from 'node:crypto';
8
+ import { spawnSync } from 'node:child_process';
9
+ import { existsSync, mkdirSync, readFileSync, realpathSync, rmSync, statSync, writeFileSync } from 'node:fs';
10
+ import { dirname, isAbsolute, join, resolve } from 'node:path';
11
+ import { fileURLToPath } from 'node:url';
12
+ import { CREDIT_LINE, ENGINE_CREDIT, EXIT, FRAME, PERF, SAMPLING } from '../engine/constants.mjs';
13
+ import { PRESETS, pickPreset, planPasses, terminalSignal } from '../engine/presets.mjs';
14
+ import { buildTimeline, normalizeBrief, shotsOf } from '../engine/timeline.mjs';
15
+ import { FONT_FILES, FrameComposer, resolveFontId } from '../engine/frame.mjs';
16
+ import { openTypeAdapter, scriptRuns } from '../engine/type.mjs';
17
+ import { parseStrokeFont, STROKE_FONTS } from '../engine/stroke.mjs';
18
+ import { FlashDetector } from '../engine/flash.mjs';
19
+ import { measureContrast, preflightGate, promoteExports, renderReport, runGate } from '../engine/gate.mjs';
20
+ import { areaResize, contactSheet, encodePreview, ffprobe, hasFfmpeg, pngDecode, pngEncode, startMaster } from '../engine/encode.mjs';
21
+ import { openRenderer } from '../engine/browser.mjs';
22
+ import { WARM, audioState, findCache, fontFile, fontState, hangulPath, runtimeRequire, skillRoot, wordTimingReady } from './runtime.mjs';
23
+ import { loadTreatment } from '../engine/treatment.mjs';
24
+ import { recordFirstTreatment } from '../engine/director.mjs';
25
+ import { stageCommand, stageRegate } from '../engine/stage.mjs';
26
+ import { completeCommand, lookCommand } from '../engine/look.mjs';
27
+ import { stampStills, stillsPlan, writeStillsSet } from '../engine/stills.mjs';
28
+ import { produceSound, soundCommand, soundGate } from '../engine/sound.mjs';
29
+ import { viewedFiles } from '../engine/director.mjs';
30
+
31
+ const USAGE = `LitHermes lit-typographic-motion
32
+ usage: node motion.mjs <subcommand> --out DIR [options] (write DIR/treatment.json first)
33
+ stage --out DIR [--stills-only] [--round 1-3] stage path: capture DIR/stage/index.html frame by frame; stills, film, sound, gate
34
+ run --out DIR [--brief FILE] [--round 1-3] [--stills-only] type path: the WebGL2 type engine; stills, cut sheet, film, preview, poster, gate
35
+ sound --out DIR build the generated sound bed and sound-cues.json from the treatment
36
+ look --out DIR --round 1-3 --answers FILE record one look round against the latest stills set
37
+ gate --out DIR rerun the gate on an existing output dir
38
+ complete --out DIR exit 0 only when this film is done (treatment, gate, look rounds)
39
+ type-path tools: stills, sheet, video, perf (--brief FILE --out DIR)
40
+ options: --scale 1-4 --word-timing --force-software
41
+ exit: 0 ok, 10 no Chrome, 11 no WebGL2, 12 no ffmpeg for video, 13 QA gate failed, 14 not pre-warmed, 15 font missing or corrupt,
42
+ 16 treatment invalid, 17 stage contract, 18 stage not deterministic, 19 stage network request, 20 sound invalid
43
+ ${CREDIT_LINE}`;
44
+
45
+ const sha = (data) => createHash('sha256').update(data).digest('hex');
46
+ const fail = (code, message) => Object.assign(new Error(message), { exitCode: code });
47
+ const writeJson = (file, value) => writeFileSync(file, `${JSON.stringify(value, null, 2)}\n`);
48
+ const NOTICE_SHA = '6734178ad953e5f40585d000c13e4803e670d9e8982b7f6ef0395d47a9eedf30';
49
+
50
+ function parseArgs(argv) {
51
+ const flags = { _: [] };
52
+ for (let i = 0; i < argv.length; i++) {
53
+ const arg = argv[i];
54
+ if (!arg.startsWith('--')) { flags._.push(arg); continue; }
55
+ const key = arg.slice(2);
56
+ if (['stills-only', 'cuts', 'word-timing', 'force-software', 'help', 'no-rerender', 'aids', 'detach'].includes(key)) flags[key] = true;
57
+ else if (key === 'viewed') flags.viewed = String(argv[++i] || '').split(',').map((v) => Number(v.replace(/^f/, ''))).filter(Number.isInteger);
58
+ else flags[key] = argv[++i];
59
+ }
60
+ return flags;
61
+ }
62
+
63
+ class FontSet {
64
+ constructor(opentype, cache) { this.opentype = opentype; this.cache = cache; this.fonts = new Map(); }
65
+ path(id) {
66
+ const file = FONT_FILES[id];
67
+ return file.startsWith('lit-pptx:') ? hangulPath(file.slice(9)) : fontFile(this.cache, file);
68
+ }
69
+ get(id) {
70
+ if (!this.fonts.has(id)) {
71
+ const bytes = readFileSync(this.path(id));
72
+ const parsed = this.opentype.parse(bytes.buffer.slice(bytes.byteOffset, bytes.byteOffset + bytes.byteLength));
73
+ this.fonts.set(id, openTypeAdapter(parsed, id, FONT_FILES[id].replace(/^lit-pptx:/, '').split('/').pop()));
74
+ }
75
+ return this.fonts.get(id);
76
+ }
77
+ }
78
+
79
+ class StrokeSet {
80
+ constructor(cache) { this.cache = cache; this.fonts = new Map(); }
81
+ get(name) {
82
+ if (!this.fonts.has(name)) {
83
+ const file = STROKE_FONTS[name];
84
+ const font = parseStrokeFont(readFileSync(fontFile(this.cache, `fonts/stroke/${file}`), 'utf8'), name);
85
+ font.file = file;
86
+ this.fonts.set(name, font);
87
+ }
88
+ return this.fonts.get(name);
89
+ }
90
+ }
91
+
92
+ const FILTER_ORDER = { 'swiss-signal': ['dither'], terminalcore: ['crt', 'dither', 'glitch'], tidal: ['glitch'] };
93
+
94
+ class Session {
95
+ constructor(flags, mode) {
96
+ this.flags = flags;
97
+ this.mode = mode;
98
+ this.out = resolve(flags.out || 'motion-output');
99
+ this.round = Number(flags.round || 1);
100
+ this.scale = Math.max(1, Math.min(FRAME.maxScale, Math.round(Number(flags.scale || 1))));
101
+ this.framesViewed = flags.viewed || [];
102
+ this.records = [];
103
+ this.previewRecords = [];
104
+ this.contrast = [];
105
+ }
106
+
107
+ prepare() {
108
+ if (!this.flags.brief) throw fail(2, 'missing --brief FILE (a JSON brief with "text": ["line", ...])');
109
+ this.briefPath = resolve(this.flags.brief);
110
+ if (!existsSync(this.briefPath)) throw fail(2, `brief not found: ${this.briefPath}`);
111
+ const rawBytes = readFileSync(this.briefPath);
112
+ let raw;
113
+ try { raw = JSON.parse(rawBytes.toString('utf8')); } catch (error) { throw fail(2, `brief is not valid JSON: ${error.message}`); }
114
+ try { this.brief = normalizeBrief(raw); } catch (error) { throw fail(2, error.message); }
115
+ this.briefSha = sha(rawBytes);
116
+ if (![1, 2, 3].includes(this.round)) throw fail(2, '--round must be 1, 2 or 3');
117
+ if ((this.flags['word-timing'] || this.brief.wordTiming) && !wordTimingReady()) {
118
+ throw fail(EXIT.BLOCKED_DEPS_NOT_PREWARMED, `BLOCKED_DEPS_NOT_PREWARMED: word-timing models are not installed; run \`${WARM} --word-timing\` outside this session (Tier 3 is fail-closed until its Korean alignment model is pinned)`);
119
+ }
120
+ this.require = runtimeRequire();
121
+ this.cache = findCache();
122
+ const fonts = fontState();
123
+ if (!fonts.ok) {
124
+ throw fail(EXIT.BLOCKED_FONT_FETCH, `BLOCKED_FONT_FETCH: ${[...fonts.missing.map((f) => `missing ${f}`), ...fonts.mismatched.map((f) => `sha256 mismatch ${f}`)].join('; ')}; run \`${WARM}\` outside this session`);
125
+ }
126
+ this.PNG = this.require('pngjs').PNG;
127
+ this.fonts = new FontSet(this.require('opentype.js'), this.cache);
128
+ this.strokes = new StrokeSet(this.cache);
129
+ if (this.treatment && this.brief.durationSec == null) this.brief.durationSec = this.treatment.durationSec;
130
+ this.choice = pickPreset(this.brief, { request: this.treatment?.request || '' });
131
+ this.presetId = this.choice.id;
132
+ this.preset = PRESETS[this.presetId];
133
+ this.signal = this.presetId === 'terminalcore' ? terminalSignal(this.brief) : this.preset.palette.signal;
134
+ this.warnings = [];
135
+ this.audioGrid = null;
136
+ if (this.brief.audio) this.audioGrid = this.analyzeAudio();
137
+ const built = buildTimeline(this.brief, { presetId: this.presetId, fps: FRAME.fps, audioGrid: this.audioGrid });
138
+ this.timeline = built.timeline;
139
+ this.durationSec = built.durationSec;
140
+ this.warnings.push(...built.warnings);
141
+ this.totalFrames = Math.round(this.durationSec * FRAME.fps);
142
+ }
143
+
144
+ analyzeAudio() {
145
+ const audioPath = isAbsolute(this.brief.audio) ? this.brief.audio : resolve(dirname(this.briefPath), this.brief.audio);
146
+ const state = audioState();
147
+ if (state.state !== 'ready') {
148
+ this.warnings.push(state.state === 'absent'
149
+ ? `audio analysis not prewarmed: run ${WARM} --audio (Tier 1 text timing used)`
150
+ : `audio venv does not match its pins (${state.detail}); run ${WARM} --audio (Tier 1 text timing used)`);
151
+ return null;
152
+ }
153
+ mkdirSync(this.out, { recursive: true });
154
+ const grid = join(this.out, 'audio-grid.json');
155
+ const result = spawnSync(state.python, [join(skillRoot, 'bin', 'audio.py'), audioPath, grid], { encoding: 'utf8', timeout: 300000 });
156
+ if (result.status !== 0 || !existsSync(grid)) {
157
+ this.warnings.push(`audio analysis failed (${(result.stderr || result.error?.message || '').trim().split('\n').at(-1)}); Tier 1 text timing used`);
158
+ return null;
159
+ }
160
+ const parsed = JSON.parse(readFileSync(grid, 'utf8'));
161
+ if (!parsed.beats?.length) { this.warnings.push('audio analysis found no beats; Tier 1 text timing used'); return null; }
162
+ this.audioPath = audioPath;
163
+ return parsed;
164
+ }
165
+
166
+ baseManifest() {
167
+ return {
168
+ schemaVersion: 1, engineCredit: ENGINE_CREDIT, presetId: this.presetId, seed: this.brief.seed, fps: FRAME.fps,
169
+ resolution: [FRAME.width * this.scale, FRAME.height * this.scale], scale: this.scale,
170
+ samples: this.samples ?? SAMPLING.masterSamples, shutter: SAMPLING.masterShutter,
171
+ renderer: this.renderer?.renderer || '', softwareRenderer: Boolean(this.renderer?.software), chromeFlags: this.renderer?.flags || [],
172
+ previewEncoder: this.previewEncoder || '', audioTier: this.audioGrid ? 'librosa-beat-grid' : 'text-reading-time',
173
+ ...(this.audioGrid ? { beatGrid: this.audioGrid.beats } : { bpm: this.brief.bpm }),
174
+ durationSec: this.durationSec, generatedAt: new Date().toISOString(),
175
+ passRanges: this.plan?.passRanges || [], timeline: this.timeline, warnings: this.warnings,
176
+ lithermes: {
177
+ mode: this.mode, round: this.round, presetReason: this.choice.reason, brief: { path: this.briefPath, sha256: this.briefSha },
178
+ signal: this.signal, events: this.plan?.events || [], shots: this.shotStates || [], egress: this.renderer?.egress, listenError: this.renderer?.listenError,
179
+ chromeSockets: this.renderer?.sockets, previewFps: this.previewFps, previewWidth: this.previewWidth, previewAttempts: this.previewAttempts,
180
+ stills: this.stillFrames, cuts: this.cutFrames, contrastFrames: this.contrastFrames, determinism: this.determinism, perf: this.perf, sound: this.sound?.summary,
181
+ reducedInk: this.reducedInk, posterInk: this.posterInk, accent: this.accent, cache: this.cache, framesViewed: this.framesViewed,
182
+ },
183
+ };
184
+ }
185
+
186
+ composer() {
187
+ const shots = shotsOf(this.timeline);
188
+ let accent = null;
189
+ const host = this.brief.accent === false ? null : shots[typeof this.brief.accent === 'number' ? this.brief.accent : 0];
190
+ if (host && this.preset.palette.accent) {
191
+ const beat = 60 / this.brief.bpm;
192
+ const from = (this.preset.motion.entranceSec ?? 0.18) + 0.1;
193
+ const capSec = Math.floor(0.1 * this.totalFrames) / FRAME.fps;
194
+ const to = Math.min(from + 2 * beat, host.holdSec - 1 / FRAME.fps, from + capSec);
195
+ if (to > from) accent = { shotId: host.id, from: Math.round(from * FRAME.fps) / FRAME.fps, to: Math.round(to * FRAME.fps) / FRAME.fps };
196
+ }
197
+ this.accent = accent;
198
+ return new FrameComposer({
199
+ fonts: this.fonts, strokeFonts: this.strokes, presetId: this.presetId, signal: this.signal, timeline: this.timeline,
200
+ plan: this.plan, fps: FRAME.fps, durationSec: this.durationSec, runSeed: this.brief.seed, software: Boolean(this.renderer?.software),
201
+ brief: this.brief, accent,
202
+ });
203
+ }
204
+
205
+ // MO-D-04 on exactly the elements that will be drawn, before any frame.
206
+ preflight() {
207
+ this.plan = planPasses({ presetId: this.presetId, timeline: this.timeline, runSeed: this.brief.seed, fps: FRAME.fps, software: false, brief: this.brief });
208
+ const composer = this.composer();
209
+ const missing = new Map();
210
+ const check = (text, voice, weight, widthStep) => {
211
+ for (const run of scriptRuns(text)) {
212
+ const font = this.fonts.get(resolveFontId(this.presetId, voice, run.script, weight, widthStep));
213
+ for (const ch of run.text) if (ch.trim() && !font.has(ch)) missing.set(`${ch}|${font.file}`, { ch, font: font.file });
214
+ }
215
+ };
216
+ shotsOf(this.timeline).forEach((_, i) => {
217
+ for (const reduced of [false, true]) {
218
+ const { display } = composer.sceneAt(0, { still: true, reduced, shotIndex: i });
219
+ for (const el of display.texts) check(el.text, el.voice, el.weight, el.widthStep);
220
+ for (const st of display.strokes || []) {
221
+ const font = this.strokes.get(st.font);
222
+ for (const ch of st.text) if (ch.trim() && !font.glyphs.has(ch)) missing.set(`${ch}|${font.file}`, { ch, font: font.file });
223
+ }
224
+ if (display.terminal) for (const text of [display.terminal.title.toUpperCase(), display.terminal.status]) check(text, 'label', 400, 100);
225
+ }
226
+ });
227
+ this.missingGlyphs = [...missing.values()];
228
+ const manifest = this.baseManifest();
229
+ const gate = preflightGate(manifest, { missingGlyphs: this.missingGlyphs });
230
+ if (gate.failed.length) {
231
+ mkdirSync(this.out, { recursive: true });
232
+ writeJson(join(this.out, 'manifest.json'), manifest);
233
+ writeFileSync(join(this.out, 'gate-report.txt'), renderReport(manifest, gate, { preflight: true }));
234
+ throw Object.assign(fail(EXIT.GATE_FAIL_QA, `GATE_FAIL_QA (pre-flight, nothing rendered): ${gate.rules.filter((r) => r.status === 'FAIL').map((r) => `${r.id} ${r.detail}`).join('; ')}`), { failed: gate.failed });
235
+ }
236
+ }
237
+
238
+ async openChrome() {
239
+ mkdirSync(join(this.out, '.run'), { recursive: true });
240
+ this.renderer = await openRenderer({
241
+ runtime: this.require, pageScript: join(skillRoot, 'engine', 'page.js'), profileRoot: join(this.out, '.run', `c${process.pid % 100000}`),
242
+ scale: this.scale, forceSoftware: Boolean(this.flags['force-software']),
243
+ });
244
+ const software = this.renderer.software;
245
+ this.samples = software ? 1 : SAMPLING.masterSamples;
246
+ if (software) this.warnings.push(`software GL detected (${this.renderer.renderer}); renders will be slower, --samples lowered to 1`);
247
+ this.plan = planPasses({ presetId: this.presetId, timeline: this.timeline, runSeed: this.brief.seed, fps: FRAME.fps, software, brief: this.brief });
248
+ const persistence = this.plan.passRanges.some((r) => r.pass === 'crt' && r.params.persistenceEnabled);
249
+ this.shotStates = shotsOf(this.timeline).map((s) => ({ sceneId: s.sceneId, shotIndex: s.shotIndex, stateful: persistence || s.sceneId === 'number-counter', prerollMax: s.sceneId === 'number-counter' ? s.holdSec : persistence ? 2 / FRAME.fps : 0 }));
250
+ this.comp = this.composer();
251
+ this.lastRendered = null;
252
+ }
253
+
254
+ persistenceFor(frame) {
255
+ const range = this.plan.passRanges.find((r) => r.pass === 'crt' && frame >= r.frameStart && frame <= r.frameEnd);
256
+ return range?.params.persistenceEnabled ? range : null;
257
+ }
258
+
259
+ async renderFrame(frame, { samples, settled = null } = {}) {
260
+ const range = settled ? null : this.persistenceFor(frame);
261
+ if (range && !(this.lastRendered && this.lastRendered.frame === frame - 1 && this.lastRendered.samples === samples)) {
262
+ const from = Math.max(range.frameStart, frame - 2);
263
+ for (let f = from; f < frame; f++) {
264
+ const { spec } = this.comp.frameSpec(f, { samples, shutter: SAMPLING.masterShutter });
265
+ spec.order = FILTER_ORDER[this.presetId]; spec.prime = true; spec.resetRing = f === from;
266
+ await this.renderer.frame(spec);
267
+ }
268
+ }
269
+ const { spec, meta } = this.comp.frameSpec(frame, { samples, shutter: SAMPLING.masterShutter, settled });
270
+ spec.order = FILTER_ORDER[this.presetId];
271
+ spec.resetRing = Boolean(range) && !(this.lastRendered && this.lastRendered.frame === frame - 1 && this.lastRendered.samples === samples) && frame === range.frameStart;
272
+ const result = await this.renderer.frame(spec);
273
+ this.lastRendered = settled ? null : { frame, samples };
274
+ const bytes = result.bytes;
275
+ const px = bytes.length / 4;
276
+ const mask = Buffer.alloc(px);
277
+ let ink = 0;
278
+ for (let i = 0, j = 3; i < px; i++, j += 4) { const a = bytes[j]; mask[i] = a; if (a >= 128) ink++; bytes[j] = 255; }
279
+ return { bytes, mask, ink, meta, page: result.meta };
280
+ }
281
+
282
+ shotFrames() {
283
+ return shotsOf(this.timeline).map((s) => {
284
+ const a = Math.round(s.start * FRAME.fps), b = Math.round(s.end * FRAME.fps) - 1;
285
+ return { shot: s, first: a, last: b, rep: Math.max(a, b - 6) };
286
+ });
287
+ }
288
+
289
+ savePng(file, bytes, width, height, opts) {
290
+ mkdirSync(dirname(file), { recursive: true });
291
+ writeFileSync(file, pngEncode(this.PNG, bytes, width, height, opts));
292
+ }
293
+
294
+ async stills() {
295
+ const W = FRAME.width * this.scale, H = FRAME.height * this.scale;
296
+ const dir = join(this.out, 'stills');
297
+ rmSync(dir, { recursive: true, force: true });
298
+ const paths = [];
299
+ this.stillFrames = [];
300
+ for (const [i, s] of this.shotFrames().entries()) {
301
+ const r = await this.renderFrame(s.rep, { samples: SAMPLING.previewSamples });
302
+ const file = join(dir, `${String(i + 1).padStart(2, '0')}-${s.shot.id}-f${s.rep}.png`);
303
+ this.savePng(file, r.bytes, W, H);
304
+ paths.push(file);
305
+ this.stillFrames.push(s.rep);
306
+ }
307
+ return paths;
308
+ }
309
+
310
+ async sheet(cuts = true) {
311
+ const W = FRAME.width * this.scale, H = FRAME.height * this.scale;
312
+ const frames = [];
313
+ if (cuts) for (const s of this.shotFrames().slice(1)) for (const f of [s.first - 6, s.first - 1, s.first, s.first + 6]) frames.push(Math.max(0, Math.min(this.totalFrames - 1, f)));
314
+ if (!frames.length) for (let i = 0; i < 12; i++) frames.push(Math.round((i * (this.totalFrames - 1)) / 11));
315
+ this.cutFrames = this.shotFrames().slice(1).map((s) => s.first);
316
+ const tiles = [];
317
+ for (const f of frames) {
318
+ const r = await this.renderFrame(f, { samples: SAMPLING.previewSamples });
319
+ tiles.push({ data: r.bytes, width: W, height: H, frame: f });
320
+ }
321
+ mkdirSync(join(this.out, 'sheet'), { recursive: true });
322
+ const file = join(this.out, 'sheet', cuts ? 'cuts.png' : 'sheet.png');
323
+ contactSheet(this.PNG, tiles, file);
324
+ return file;
325
+ }
326
+
327
+ // The master: every byte streamed to ffmpeg is the byte hashed and flash-audited.
328
+ async master() {
329
+ const W = FRAME.width * this.scale, H = FRAME.height * this.scale;
330
+ const run = join(this.out, '.run');
331
+ const film = join(run, 'film.mp4');
332
+ const video = join(run, 'video.mp4');
333
+ const encoder = startMaster({ width: W, height: H, fps: FRAME.fps, output: video });
334
+ const detector = new FlashDetector(W, H);
335
+ const previewDir = join(run, 'preview-src');
336
+ rmSync(previewDir, { recursive: true, force: true });
337
+ mkdirSync(previewDir, { recursive: true });
338
+ const previewFrames = [];
339
+ const shots = this.shotFrames();
340
+ const sampled = new Set([...shots.map((s) => s.rep), ...shots.slice(1).map((s) => s.first), 0]);
341
+ this.contrastFrames = [...sampled].sort((a, b) => a - b);
342
+ const LUT = Float64Array.from({ length: 256 }, (_, v) => { const s = v / 255; return s <= 0.04045 ? s / 12.92 : ((s + 0.055) / 1.055) ** 2.4; });
343
+ const passes = this.preset.passes;
344
+ this.dplan = this.directorPlan();
345
+ const planFrames = new Set(this.dplan.frames);
346
+ this.planPngs = new Map();
347
+ for (let f = 0; f < this.totalFrames; f++) {
348
+ const r = await this.renderFrame(f, { samples: this.samples });
349
+ const flash = detector.push(r.bytes);
350
+ const bins = new Uint32Array(1024);
351
+ for (let i = 0; i < r.bytes.length; i += 4) {
352
+ const l = 0.2126 * LUT[r.bytes[i]] + 0.7152 * LUT[r.bytes[i + 1]] + 0.0722 * LUT[r.bytes[i + 2]];
353
+ bins[Math.min(1023, Math.floor(l * 1024))]++;
354
+ }
355
+ let acc = 0, p995 = 1;
356
+ const target = 0.995 * (r.bytes.length / 4);
357
+ for (let i = 0; i < 1024; i++) { acc += bins[i]; if (acc >= target) { p995 = (i + 1) / 1024; break; } }
358
+ if (planFrames.has(f)) this.planPngs.set(f, pngEncode(this.PNG, r.bytes, W, H, { level: 1, scratch: true }));
359
+ await encoder.write(r.bytes);
360
+ if (f % 2 === 0) {
361
+ const small = areaResize(r.bytes, W, H, 960);
362
+ const file = join(previewDir, `s${String(f).padStart(5, '0')}.png`);
363
+ writeFileSync(file, pngEncode(this.PNG, small.data, small.width, small.height, { level: 1, scratch: true }));
364
+ previewFrames[f] = file;
365
+ }
366
+ if (sampled.has(f)) {
367
+ this.savePng(join(run, 'masks', `f${String(f).padStart(5, '0')}.png`), r.mask, W, H, { gray: true });
368
+ this.savePng(join(run, 'frames', `f${String(f).padStart(5, '0')}.png`), r.bytes, W, H);
369
+ for (const box of r.meta.textBoxes) {
370
+ if (!box.settled) continue;
371
+ const m = measureContrast(r.bytes, r.mask, W, H, box, this.scale);
372
+ if (m) this.contrast.push({ frame: f, elementId: box.elementId, ratio: m.ratio, floor: m.floor, fontSizePx: box.fontSizePx, weight: box.weight, fill: box.fill });
373
+ }
374
+ }
375
+ this.records.push({
376
+ frame: f, pass: null, rgbaSha256: sha(r.bytes), textBoxes: r.meta.textBoxes, graphics: r.meta.graphics, block: r.meta.block,
377
+ glyphInk: r.ink, lumP995: Number(p995.toFixed(4)), flash: { general: flash.general, generalBoth: flash.generalBoth, red: flash.red, redBoth: flash.redBoth },
378
+ fullFrameStep: Number(flash.fullFrameStep.toFixed(4)), overrides: r.meta.overrides, accent: r.meta.accent, fills: r.meta.fills,
379
+ sampleTimes: r.meta.sampleTimes, sceneId: r.meta.sceneId, shotIndex: r.meta.shotIndex, renderMs: Number(r.page.renderMs.toFixed(2)),
380
+ });
381
+ for (const pass of passes) {
382
+ const logged = r.page.passes[pass];
383
+ this.records.push({ frame: f, pass, draws: logged?.draws || 0, uniforms: logged?.uniforms || {} });
384
+ }
385
+ if (f % 60 === 59) process.stderr.write(`motion: ${f + 1}/${this.totalFrames} frames\n`);
386
+ }
387
+ const encoded = await encoder.finish();
388
+ if (encoded.code !== 0) throw fail(1, `ffmpeg master encode failed: ${encoded.stderr.split('\n').filter(Boolean).at(-1) || encoded.code}`);
389
+ // Every planned track is muxed here, whatever the --audio tier's state:
390
+ // the beat grid is optional, the soundtrack is not.
391
+ const supplied = this.brief.audio ? (isAbsolute(this.brief.audio) ? this.brief.audio : resolve(dirname(this.briefPath), this.brief.audio)) : null;
392
+ this.sound = await produceSound({
393
+ out: this.out, treatment: this.treatment, fps: FRAME.fps, totalFrames: this.totalFrames,
394
+ cuts: this.shotFrames().slice(1).map((s) => s.first / FRAME.fps), video, output: film, suppliedAudio: supplied,
395
+ });
396
+ rmSync(video, { force: true });
397
+ const preview = encodePreview({ PNG: this.PNG, sourceFrames: previewFrames, masterFps: FRAME.fps, durationSec: this.durationSec, workDir: run,
398
+ minGlyphPx: Math.min(...this.records.flatMap((row) => (row.textBoxes || []).map((b) => b.fontSizePx)).filter(Boolean), 64) });
399
+ rmSync(previewDir, { recursive: true, force: true });
400
+ this.previewAttempts = preview.attempts;
401
+ if (preview.file) {
402
+ this.previewEncoder = preview.encoder; this.previewFps = preview.fps; this.previewWidth = preview.width;
403
+ this.previewRecords = preview.records.map((row) => ({ ...row, preview: true }));
404
+ this.previewName = preview.encoder === 'gif' ? 'preview.gif' : 'preview.webp';
405
+ }
406
+ return film;
407
+ }
408
+
409
+ async stillsForExport() {
410
+ const W = FRAME.width * this.scale, H = FRAME.height * this.scale;
411
+ const shots = shotsOf(this.timeline);
412
+ const poster = await this.renderFrame(Math.round(shots[0].end * FRAME.fps) - 1, { samples: 1, settled: { shotIndex: 0, reduced: false } });
413
+ this.savePng(join(this.out, '.run', 'poster.png'), poster.bytes, W, H, { level: 9 });
414
+ this.posterInk = poster.ink;
415
+ const reduced = await this.renderFrame(this.totalFrames - 1, { samples: 1, settled: { shotIndex: shots.length - 1, reduced: true } });
416
+ this.savePng(join(this.out, '.run', 'reduced-motion.png'), reduced.bytes, W, H, { level: 9 });
417
+ this.savePng(join(this.out, '.run', 'masks', 'reduced.png'), reduced.mask, W, H, { gray: true });
418
+ this.reducedInk = reduced.ink;
419
+ }
420
+
421
+ // MO-C-09 / MO-A-25: each cut frame re-rendered as a seek in a fresh process.
422
+ determinismCheck() {
423
+ const shots = this.shotFrames();
424
+ const frames = [...new Set([0, ...shots.slice(1).map((s) => s.first), ...shots.filter((s) => s.shot.sceneId === 'number-counter').map((s) => Math.round((s.first + s.last) / 2))])].slice(0, 6);
425
+ const byFrame = new Map(this.records.filter((r) => r.pass === null).map((r) => [r.frame, r.rgbaSha256]));
426
+ const child = (frame, software) => {
427
+ const dir = join(this.out, '.run', `det-${frame}${software ? '-sw' : ''}-${Math.random().toString(36).slice(2, 6)}`);
428
+ const args = [fileURLToPath(import.meta.url), 'hash-frame', '--brief', this.briefPath, '--out', dir, '--frame', String(frame), '--samples', String(this.samples), '--scale', String(this.scale)];
429
+ if (software) args.push('--force-software');
430
+ if (this.flags['force-software']) args.push('--force-software');
431
+ const res = spawnSync(process.execPath, args, { encoding: 'utf8', timeout: 600000 });
432
+ rmSync(dir, { recursive: true, force: true });
433
+ const line = (res.stdout || '').split('\n').find((l) => l.startsWith('MOTION_FRAME '));
434
+ if (!line) throw new Error(`determinism child for frame ${frame} failed: ${(res.stderr || '').trim().split('\n').at(-1) || res.status}`);
435
+ return JSON.parse(line.slice('MOTION_FRAME '.length));
436
+ };
437
+ const checks = [];
438
+ for (const frame of frames) {
439
+ const seeked = child(frame, false);
440
+ const sameHost = seeked.renderer === this.renderer.renderer && seeked.flags.join(' ') === this.renderer.flags.join(' ');
441
+ const entry = { frame, sequential: byFrame.get(frame), seeked: seeked.rgbaSha256, match: sameHost && seeked.rgbaSha256 === byFrame.get(frame), renderer: seeked.renderer };
442
+ if (!entry.match) {
443
+ const a = child(frame, true), b = child(frame, true);
444
+ entry.software = { first: a.rgbaSha256, second: b.rgbaSha256, renderer: a.renderer };
445
+ }
446
+ checks.push(entry);
447
+ }
448
+ this.determinism = { checks, samples: this.samples };
449
+ }
450
+
451
+ async perfRun() {
452
+ const times = [];
453
+ for (let i = 0; i < PERF.frames; i++) {
454
+ const f = Math.round((i * (this.totalFrames - 1)) / (PERF.frames - 1));
455
+ this.lastRendered = null;
456
+ const r = await this.renderFrame(f, { samples: 1 });
457
+ times.push(r.page.renderMs);
458
+ }
459
+ times.sort((a, b) => a - b);
460
+ this.perf = { frames: times.length, p50Ms: times[Math.floor(times.length / 2)], p95Ms: times[Math.ceil(times.length * 0.95) - 1], maxMs: times.at(-1), software: this.renderer.software, samples: 1 };
461
+ return this.perf;
462
+ }
463
+
464
+ // The director stills set (craft-loop.md): every shot's midpoint, a strip
465
+ // per cut, the contact sheet and the poster.
466
+ directorPlan() {
467
+ const beats = this.shotFrames().map((s, index) => ({ index, first: s.first, last: s.last, mid: Math.round((s.first + s.last) / 2) }));
468
+ return stillsPlan({ totalFrames: this.totalFrames, beats });
469
+ }
470
+
471
+ async directorStillsOnly() {
472
+ const W = FRAME.width * this.scale, H = FRAME.height * this.scale;
473
+ const plan = this.directorPlan();
474
+ const pngs = new Map();
475
+ for (const f of plan.frames) {
476
+ const r = await this.renderFrame(f, { samples: SAMPLING.previewSamples });
477
+ pngs.set(f, pngEncode(this.PNG, r.bytes, W, H, { level: 1, scratch: true }));
478
+ }
479
+ const shots = shotsOf(this.timeline);
480
+ const poster = await this.renderFrame(Math.round(shots[0].end * FRAME.fps) - 1, { samples: 1, settled: { shotIndex: 0, reduced: false } });
481
+ return writeStillsSet({ out: this.out, PNG: this.PNG, pngs, plan, size: [W, H], round: this.round, mode: 'stills-only', posterPng: pngEncode(this.PNG, poster.bytes, W, H) });
482
+ }
483
+
484
+ directorStillsFromMaster() {
485
+ const W = FRAME.width * this.scale, H = FRAME.height * this.scale;
486
+ return writeStillsSet({ out: this.out, PNG: this.PNG, pngs: this.planPngs, plan: this.dplan, size: [W, H], round: this.round, mode: this.mode, posterPng: readFileSync(join(this.out, '.run', 'poster.png')) });
487
+ }
488
+
489
+ gateNow() {
490
+ const manifest = this.baseManifest();
491
+ const where = (name) => [join(this.out, '.run', name), join(this.out, name), join(this.out, 'withheld', name)].find((p) => existsSync(p));
492
+ const films = where('film.mp4'), prev = this.previewName && where(this.previewName), poster = where('poster.png'), reduced = where('reduced-motion.png');
493
+ const exports = {
494
+ probe: films ? ffprobe(films) : null,
495
+ sizes: { film: films && statSync(films).size, preview: prev && statSync(prev).size, poster: poster && statSync(poster).size, reduced: reduced && statSync(reduced).size },
496
+ present: { film: Boolean(films), preview: Boolean(prev), poster: Boolean(poster), reduced: Boolean(reduced), manifest: true },
497
+ };
498
+ const notice = existsSync(join(skillRoot, 'engine', 'NOTICE')) && sha(readFileSync(join(skillRoot, 'engine', 'NOTICE'))) === NOTICE_SHA;
499
+ const gate = runGate({ manifest, records: this.records, preview: this.previewRecords, exports, contrast: this.contrast, preflight: { missingGlyphs: this.missingGlyphs || [] }, notice });
500
+ gate.rules.push(...(this.sound?.rules || []));
501
+ gate.failed = gate.rules.filter((r) => r.status === 'FAIL').map((r) => r.id);
502
+ return { manifest, gate, exports };
503
+ }
504
+
505
+ writeOutputs(manifest, gate, { keepManifest = false } = {}) {
506
+ if (!keepManifest) writeJson(join(this.out, 'manifest.json'), manifest);
507
+ writeFileSync(join(this.out, 'render.jsonl'), [...this.records, ...this.previewRecords].map((row) => JSON.stringify(row)).join('\n') + '\n');
508
+ const outputs = gate.withhold
509
+ ? { film: 'withheld/film.mp4', preview: `withheld/${this.previewName || 'preview.webp'}`, poster: 'withheld/poster.png', reduced: 'withheld/reduced-motion.png' }
510
+ : { film: 'film.mp4', preview: this.previewName || 'preview (not produced)', poster: 'poster.png', reduced: 'reduced-motion.png' };
511
+ const looked = viewedFiles(this.out);
512
+ writeFileSync(join(this.out, 'gate-report.txt'), renderReport(manifest, gate, { outputs, framesViewed: looked.length ? looked : this.framesViewed, egress: this.renderer?.egress, withheld: gate.withhold }));
513
+ }
514
+ }
515
+
516
+ // Type path: the treatment comes first. Without --brief the engine brief is
517
+ // DIR/brief.json, written from the treatment's copy the first time and then
518
+ // yours to refine (scenes, style, accent).
519
+ function typePathTreatment(session) {
520
+ const { treatment } = loadTreatment(session.out, EXIT.BLOCKED_TREATMENT_INVALID);
521
+ if (treatment.path !== 'type') {
522
+ throw fail(EXIT.BLOCKED_TREATMENT_INVALID, 'BLOCKED_TREATMENT_INVALID: field path: this treatment takes the stage path; render it with `stage --out DIR`');
523
+ }
524
+ recordFirstTreatment(session.out, treatment);
525
+ session.treatment = treatment;
526
+ if (!session.flags.brief) {
527
+ const derived = join(session.out, 'brief.json');
528
+ if (!existsSync(derived)) writeJson(derived, { text: treatment.copy.lines, durationSec: treatment.durationSec });
529
+ session.flags.brief = derived;
530
+ }
531
+ }
532
+
533
+ function writeState(out, state) {
534
+ if (!out) return;
535
+ mkdirSync(out, { recursive: true });
536
+ writeJson(join(out, 'run-state.json'), { ...state, finishedAt: new Date().toISOString() });
537
+ }
538
+
539
+ async function main(argv) {
540
+ const flags = parseArgs(argv);
541
+ const mode = flags._[0];
542
+ if (!mode || flags.help || mode === 'help') { console.log(USAGE); return 0; }
543
+ if (mode === 'complete') return completeCommand(resolve(flags.out || 'motion-output'));
544
+ if (mode === 'stage') return stageCommand(flags);
545
+ if (mode === 'sound') return soundCommand(flags);
546
+ if (mode === 'look') return lookCommand(flags);
547
+ if (!['run', 'stills', 'sheet', 'video', 'perf', 'gate', 'hash-frame'].includes(mode)) { console.error(USAGE); return 2; }
548
+ if (mode === 'gate') return regate(flags);
549
+ const session = new Session(flags, flags['stills-only'] ? 'stills-only' : mode);
550
+ const stateOut = mode === 'hash-frame' ? null : session.out;
551
+ if (stateOut) writeState(stateOut, { exitCode: null, mode: session.mode, round: session.round, finished: false });
552
+ try {
553
+ if (mode !== 'hash-frame') typePathTreatment(session);
554
+ session.prepare();
555
+ if (mode !== 'hash-frame') session.preflight();
556
+ const ffmpeg = hasFfmpeg();
557
+ if (mode === 'video' && !ffmpeg) throw fail(EXIT.BLOCKED_NO_FFMPEG_FOR_VIDEO, 'BLOCKED_NO_FFMPEG_FOR_VIDEO: ffmpeg is not on PATH; `stills` and `sheet` still work, install ffmpeg for the film');
558
+ await session.openChrome();
559
+ try {
560
+ if (mode === 'hash-frame') {
561
+ const frame = Number(flags.frame);
562
+ if (!Number.isInteger(frame) || frame < 0 || frame >= session.totalFrames) throw fail(2, '--frame must name a frame of this film');
563
+ session.samples = Number(flags.samples || session.samples);
564
+ // --from K renders K..frame sequentially in this one process (a video-mode
565
+ // frame line); without it the frame is a cold seek (MO-A-25, MO-C-09).
566
+ const from = flags.from == null ? frame : Number(flags.from);
567
+ let r;
568
+ for (let f = Math.max(0, Math.min(from, frame)); f <= frame; f++) r = await session.renderFrame(f, { samples: session.samples });
569
+ console.log(`MOTION_FRAME ${JSON.stringify({ frame, rgbaSha256: sha(r.bytes), renderer: session.renderer.renderer, flags: session.renderer.flags, egress: session.renderer.egress })}`);
570
+ return 0;
571
+ }
572
+ if (mode === 'perf') {
573
+ const perf = await session.perfRun();
574
+ mkdirSync(session.out, { recursive: true });
575
+ writeJson(join(session.out, 'perf.json'), { ...perf, renderer: session.renderer.renderer, flags: session.renderer.flags });
576
+ console.log(`motion perf: p95 ${perf.p95Ms.toFixed(1)} ms (p50 ${perf.p50Ms.toFixed(1)}, max ${perf.maxMs.toFixed(1)}) over ${perf.frames} frames at samples 1; renderer ${session.renderer.renderer}`);
577
+ const ceiling = perf.software ? PERF.softwareP95Ms : PERF.hardwareP95Ms;
578
+ writeState(session.out, { exitCode: perf.p95Ms > ceiling ? 13 : 0, mode, round: session.round, finished: true, failed: perf.p95Ms > ceiling ? ['MO-D-02'] : [] });
579
+ return perf.p95Ms > ceiling ? 13 : 0;
580
+ }
581
+ if (mode === 'run' || mode === 'stills') {
582
+ const stills = await session.stills();
583
+ console.log(`stills: ${stills.join(' ')}`);
584
+ }
585
+ if (mode === 'run' || mode === 'sheet') {
586
+ const sheet = await session.sheet(mode === 'run' || Boolean(flags.cuts));
587
+ console.log(`sheet: ${sheet}`);
588
+ }
589
+ if (mode === 'run' && flags['stills-only']) {
590
+ const set = await session.directorStillsOnly();
591
+ console.log(`stills set: ${set.files.map((f) => join(session.out, f.file)).join(' ')}`);
592
+ }
593
+ if (mode === 'stills' || mode === 'sheet' || flags['stills-only']) {
594
+ writeJson(join(session.out, 'manifest.json'), session.baseManifest());
595
+ if (mode === 'run') stampStills(session.out);
596
+ writeState(session.out, { exitCode: 0, mode: session.mode, round: session.round, finished: true, failed: [] });
597
+ console.log('View every still, strip and the contact sheet with your image tool, then record the round with `look` before the full render.');
598
+ return 0;
599
+ }
600
+ if (!ffmpeg) {
601
+ writeJson(join(session.out, 'manifest.json'), session.baseManifest());
602
+ throw fail(EXIT.BLOCKED_NO_FFMPEG_FOR_VIDEO, `BLOCKED_NO_FFMPEG_FOR_VIDEO: stills and the cut sheet are in ${session.out}; ffmpeg is not on PATH, so no film was encoded`);
603
+ }
604
+ await session.master();
605
+ await session.stillsForExport();
606
+ await session.perfRun();
607
+ session.determinismCheck();
608
+ if (mode === 'run') session.directorStillsFromMaster();
609
+ const { manifest, gate } = session.gateNow();
610
+ promoteExports(session.out, { withhold: gate.withhold, previewName: session.previewName || 'preview.webp' });
611
+ session.writeOutputs(manifest, gate);
612
+ if (mode === 'run') stampStills(session.out);
613
+ const code = gate.failed.length ? EXIT.GATE_FAIL_QA : EXIT.OK;
614
+ writeState(session.out, { exitCode: code, mode: session.mode, round: session.round, finished: true, failed: gate.failed, withheld: gate.withhold });
615
+ console.log(`motion ${gate.failed.length ? `QA FAIL (${gate.failed.join(', ')})` : 'QA PASS'}; report ${join(session.out, 'gate-report.txt')}${gate.withhold ? '; exports WITHHELD in withheld/' : ''}`);
616
+ if (gate.failed.length && session.round >= 3) console.log(gate.withhold ? 'Round 3 of 3: the render is withheld pending a fix of the flash failure.' : 'Round 3 of 3: stop and hand back the report with the delivered artifacts.');
617
+ else if (gate.failed.length) console.log(`Fix the named rules and rerun with --round ${session.round + 1}.`);
618
+ return code;
619
+ } finally { await session.renderer.close(); }
620
+ } catch (error) {
621
+ const code = error.exitCode ?? 1;
622
+ console.error(error.exitCode ? error.message : `motion internal error: ${error.stack || error.message}`);
623
+ if (stateOut) writeState(stateOut, { exitCode: code, mode: session.mode, round: session.round, finished: true, failed: error.failed || [], message: String(error.message).split('\n')[0] });
624
+ return code;
625
+ }
626
+ }
627
+
628
+ // `gate`: re-measure contrast from the saved masks, rerun determinism and perf,
629
+ // and rewrite the report for an existing output directory.
630
+ async function regate(flags) {
631
+ const out = resolve(flags.out || 'motion-output');
632
+ const manifestPath = join(out, 'manifest.json');
633
+ if (!existsSync(manifestPath) || !existsSync(join(out, 'render.jsonl'))) { console.error(`no finished render in ${out}`); return 2; }
634
+ const manifest = JSON.parse(readFileSync(manifestPath, 'utf8'));
635
+ if (manifest.path === 'stage') return stageRegate(out);
636
+ const session = new Session({ ...flags, brief: manifest.lithermes.brief.path, round: manifest.lithermes.round, scale: manifest.scale }, manifest.lithermes.mode);
637
+ try {
638
+ session.prepare();
639
+ session.preflight();
640
+ const rows = readFileSync(join(out, 'render.jsonl'), 'utf8').trim().split('\n').map((line) => JSON.parse(line));
641
+ session.records = rows.filter((r) => !r.preview);
642
+ session.previewRecords = rows.filter((r) => r.preview);
643
+ session.previewEncoder = manifest.previewEncoder; session.previewFps = manifest.lithermes.previewFps; session.previewWidth = manifest.lithermes.previewWidth;
644
+ session.previewName = manifest.previewEncoder === 'gif' ? 'preview.gif' : 'preview.webp';
645
+ session.reducedInk = manifest.lithermes.reducedInk; session.posterInk = manifest.lithermes.posterInk;
646
+ session.framesViewed = manifest.lithermes.framesViewed || [];
647
+ session.stillFrames = manifest.lithermes.stills; session.cutFrames = manifest.lithermes.cuts; session.contrastFrames = manifest.lithermes.contrastFrames;
648
+ const W = FRAME.width * session.scale, H = FRAME.height * session.scale;
649
+ for (const f of session.contrastFrames || []) {
650
+ const framePng = join(out, '.run', 'frames', `f${String(f).padStart(5, '0')}.png`), maskPng = join(out, '.run', 'masks', `f${String(f).padStart(5, '0')}.png`);
651
+ if (!existsSync(framePng) || !existsSync(maskPng)) continue;
652
+ const rgba = pngDecode(session.PNG, framePng).data, maskImg = pngDecode(session.PNG, maskPng).data;
653
+ const mask = Buffer.alloc(W * H);
654
+ for (let i = 0; i < mask.length; i++) mask[i] = maskImg[i * 4];
655
+ const row = session.records.find((r) => r.pass === null && r.frame === f);
656
+ for (const box of row?.textBoxes || []) {
657
+ if (!box.settled) continue;
658
+ const m = measureContrast(rgba, mask, W, H, box, session.scale);
659
+ if (m) session.contrast.push({ frame: f, elementId: box.elementId, ratio: m.ratio, floor: m.floor, fontSizePx: box.fontSizePx, weight: box.weight, fill: box.fill });
660
+ }
661
+ }
662
+ if (flags['no-rerender']) { session.determinism = manifest.lithermes.determinism; session.perf = manifest.lithermes.perf; session.renderer = { renderer: manifest.renderer, flags: manifest.chromeFlags, software: manifest.softwareRenderer, egress: manifest.lithermes.egress }; }
663
+ else {
664
+ await session.openChrome();
665
+ try { await session.perfRun(); } finally { await session.renderer.close(); }
666
+ session.determinismCheck();
667
+ }
668
+ session.plan = { passRanges: manifest.passRanges, events: manifest.lithermes.events };
669
+ const planned = manifest.lithermes.sound;
670
+ const filmFile = [join(out, 'film.mp4'), join(out, 'withheld', 'film.mp4')].find((f) => existsSync(f));
671
+ session.sound = { summary: planned, rules: planned && planned.mode !== 'none' && filmFile ? soundGate({ file: filmFile, mode: planned.mode }).rules : [{ id: 'sound-stream', status: 'PASS', detail: 'no sound planned' }] };
672
+ session.shotStates = manifest.lithermes.shots;
673
+ session.samples = manifest.samples;
674
+ const { manifest: fresh, gate } = session.gateNow();
675
+ session.writeOutputs({ ...fresh, generatedAt: manifest.generatedAt }, gate, { keepManifest: true });
676
+ console.log(readFileSync(join(out, 'gate-report.txt'), 'utf8'));
677
+ writeState(out, { exitCode: gate.failed.length ? 13 : 0, mode: manifest.lithermes.mode, round: manifest.lithermes.round, finished: true, failed: gate.failed, withheld: gate.withhold });
678
+ return gate.failed.length ? EXIT.GATE_FAIL_QA : EXIT.OK;
679
+ } catch (error) {
680
+ console.error(error.exitCode ? error.message : `motion internal error: ${error.stack || error.message}`);
681
+ return error.exitCode ?? 1;
682
+ }
683
+ }
684
+
685
+ function isMain() {
686
+ try { return realpathSync(process.argv[1]) === realpathSync(fileURLToPath(import.meta.url)); } catch { return false; }
687
+ }
688
+ if (isMain()) process.exitCode = await main(process.argv.slice(2));
689
+
690
+ export { main, parseArgs, USAGE };