@litfamily/lithermes 1.0.8 → 1.0.10

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 (653) hide show
  1. package/README.md +312 -13
  2. package/README_Ko-KR.md +313 -14
  3. package/assets/lithermes-plugin/README.md +40 -6
  4. package/assets/lithermes-plugin/__init__.py +126 -26
  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 +62 -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/jev_hint.py +461 -0
  16. package/assets/lithermes-plugin/lit_mark.py +1 -1
  17. package/assets/lithermes-plugin/motion_receipts.py +80 -0
  18. package/assets/lithermes-plugin/payload-version.json +2244 -64
  19. package/assets/lithermes-plugin/plugin.yaml +1 -1
  20. package/assets/lithermes-plugin/rules/bundled-rules/lit-humanizer.md +14 -0
  21. package/assets/lithermes-plugin/skills/autoconference/assets/report_template.md +2 -1
  22. package/assets/lithermes-plugin/skills/autoconference/modes/ship/SKILL.md +11 -8
  23. package/assets/lithermes-plugin/skills/autoresearch/modes/ship/type-checklists.md +2 -2
  24. package/assets/lithermes-plugin/skills/browser-drive/ORIGIN.json +17 -0
  25. package/assets/lithermes-plugin/skills/browser-drive/SKILL.md +41 -16
  26. package/assets/lithermes-plugin/skills/browser-drive/scripts/capability_probe.py +122 -10
  27. package/assets/lithermes-plugin/skills/frontend-ui-ux/SKILL.md +45 -13
  28. package/assets/lithermes-plugin/skills/frontend-ui-ux/examples/phase-3-readme-ab/README.md +51 -0
  29. package/assets/lithermes-plugin/skills/frontend-ui-ux/references/README.md +44 -0
  30. package/assets/lithermes-plugin/skills/frontend-ui-ux/references/adaptive-layout.md +34 -62
  31. package/assets/lithermes-plugin/skills/frontend-ui-ux/references/brand-and-imagery.md +22 -70
  32. package/assets/lithermes-plugin/skills/frontend-ui-ux/references/complete-contract.md +18 -4
  33. package/assets/lithermes-plugin/skills/frontend-ui-ux/references/composition.md +27 -78
  34. package/assets/lithermes-plugin/skills/frontend-ui-ux/references/craft-floor.md +74 -0
  35. package/assets/lithermes-plugin/skills/frontend-ui-ux/references/creative-directions.md +25 -69
  36. package/assets/lithermes-plugin/skills/frontend-ui-ux/references/evidence-review.md +18 -97
  37. package/assets/lithermes-plugin/skills/frontend-ui-ux/references/implementation-platforms.md +23 -83
  38. package/assets/lithermes-plugin/skills/frontend-ui-ux/references/inclusive-interface.md +22 -70
  39. package/assets/lithermes-plugin/skills/frontend-ui-ux/references/interaction-motion.md +34 -68
  40. package/assets/lithermes-plugin/skills/frontend-ui-ux/references/motion-guide.md +62 -0
  41. package/assets/lithermes-plugin/skills/frontend-ui-ux/references/operating-lanes.md +14 -78
  42. package/assets/lithermes-plugin/skills/frontend-ui-ux/references/performance-delivery.md +22 -71
  43. package/assets/lithermes-plugin/skills/frontend-ui-ux/references/product-direction.md +17 -70
  44. package/assets/lithermes-plugin/skills/frontend-ui-ux/references/production.md +19 -7
  45. package/assets/lithermes-plugin/skills/frontend-ui-ux/references/redesign-playbook.md +23 -76
  46. package/assets/lithermes-plugin/skills/frontend-ui-ux/references/slop-register.md +69 -0
  47. package/assets/lithermes-plugin/skills/frontend-ui-ux/references/system-foundations.md +22 -67
  48. package/assets/lithermes-plugin/skills/frontend-ui-ux/references/visual-language.md +16 -72
  49. package/assets/lithermes-plugin/skills/frontend-ui-ux/references/visual-reconstruction.md +16 -81
  50. package/assets/lithermes-plugin/skills/frontend-ui-ux/resources/THIRD-PARTY-NOTICE.txt +15 -0
  51. package/assets/lithermes-plugin/skills/frontend-ui-ux/scripts/probe-page.js +311 -0
  52. package/assets/lithermes-plugin/skills/frontend-ui-ux/scripts/probe-rules.json +46 -0
  53. package/assets/lithermes-plugin/skills/frontend-ui-ux/scripts/probe.mjs +231 -0
  54. package/assets/lithermes-plugin/skills/lit-comprehend/SKILL.md +36 -25
  55. package/assets/lithermes-plugin/skills/lit-comprehend/references/artifact-template.md +45 -87
  56. package/assets/lithermes-plugin/skills/lit-comprehend/scripts/verify-explainer.py +3 -27
  57. package/assets/lithermes-plugin/skills/lit-diagram-drawer/NOTICE +33 -0
  58. package/assets/lithermes-plugin/skills/lit-diagram-drawer/SKILL.md +308 -0
  59. package/assets/lithermes-plugin/skills/lit-diagram-drawer/assets/examples/type-architecture-dark.html +1 -0
  60. package/assets/lithermes-plugin/skills/lit-diagram-drawer/assets/examples/type-architecture-full.html +1 -0
  61. package/assets/lithermes-plugin/skills/lit-diagram-drawer/assets/examples/type-architecture-light.html +1 -0
  62. package/assets/lithermes-plugin/skills/lit-diagram-drawer/assets/examples/type-bar-dark.html +1 -0
  63. package/assets/lithermes-plugin/skills/lit-diagram-drawer/assets/examples/type-bar-full.html +1 -0
  64. package/assets/lithermes-plugin/skills/lit-diagram-drawer/assets/examples/type-bar-light.html +1 -0
  65. package/assets/lithermes-plugin/skills/lit-diagram-drawer/assets/examples/type-beeswarm-dark.html +1 -0
  66. package/assets/lithermes-plugin/skills/lit-diagram-drawer/assets/examples/type-beeswarm-full.html +1 -0
  67. package/assets/lithermes-plugin/skills/lit-diagram-drawer/assets/examples/type-beeswarm-light.html +1 -0
  68. package/assets/lithermes-plugin/skills/lit-diagram-drawer/assets/examples/type-bubble-dark.html +1 -0
  69. package/assets/lithermes-plugin/skills/lit-diagram-drawer/assets/examples/type-bubble-full.html +1 -0
  70. package/assets/lithermes-plugin/skills/lit-diagram-drawer/assets/examples/type-bubble-light.html +1 -0
  71. package/assets/lithermes-plugin/skills/lit-diagram-drawer/assets/examples/type-bump-dark.html +1 -0
  72. package/assets/lithermes-plugin/skills/lit-diagram-drawer/assets/examples/type-bump-full.html +1 -0
  73. package/assets/lithermes-plugin/skills/lit-diagram-drawer/assets/examples/type-bump-light.html +1 -0
  74. package/assets/lithermes-plugin/skills/lit-diagram-drawer/assets/examples/type-data-flow-dark.html +1 -0
  75. package/assets/lithermes-plugin/skills/lit-diagram-drawer/assets/examples/type-data-flow-full.html +1 -0
  76. package/assets/lithermes-plugin/skills/lit-diagram-drawer/assets/examples/type-data-flow-light.html +1 -0
  77. package/assets/lithermes-plugin/skills/lit-diagram-drawer/assets/examples/type-datalake-dark.html +1 -0
  78. package/assets/lithermes-plugin/skills/lit-diagram-drawer/assets/examples/type-datalake-full.html +1 -0
  79. package/assets/lithermes-plugin/skills/lit-diagram-drawer/assets/examples/type-datalake-light.html +1 -0
  80. package/assets/lithermes-plugin/skills/lit-diagram-drawer/assets/examples/type-db-schema-dark.html +1 -0
  81. package/assets/lithermes-plugin/skills/lit-diagram-drawer/assets/examples/type-db-schema-full.html +1 -0
  82. package/assets/lithermes-plugin/skills/lit-diagram-drawer/assets/examples/type-db-schema-light.html +1 -0
  83. package/assets/lithermes-plugin/skills/lit-diagram-drawer/assets/examples/type-dependency-dark.html +1 -0
  84. package/assets/lithermes-plugin/skills/lit-diagram-drawer/assets/examples/type-dependency-full.html +1 -0
  85. package/assets/lithermes-plugin/skills/lit-diagram-drawer/assets/examples/type-dependency-light.html +1 -0
  86. package/assets/lithermes-plugin/skills/lit-diagram-drawer/assets/examples/type-deployment-dark.html +1 -0
  87. package/assets/lithermes-plugin/skills/lit-diagram-drawer/assets/examples/type-deployment-full.html +1 -0
  88. package/assets/lithermes-plugin/skills/lit-diagram-drawer/assets/examples/type-deployment-light.html +1 -0
  89. package/assets/lithermes-plugin/skills/lit-diagram-drawer/assets/examples/type-dp-integration-dark.html +1 -0
  90. package/assets/lithermes-plugin/skills/lit-diagram-drawer/assets/examples/type-dp-integration-full.html +1 -0
  91. package/assets/lithermes-plugin/skills/lit-diagram-drawer/assets/examples/type-dp-integration-light.html +1 -0
  92. package/assets/lithermes-plugin/skills/lit-diagram-drawer/assets/examples/type-dp-security-matrix-dark.html +1 -0
  93. package/assets/lithermes-plugin/skills/lit-diagram-drawer/assets/examples/type-dp-security-matrix-full.html +1 -0
  94. package/assets/lithermes-plugin/skills/lit-diagram-drawer/assets/examples/type-dp-security-matrix-light.html +1 -0
  95. package/assets/lithermes-plugin/skills/lit-diagram-drawer/assets/examples/type-er-dark.html +1 -0
  96. package/assets/lithermes-plugin/skills/lit-diagram-drawer/assets/examples/type-er-full.html +1 -0
  97. package/assets/lithermes-plugin/skills/lit-diagram-drawer/assets/examples/type-er-light.html +1 -0
  98. package/assets/lithermes-plugin/skills/lit-diagram-drawer/assets/examples/type-fishbone-dark.html +1 -0
  99. package/assets/lithermes-plugin/skills/lit-diagram-drawer/assets/examples/type-fishbone-full.html +1 -0
  100. package/assets/lithermes-plugin/skills/lit-diagram-drawer/assets/examples/type-fishbone-light.html +1 -0
  101. package/assets/lithermes-plugin/skills/lit-diagram-drawer/assets/examples/type-flowchart-dark.html +1 -0
  102. package/assets/lithermes-plugin/skills/lit-diagram-drawer/assets/examples/type-flowchart-full.html +1 -0
  103. package/assets/lithermes-plugin/skills/lit-diagram-drawer/assets/examples/type-flowchart-light.html +1 -0
  104. package/assets/lithermes-plugin/skills/lit-diagram-drawer/assets/examples/type-gantt-dark.html +1 -0
  105. package/assets/lithermes-plugin/skills/lit-diagram-drawer/assets/examples/type-gantt-full.html +1 -0
  106. package/assets/lithermes-plugin/skills/lit-diagram-drawer/assets/examples/type-gantt-light.html +1 -0
  107. package/assets/lithermes-plugin/skills/lit-diagram-drawer/assets/examples/type-heatmap-dark.html +1 -0
  108. package/assets/lithermes-plugin/skills/lit-diagram-drawer/assets/examples/type-heatmap-full.html +1 -0
  109. package/assets/lithermes-plugin/skills/lit-diagram-drawer/assets/examples/type-heatmap-light.html +1 -0
  110. package/assets/lithermes-plugin/skills/lit-diagram-drawer/assets/examples/type-high-level-dark.html +1 -0
  111. package/assets/lithermes-plugin/skills/lit-diagram-drawer/assets/examples/type-high-level-full.html +1 -0
  112. package/assets/lithermes-plugin/skills/lit-diagram-drawer/assets/examples/type-high-level-light.html +1 -0
  113. package/assets/lithermes-plugin/skills/lit-diagram-drawer/assets/examples/type-high-level-vertical-dark.html +1 -0
  114. package/assets/lithermes-plugin/skills/lit-diagram-drawer/assets/examples/type-high-level-vertical-full.html +1 -0
  115. package/assets/lithermes-plugin/skills/lit-diagram-drawer/assets/examples/type-high-level-vertical-light.html +1 -0
  116. package/assets/lithermes-plugin/skills/lit-diagram-drawer/assets/examples/type-import-drawio-dark.html +1 -0
  117. package/assets/lithermes-plugin/skills/lit-diagram-drawer/assets/examples/type-import-drawio-full.html +1 -0
  118. package/assets/lithermes-plugin/skills/lit-diagram-drawer/assets/examples/type-import-drawio-light.html +1 -0
  119. package/assets/lithermes-plugin/skills/lit-diagram-drawer/assets/examples/type-import-excalidraw-dark.html +1 -0
  120. package/assets/lithermes-plugin/skills/lit-diagram-drawer/assets/examples/type-import-excalidraw-full.html +1 -0
  121. package/assets/lithermes-plugin/skills/lit-diagram-drawer/assets/examples/type-import-excalidraw-light.html +1 -0
  122. package/assets/lithermes-plugin/skills/lit-diagram-drawer/assets/examples/type-import-mermaid-dark.html +1 -0
  123. package/assets/lithermes-plugin/skills/lit-diagram-drawer/assets/examples/type-import-mermaid-full.html +1 -0
  124. package/assets/lithermes-plugin/skills/lit-diagram-drawer/assets/examples/type-import-mermaid-light.html +1 -0
  125. package/assets/lithermes-plugin/skills/lit-diagram-drawer/assets/examples/type-it-state-dark.html +1 -0
  126. package/assets/lithermes-plugin/skills/lit-diagram-drawer/assets/examples/type-it-state-full.html +1 -0
  127. package/assets/lithermes-plugin/skills/lit-diagram-drawer/assets/examples/type-it-state-light.html +1 -0
  128. package/assets/lithermes-plugin/skills/lit-diagram-drawer/assets/examples/type-journey-dark.html +1 -0
  129. package/assets/lithermes-plugin/skills/lit-diagram-drawer/assets/examples/type-journey-full.html +1 -0
  130. package/assets/lithermes-plugin/skills/lit-diagram-drawer/assets/examples/type-journey-light.html +1 -0
  131. package/assets/lithermes-plugin/skills/lit-diagram-drawer/assets/examples/type-kanban-dark.html +1 -0
  132. package/assets/lithermes-plugin/skills/lit-diagram-drawer/assets/examples/type-kanban-full.html +1 -0
  133. package/assets/lithermes-plugin/skills/lit-diagram-drawer/assets/examples/type-kanban-light.html +1 -0
  134. package/assets/lithermes-plugin/skills/lit-diagram-drawer/assets/examples/type-layers-dark.html +1 -0
  135. package/assets/lithermes-plugin/skills/lit-diagram-drawer/assets/examples/type-layers-full.html +1 -0
  136. package/assets/lithermes-plugin/skills/lit-diagram-drawer/assets/examples/type-layers-light.html +1 -0
  137. package/assets/lithermes-plugin/skills/lit-diagram-drawer/assets/examples/type-line-dark.html +1 -0
  138. package/assets/lithermes-plugin/skills/lit-diagram-drawer/assets/examples/type-line-full.html +1 -0
  139. package/assets/lithermes-plugin/skills/lit-diagram-drawer/assets/examples/type-line-light.html +1 -0
  140. package/assets/lithermes-plugin/skills/lit-diagram-drawer/assets/examples/type-loop-dark.html +1 -0
  141. package/assets/lithermes-plugin/skills/lit-diagram-drawer/assets/examples/type-loop-full.html +1 -0
  142. package/assets/lithermes-plugin/skills/lit-diagram-drawer/assets/examples/type-loop-light.html +1 -0
  143. package/assets/lithermes-plugin/skills/lit-diagram-drawer/assets/examples/type-loop-terminal-dark.html +1 -0
  144. package/assets/lithermes-plugin/skills/lit-diagram-drawer/assets/examples/type-loop-terminal-full.html +1 -0
  145. package/assets/lithermes-plugin/skills/lit-diagram-drawer/assets/examples/type-loop-terminal-light.html +1 -0
  146. package/assets/lithermes-plugin/skills/lit-diagram-drawer/assets/examples/type-marimekko-dark.html +1 -0
  147. package/assets/lithermes-plugin/skills/lit-diagram-drawer/assets/examples/type-marimekko-full.html +1 -0
  148. package/assets/lithermes-plugin/skills/lit-diagram-drawer/assets/examples/type-marimekko-light.html +1 -0
  149. package/assets/lithermes-plugin/skills/lit-diagram-drawer/assets/examples/type-medallion-dark.html +1 -0
  150. package/assets/lithermes-plugin/skills/lit-diagram-drawer/assets/examples/type-medallion-full.html +1 -0
  151. package/assets/lithermes-plugin/skills/lit-diagram-drawer/assets/examples/type-medallion-light.html +1 -0
  152. package/assets/lithermes-plugin/skills/lit-diagram-drawer/assets/examples/type-nested-dark.html +1 -0
  153. package/assets/lithermes-plugin/skills/lit-diagram-drawer/assets/examples/type-nested-full.html +1 -0
  154. package/assets/lithermes-plugin/skills/lit-diagram-drawer/assets/examples/type-nested-light.html +1 -0
  155. package/assets/lithermes-plugin/skills/lit-diagram-drawer/assets/examples/type-org-chart-dark.html +1 -0
  156. package/assets/lithermes-plugin/skills/lit-diagram-drawer/assets/examples/type-org-chart-full.html +1 -0
  157. package/assets/lithermes-plugin/skills/lit-diagram-drawer/assets/examples/type-org-chart-light.html +1 -0
  158. package/assets/lithermes-plugin/skills/lit-diagram-drawer/assets/examples/type-paved-road-animated-dark.html +1 -0
  159. package/assets/lithermes-plugin/skills/lit-diagram-drawer/assets/examples/type-paved-road-animated-full.html +1 -0
  160. package/assets/lithermes-plugin/skills/lit-diagram-drawer/assets/examples/type-paved-road-animated-light.html +1 -0
  161. package/assets/lithermes-plugin/skills/lit-diagram-drawer/assets/examples/type-polar-dark.html +1 -0
  162. package/assets/lithermes-plugin/skills/lit-diagram-drawer/assets/examples/type-polar-full.html +1 -0
  163. package/assets/lithermes-plugin/skills/lit-diagram-drawer/assets/examples/type-polar-light.html +1 -0
  164. package/assets/lithermes-plugin/skills/lit-diagram-drawer/assets/examples/type-policy-trace-animated-dark.html +1 -0
  165. package/assets/lithermes-plugin/skills/lit-diagram-drawer/assets/examples/type-policy-trace-animated-full.html +1 -0
  166. package/assets/lithermes-plugin/skills/lit-diagram-drawer/assets/examples/type-policy-trace-animated-light.html +1 -0
  167. package/assets/lithermes-plugin/skills/lit-diagram-drawer/assets/examples/type-process-dark.html +1 -0
  168. package/assets/lithermes-plugin/skills/lit-diagram-drawer/assets/examples/type-process-full.html +1 -0
  169. package/assets/lithermes-plugin/skills/lit-diagram-drawer/assets/examples/type-process-light.html +1 -0
  170. package/assets/lithermes-plugin/skills/lit-diagram-drawer/assets/examples/type-pyramid-dark.html +1 -0
  171. package/assets/lithermes-plugin/skills/lit-diagram-drawer/assets/examples/type-pyramid-full.html +1 -0
  172. package/assets/lithermes-plugin/skills/lit-diagram-drawer/assets/examples/type-pyramid-light.html +1 -0
  173. package/assets/lithermes-plugin/skills/lit-diagram-drawer/assets/examples/type-quadrant-consultant-dark.html +1 -0
  174. package/assets/lithermes-plugin/skills/lit-diagram-drawer/assets/examples/type-quadrant-consultant-full.html +1 -0
  175. package/assets/lithermes-plugin/skills/lit-diagram-drawer/assets/examples/type-quadrant-consultant-light.html +1 -0
  176. package/assets/lithermes-plugin/skills/lit-diagram-drawer/assets/examples/type-quadrant-dark.html +1 -0
  177. package/assets/lithermes-plugin/skills/lit-diagram-drawer/assets/examples/type-quadrant-full.html +1 -0
  178. package/assets/lithermes-plugin/skills/lit-diagram-drawer/assets/examples/type-quadrant-light.html +1 -0
  179. package/assets/lithermes-plugin/skills/lit-diagram-drawer/assets/examples/type-queue-animated-dark.html +1 -0
  180. package/assets/lithermes-plugin/skills/lit-diagram-drawer/assets/examples/type-queue-animated-full.html +1 -0
  181. package/assets/lithermes-plugin/skills/lit-diagram-drawer/assets/examples/type-queue-animated-light.html +1 -0
  182. package/assets/lithermes-plugin/skills/lit-diagram-drawer/assets/examples/type-radar-dark.html +1 -0
  183. package/assets/lithermes-plugin/skills/lit-diagram-drawer/assets/examples/type-radar-full.html +1 -0
  184. package/assets/lithermes-plugin/skills/lit-diagram-drawer/assets/examples/type-radar-light.html +1 -0
  185. package/assets/lithermes-plugin/skills/lit-diagram-drawer/assets/examples/type-ridgeline-dark.html +1 -0
  186. package/assets/lithermes-plugin/skills/lit-diagram-drawer/assets/examples/type-ridgeline-full.html +1 -0
  187. package/assets/lithermes-plugin/skills/lit-diagram-drawer/assets/examples/type-ridgeline-light.html +1 -0
  188. package/assets/lithermes-plugin/skills/lit-diagram-drawer/assets/examples/type-sankey-dark.html +1 -0
  189. package/assets/lithermes-plugin/skills/lit-diagram-drawer/assets/examples/type-sankey-full.html +1 -0
  190. package/assets/lithermes-plugin/skills/lit-diagram-drawer/assets/examples/type-sankey-light.html +1 -0
  191. package/assets/lithermes-plugin/skills/lit-diagram-drawer/assets/examples/type-scatter-dark.html +1 -0
  192. package/assets/lithermes-plugin/skills/lit-diagram-drawer/assets/examples/type-scatter-full.html +1 -0
  193. package/assets/lithermes-plugin/skills/lit-diagram-drawer/assets/examples/type-scatter-light.html +1 -0
  194. package/assets/lithermes-plugin/skills/lit-diagram-drawer/assets/examples/type-sequence-dark.html +1 -0
  195. package/assets/lithermes-plugin/skills/lit-diagram-drawer/assets/examples/type-sequence-full.html +1 -0
  196. package/assets/lithermes-plugin/skills/lit-diagram-drawer/assets/examples/type-sequence-light.html +1 -0
  197. package/assets/lithermes-plugin/skills/lit-diagram-drawer/assets/examples/type-sequence-oauth-dark.html +1 -0
  198. package/assets/lithermes-plugin/skills/lit-diagram-drawer/assets/examples/type-sequence-oauth-full.html +1 -0
  199. package/assets/lithermes-plugin/skills/lit-diagram-drawer/assets/examples/type-sequence-oauth-light.html +1 -0
  200. package/assets/lithermes-plugin/skills/lit-diagram-drawer/assets/examples/type-slopegraph-dark.html +1 -0
  201. package/assets/lithermes-plugin/skills/lit-diagram-drawer/assets/examples/type-slopegraph-full.html +1 -0
  202. package/assets/lithermes-plugin/skills/lit-diagram-drawer/assets/examples/type-slopegraph-light.html +1 -0
  203. package/assets/lithermes-plugin/skills/lit-diagram-drawer/assets/examples/type-state-dark.html +1 -0
  204. package/assets/lithermes-plugin/skills/lit-diagram-drawer/assets/examples/type-state-full.html +1 -0
  205. package/assets/lithermes-plugin/skills/lit-diagram-drawer/assets/examples/type-state-lifecycle-dark.html +1 -0
  206. package/assets/lithermes-plugin/skills/lit-diagram-drawer/assets/examples/type-state-lifecycle-full.html +1 -0
  207. package/assets/lithermes-plugin/skills/lit-diagram-drawer/assets/examples/type-state-lifecycle-light.html +1 -0
  208. package/assets/lithermes-plugin/skills/lit-diagram-drawer/assets/examples/type-state-light.html +1 -0
  209. package/assets/lithermes-plugin/skills/lit-diagram-drawer/assets/examples/type-story-map-dark.html +1 -0
  210. package/assets/lithermes-plugin/skills/lit-diagram-drawer/assets/examples/type-story-map-full.html +1 -0
  211. package/assets/lithermes-plugin/skills/lit-diagram-drawer/assets/examples/type-story-map-light.html +1 -0
  212. package/assets/lithermes-plugin/skills/lit-diagram-drawer/assets/examples/type-streamgraph-dark.html +1 -0
  213. package/assets/lithermes-plugin/skills/lit-diagram-drawer/assets/examples/type-streamgraph-full.html +1 -0
  214. package/assets/lithermes-plugin/skills/lit-diagram-drawer/assets/examples/type-streamgraph-light.html +1 -0
  215. package/assets/lithermes-plugin/skills/lit-diagram-drawer/assets/examples/type-swimlane-dark.html +1 -0
  216. package/assets/lithermes-plugin/skills/lit-diagram-drawer/assets/examples/type-swimlane-full.html +1 -0
  217. package/assets/lithermes-plugin/skills/lit-diagram-drawer/assets/examples/type-swimlane-light.html +1 -0
  218. package/assets/lithermes-plugin/skills/lit-diagram-drawer/assets/examples/type-timeline-dark.html +1 -0
  219. package/assets/lithermes-plugin/skills/lit-diagram-drawer/assets/examples/type-timeline-full.html +1 -0
  220. package/assets/lithermes-plugin/skills/lit-diagram-drawer/assets/examples/type-timeline-light.html +1 -0
  221. package/assets/lithermes-plugin/skills/lit-diagram-drawer/assets/examples/type-tree-block-decomposition-dark.html +1 -0
  222. package/assets/lithermes-plugin/skills/lit-diagram-drawer/assets/examples/type-tree-block-decomposition-full.html +1 -0
  223. package/assets/lithermes-plugin/skills/lit-diagram-drawer/assets/examples/type-tree-block-decomposition-light.html +1 -0
  224. package/assets/lithermes-plugin/skills/lit-diagram-drawer/assets/examples/type-tree-dark.html +1 -0
  225. package/assets/lithermes-plugin/skills/lit-diagram-drawer/assets/examples/type-tree-full.html +1 -0
  226. package/assets/lithermes-plugin/skills/lit-diagram-drawer/assets/examples/type-tree-light.html +1 -0
  227. package/assets/lithermes-plugin/skills/lit-diagram-drawer/assets/examples/type-treemap-dark.html +1 -0
  228. package/assets/lithermes-plugin/skills/lit-diagram-drawer/assets/examples/type-treemap-full.html +1 -0
  229. package/assets/lithermes-plugin/skills/lit-diagram-drawer/assets/examples/type-treemap-light.html +1 -0
  230. package/assets/lithermes-plugin/skills/lit-diagram-drawer/assets/examples/type-uml-class-dark.html +1 -0
  231. package/assets/lithermes-plugin/skills/lit-diagram-drawer/assets/examples/type-uml-class-full.html +1 -0
  232. package/assets/lithermes-plugin/skills/lit-diagram-drawer/assets/examples/type-uml-class-light.html +1 -0
  233. package/assets/lithermes-plugin/skills/lit-diagram-drawer/assets/examples/type-venn-dark.html +1 -0
  234. package/assets/lithermes-plugin/skills/lit-diagram-drawer/assets/examples/type-venn-full.html +1 -0
  235. package/assets/lithermes-plugin/skills/lit-diagram-drawer/assets/examples/type-venn-light.html +1 -0
  236. package/assets/lithermes-plugin/skills/lit-diagram-drawer/assets/examples/type-wardley-dark.html +1 -0
  237. package/assets/lithermes-plugin/skills/lit-diagram-drawer/assets/examples/type-wardley-full.html +1 -0
  238. package/assets/lithermes-plugin/skills/lit-diagram-drawer/assets/examples/type-wardley-light.html +1 -0
  239. package/assets/lithermes-plugin/skills/lit-diagram-drawer/assets/examples/type-waterfall-dark.html +1 -0
  240. package/assets/lithermes-plugin/skills/lit-diagram-drawer/assets/examples/type-waterfall-full.html +1 -0
  241. package/assets/lithermes-plugin/skills/lit-diagram-drawer/assets/examples/type-waterfall-light.html +1 -0
  242. package/assets/lithermes-plugin/skills/lit-diagram-drawer/assets/fonts/OFL.txt +94 -0
  243. package/assets/lithermes-plugin/skills/lit-diagram-drawer/assets/fonts/PretendardVariable.woff2 +0 -0
  244. package/assets/lithermes-plugin/skills/lit-diagram-drawer/assets/fonts/provenance.json +22 -0
  245. package/assets/lithermes-plugin/skills/lit-diagram-drawer/assets/icons.html +231 -0
  246. package/assets/lithermes-plugin/skills/lit-diagram-drawer/assets/index.html +1 -0
  247. package/assets/lithermes-plugin/skills/lit-diagram-drawer/assets/licenses/devicon-MIT.txt +20 -0
  248. package/assets/lithermes-plugin/skills/lit-diagram-drawer/assets/licenses/diagram-design-MIT.txt +21 -0
  249. package/assets/lithermes-plugin/skills/lit-diagram-drawer/assets/licenses/log-z-MIT.txt +21 -0
  250. package/assets/lithermes-plugin/skills/lit-diagram-drawer/assets/licenses/simple-icons-CC0.md +30 -0
  251. package/assets/lithermes-plugin/skills/lit-diagram-drawer/assets/licenses/tabler-MIT.txt +21 -0
  252. package/assets/lithermes-plugin/skills/lit-diagram-drawer/examples/01-service-architecture/after.html +1 -0
  253. package/assets/lithermes-plugin/skills/lit-diagram-drawer/examples/01-service-architecture/brief.md +33 -0
  254. package/assets/lithermes-plugin/skills/lit-diagram-drawer/examples/02-release-decision/after.html +1 -0
  255. package/assets/lithermes-plugin/skills/lit-diagram-drawer/examples/02-release-decision/brief.md +18 -0
  256. package/assets/lithermes-plugin/skills/lit-diagram-drawer/examples/03-data-retention/after.html +1 -0
  257. package/assets/lithermes-plugin/skills/lit-diagram-drawer/examples/03-data-retention/brief.md +19 -0
  258. package/assets/lithermes-plugin/skills/lit-diagram-drawer/examples/04-oauth-sequence/after.html +1 -0
  259. package/assets/lithermes-plugin/skills/lit-diagram-drawer/examples/04-oauth-sequence/brief.md +17 -0
  260. package/assets/lithermes-plugin/skills/lit-diagram-drawer/examples/05-review-lanes/after.html +1 -0
  261. package/assets/lithermes-plugin/skills/lit-diagram-drawer/examples/05-review-lanes/brief.md +17 -0
  262. package/assets/lithermes-plugin/skills/lit-diagram-drawer/examples/06-rollout-gates/after.html +1 -0
  263. package/assets/lithermes-plugin/skills/lit-diagram-drawer/examples/06-rollout-gates/brief.md +17 -0
  264. package/assets/lithermes-plugin/skills/lit-diagram-drawer/examples/07-deployment-boundary/after.html +1 -0
  265. package/assets/lithermes-plugin/skills/lit-diagram-drawer/examples/07-deployment-boundary/brief.md +19 -0
  266. package/assets/lithermes-plugin/skills/lit-diagram-drawer/examples/08-policy-traces/after.html +1 -0
  267. package/assets/lithermes-plugin/skills/lit-diagram-drawer/examples/08-policy-traces/brief.md +20 -0
  268. package/assets/lithermes-plugin/skills/lit-diagram-drawer/references/accessibility.md +37 -0
  269. package/assets/lithermes-plugin/skills/lit-diagram-drawer/references/export.md +29 -0
  270. package/assets/lithermes-plugin/skills/lit-diagram-drawer/references/import-drawio.md +21 -0
  271. package/assets/lithermes-plugin/skills/lit-diagram-drawer/references/import-excalidraw.md +14 -0
  272. package/assets/lithermes-plugin/skills/lit-diagram-drawer/references/import-mermaid.md +18 -0
  273. package/assets/lithermes-plugin/skills/lit-diagram-drawer/references/import-schema.md +28 -0
  274. package/assets/lithermes-plugin/skills/lit-diagram-drawer/references/korean-typography.md +34 -0
  275. package/assets/lithermes-plugin/skills/lit-diagram-drawer/references/motion.md +29 -0
  276. package/assets/lithermes-plugin/skills/lit-diagram-drawer/references/office-pptx-docx.md +40 -0
  277. package/assets/lithermes-plugin/skills/lit-diagram-drawer/references/output-spec.md +48 -0
  278. package/assets/lithermes-plugin/skills/lit-diagram-drawer/references/primitive-annotation.md +12 -0
  279. package/assets/lithermes-plugin/skills/lit-diagram-drawer/references/primitive-icons.md +21 -0
  280. package/assets/lithermes-plugin/skills/lit-diagram-drawer/references/primitive-sketchy.md +11 -0
  281. package/assets/lithermes-plugin/skills/lit-diagram-drawer/references/primitive-terminal.md +11 -0
  282. package/assets/lithermes-plugin/skills/lit-diagram-drawer/references/profiles.md +24 -0
  283. package/assets/lithermes-plugin/skills/lit-diagram-drawer/references/semantic-patterns.md +27 -0
  284. package/assets/lithermes-plugin/skills/lit-diagram-drawer/references/style-guide.md +67 -0
  285. package/assets/lithermes-plugin/skills/lit-diagram-drawer/references/type-architecture.md +51 -0
  286. package/assets/lithermes-plugin/skills/lit-diagram-drawer/references/type-bar.md +51 -0
  287. package/assets/lithermes-plugin/skills/lit-diagram-drawer/references/type-beeswarm.md +49 -0
  288. package/assets/lithermes-plugin/skills/lit-diagram-drawer/references/type-bubble.md +49 -0
  289. package/assets/lithermes-plugin/skills/lit-diagram-drawer/references/type-bump.md +49 -0
  290. package/assets/lithermes-plugin/skills/lit-diagram-drawer/references/type-catalog.json +1433 -0
  291. package/assets/lithermes-plugin/skills/lit-diagram-drawer/references/type-data-flow.md +51 -0
  292. package/assets/lithermes-plugin/skills/lit-diagram-drawer/references/type-datalake.md +49 -0
  293. package/assets/lithermes-plugin/skills/lit-diagram-drawer/references/type-db-schema.md +49 -0
  294. package/assets/lithermes-plugin/skills/lit-diagram-drawer/references/type-dependency.md +49 -0
  295. package/assets/lithermes-plugin/skills/lit-diagram-drawer/references/type-deployment.md +49 -0
  296. package/assets/lithermes-plugin/skills/lit-diagram-drawer/references/type-dp-integration.md +49 -0
  297. package/assets/lithermes-plugin/skills/lit-diagram-drawer/references/type-dp-security-matrix.md +49 -0
  298. package/assets/lithermes-plugin/skills/lit-diagram-drawer/references/type-er.md +49 -0
  299. package/assets/lithermes-plugin/skills/lit-diagram-drawer/references/type-fishbone.md +49 -0
  300. package/assets/lithermes-plugin/skills/lit-diagram-drawer/references/type-flowchart.md +49 -0
  301. package/assets/lithermes-plugin/skills/lit-diagram-drawer/references/type-gantt.md +49 -0
  302. package/assets/lithermes-plugin/skills/lit-diagram-drawer/references/type-heatmap.md +53 -0
  303. package/assets/lithermes-plugin/skills/lit-diagram-drawer/references/type-high-level-vertical.md +53 -0
  304. package/assets/lithermes-plugin/skills/lit-diagram-drawer/references/type-high-level.md +53 -0
  305. package/assets/lithermes-plugin/skills/lit-diagram-drawer/references/type-import-drawio.md +53 -0
  306. package/assets/lithermes-plugin/skills/lit-diagram-drawer/references/type-import-excalidraw.md +53 -0
  307. package/assets/lithermes-plugin/skills/lit-diagram-drawer/references/type-import-mermaid.md +53 -0
  308. package/assets/lithermes-plugin/skills/lit-diagram-drawer/references/type-it-state.md +54 -0
  309. package/assets/lithermes-plugin/skills/lit-diagram-drawer/references/type-journey.md +54 -0
  310. package/assets/lithermes-plugin/skills/lit-diagram-drawer/references/type-kanban.md +54 -0
  311. package/assets/lithermes-plugin/skills/lit-diagram-drawer/references/type-layers.md +54 -0
  312. package/assets/lithermes-plugin/skills/lit-diagram-drawer/references/type-line.md +54 -0
  313. package/assets/lithermes-plugin/skills/lit-diagram-drawer/references/type-loop-terminal.md +53 -0
  314. package/assets/lithermes-plugin/skills/lit-diagram-drawer/references/type-loop.md +54 -0
  315. package/assets/lithermes-plugin/skills/lit-diagram-drawer/references/type-marimekko.md +54 -0
  316. package/assets/lithermes-plugin/skills/lit-diagram-drawer/references/type-medallion.md +54 -0
  317. package/assets/lithermes-plugin/skills/lit-diagram-drawer/references/type-nested.md +59 -0
  318. package/assets/lithermes-plugin/skills/lit-diagram-drawer/references/type-org-chart.md +58 -0
  319. package/assets/lithermes-plugin/skills/lit-diagram-drawer/references/type-paved-road-animated.md +72 -0
  320. package/assets/lithermes-plugin/skills/lit-diagram-drawer/references/type-polar.md +67 -0
  321. package/assets/lithermes-plugin/skills/lit-diagram-drawer/references/type-policy-trace-animated.md +69 -0
  322. package/assets/lithermes-plugin/skills/lit-diagram-drawer/references/type-process.md +58 -0
  323. package/assets/lithermes-plugin/skills/lit-diagram-drawer/references/type-pyramid.md +59 -0
  324. package/assets/lithermes-plugin/skills/lit-diagram-drawer/references/type-quadrant-consultant.md +60 -0
  325. package/assets/lithermes-plugin/skills/lit-diagram-drawer/references/type-quadrant.md +57 -0
  326. package/assets/lithermes-plugin/skills/lit-diagram-drawer/references/type-queue-animated.md +63 -0
  327. package/assets/lithermes-plugin/skills/lit-diagram-drawer/references/type-radar.md +57 -0
  328. package/assets/lithermes-plugin/skills/lit-diagram-drawer/references/type-ridgeline.md +63 -0
  329. package/assets/lithermes-plugin/skills/lit-diagram-drawer/references/type-sankey.md +68 -0
  330. package/assets/lithermes-plugin/skills/lit-diagram-drawer/references/type-scatter.md +60 -0
  331. package/assets/lithermes-plugin/skills/lit-diagram-drawer/references/type-sequence-oauth.md +66 -0
  332. package/assets/lithermes-plugin/skills/lit-diagram-drawer/references/type-sequence.md +63 -0
  333. package/assets/lithermes-plugin/skills/lit-diagram-drawer/references/type-slopegraph.md +65 -0
  334. package/assets/lithermes-plugin/skills/lit-diagram-drawer/references/type-state-lifecycle.md +53 -0
  335. package/assets/lithermes-plugin/skills/lit-diagram-drawer/references/type-state.md +59 -0
  336. package/assets/lithermes-plugin/skills/lit-diagram-drawer/references/type-story-map.md +52 -0
  337. package/assets/lithermes-plugin/skills/lit-diagram-drawer/references/type-streamgraph.md +53 -0
  338. package/assets/lithermes-plugin/skills/lit-diagram-drawer/references/type-swimlane.md +52 -0
  339. package/assets/lithermes-plugin/skills/lit-diagram-drawer/references/type-timeline.md +52 -0
  340. package/assets/lithermes-plugin/skills/lit-diagram-drawer/references/type-tree-block-decomposition.md +57 -0
  341. package/assets/lithermes-plugin/skills/lit-diagram-drawer/references/type-tree.md +54 -0
  342. package/assets/lithermes-plugin/skills/lit-diagram-drawer/references/type-treemap.md +54 -0
  343. package/assets/lithermes-plugin/skills/lit-diagram-drawer/references/type-uml-class.md +52 -0
  344. package/assets/lithermes-plugin/skills/lit-diagram-drawer/references/type-venn.md +51 -0
  345. package/assets/lithermes-plugin/skills/lit-diagram-drawer/references/type-wardley.md +52 -0
  346. package/assets/lithermes-plugin/skills/lit-diagram-drawer/references/type-waterfall.md +54 -0
  347. package/assets/lithermes-plugin/skills/lit-diagram-drawer/references/verifier-guide.md +31 -0
  348. package/assets/lithermes-plugin/skills/lit-diagram-drawer/scripts/block-registry.mjs +43 -0
  349. package/assets/lithermes-plugin/skills/lit-diagram-drawer/scripts/browser-version.mjs +12 -0
  350. package/assets/lithermes-plugin/skills/lit-diagram-drawer/scripts/check-visible-text.py +12 -0
  351. package/assets/lithermes-plugin/skills/lit-diagram-drawer/scripts/diagram_brief.py +192 -0
  352. package/assets/lithermes-plugin/skills/lit-diagram-drawer/scripts/diagram_catalog.py +135 -0
  353. package/assets/lithermes-plugin/skills/lit-diagram-drawer/scripts/diagram_checks.py +123 -0
  354. package/assets/lithermes-plugin/skills/lit-diagram-drawer/scripts/diagram_cli.py +94 -0
  355. package/assets/lithermes-plugin/skills/lit-diagram-drawer/scripts/diagram_geometry.py +130 -0
  356. package/assets/lithermes-plugin/skills/lit-diagram-drawer/scripts/diagram_metrics.py +166 -0
  357. package/assets/lithermes-plugin/skills/lit-diagram-drawer/scripts/diagram_quality.py +293 -0
  358. package/assets/lithermes-plugin/skills/lit-diagram-drawer/scripts/diagram_quality_geometry.py +200 -0
  359. package/assets/lithermes-plugin/skills/lit-diagram-drawer/scripts/diagram_records.py +205 -0
  360. package/assets/lithermes-plugin/skills/lit-diagram-drawer/scripts/diagram_sequence.py +55 -0
  361. package/assets/lithermes-plugin/skills/lit-diagram-drawer/scripts/doctor.mjs +24 -0
  362. package/assets/lithermes-plugin/skills/lit-diagram-drawer/scripts/drawio_extract.py +209 -0
  363. package/assets/lithermes-plugin/skills/lit-diagram-drawer/scripts/drawio_source.py +188 -0
  364. package/assets/lithermes-plugin/skills/lit-diagram-drawer/scripts/excalidraw_extract.py +233 -0
  365. package/assets/lithermes-plugin/skills/lit-diagram-drawer/scripts/excalidraw_support.py +64 -0
  366. package/assets/lithermes-plugin/skills/lit-diagram-drawer/scripts/export.mjs +125 -0
  367. package/assets/lithermes-plugin/skills/lit-diagram-drawer/scripts/mermaid_extract.py +240 -0
  368. package/assets/lithermes-plugin/skills/lit-diagram-drawer/scripts/mermaid_source.py +39 -0
  369. package/assets/lithermes-plugin/skills/lit-diagram-drawer/scripts/office-safety.mjs +54 -0
  370. package/assets/lithermes-plugin/skills/lit-diagram-drawer/scripts/verify-all.py +12 -0
  371. package/assets/lithermes-plugin/skills/lit-diagram-drawer/scripts/verify-brief.py +12 -0
  372. package/assets/lithermes-plugin/skills/lit-diagram-drawer/scripts/verify-diagram.py +12 -0
  373. package/assets/lithermes-plugin/skills/lit-diagram-drawer/scripts/verify-motion.py +12 -0
  374. package/assets/lithermes-plugin/skills/lit-diagram-drawer/scripts/verify-type.py +12 -0
  375. package/assets/lithermes-plugin/skills/lit-docx/NOTICE +1 -0
  376. package/assets/lithermes-plugin/skills/lit-docx/SKILL.md +97 -0
  377. package/assets/lithermes-plugin/skills/lit-docx/references/frontmatter_schema.md +42 -0
  378. package/assets/lithermes-plugin/skills/lit-docx/references/journal_style_spec.md +17 -0
  379. package/assets/lithermes-plugin/skills/lit-docx/references/markdown_quality_checklist.md +37 -0
  380. package/assets/lithermes-plugin/skills/lit-docx/references/slop_phrase_list.yaml +58 -0
  381. package/assets/lithermes-plugin/skills/lit-docx/references/slop_rules.md +35 -0
  382. package/assets/lithermes-plugin/skills/lit-docx/scripts/clean_markdown.py +95 -0
  383. package/assets/lithermes-plugin/skills/lit-docx/scripts/convert_md_to_docx.py +1041 -0
  384. package/assets/lithermes-plugin/skills/lit-docx/scripts/convert_md_to_pdf.py +281 -0
  385. package/assets/lithermes-plugin/skills/lit-docx/scripts/convert_pdf.py +130 -0
  386. package/assets/lithermes-plugin/skills/lit-docx/scripts/edit_docx.py +297 -0
  387. package/assets/lithermes-plugin/skills/lit-docx/scripts/embed_images.py +78 -0
  388. package/assets/lithermes-plugin/skills/lit-docx/scripts/generate_docx_templates.py +491 -0
  389. package/assets/lithermes-plugin/skills/lit-docx/scripts/slop_lint.py +536 -0
  390. package/assets/lithermes-plugin/skills/lit-docx/scripts/visual_audit.py +41 -0
  391. package/assets/lithermes-plugin/skills/lit-docx/templates/docx/acs.docx +0 -0
  392. package/assets/lithermes-plugin/skills/lit-docx/templates/docx/elsevier.docx +0 -0
  393. package/assets/lithermes-plugin/skills/lit-docx/templates/docx/ieee.docx +0 -0
  394. package/assets/lithermes-plugin/skills/lit-docx/templates/docx/korean-generic.docx +0 -0
  395. package/assets/lithermes-plugin/skills/lit-docx/templates/docx/nature.docx +0 -0
  396. package/assets/lithermes-plugin/skills/lit-docx/templates/latex/acs/README.md +5 -0
  397. package/assets/lithermes-plugin/skills/lit-docx/templates/latex/acs/template.tex +37 -0
  398. package/assets/lithermes-plugin/skills/lit-docx/templates/latex/elsevier/README.md +5 -0
  399. package/assets/lithermes-plugin/skills/lit-docx/templates/latex/elsevier/template.tex +38 -0
  400. package/assets/lithermes-plugin/skills/lit-docx/templates/latex/ieee/README.md +5 -0
  401. package/assets/lithermes-plugin/skills/lit-docx/templates/latex/ieee/template.tex +37 -0
  402. package/assets/lithermes-plugin/skills/lit-docx/templates/latex/korean-generic/README.md +5 -0
  403. package/assets/lithermes-plugin/skills/lit-docx/templates/latex/korean-generic/template.tex +37 -0
  404. package/assets/lithermes-plugin/skills/lit-docx/templates/latex/nature/README.md +5 -0
  405. package/assets/lithermes-plugin/skills/lit-docx/templates/latex/nature/template.tex +37 -0
  406. package/assets/lithermes-plugin/skills/lit-docx/templates/registry.yaml +1366 -0
  407. package/assets/lithermes-plugin/skills/lit-humanizer/NOTICE +170 -0
  408. package/assets/lithermes-plugin/skills/lit-humanizer/SKILL.md +125 -0
  409. package/assets/lithermes-plugin/skills/lit-humanizer/assets/report-skeleton.md +26 -0
  410. package/assets/lithermes-plugin/skills/lit-humanizer/assets/slide-text-skeleton.md +30 -0
  411. package/assets/lithermes-plugin/skills/lit-humanizer/examples/accessibility-note/after.md +7 -0
  412. package/assets/lithermes-plugin/skills/lit-humanizer/examples/accessibility-note/before.md +7 -0
  413. package/assets/lithermes-plugin/skills/lit-humanizer/examples/api-reference/after.md +9 -0
  414. package/assets/lithermes-plugin/skills/lit-humanizer/examples/api-reference/before.md +15 -0
  415. package/assets/lithermes-plugin/skills/lit-humanizer/examples/changelog/after.md +5 -0
  416. package/assets/lithermes-plugin/skills/lit-humanizer/examples/changelog/before.md +12 -0
  417. package/assets/lithermes-plugin/skills/lit-humanizer/examples/code-comments/after.md +10 -0
  418. package/assets/lithermes-plugin/skills/lit-humanizer/examples/code-comments/before.md +19 -0
  419. package/assets/lithermes-plugin/skills/lit-humanizer/examples/commit/after.md +5 -0
  420. package/assets/lithermes-plugin/skills/lit-humanizer/examples/commit/before.md +7 -0
  421. package/assets/lithermes-plugin/skills/lit-humanizer/examples/data-release/after.md +7 -0
  422. package/assets/lithermes-plugin/skills/lit-humanizer/examples/data-release/before.md +9 -0
  423. package/assets/lithermes-plugin/skills/lit-humanizer/examples/detector-validation/ko-metrics-golden.json +49 -0
  424. package/assets/lithermes-plugin/skills/lit-humanizer/examples/detector-validation/pos-real.txt +26 -0
  425. package/assets/lithermes-plugin/skills/lit-humanizer/examples/detector-validation/rule-cases.json +306 -0
  426. package/assets/lithermes-plugin/skills/lit-humanizer/examples/english-essay/after.md +5 -0
  427. package/assets/lithermes-plugin/skills/lit-humanizer/examples/english-essay/before.md +5 -0
  428. package/assets/lithermes-plugin/skills/lit-humanizer/examples/incident-update/after.md +7 -0
  429. package/assets/lithermes-plugin/skills/lit-humanizer/examples/incident-update/before.md +7 -0
  430. package/assets/lithermes-plugin/skills/lit-humanizer/examples/ko-essay/after.md +7 -0
  431. package/assets/lithermes-plugin/skills/lit-humanizer/examples/ko-essay/before.md +9 -0
  432. package/assets/lithermes-plugin/skills/lit-humanizer/examples/ko-report/after.md +9 -0
  433. package/assets/lithermes-plugin/skills/lit-humanizer/examples/ko-report/before.md +13 -0
  434. package/assets/lithermes-plugin/skills/lit-humanizer/examples/ko-slide/after.md +19 -0
  435. package/assets/lithermes-plugin/skills/lit-humanizer/examples/ko-slide/before.md +21 -0
  436. package/assets/lithermes-plugin/skills/lit-humanizer/examples/meeting-brief/after.md +9 -0
  437. package/assets/lithermes-plugin/skills/lit-humanizer/examples/meeting-brief/before.md +11 -0
  438. package/assets/lithermes-plugin/skills/lit-humanizer/examples/policy-faq/after.md +9 -0
  439. package/assets/lithermes-plugin/skills/lit-humanizer/examples/policy-faq/before.md +9 -0
  440. package/assets/lithermes-plugin/skills/lit-humanizer/examples/pr/after.md +15 -0
  441. package/assets/lithermes-plugin/skills/lit-humanizer/examples/pr/before.md +17 -0
  442. package/assets/lithermes-plugin/skills/lit-humanizer/examples/project-update/after.md +7 -0
  443. package/assets/lithermes-plugin/skills/lit-humanizer/examples/project-update/before.md +9 -0
  444. package/assets/lithermes-plugin/skills/lit-humanizer/examples/readme/after.md +12 -0
  445. package/assets/lithermes-plugin/skills/lit-humanizer/examples/readme/before.md +14 -0
  446. package/assets/lithermes-plugin/skills/lit-humanizer/examples/report/after.md +13 -0
  447. package/assets/lithermes-plugin/skills/lit-humanizer/examples/report/before.md +11 -0
  448. package/assets/lithermes-plugin/skills/lit-humanizer/examples/research-abstract/after.md +5 -0
  449. package/assets/lithermes-plugin/skills/lit-humanizer/examples/research-abstract/before.md +5 -0
  450. package/assets/lithermes-plugin/skills/lit-humanizer/examples/slides/after.md +19 -0
  451. package/assets/lithermes-plugin/skills/lit-humanizer/examples/slides/before.md +19 -0
  452. package/assets/lithermes-plugin/skills/lit-humanizer/examples/troubleshooting/after.md +11 -0
  453. package/assets/lithermes-plugin/skills/lit-humanizer/examples/troubleshooting/before.md +11 -0
  454. package/assets/lithermes-plugin/skills/lit-humanizer/references/README.md +16 -0
  455. package/assets/lithermes-plugin/skills/lit-humanizer/references/always-on-rule.md +9 -0
  456. package/assets/lithermes-plugin/skills/lit-humanizer/references/code-patterns.md +468 -0
  457. package/assets/lithermes-plugin/skills/lit-humanizer/references/deliverable-channels.md +111 -0
  458. package/assets/lithermes-plugin/skills/lit-humanizer/references/en-patterns-checklist.md +43 -0
  459. package/assets/lithermes-plugin/skills/lit-humanizer/references/en-patterns-content.md +243 -0
  460. package/assets/lithermes-plugin/skills/lit-humanizer/references/en-patterns-structure.md +375 -0
  461. package/assets/lithermes-plugin/skills/lit-humanizer/references/en-patterns.md +57 -0
  462. package/assets/lithermes-plugin/skills/lit-humanizer/references/ko-metrics.md +33 -0
  463. package/assets/lithermes-plugin/skills/lit-humanizer/references/ko-patterns-a-d.md +659 -0
  464. package/assets/lithermes-plugin/skills/lit-humanizer/references/ko-patterns-e-j.md +387 -0
  465. package/assets/lithermes-plugin/skills/lit-humanizer/references/ko-patterns.md +31 -0
  466. package/assets/lithermes-plugin/skills/lit-humanizer/references/rewrite-playbook.md +54 -0
  467. package/assets/lithermes-plugin/skills/lit-humanizer/references/taxonomy.md +153 -0
  468. package/assets/lithermes-plugin/skills/lit-humanizer/rules.json +884 -0
  469. package/assets/lithermes-plugin/skills/lit-humanizer/scripts/detect.py +17 -0
  470. package/assets/lithermes-plugin/skills/lit-humanizer/scripts/extract_office_text.py +114 -0
  471. package/assets/lithermes-plugin/skills/lit-humanizer/scripts/ko_metrics.py +35 -0
  472. package/assets/lithermes-plugin/skills/lit-pptx/NOTICE +1 -0
  473. package/assets/lithermes-plugin/skills/lit-pptx/SKILL.md +109 -0
  474. package/assets/lithermes-plugin/skills/lit-pptx/agents/analyst.md +49 -0
  475. package/assets/lithermes-plugin/skills/lit-pptx/agents/antithesis.md +65 -0
  476. package/assets/lithermes-plugin/skills/lit-pptx/agents/architect.md +44 -0
  477. package/assets/lithermes-plugin/skills/lit-pptx/agents/critic.md +42 -0
  478. package/assets/lithermes-plugin/skills/lit-pptx/agents/synthesizer.md +47 -0
  479. package/assets/lithermes-plugin/skills/lit-pptx/agents/thesis.md +33 -0
  480. package/assets/lithermes-plugin/skills/lit-pptx/assets/azure/circle-lg.png +0 -0
  481. package/assets/lithermes-plugin/skills/lit-pptx/assets/azure/circle-md.png +0 -0
  482. package/assets/lithermes-plugin/skills/lit-pptx/assets/azure/circle-sm.png +0 -0
  483. package/assets/lithermes-plugin/skills/lit-pptx/bin/office.mjs +77 -0
  484. package/assets/lithermes-plugin/skills/lit-pptx/fonts/PRETENDARD-OFL.txt +94 -0
  485. package/assets/lithermes-plugin/skills/lit-pptx/fonts/a2z-font/A2Z-Black.otf +0 -0
  486. package/assets/lithermes-plugin/skills/lit-pptx/fonts/a2z-font/A2Z-Bold.otf +0 -0
  487. package/assets/lithermes-plugin/skills/lit-pptx/fonts/a2z-font/A2Z-ExtraBold.otf +0 -0
  488. package/assets/lithermes-plugin/skills/lit-pptx/fonts/a2z-font/A2Z-ExtraLight.otf +0 -0
  489. package/assets/lithermes-plugin/skills/lit-pptx/fonts/a2z-font/A2Z-Light.otf +0 -0
  490. package/assets/lithermes-plugin/skills/lit-pptx/fonts/a2z-font/A2Z-Medium.otf +0 -0
  491. package/assets/lithermes-plugin/skills/lit-pptx/fonts/a2z-font/A2Z-Regular.otf +0 -0
  492. package/assets/lithermes-plugin/skills/lit-pptx/fonts/a2z-font/A2Z-SemiBold.otf +0 -0
  493. package/assets/lithermes-plugin/skills/lit-pptx/fonts/a2z-font/A2Z-Thin.otf +0 -0
  494. package/assets/lithermes-plugin/skills/lit-pptx/fonts/a2z-font/OFL.txt +94 -0
  495. package/assets/lithermes-plugin/skills/lit-pptx/fonts/a2z-font/SOURCE.md +29 -0
  496. package/assets/lithermes-plugin/skills/lit-pptx/pretendard-font/public/static/PretendardGOV-Bold.otf +0 -0
  497. package/assets/lithermes-plugin/skills/lit-pptx/pretendard-font/public/static/PretendardGOV-Regular.otf +0 -0
  498. package/assets/lithermes-plugin/skills/lit-pptx/references/anti-slop-checklist.md +71 -0
  499. package/assets/lithermes-plugin/skills/lit-pptx/references/authoring-guide.md +139 -0
  500. package/assets/lithermes-plugin/skills/lit-pptx/references/consensus-protocol.md +125 -0
  501. package/assets/lithermes-plugin/skills/lit-pptx/references/data-display-cookbook.md +45 -0
  502. package/assets/lithermes-plugin/skills/lit-pptx/references/design-system-azure.md +58 -0
  503. package/assets/lithermes-plugin/skills/lit-pptx/runtime/package-lock.json +750 -0
  504. package/assets/lithermes-plugin/skills/lit-pptx/runtime/package.json +15 -0
  505. package/assets/lithermes-plugin/skills/lit-pptx/runtime/requirements.in +7 -0
  506. package/assets/lithermes-plugin/skills/lit-pptx/runtime/requirements.lock +391 -0
  507. package/assets/lithermes-plugin/skills/lit-pptx/scripts/compile-deck.js +447 -0
  508. package/assets/lithermes-plugin/skills/lit-pptx/scripts/craft_extras.py +215 -0
  509. package/assets/lithermes-plugin/skills/lit-pptx/scripts/embed_fonts.py +199 -0
  510. package/assets/lithermes-plugin/skills/lit-pptx/scripts/integrity.py +60 -0
  511. package/assets/lithermes-plugin/skills/lit-pptx/scripts/inventory.py +64 -0
  512. package/assets/lithermes-plugin/skills/lit-pptx/scripts/learn_template.py +433 -0
  513. package/assets/lithermes-plugin/skills/lit-pptx/scripts/lib/derive-palette.js +176 -0
  514. package/assets/lithermes-plugin/skills/lit-pptx/scripts/lib/directive-parser.js +244 -0
  515. package/assets/lithermes-plugin/skills/lit-pptx/scripts/lib/font-map.js +79 -0
  516. package/assets/lithermes-plugin/skills/lit-pptx/scripts/lib/gen-bg.js +85 -0
  517. package/assets/lithermes-plugin/skills/lit-pptx/scripts/lib/gen-gradient-assets.js +36 -0
  518. package/assets/lithermes-plugin/skills/lit-pptx/scripts/lib/layout-resolver.js +736 -0
  519. package/assets/lithermes-plugin/skills/lit-pptx/scripts/lib/markdown-loader.js +136 -0
  520. package/assets/lithermes-plugin/skills/lit-pptx/scripts/lib/render-adapter-html.js +357 -0
  521. package/assets/lithermes-plugin/skills/lit-pptx/scripts/lib/render-adapter-pptx.js +1864 -0
  522. package/assets/lithermes-plugin/skills/lit-pptx/scripts/lib/slide-ast.js +539 -0
  523. package/assets/lithermes-plugin/skills/lit-pptx/scripts/lib/spec-validator.js +94 -0
  524. package/assets/lithermes-plugin/skills/lit-pptx/scripts/lib/template-registry.js +355 -0
  525. package/assets/lithermes-plugin/skills/lit-pptx/scripts/qa_deck.py +791 -0
  526. package/assets/lithermes-plugin/skills/lit-pptx/scripts/validate_pptx.py +206 -0
  527. package/assets/lithermes-plugin/skills/lit-pptx/slide-formats/markdown-slide-spec-v1.md +251 -0
  528. package/assets/lithermes-plugin/skills/lit-pptx/slide-formats/markdown-slide-spec-v2.md +221 -0
  529. package/assets/lithermes-plugin/skills/lit-pptx/slide-formats/slide-ast-v1.schema.json +229 -0
  530. package/assets/lithermes-plugin/skills/lit-pptx/slide-formats/slide-ast-v2.schema.json +144 -0
  531. package/assets/lithermes-plugin/skills/lit-pptx/slide-formats/template-enrollment-contract.md +228 -0
  532. package/assets/lithermes-plugin/skills/lit-pptx/templates/enrolled/AZURE-A2Z/capabilities.yaml +146 -0
  533. package/assets/lithermes-plugin/skills/lit-pptx/templates/enrolled/AZURE-A2Z/layout-mapping.yaml +384 -0
  534. package/assets/lithermes-plugin/skills/lit-pptx/templates/enrolled/AZURE-A2Z/template.yaml +37 -0
  535. package/assets/lithermes-plugin/skills/lit-pptx/templates/enrolled/AZURE-PRO/capabilities.yaml +154 -0
  536. package/assets/lithermes-plugin/skills/lit-pptx/templates/enrolled/AZURE-PRO/layout-mapping.yaml +405 -0
  537. package/assets/lithermes-plugin/skills/lit-pptx/templates/enrolled/AZURE-PRO/template.yaml +37 -0
  538. package/assets/lithermes-plugin/skills/lit-pptx/templates/enrolled/BOILERPLATE-A2Z/capabilities.yaml +179 -0
  539. package/assets/lithermes-plugin/skills/lit-pptx/templates/enrolled/BOILERPLATE-A2Z/layout-mapping.yaml +299 -0
  540. package/assets/lithermes-plugin/skills/lit-pptx/templates/enrolled/BOILERPLATE-A2Z/template.yaml +45 -0
  541. package/assets/lithermes-plugin/skills/lit-pptx/templates/enrolled/BOILERPLATE-PRETENDARD/capabilities.yaml +181 -0
  542. package/assets/lithermes-plugin/skills/lit-pptx/templates/enrolled/BOILERPLATE-PRETENDARD/layout-mapping.yaml +299 -0
  543. package/assets/lithermes-plugin/skills/lit-pptx/templates/enrolled/BOILERPLATE-PRETENDARD/template.yaml +44 -0
  544. package/assets/lithermes-plugin/skills/lit-scientific-visualization/SKILL.md +2 -0
  545. package/assets/lithermes-plugin/skills/lit-typographic-motion/SKILL.md +71 -0
  546. package/assets/lithermes-plugin/skills/lit-typographic-motion/bin/audio.py +45 -0
  547. package/assets/lithermes-plugin/skills/lit-typographic-motion/bin/motion.mjs +690 -0
  548. package/assets/lithermes-plugin/skills/lit-typographic-motion/bin/runtime.mjs +299 -0
  549. package/assets/lithermes-plugin/skills/lit-typographic-motion/engine/NOTICE +23 -0
  550. package/assets/lithermes-plugin/skills/lit-typographic-motion/engine/THIRD_PARTY_NOTICES +55 -0
  551. package/assets/lithermes-plugin/skills/lit-typographic-motion/engine/browser.mjs +169 -0
  552. package/assets/lithermes-plugin/skills/lit-typographic-motion/engine/completion.mjs +52 -0
  553. package/assets/lithermes-plugin/skills/lit-typographic-motion/engine/constants.mjs +162 -0
  554. package/assets/lithermes-plugin/skills/lit-typographic-motion/engine/director.mjs +33 -0
  555. package/assets/lithermes-plugin/skills/lit-typographic-motion/engine/encode.mjs +191 -0
  556. package/assets/lithermes-plugin/skills/lit-typographic-motion/engine/flash.mjs +163 -0
  557. package/assets/lithermes-plugin/skills/lit-typographic-motion/engine/frame.mjs +428 -0
  558. package/assets/lithermes-plugin/skills/lit-typographic-motion/engine/gate.mjs +483 -0
  559. package/assets/lithermes-plugin/skills/lit-typographic-motion/engine/look.mjs +223 -0
  560. package/assets/lithermes-plugin/skills/lit-typographic-motion/engine/page.js +622 -0
  561. package/assets/lithermes-plugin/skills/lit-typographic-motion/engine/presets.mjs +170 -0
  562. package/assets/lithermes-plugin/skills/lit-typographic-motion/engine/scenes.mjs +242 -0
  563. package/assets/lithermes-plugin/skills/lit-typographic-motion/engine/sound.mjs +382 -0
  564. package/assets/lithermes-plugin/skills/lit-typographic-motion/engine/stage-gate.mjs +97 -0
  565. package/assets/lithermes-plugin/skills/lit-typographic-motion/engine/stage-init.js +186 -0
  566. package/assets/lithermes-plugin/skills/lit-typographic-motion/engine/stage-kit.js +389 -0
  567. package/assets/lithermes-plugin/skills/lit-typographic-motion/engine/stage-qa.mjs +358 -0
  568. package/assets/lithermes-plugin/skills/lit-typographic-motion/engine/stage-worker.mjs +33 -0
  569. package/assets/lithermes-plugin/skills/lit-typographic-motion/engine/stage.mjs +691 -0
  570. package/assets/lithermes-plugin/skills/lit-typographic-motion/engine/stills.mjs +71 -0
  571. package/assets/lithermes-plugin/skills/lit-typographic-motion/engine/stroke.mjs +231 -0
  572. package/assets/lithermes-plugin/skills/lit-typographic-motion/engine/timeline.mjs +177 -0
  573. package/assets/lithermes-plugin/skills/lit-typographic-motion/engine/treatment.mjs +244 -0
  574. package/assets/lithermes-plugin/skills/lit-typographic-motion/engine/type.mjs +183 -0
  575. package/assets/lithermes-plugin/skills/lit-typographic-motion/engine/util.mjs +152 -0
  576. package/assets/lithermes-plugin/skills/lit-typographic-motion/references/craft-loop.md +175 -0
  577. package/assets/lithermes-plugin/skills/lit-typographic-motion/references/engine-contract.md +166 -0
  578. package/assets/lithermes-plugin/skills/lit-typographic-motion/references/runtime.md +122 -0
  579. package/assets/lithermes-plugin/skills/lit-typographic-motion/references/stage.md +261 -0
  580. package/assets/lithermes-plugin/skills/lit-typographic-motion/references/style-bibles.md +122 -0
  581. package/assets/lithermes-plugin/skills/lit-typographic-motion/references/treatment.md +164 -0
  582. package/assets/lithermes-plugin/skills/lit-typographic-motion/references/type-craft.md +92 -0
  583. package/assets/lithermes-plugin/skills/lit-typographic-motion/runtime/fonts.json +154 -0
  584. package/assets/lithermes-plugin/skills/lit-typographic-motion/runtime/licenses/CREDITS +20 -0
  585. package/assets/lithermes-plugin/skills/lit-typographic-motion/runtime/licenses/EMS-OFL.txt +91 -0
  586. package/assets/lithermes-plugin/skills/lit-typographic-motion/runtime/package-lock.json +88 -0
  587. package/assets/lithermes-plugin/skills/lit-typographic-motion/runtime/package.json +12 -0
  588. package/assets/lithermes-plugin/skills/lit-typographic-motion/runtime/requirements.in +1 -0
  589. package/assets/lithermes-plugin/skills/lit-typographic-motion/runtime/requirements.lock +727 -0
  590. package/assets/lithermes-plugin/skills/lit-typographic-motion/runtime/word-timing.json +9 -0
  591. package/assets/lithermes-plugin/skills/litresearch/SKILL.md +19 -18
  592. package/assets/lithermes-plugin/skills/litwork/SKILL.md +28 -0
  593. package/assets/lithermes-plugin/skills/visual-qa/references/complete-contract.md +3 -3
  594. package/package.json +1 -1
  595. package/readme-assets/ab-simple/s11-ui-baseline-desktop.webp +0 -0
  596. package/readme-assets/ab-simple/s11-ui-lithermes-desktop.webp +0 -0
  597. package/readme-assets/ab-simple/s3-ui-baseline-desktop.webp +0 -0
  598. package/readme-assets/ab-simple/s3-ui-lithermes-desktop.webp +0 -0
  599. package/readme-assets/ab-simple/s4-ui-baseline-desktop.webp +0 -0
  600. package/readme-assets/ab-simple/s4-ui-lithermes-desktop.webp +0 -0
  601. package/readme-assets/ab-simple/s5-office-baseline-slides.webp +0 -0
  602. package/readme-assets/ab-simple/s5-office-lithermes-slides.webp +0 -0
  603. package/readme-assets/ab-simple/s7-lithermes-diagram.webp +0 -0
  604. package/readme-assets/ab-simple/s8-office-baseline-slides.webp +0 -0
  605. package/readme-assets/ab-simple/s8-office-lithermes-slides.webp +0 -0
  606. package/readme-assets/ab-simple/s9-office-lithermes-pages.webp +0 -0
  607. package/readme-assets/badge-version.svg +1 -1
  608. package/readme-assets/cover-motion-still.webp +0 -0
  609. package/readme-assets/cover-motion.webp +0 -0
  610. package/readme-assets/skills/autoconference.webp +0 -0
  611. package/readme-assets/skills/autoresearch.webp +0 -0
  612. package/readme-assets/skills/browser-drive.webp +0 -0
  613. package/readme-assets/skills/comment-checker.webp +0 -0
  614. package/readme-assets/skills/debugging.webp +0 -0
  615. package/readme-assets/skills/deep-interview.webp +0 -0
  616. package/readme-assets/skills/frontend-ui-ux.webp +0 -0
  617. package/readme-assets/skills/lit-burnoff-file.webp +0 -0
  618. package/readme-assets/skills/lit-burnoff.webp +0 -0
  619. package/readme-assets/skills/lit-code.webp +0 -0
  620. package/readme-assets/skills/lit-commit.webp +0 -0
  621. package/readme-assets/skills/lit-comprehend.webp +0 -0
  622. package/readme-assets/skills/lit-crucible.webp +0 -0
  623. package/readme-assets/skills/lit-diagram-drawer.webp +0 -0
  624. package/readme-assets/skills/lit-docx.webp +0 -0
  625. package/readme-assets/skills/lit-handoff.webp +0 -0
  626. package/readme-assets/skills/lit-humanizer.webp +0 -0
  627. package/readme-assets/skills/lit-init.webp +0 -0
  628. package/readme-assets/skills/lit-plan.webp +0 -0
  629. package/readme-assets/skills/lit-pptx.webp +0 -0
  630. package/readme-assets/skills/lit-recap.webp +0 -0
  631. package/readme-assets/skills/lit-scientific-visualization.webp +0 -0
  632. package/readme-assets/skills/lit-typographic-motion.webp +0 -0
  633. package/readme-assets/skills/litgoal.webp +0 -0
  634. package/readme-assets/skills/litresearch.webp +0 -0
  635. package/readme-assets/skills/litwork.webp +0 -0
  636. package/readme-assets/skills/lsp-setup.webp +0 -0
  637. package/readme-assets/skills/lsp.webp +0 -0
  638. package/readme-assets/skills/readme-studio.webp +0 -0
  639. package/readme-assets/skills/refactor.webp +0 -0
  640. package/readme-assets/skills/review-work.webp +0 -0
  641. package/readme-assets/skills/rules.webp +0 -0
  642. package/readme-assets/skills/start-work.webp +0 -0
  643. package/readme-assets/skills/structural-search.webp +0 -0
  644. package/readme-assets/skills/visual-qa.webp +0 -0
  645. package/readme-assets/skills/wikify.webp +0 -0
  646. package/src/cli.js +40 -1
  647. package/src/lib/check.js +21 -0
  648. package/src/lib/install.js +262 -7
  649. package/src/lib/skillPayload.js +3 -3
  650. package/assets/lithermes-plugin/skills/lit-korean/SKILL.md +0 -237
  651. package/assets/lithermes-plugin/skills/lit-korean/references/quick-rules.md +0 -24
  652. package/assets/lithermes-plugin/skills/lit-korean/references/safety-checklist.md +0 -23
  653. package/readme-assets/cover.webp +0 -0
@@ -0,0 +1,461 @@
1
+ """Optional Jev skill hint for the per-turn ``pre_llm_call`` route.
2
+
3
+ Off by default. It runs only when ``LITHERMES_JEV=1`` and ``TYPESAFE_API_KEY``
4
+ are both present in the process environment, on a top-level turn that no
5
+ deterministic LitHermes route already claimed. One POST per eligible turn asks
6
+ Jev which bundled LitHermes skill fits the redacted prompt. The answer is
7
+ untrusted data: only an exact catalog id with enough confidence becomes one
8
+ fixed advisory sentence. Every failure falls back to the unchanged turn, with
9
+ one visible note per session delivered through ``transform_llm_output``. When
10
+ both switches are on, the first reply of each session also opens with one plain
11
+ ``✦ Jev skill hint ON`` line so the user notices the feature is enabled.
12
+
13
+ Status and doctor show the last accepted hint (skill id and latency only). They
14
+ run as a separate ``hermes`` CLI process, so the hinting process also writes that
15
+ pair, with a timestamp, to Hermes home ``lithermes/jev-last.json``.
16
+
17
+ The key is read from the environment and used only in the request header. It
18
+ is never logged, traced, stored, or placed in an error or note.
19
+ """
20
+
21
+ from __future__ import annotations
22
+
23
+ import contextlib
24
+ import hashlib
25
+ import json
26
+ import math
27
+ import os
28
+ import re
29
+ import threading
30
+ import time
31
+ import urllib.error
32
+ import urllib.request
33
+ from pathlib import Path
34
+ from typing import Any, Callable, Iterable
35
+
36
+ try:
37
+ from .core_runtime import assert_within_isolation, get_hermes_home, redact_obj, utc_now
38
+ except (ImportError, ModuleNotFoundError):
39
+ from core_runtime import assert_within_isolation, get_hermes_home, redact_obj, utc_now # type: ignore
40
+
41
+
42
+ FLAG = "LITHERMES_JEV"
43
+ KEY_ENV = "TYPESAFE_API_KEY"
44
+ ENDPOINT = "https://api.typesafe.ai/v1/systemone"
45
+ DEFAULT_MODEL = "jev-1.13.0"
46
+ DEFAULT_TIMEOUT_MS = 1500
47
+ MAX_TIMEOUT_MS = 3000
48
+ DEFAULT_MAX_CALLS = 200
49
+ DEFAULT_MIN_CONFIDENCE = 0.35
50
+ MAX_PROMPT_CHARS = 2000
51
+ REDACTION_WINDOW_CHARS = 8000
52
+ MAX_DESCRIPTION_CHARS = 300
53
+ MAX_REQUEST_BYTES = 64 * 1024
54
+ MAX_RESPONSE_BYTES = 64 * 1024
55
+ MAX_TRACKED_SESSIONS = 256
56
+ LAST_HINT_FILE = "jev-last.json"
57
+ MAX_LAST_HINT_BYTES = 4096
58
+ NONE_ID = "none"
59
+ _NOFOLLOW = getattr(os, "O_NOFOLLOW", 0)
60
+ # Reply transforms land in Markdown and transcripts, where the product keeps
61
+ # every mark plain; the banner therefore carries no ANSI colour.
62
+ BANNER = "✦ Jev skill hint ON"
63
+ QUESTION = (
64
+ "Which one skill, if any, is the best fit for the user's request? "
65
+ "Choose none when no catalog skill fits."
66
+ )
67
+ NONE_CRITERION = "No specialized skill in this catalog fits; answer the user directly."
68
+
69
+ # A transport takes (url, headers, body, timeout seconds) and returns
70
+ # (HTTP status, response bytes). Tests replace it; production uses urllib.
71
+ Transport = Callable[[str, dict[str, str], bytes, float], tuple[int, bytes]]
72
+
73
+
74
+ class TransportTimeout(Exception):
75
+ """The request did not finish inside the hard timeout."""
76
+
77
+
78
+ class TransportError(Exception):
79
+ """The request failed before an HTTP status was available."""
80
+
81
+
82
+ class _RefuseRedirects(urllib.request.HTTPRedirectHandler):
83
+ """A redirect surfaces as its own HTTP status instead of being followed."""
84
+
85
+ def redirect_request(self, req, fp, code, msg, headers, newurl):
86
+ return None
87
+
88
+
89
+ _OPENER = urllib.request.build_opener(_RefuseRedirects())
90
+
91
+
92
+ def _urllib_transport(url: str, headers: dict[str, str], body: bytes, timeout: float) -> tuple[int, bytes]:
93
+ plain = {name: value for name, value in headers.items() if name.lower() != "authorization"}
94
+ request = urllib.request.Request(url, data=body, headers=plain, method="POST")
95
+ for name, value in headers.items():
96
+ if name.lower() == "authorization":
97
+ # Never copied onto a follow-up request, should a redirect ever be taken.
98
+ request.add_unredirected_header(name, value)
99
+ try:
100
+ with _OPENER.open(request, timeout=timeout) as response: # noqa: S310 - fixed https endpoint
101
+ return int(response.status), response.read(MAX_RESPONSE_BYTES + 1)
102
+ except urllib.error.HTTPError as exc:
103
+ exc.close()
104
+ return int(exc.code), b""
105
+ except (TimeoutError, OSError) as exc:
106
+ # Exception text can carry request details; only the category leaves here.
107
+ if isinstance(exc, TimeoutError) or "timed out" in str(getattr(exc, "reason", "")):
108
+ raise TransportTimeout() from None
109
+ raise TransportError() from None
110
+
111
+
112
+ TRANSPORT: Transport = _urllib_transport
113
+
114
+ _CALLS: dict[str, int] = {}
115
+ _NOTED: dict[str, bool] = {}
116
+ _PENDING_NOTE: dict[str, str] = {}
117
+ _BANNERED: dict[str, bool] = {}
118
+ _LAST_HINT: dict[str, Any] = {}
119
+ _SKILL_ID = re.compile(r"[a-z0-9][a-z0-9-]{0,63}")
120
+
121
+
122
+ def _env(env: dict[str, str] | None) -> dict[str, str]:
123
+ return os.environ if env is None else env # type: ignore[return-value]
124
+
125
+
126
+ def _flag_on(env: dict[str, str]) -> bool:
127
+ return (env.get(FLAG) or "").strip() == "1"
128
+
129
+
130
+ def _key(env: dict[str, str]) -> str:
131
+ return (env.get(KEY_ENV) or "").strip()
132
+
133
+
134
+ def status(env: dict[str, str] | None = None) -> str:
135
+ values = _env(env)
136
+ if not _flag_on(values):
137
+ return "off"
138
+ if not _key(values):
139
+ return "flag on but TYPESAFE_API_KEY missing"
140
+ return "on"
141
+
142
+
143
+ def _last_hint_path() -> Path:
144
+ return get_hermes_home() / "lithermes" / LAST_HINT_FILE
145
+
146
+
147
+ def _refuse_symlink(path: Path) -> None:
148
+ if path.is_symlink():
149
+ raise OSError(f"refusing to write through a symlink: {path.name}")
150
+
151
+
152
+ def _append_private(path: Path, payload: dict[str, Any]) -> None:
153
+ """Append one JSON line without following a symlink planted at ``path``."""
154
+ assert_within_isolation(path)
155
+ path.parent.mkdir(parents=True, exist_ok=True)
156
+ _refuse_symlink(path)
157
+ fd = os.open(path, os.O_WRONLY | os.O_APPEND | os.O_CREAT | _NOFOLLOW, 0o600)
158
+ with os.fdopen(fd, "a", encoding="utf-8") as handle:
159
+ handle.write(json.dumps(redact_obj(payload), sort_keys=True) + "\n")
160
+
161
+
162
+ def _record_hint(skill_id: str, latency_ms: int) -> None:
163
+ """Keep the last accepted hint for status and doctor: id, latency and time only."""
164
+ record = {"skill": skill_id, "latency_ms": latency_ms, "timestamp": utc_now().isoformat()}
165
+ _LAST_HINT.clear()
166
+ _LAST_HINT.update(record)
167
+ path = _last_hint_path()
168
+ temporary = path.with_name(f".{path.name}.{os.getpid()}.{threading.get_ident()}.tmp")
169
+ try:
170
+ assert_within_isolation(path)
171
+ path.parent.mkdir(parents=True, exist_ok=True)
172
+ _refuse_symlink(temporary)
173
+ fd = os.open(temporary, os.O_WRONLY | os.O_CREAT | os.O_TRUNC | _NOFOLLOW, 0o600)
174
+ if hasattr(os, "fchmod"):
175
+ os.fchmod(fd, 0o600) # a leftover temporary keeps its old mode otherwise
176
+ with os.fdopen(fd, "w", encoding="utf-8") as handle:
177
+ json.dump(record, handle, sort_keys=True)
178
+ # os.replace swaps a symlink at ``path`` for the file; it never writes through it.
179
+ os.replace(temporary, path)
180
+ except (OSError, RuntimeError): # RuntimeError: the isolation root refused the path
181
+ with contextlib.suppress(OSError):
182
+ temporary.unlink()
183
+
184
+
185
+ def last_hint() -> tuple[str, int] | None:
186
+ """Return (skill id, latency ms) of the last accepted hint, or None when unknown or unreadable."""
187
+ record: Any = dict(_LAST_HINT)
188
+ if not record:
189
+ try:
190
+ with _last_hint_path().open("rb") as handle:
191
+ record = json.loads(handle.read(MAX_LAST_HINT_BYTES + 1)[:MAX_LAST_HINT_BYTES].decode("utf-8"))
192
+ except (OSError, ValueError, UnicodeDecodeError):
193
+ return None
194
+ if not isinstance(record, dict):
195
+ return None
196
+ skill, latency = record.get("skill"), record.get("latency_ms")
197
+ if not isinstance(skill, str) or not _SKILL_ID.fullmatch(skill):
198
+ return None
199
+ if isinstance(latency, bool) or not isinstance(latency, int) or not 0 <= latency <= 600_000:
200
+ return None
201
+ return skill, latency
202
+
203
+
204
+ def status_line(env: dict[str, str] | None = None) -> str:
205
+ state = status(env)
206
+ if state != "on":
207
+ return f"Jev skill hint: {state}"
208
+ last = last_hint()
209
+ if last is None:
210
+ return "Jev skill hint: on — no hint yet"
211
+ skill, latency_ms = last
212
+ return f"Jev skill hint: on — last hint {skill} ({latency_ms / 1000:.2f}s)"
213
+
214
+
215
+ def _int_setting(env: dict[str, str], name: str, default: int, low: int, high: int) -> int:
216
+ try:
217
+ value = int((env.get(name) or "").strip())
218
+ except ValueError:
219
+ return default
220
+ return value if low <= value <= high else default
221
+
222
+
223
+ def _float_setting(env: dict[str, str], name: str, default: float) -> float:
224
+ try:
225
+ value = float((env.get(name) or "").strip())
226
+ except ValueError:
227
+ return default
228
+ return value if 0.0 <= value <= 1.0 else default
229
+
230
+
231
+ # A home folder, with or without a trailing separator, up to the next separator.
232
+ _HOME_PATHS = (
233
+ (re.compile(r"/(?:Users|home)/[^/\s]+"), "~"),
234
+ (re.compile(r"[A-Za-z]:\\Users\\[^\\/\s]+\\"), "~/"),
235
+ (re.compile(r"[A-Za-z]:\\Users\\[^\\/\s]+"), "~"),
236
+ )
237
+ _EMAIL = re.compile(r"[A-Za-z0-9._%+-]+@[A-Za-z0-9-]+(?:\.[A-Za-z0-9-]+)*\.[A-Za-z]{2,}")
238
+ _TOKENS = (
239
+ re.compile(r"-----BEGIN [A-Z0-9 ]+-----[\s\S]*?(?:-----END [A-Z0-9 ]+-----|$)"),
240
+ re.compile(r"eyJ[A-Za-z0-9_-]*\.eyJ[A-Za-z0-9_-]*(?:\.[A-Za-z0-9_-]*)?"),
241
+ re.compile(r"(?<![A-Za-z0-9])(?:sk-ant-|sk-|ghp_|gho_|github_pat_|npm_|apikey_|xox[abprs]-)[A-Za-z0-9_-]{8,}"),
242
+ re.compile(r"(?<![A-Za-z0-9])AKIA[0-9A-Z]{16}(?![A-Za-z0-9])"),
243
+ re.compile(r"(?<![A-Za-z0-9])AIza[0-9A-Za-z_-]{20,}"),
244
+ re.compile(r"[A-Za-z0-9+/_-]{32,}={0,2}"),
245
+ )
246
+ _TRAILING_TOKEN_RUN = re.compile(r"[A-Za-z0-9+/_=-]{8,}\Z")
247
+
248
+
249
+ def redact_prompt(text: str) -> str:
250
+ """Redact a bounded window, then cut to the prompt limit.
251
+
252
+ Redacting before the cut means a secret straddling the limit is matched
253
+ whole; a token-character run the cut still splits becomes ``[secret]``.
254
+ """
255
+ value = str(text or "")[:REDACTION_WINDOW_CHARS]
256
+ for pattern, replacement in _HOME_PATHS:
257
+ value = pattern.sub(replacement, value)
258
+ value = _EMAIL.sub("[email]", value)
259
+ for pattern in _TOKENS:
260
+ value = pattern.sub("[secret]", value)
261
+ if len(value) > MAX_PROMPT_CHARS:
262
+ value = _TRAILING_TOKEN_RUN.sub("[secret]", value[:MAX_PROMPT_CHARS])
263
+ return value
264
+
265
+
266
+ def eligible(user_message: str) -> bool:
267
+ """A plain top-level prompt: no slash command and no LitHermes command envelope."""
268
+ text = str(user_message or "").strip()
269
+ if len(re.sub(r"\s+", "", text)) < 4:
270
+ return False
271
+ if text.startswith("/"):
272
+ return False
273
+ # Native slash commands re-enter as injected messages carrying a route
274
+ # envelope or the activation probe contract; those turns are already routed.
275
+ return "<lithermes-" not in text and "model-emitted line" not in text
276
+
277
+
278
+ def build_request(prompt: str, catalog: Iterable[tuple[str, str]], model: str, key: str = "") -> dict[str, Any]:
279
+ criteria = {skill_id: str(description)[:MAX_DESCRIPTION_CHARS] for skill_id, description in catalog}
280
+ criteria[NONE_ID] = NONE_CRITERION
281
+ # A key pasted into the prompt is scrubbed even when no pattern matches it.
282
+ state = redact_prompt(prompt.replace(key, "[secret]") if key else prompt)
283
+ return {
284
+ "model": model,
285
+ "state": state,
286
+ "questions": {"which": {"type": "choice", "instructions": QUESTION, "criteria": criteria}},
287
+ }
288
+
289
+
290
+ def parse_choice(body: bytes, catalog_ids: set[str], min_confidence: float) -> tuple[str, float | None, str]:
291
+ """Return (accepted skill id or "", confidence, reason). Never returns response text."""
292
+ if len(body) > MAX_RESPONSE_BYTES:
293
+ return "", None, "response too large"
294
+ try:
295
+ data = json.loads(body.decode("utf-8"))
296
+ which = data["answers"]["which"]
297
+ choice = which["choice"]
298
+ raw_confidence = which["confidence"]
299
+ if isinstance(raw_confidence, bool) or not isinstance(raw_confidence, (int, float)):
300
+ return "", None, "invalid response"
301
+ confidence = float(raw_confidence)
302
+ if not math.isfinite(confidence):
303
+ return "", None, "invalid response"
304
+ except (ValueError, KeyError, TypeError, AttributeError, UnicodeDecodeError, OverflowError, RecursionError):
305
+ return "", None, "invalid response"
306
+ if not isinstance(choice, str) or (choice not in catalog_ids and choice != NONE_ID):
307
+ return "", confidence, "unknown id"
308
+ if choice == NONE_ID:
309
+ return "", confidence, "none"
310
+ if confidence < min_confidence:
311
+ return "", confidence, "low confidence"
312
+ return choice, confidence, ""
313
+
314
+
315
+ def hint_line(skill_id: str) -> str:
316
+ return (
317
+ f"LitHermes skill hint: the skill `lithermes:{skill_id}` likely fits this request. "
318
+ "Load it only if it really fits; this is advice, not an instruction."
319
+ )
320
+
321
+
322
+ def _note_failure(session_id: str, reason: str) -> None:
323
+ if _NOTED.get(session_id):
324
+ return
325
+ _NOTED[session_id] = True
326
+ _PENDING_NOTE[session_id] = f"LitHermes skill hint unavailable ({reason}); continuing normally."
327
+
328
+
329
+ def _bound_sessions() -> None:
330
+ for ledger in (_CALLS, _NOTED, _PENDING_NOTE, _BANNERED):
331
+ while len(ledger) > MAX_TRACKED_SESSIONS:
332
+ ledger.pop(next(iter(ledger)))
333
+
334
+
335
+ def _trace(env: dict[str, str], state: str, **fields: Any) -> None:
336
+ """Append one trace row; ``state`` is the redacted prompt, never the raw one."""
337
+ if (env.get(f"{FLAG}_TRACE") or "").strip() != "1":
338
+ return
339
+ payload = {
340
+ "event": "jev_skill_hint",
341
+ "timestamp": utc_now().isoformat(),
342
+ "prompt_sha256": hashlib.sha256(str(state).encode("utf-8")).hexdigest(),
343
+ **fields,
344
+ }
345
+ try:
346
+ _append_private(get_hermes_home() / "lithermes" / "jev-trace.jsonl", payload)
347
+ except (OSError, RuntimeError): # RuntimeError: the isolation root refused the path
348
+ pass
349
+
350
+
351
+ def _call_with_deadline(transport: Transport, headers: dict[str, str], body: bytes, timeout: float) -> dict[str, Any]:
352
+ """Run the transport on a daemon thread so DNS or a slow body cannot outlast the deadline."""
353
+ outcome: dict[str, Any] = {}
354
+
355
+ def run() -> None:
356
+ try:
357
+ outcome["result"] = transport(ENDPOINT, headers, body, timeout)
358
+ except Exception as exc: # noqa: BLE001 - only the category is kept
359
+ outcome["error"] = exc
360
+
361
+ worker = threading.Thread(target=run, name="lithermes-jev-hint", daemon=True)
362
+ worker.start()
363
+ worker.join(timeout)
364
+ if worker.is_alive():
365
+ return {"timeout": True}
366
+ return dict(outcome)
367
+
368
+
369
+ def pre_llm_call(
370
+ *,
371
+ session_id: str,
372
+ user_message: str,
373
+ catalog: Iterable[tuple[str, str]],
374
+ env: dict[str, str] | None = None,
375
+ transport: Transport | None = None,
376
+ ) -> str:
377
+ """Return one advisory hint line, or "" to leave the turn unchanged."""
378
+ values = _env(env)
379
+ if not _flag_on(values):
380
+ return ""
381
+ key = _key(values)
382
+ if not key or not eligible(user_message):
383
+ return ""
384
+ session = str(session_id or "")
385
+ catalog_list = [(str(skill_id), str(description)) for skill_id, description in catalog]
386
+ model = (values.get(f"{FLAG}_MODEL") or "").strip() or DEFAULT_MODEL
387
+ request = build_request(str(user_message), catalog_list, model, key)
388
+ state = request["state"]
389
+ calls = _CALLS.get(session, 0)
390
+ if calls >= _int_setting(values, f"{FLAG}_MAX_CALLS", DEFAULT_MAX_CALLS, 0, 1_000_000):
391
+ _note_failure(session, "call cap reached")
392
+ _trace(values, state, choice="", confidence=None, latency_ms=0, http_status=None, fallback_reason="call cap reached")
393
+ return ""
394
+ body = json.dumps(request, ensure_ascii=False).encode("utf-8")
395
+ if len(body) > MAX_REQUEST_BYTES:
396
+ _note_failure(session, "request too large")
397
+ _trace(values, state, choice="", confidence=None, latency_ms=0, http_status=None, fallback_reason="request too large")
398
+ return ""
399
+ _CALLS[session] = calls + 1
400
+ _bound_sessions()
401
+ timeout_ms = _int_setting(values, f"{FLAG}_TIMEOUT_MS", DEFAULT_TIMEOUT_MS, 1, MAX_TIMEOUT_MS)
402
+ headers = {
403
+ "Authorization": f"Bearer {key}",
404
+ "Content-Type": "application/json",
405
+ "Accept": "application/json",
406
+ }
407
+ started = time.monotonic()
408
+ http_status: int | None = None
409
+ response = b""
410
+ outcome = _call_with_deadline(transport or TRANSPORT, headers, body, timeout_ms / 1000.0)
411
+ if "result" in outcome:
412
+ http_status, response = outcome["result"]
413
+ reason = "" if http_status == 200 else f"HTTP {http_status}"
414
+ elif outcome.get("timeout") or isinstance(outcome.get("error"), TransportTimeout):
415
+ reason = "timeout"
416
+ else:
417
+ reason = "network error"
418
+ latency_ms = int((time.monotonic() - started) * 1000)
419
+ if reason:
420
+ _note_failure(session, reason)
421
+ _trace(values, state, choice="", confidence=None, latency_ms=latency_ms, http_status=http_status, fallback_reason=reason)
422
+ return ""
423
+ min_confidence = _float_setting(values, f"{FLAG}_MIN_CONFIDENCE", DEFAULT_MIN_CONFIDENCE)
424
+ choice, confidence, reason = parse_choice(response, {skill_id for skill_id, _ in catalog_list}, min_confidence)
425
+ if reason in {"invalid response", "response too large"}:
426
+ _note_failure(session, reason)
427
+ _trace(
428
+ values,
429
+ state,
430
+ choice=choice,
431
+ confidence=confidence,
432
+ latency_ms=latency_ms,
433
+ http_status=http_status,
434
+ fallback_reason=reason,
435
+ )
436
+ if not choice:
437
+ return ""
438
+ _record_hint(choice, latency_ms)
439
+ return hint_line(choice)
440
+
441
+
442
+ def consume_note(session_id: str) -> str:
443
+ return _PENDING_NOTE.pop(str(session_id or ""), "")
444
+
445
+
446
+ def consume_banner(session_id: str, env: dict[str, str] | None = None) -> str:
447
+ """Return the enabled banner once per session while both switches are on, else ""."""
448
+ session = str(session_id or "")
449
+ if status(env) != "on" or _BANNERED.get(session):
450
+ return ""
451
+ _BANNERED[session] = True
452
+ _bound_sessions()
453
+ return BANNER
454
+
455
+
456
+ def release_session(session_id: str) -> None:
457
+ session = str(session_id or "")
458
+ _CALLS.pop(session, None)
459
+ _NOTED.pop(session, None)
460
+ _PENDING_NOTE.pop(session, None)
461
+ _BANNERED.pop(session, None)
@@ -85,7 +85,7 @@ def render(rows, *, env=None, stream=None, json=False, mode=None) -> list[str]:
85
85
  def discipline(route: str) -> str:
86
86
  canonical = {"lit": "litwork", "litwork-loop": "lit-loop", "litwork-plan": "lit-plan",
87
87
  "durable-workflow": "lit-loop", "kanban-team": "lit-team",
88
- "korean-prose-cleanup": "lit-korean"}.get(route, route)
88
+ "korean-prose-cleanup": "lit-humanizer"}.get(route, route)
89
89
  if not re.fullmatch(r"[a-z0-9]+(?:-[a-z0-9]+)*", canonical):
90
90
  raise ValueError("invalid route discipline")
91
91
  return canonical
@@ -0,0 +1,80 @@
1
+ """Host-event receipts for the film director's look rounds.
2
+
3
+ ``post_tool_call`` sees every completed tool call. When ``vision_analyze``
4
+ loads a stills PNG that belongs to a motion run directory (one holding
5
+ ``treatment.json`` and ``stills/stills.json``), this module appends a receipt
6
+ with the file's SHA-256 to ``<run>/.run/host-events.jsonl``; when a terminal
7
+ call runs the motion CLI with an absolute ``--out`` it appends a marker. The
8
+ motion ``complete`` command then requires a receipt for every frame the last
9
+ look round lists. Nothing else is written, and a failure here never reaches
10
+ the tool call.
11
+ """
12
+
13
+ from __future__ import annotations
14
+
15
+ import hashlib
16
+ import os
17
+ import shlex
18
+ from pathlib import Path
19
+ from typing import Any
20
+ from urllib.parse import unquote, urlsplit
21
+
22
+ try:
23
+ from .core_runtime import append_jsonl
24
+ except (ImportError, ModuleNotFoundError):
25
+ from core_runtime import append_jsonl
26
+
27
+ _MAX_LEVELS = 4
28
+
29
+
30
+ def _run_dir(path: Path) -> Path | None:
31
+ for parent in list(path.parents)[:_MAX_LEVELS]:
32
+ if (parent / "treatment.json").is_file() and (parent / "stills" / "stills.json").is_file():
33
+ return parent
34
+ return None
35
+
36
+
37
+ def _local_image(value: Any, workspace: Any = None) -> Path | None:
38
+ text = str(value or "").strip()
39
+ if not text or text.startswith(("http://", "https://", "data:")):
40
+ return None
41
+ if text.startswith("file://"):
42
+ text = unquote(urlsplit(text).path)
43
+ path = Path(os.path.expanduser(text))
44
+ if not path.is_absolute():
45
+ base = Path(str(workspace)) if workspace else Path.cwd()
46
+ path = base / path
47
+ try:
48
+ path = path.resolve()
49
+ except OSError:
50
+ return None
51
+ return path if path.is_file() and path.suffix.lower() == ".png" else None
52
+
53
+
54
+ def _append(run: Path, event: dict[str, Any]) -> None:
55
+ append_jsonl(run / ".run" / "host-events.jsonl", event)
56
+
57
+
58
+ def observe(tool_name: str, args: Any, *, workspace: Any = None) -> None:
59
+ """Record a motion receipt for a completed tool call, when it is one."""
60
+ try:
61
+ params = args if isinstance(args, dict) else {}
62
+ if tool_name == "vision_analyze":
63
+ image = _local_image(params.get("image_url"), workspace)
64
+ run = _run_dir(image) if image else None
65
+ if run:
66
+ digest = hashlib.sha256(image.read_bytes()).hexdigest()
67
+ _append(run, {"tool": "vision_analyze", "file": image.relative_to(run.resolve()).as_posix(), "sha256": digest})
68
+ elif tool_name == "terminal":
69
+ command = str(params.get("command") or "")
70
+ if "motion.mjs" not in command:
71
+ return
72
+ words = shlex.split(command, posix=True)
73
+ for index, word in enumerate(words[:-1]):
74
+ if word == "--out":
75
+ out = Path(os.path.expanduser(words[index + 1]))
76
+ if out.is_absolute() and (out / "treatment.json").is_file():
77
+ _append(out, {"tool": "terminal", "motion": True})
78
+ break
79
+ except Exception: # noqa: BLE001 - an observer must never break the tool call it watches
80
+ return