@litfamily/lithermes 1.0.7 → 1.0.9

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (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 +76 -8
  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
@@ -1,140 +1,52 @@
1
- """Declaration-driven hedge findings for completed reader-facing writes.
1
+ """Changed-text LitHumanizer enforcement at Hermes' supported file hooks.
2
2
 
3
- Hermes discards ``post_tool_call`` return values. This module therefore records
4
- only bounded, trusted finding metadata at that event and renders it through the
5
- next ``pre_llm_call`` context. Artifact text and paths never enter model context.
3
+ ``pre_tool_call`` can deny ``write_file`` and ``patch`` before persistence. The
4
+ ``post_tool_call`` observer cannot undo a completed Office/PDF export, so those
5
+ checks are advisory and ask for a source edit and rebuild.
6
6
  """
7
7
 
8
8
  from __future__ import annotations
9
9
 
10
+ import difflib
11
+ import json
10
12
  import os
11
13
  import re
12
14
  import stat
15
+ import subprocess
16
+ import sys
13
17
  from dataclasses import dataclass
14
18
  from pathlib import Path
15
19
  from typing import Iterable
16
20
 
17
21
 
18
- SKILLS_ROOT = Path(__file__).resolve().parent / "skills"
22
+ PLUGIN_ROOT = Path(__file__).resolve().parent
23
+ DETECTOR = PLUGIN_ROOT / "skills" / "lit-humanizer" / "scripts" / "detect.py"
19
24
  MAX_SESSIONS = 64
20
25
  MAX_FILE_BYTES = 2 * 1024 * 1024
26
+ MAX_DETECT_BYTES = 512 * 1024
27
+ MAX_DETECT_OUTPUT = 2 * 1024 * 1024
21
28
  MAX_ARTIFACT_PATHS = 32
22
29
  MAX_AGGREGATE_FILE_BYTES = 4 * 1024 * 1024
23
- MAX_CONTEXT_FINDINGS = 100
24
- READER_FACING_SUFFIXES = frozenset(
25
- {".adoc", ".csv", ".htm", ".html", ".md", ".mdx", ".rst", ".tex", ".txt"}
30
+ MAX_CONTEXT_LINES = 6
31
+ DETECT_TIMEOUT_SECONDS = 3
32
+ TEXT_SUFFIXES = frozenset({".adoc", ".csv", ".htm", ".html", ".md", ".mdx", ".rst", ".svg", ".tex", ".txt"})
33
+ OFFICE_SUFFIXES = frozenset({".docx", ".pptx", ".pdf"})
34
+ READER_FACING_SUFFIXES = TEXT_SUFFIXES | OFFICE_SUFFIXES
35
+
36
+ _QUOTED_SPAN = re.compile(
37
+ r'"([^"\n]{1,2000})"|“([^”\n]{1,2000})”|'
38
+ r"‘([^’\n]{1,2000})’|«([^»\n]{1,2000})»|"
39
+ r"(?<!\w)'([^'\n]{8,1000})'(?!\w)"
26
40
  )
27
- CHANNEL_BY_GENRE = {
28
- "client_deliverable": "reply",
29
- "internal_analysis": "designated_section",
30
- "audit_report": "methodology_paragraph",
31
- "working_note": "inline",
32
- "no_artifact": "reply",
33
- }
34
- ROUTE_SKILL_ALIASES = {
35
- "korean-prose-cleanup": "lit-korean",
36
- }
37
- REFERENCE_CONTRACT_SKILLS = frozenset({"frontend-ui-ux", "visual-qa"})
38
-
39
- _OUTPUT_BLOCK = re.compile(
40
- r"(?ms)^## #contract\.output_channels\s*$\s*^```yaml\s*$\n(?P<body>.*?)^```\s*$"
41
- )
42
- _SCALAR = re.compile(
43
- r"^\s*(artifact_genre|limitations_channel)\s*:\s*([a-z_]+)\s*$",
44
- re.MULTILINE,
45
- )
46
- _FENCE = re.compile(r"^\s*(`{3,}|~{3,})")
47
- _YAML_OR_JSON_SCALAR = re.compile(
48
- r'^\s*(?:[A-Za-z_][A-Za-z0-9_.-]*|"[^"]+"|\'[^\']+\')\s*:\s*.+?\s*,?\s*$'
49
- )
50
- _QUOTED = re.compile(r'(["\'`])([^"\'`]+)\1')
51
- _STATUS_VALUE = re.compile(
52
- r"^(?:pending|blocked|in[_ -]?progress|done|complete|pass|fail|보류\s*중|진행\s*중|완료|차단)$",
53
- re.IGNORECASE,
54
- )
55
-
56
- _EVIDENCE_NOUN_KO = (
57
- r"(?:근거|자료|데이터|측정(?:값|치|자료)|관찰\s*기록|사용자\s*관찰|실험\s*결과|"
58
- r"검증\s*결과|평가\s*자료|출처|문헌|증거|수치)"
59
- )
60
- _ABSENCE_KO = (
61
- r"(?:없(?:다|습니다|음|어|어서|으므로|기\s*때문)?|부재|제공되지\s*않|주어지지\s*않|"
62
- r"확인되지\s*않|검증되지\s*않)"
63
- )
64
- _ABILITY_KO = r"(?:(?:평가|판단|산정)할\s*수\s*없|알\s*수\s*없)"
65
- _ABSENT_EVIDENCE_KO = re.compile(
66
- rf"(?:{_EVIDENCE_NOUN_KO}.{{0,48}}{_ABSENCE_KO}|{_ABSENCE_KO}.{{0,24}}{_EVIDENCE_NOUN_KO}|"
67
- rf"{_EVIDENCE_NOUN_KO}.{{0,64}}{_ABILITY_KO})",
68
- re.IGNORECASE,
69
- )
70
- _ABSENT_EVIDENCE_EN = re.compile(
71
- r"(?:no\s+(?:supporting\s+)?evidence\s+yet|not\s+yet\s+substantiated|"
72
- r"(?:evidence|data|measurements?|observations?|records?|sources?|citations?|test\s+results?)"
73
- r".{0,48}(?:is|are|was|were)?\s*(?:absent|missing|unavailable|not\s+provided|not\s+verified)|"
74
- r"(?:cannot|could\s+not)\s+(?:assess|determine|calculate).{0,48}"
75
- r"(?:evidence|data|measurements?|observations?|records?|sources?|citations?))",
76
- re.IGNORECASE,
77
- )
78
-
79
- _PATTERNS = (
80
- (
81
- "deferred",
82
- re.compile(
83
- r"보류\s*중|별도로\s*진행|추후\s*진행|to be determined separately",
84
- re.IGNORECASE,
85
- ),
86
- ),
87
- ("absent-evidence", _ABSENT_EVIDENCE_KO),
88
- ("absent-evidence", _ABSENT_EVIDENCE_EN),
89
- (
90
- "scope-limit",
91
- re.compile(
92
- r"한정됩니다|국한됩니다|범위\s*내에서만|limited to the provided evidence",
93
- re.IGNORECASE,
94
- ),
95
- ),
96
- (
97
- "negated-action",
98
- re.compile(
99
- r"하지\s*않았습니다|포함되지\s*않습니다|다루지\s*않습니다|was not performed|is not included",
100
- re.IGNORECASE,
101
- ),
102
- ),
103
- (
104
- "self-protection",
105
- re.compile(
106
- r"참고용|추가\s*검증이\s*필요|완전하지\s*않을\s*수\s*있|for reference only|may be incomplete",
107
- re.IGNORECASE,
108
- ),
109
- ),
110
- ("process-meta", re.compile(r"as an AI|이\s*작업에서는|프롬프트가", re.IGNORECASE)),
111
- )
112
-
113
-
114
- @dataclass(frozen=True)
115
- class OutputChannel:
116
- artifact_genre: str
117
- limitations_channel: str
118
-
119
-
120
- @dataclass(frozen=True)
121
- class Finding:
122
- pattern_class: str
123
- line_number: int
124
-
125
-
126
- @dataclass(frozen=True)
127
- class PendingReceipt:
128
- skill_id: str
129
- contract: OutputChannel
130
- finding_count: int
131
- line_numbers: tuple[int, ...]
132
- file_count: int
41
+ _INTERNAL_FILE = re.compile(r"(?:^|/)(?:plans|evidence|ledgers?|\.hermes|\.lit[^/]*)(?:/|$)|(?:^|/)HANDOFF[^/]*$", re.I)
42
+ _V4A_FILE = re.compile(r"^\*\*\* (Add|Update|Delete) File: (.+)$")
43
+ _V4A_MOVE = re.compile(r"^\*\*\* Move to: (.+)$")
44
+ _RULE_ID = re.compile(r"^[a-z0-9][a-z0-9-]{0,79}$")
133
45
 
134
46
 
135
47
  @dataclass(frozen=True)
136
- class _StableText:
137
- text: str
48
+ class _StableFile:
49
+ data: bytes
138
50
  byte_count: int
139
51
 
140
52
 
@@ -143,27 +55,23 @@ class _ReadBudgetExceeded:
143
55
 
144
56
 
145
57
  _READ_BUDGET_EXCEEDED = _ReadBudgetExceeded()
146
-
147
-
148
- _ACTIVE_SKILLS: dict[str, str] = {}
149
58
  _ROOT_TURNS: dict[str, str] = {}
150
- _PENDING_RECEIPTS: dict[str, list[PendingReceipt]] = {}
59
+ _USER_QUOTES: dict[str, tuple[str, ...]] = {}
60
+ _PENDING_ADVISORIES: dict[str, list[str]] = {}
151
61
 
152
62
 
153
63
  def reset_state() -> None:
154
- """Clear in-memory hook state; used by host lifecycle and isolated drivers."""
155
- _ACTIVE_SKILLS.clear()
156
64
  _ROOT_TURNS.clear()
157
- _PENDING_RECEIPTS.clear()
65
+ _USER_QUOTES.clear()
66
+ _PENDING_ADVISORIES.clear()
158
67
 
159
68
 
160
69
  def release_session(session_id: object) -> None:
161
70
  key = str(session_id or "")
162
- if not key:
163
- return
164
- _ACTIVE_SKILLS.pop(key, None)
165
- _ROOT_TURNS.pop(key, None)
166
- _PENDING_RECEIPTS.pop(key, None)
71
+ if key:
72
+ _ROOT_TURNS.pop(key, None)
73
+ _USER_QUOTES.pop(key, None)
74
+ _PENDING_ADVISORIES.pop(key, None)
167
75
 
168
76
 
169
77
  def _bounded_set(mapping: dict[str, object], key: str, value: object) -> None:
@@ -173,165 +81,60 @@ def _bounded_set(mapping: dict[str, object], key: str, value: object) -> None:
173
81
  mapping.pop(next(iter(mapping)), None)
174
82
 
175
83
 
176
- def _contract_path(skill_id: str) -> Path:
177
- skill_root = SKILLS_ROOT / skill_id
178
- entrypoint = skill_root / "SKILL.md"
179
- if skill_id not in REFERENCE_CONTRACT_SKILLS:
180
- return entrypoint
181
- if entrypoint.is_file() and "## #contract.output_channels" in entrypoint.read_text(encoding="utf-8"):
182
- raise ValueError(f"lazy-reference skill declares output channel in entrypoint: {skill_id}")
183
- return skill_root / "references" / "complete-contract.md"
184
-
185
-
186
- def load_output_channel(skill_id: str) -> OutputChannel:
187
- if not re.fullmatch(r"[a-z0-9-]+", str(skill_id or "")):
188
- raise ValueError("invalid skill id")
189
- path = _contract_path(skill_id)
190
- text = path.read_text(encoding="utf-8")
191
- match = _OUTPUT_BLOCK.search(text)
192
- if match is None:
193
- raise ValueError(f"output channel declaration missing for {skill_id}")
194
- values = dict(_SCALAR.findall(match.group("body")))
195
- genre = values.get("artifact_genre", "")
196
- channel = values.get("limitations_channel", "")
197
- if genre not in CHANNEL_BY_GENRE or CHANNEL_BY_GENRE[genre] != channel:
198
- raise ValueError(f"invalid output channel declaration for {skill_id}")
199
- return OutputChannel(genre, channel)
200
-
201
-
202
- def activate_skill(session_id: object, route_or_skill: object) -> bool:
203
- key = str(session_id or "")
204
- candidate = ROUTE_SKILL_ALIASES.get(str(route_or_skill or ""), str(route_or_skill or ""))
205
- if not key:
206
- return False
207
- try:
208
- load_output_channel(candidate)
209
- except (OSError, UnicodeError, ValueError):
210
- _ACTIVE_SKILLS.pop(key, None)
211
- return False
212
- _bounded_set(_ACTIVE_SKILLS, key, candidate)
213
- return True
214
-
215
-
216
- def clear_active_skill(session_id: object) -> None:
217
- """End the previous root turn without discarding a pending finding receipt."""
218
- _ACTIVE_SKILLS.pop(str(session_id or ""), None)
219
-
220
-
221
84
  def begin_root_turn(session_id: object, turn_id: object) -> None:
222
- """Rebind guard state only at a host-authored root-turn boundary.
223
-
224
- Current Hermes passes a fresh ``turn_id`` into ``pre_llm_call`` once per
225
- root turn. Repeated callbacks carrying that same identity belong to the
226
- assistant/tool loop and must keep the active skill after an advisory is
227
- consumed. Missing identities are not promoted into boundaries from raw user
228
- text; session lifecycle hooks remain the fallback reset surface.
229
- """
230
85
  key = str(session_id or "")
231
86
  identity = turn_id if isinstance(turn_id, str) else ""
232
87
  if not key or not identity or len(identity.encode("utf-8")) > 512:
233
88
  return
234
89
  if _ROOT_TURNS.get(key) != identity:
235
- clear_active_skill(key)
90
+ _USER_QUOTES.pop(key, None)
236
91
  _bounded_set(_ROOT_TURNS, key, identity)
237
92
 
238
93
 
239
- def _quoted_status_contains(line: str, start: int, end: int) -> bool:
240
- for match in _QUOTED.finditer(line):
241
- if (
242
- match.start(2) <= start
243
- and end <= match.end(2)
244
- and _STATUS_VALUE.fullmatch(match.group(2).strip())
245
- ):
246
- return True
247
- return False
248
-
249
-
250
- def _status_table_line(line: str) -> bool:
251
- if "|" not in line:
252
- return False
253
- cells = [cell.strip().strip("`\"'") for cell in line.strip().strip("|").split("|")]
254
- return any(_STATUS_VALUE.fullmatch(cell) for cell in cells)
255
-
256
-
257
- def _methodology_lines(lines: list[str]) -> set[int]:
258
- paragraphs: list[list[int]] = []
259
- current: list[int] = []
260
- for index, line in enumerate(lines):
261
- if line.strip():
262
- current.append(index)
263
- elif current:
264
- paragraphs.append(current)
265
- current = []
266
- if current:
267
- paragraphs.append(current)
268
- marker = re.compile(r"(?:methodology|method|방법론|검토\s*방법)", re.IGNORECASE)
269
- for position, paragraph in enumerate(paragraphs):
270
- if not marker.search(" ".join(lines[index] for index in paragraph)):
271
- continue
272
- allowed = set(paragraph)
273
- if (
274
- len(paragraph) == 1
275
- and lines[paragraph[0]].lstrip().startswith("#")
276
- and position + 1 < len(paragraphs)
277
- ):
278
- allowed.update(paragraphs[position + 1])
279
- return allowed
280
- return set()
281
-
282
-
283
- def _designated_section_lines(lines: list[str]) -> set[int]:
284
- heading = re.compile(r"^\s*(#{1,6})\s+.*(?:limitations?|한계|제한)", re.IGNORECASE)
285
- allowed: set[int] = set()
286
- active_level: int | None = None
287
- for index, line in enumerate(lines):
288
- matched = heading.match(line)
289
- if matched:
290
- active_level = len(matched.group(1))
291
- allowed.add(index)
292
- continue
293
- next_heading = re.match(r"^\s*(#{1,6})\s+", line)
294
- if active_level is not None and next_heading and len(next_heading.group(1)) <= active_level:
295
- active_level = None
296
- if active_level is not None:
297
- allowed.add(index)
298
- return allowed
299
-
300
-
301
- def scan_text(text: str, contract: OutputChannel) -> list[Finding]:
302
- if contract.artifact_genre in {"working_note", "no_artifact"}:
303
- return []
304
- lines = str(text or "").splitlines()
305
- allowed = (
306
- _methodology_lines(lines)
307
- if contract.artifact_genre == "audit_report"
308
- else _designated_section_lines(lines)
309
- if contract.artifact_genre == "internal_analysis"
310
- else set()
311
- )
312
- findings: list[Finding] = []
313
- fence: str | None = None
314
- for index, line in enumerate(lines):
315
- fence_match = _FENCE.match(line)
316
- if fence_match:
317
- marker = fence_match.group(1)[0]
318
- fence = None if fence == marker else marker if fence is None else fence
319
- continue
320
- if fence is not None or index in allowed:
321
- continue
322
- scalar = bool(_YAML_OR_JSON_SCALAR.fullmatch(line))
323
- table = _status_table_line(line)
324
- for pattern_class, pattern in _PATTERNS:
325
- match = pattern.search(line)
326
- if match is None:
327
- continue
328
- if pattern_class == "deferred" and (
329
- scalar or table or _quoted_status_contains(line, match.start(), match.end())
330
- ):
331
- continue
332
- findings.append(Finding(pattern_class, index + 1))
333
- break
334
- return findings
94
+ def capture_user_text(session_id: object, user_message: object, turn_id: object = None) -> None:
95
+ """Keep only bounded exact quote spans, never the full user message."""
96
+ key = str(session_id or "")
97
+ message = user_message if isinstance(user_message, str) else ""
98
+ if not key or not message:
99
+ return
100
+ identity = turn_id if isinstance(turn_id, str) else _ROOT_TURNS.get(key, "")
101
+ if identity and _ROOT_TURNS.get(key) not in (None, identity):
102
+ _USER_QUOTES.pop(key, None)
103
+ quotes: list[str] = []
104
+ used = 0
105
+ for line in message.splitlines():
106
+ stripped = line.lstrip()
107
+ if stripped.startswith("> ") and len(stripped) > 2:
108
+ quote = stripped[2:].strip()
109
+ if quote:
110
+ quotes.append(quote[:2000])
111
+ for match in _QUOTED_SPAN.finditer(message[:16_384]):
112
+ quote = next((group for group in match.groups() if group), "")
113
+ if quote:
114
+ quotes.append(quote[:2000])
115
+ bounded: list[str] = []
116
+ for quote in quotes:
117
+ quote = quote.strip()
118
+ if quote and quote not in bounded and len(bounded) < 16 and used + len(quote) <= 8000:
119
+ bounded.append(quote)
120
+ used += len(quote)
121
+ _bounded_set(_USER_QUOTES, key, tuple(bounded))
122
+
123
+
124
+ def _mask_exact_user_quotes(text: str, session_id: str) -> str:
125
+ masked = text
126
+ for quote in _USER_QUOTES.get(session_id, ()):
127
+ masked = masked.replace(quote, "".join("\n" if char == "\n" else " " for char in quote))
128
+ return masked
129
+
130
+
131
+ def activate_skill(session_id: object, route_or_skill: object) -> bool:
132
+ """Compatibility no-op: reader-facing checks do not depend on skill genre."""
133
+ return bool(str(session_id or ""))
134
+
135
+
136
+ def clear_active_skill(session_id: object) -> None:
137
+ """Compatibility no-op; guards are always active for supported paths."""
335
138
 
336
139
 
337
140
  def _directory_flags() -> int | None:
@@ -354,16 +157,17 @@ def _relative_artifact_path(path_text: str, workspace: Path) -> Path | None:
354
157
  not relative.parts
355
158
  or any(part in {"", ".", ".."} for part in relative.parts)
356
159
  or relative.suffix.lower() not in READER_FACING_SUFFIXES
160
+ or _INTERNAL_FILE.search(relative.as_posix())
357
161
  ):
358
162
  return None
359
163
  return relative
360
164
 
361
165
 
362
- def _read_stable_text_file_result(
166
+ def _read_stable_file_result(
363
167
  path_text: str,
364
168
  workspace: Path,
365
169
  byte_limit: int,
366
- ) -> _StableText | _ReadBudgetExceeded | None:
170
+ ) -> _StableFile | _ReadBudgetExceeded | None:
367
171
  relative = _relative_artifact_path(path_text, workspace)
368
172
  directory_flags = _directory_flags()
369
173
  if relative is None or directory_flags is None or byte_limit < 0:
@@ -411,10 +215,7 @@ def _read_stable_text_file_result(
411
215
  return None
412
216
  if initial.st_size > read_limit:
413
217
  return _READ_BUDGET_EXCEEDED
414
- edges.append(
415
- (parent_fd, relative.parts[-1], (initial.st_dev, initial.st_ino), False)
416
- )
417
-
218
+ edges.append((parent_fd, relative.parts[-1], (initial.st_dev, initial.st_ino), False))
418
219
  chunks: list[bytes] = []
419
220
  total = 0
420
221
  while total <= read_limit:
@@ -423,10 +224,9 @@ def _read_stable_text_file_result(
423
224
  break
424
225
  chunks.append(chunk)
425
226
  total += len(chunk)
426
- raw = b"".join(chunks)
427
- if len(raw) > read_limit:
227
+ data = b"".join(chunks)
228
+ if len(data) > read_limit:
428
229
  return _READ_BUDGET_EXCEEDED
429
-
430
230
  final = os.fstat(artifact_fd)
431
231
  if (
432
232
  not stat.S_ISREG(final.st_mode)
@@ -434,20 +234,16 @@ def _read_stable_text_file_result(
434
234
  or final.st_size != initial.st_size
435
235
  or final.st_mtime_ns != initial.st_mtime_ns
436
236
  or final.st_ctime_ns != initial.st_ctime_ns
437
- or len(raw) != initial.st_size
237
+ or len(data) != initial.st_size
438
238
  ):
439
239
  return None
440
240
  for parent_fd, name, identity, is_directory in edges:
441
241
  current = os.stat(name, dir_fd=parent_fd, follow_symlinks=False)
442
- correct_type = (
443
- stat.S_ISDIR(current.st_mode)
444
- if is_directory
445
- else stat.S_ISREG(current.st_mode)
446
- )
242
+ correct_type = stat.S_ISDIR(current.st_mode) if is_directory else stat.S_ISREG(current.st_mode)
447
243
  if (current.st_dev, current.st_ino) != identity or not correct_type:
448
244
  return None
449
- return _StableText(raw.decode("utf-8"), len(raw))
450
- except (OSError, UnicodeError, ValueError):
245
+ return _StableFile(data, len(data))
246
+ except (OSError, ValueError):
451
247
  return None
452
248
  finally:
453
249
  if artifact_fd >= 0:
@@ -462,9 +258,25 @@ def _read_stable_text_file_result(
462
258
  pass
463
259
 
464
260
 
261
+ def _read_stable_text_file_result(
262
+ path_text: str,
263
+ workspace: Path,
264
+ byte_limit: int,
265
+ ) -> _StableFile | _ReadBudgetExceeded | None:
266
+ result = _read_stable_file_result(path_text, workspace, byte_limit)
267
+ if isinstance(result, _StableFile) and Path(path_text).suffix.lower() not in TEXT_SUFFIXES:
268
+ return None
269
+ return result
270
+
271
+
465
272
  def _read_stable_text_file(path_text: str, workspace: Path) -> str | None:
466
273
  result = _read_stable_text_file_result(path_text, workspace, MAX_FILE_BYTES)
467
- return result.text if isinstance(result, _StableText) else None
274
+ if not isinstance(result, _StableFile):
275
+ return None
276
+ try:
277
+ return result.data.decode("utf-8")
278
+ except UnicodeError:
279
+ return None
468
280
 
469
281
 
470
282
  def _bounded_artifact_paths(paths: Iterable[object]) -> list[object] | None:
@@ -482,81 +294,290 @@ def _bounded_artifact_paths(paths: Iterable[object]) -> list[object] | None:
482
294
  return bounded
483
295
 
484
296
 
297
+ def _queue_advisory(session_id: str, message: str) -> None:
298
+ if not session_id:
299
+ return
300
+ pending = list(_PENDING_ADVISORIES.get(session_id, ()))
301
+ if message not in pending:
302
+ pending.append(message)
303
+ _bounded_set(_PENDING_ADVISORIES, session_id, pending[-8:])
304
+
305
+
306
+ def consume_context(session_id: object) -> str:
307
+ key = str(session_id or "")
308
+ messages = _PENDING_ADVISORIES.pop(key, ())
309
+ return "\n".join(messages)
310
+
311
+
312
+ def _path_is_reader_copy(path_text: str, workspace: Path) -> bool:
313
+ return _relative_artifact_path(path_text, workspace) is not None
314
+
315
+
316
+ def _changed_lines(previous: str, proposed: str) -> set[int]:
317
+ old_lines = previous.splitlines(keepends=True)
318
+ new_lines = proposed.splitlines(keepends=True)
319
+ changed: set[int] = set()
320
+ for tag, _old_start, _old_end, new_start, new_end in difflib.SequenceMatcher(
321
+ None, old_lines, new_lines, autojunk=True
322
+ ).get_opcodes():
323
+ if tag in {"replace", "insert"}:
324
+ changed.update(range(new_start + 1, new_end + 1))
325
+ return changed
326
+
327
+
328
+ def _run_detector(text: str, path_text: str) -> list[dict] | None:
329
+ encoded = text.encode("utf-8")
330
+ if len(encoded) > MAX_DETECT_BYTES:
331
+ return None
332
+ payload = json.dumps({"text": text, "file": path_text}, ensure_ascii=False).encode("utf-8")
333
+ if len(payload) > MAX_DETECT_BYTES + 16_384:
334
+ return None
335
+ try:
336
+ result = subprocess.run(
337
+ [sys.executable, "-B", "-I", str(DETECTOR), "--stdin-json"],
338
+ input=payload,
339
+ capture_output=True,
340
+ timeout=DETECT_TIMEOUT_SECONDS,
341
+ check=False,
342
+ )
343
+ except (OSError, subprocess.TimeoutExpired):
344
+ return None
345
+ if result.returncode != 0 or len(result.stdout) > MAX_DETECT_OUTPUT:
346
+ return None
347
+ try:
348
+ findings = json.loads(result.stdout.decode("utf-8"))
349
+ except (UnicodeError, json.JSONDecodeError):
350
+ return None
351
+ if not isinstance(findings, list) or len(findings) > 4096:
352
+ return None
353
+ for finding in findings:
354
+ if (
355
+ not isinstance(finding, dict)
356
+ or not _RULE_ID.fullmatch(str(finding.get("rule") or ""))
357
+ or finding.get("severity") not in {"block", "warn"}
358
+ or not isinstance(finding.get("line"), int)
359
+ or not isinstance(finding.get("line_end"), int)
360
+ or finding["line"] < 1
361
+ or finding["line_end"] < finding["line"]
362
+ or not isinstance(finding.get("match"), str)
363
+ ):
364
+ return None
365
+ return findings
366
+
367
+
368
+ def _changed_findings(text: str, path_text: str, changed: set[int], session_id: str) -> list[dict] | None:
369
+ findings = _run_detector(_mask_exact_user_quotes(text, session_id), path_text)
370
+ if findings is None:
371
+ return None
372
+ return [
373
+ finding
374
+ for finding in findings
375
+ if any(finding["line"] <= line <= finding["line_end"] for line in changed)
376
+ ]
377
+
378
+
379
+ def _block_message(findings: list[dict]) -> dict[str, str] | None:
380
+ blocks = [finding for finding in findings if finding["severity"] == "block"]
381
+ if not blocks:
382
+ return None
383
+ refs = ", ".join(f"{item['rule']}:{item['line']}" for item in blocks[:5])
384
+ extra = f" (+{len(blocks) - 5})" if len(blocks) > 5 else ""
385
+ return {
386
+ "action": "block",
387
+ "message": f"LitHumanizer blocked {len(blocks)} block-tier finding(s) in added prose ({refs}{extra}). Revise the added wording; warnings remain contextual review signals.",
388
+ }
389
+
390
+
391
+ def _warn_if_needed(session_id: str, findings: list[dict]) -> None:
392
+ warnings = [finding for finding in findings if finding["severity"] == "warn"]
393
+ if warnings:
394
+ refs = ", ".join(f"{item['rule']}:{item['line']}" for item in warnings[:5])
395
+ _queue_advisory(session_id, f"LitHumanizer warning-tier review signal(s) in added prose: {refs}. Consider them in context; they are not a ban or authorship judgment.")
396
+
397
+
398
+ def _fail_open(session_id: str) -> None:
399
+ _queue_advisory(session_id, "LitHumanizer check unavailable; the write was allowed. Run the detector manually before delivery.")
400
+
401
+
402
+ def _read_previous(path_text: str, workspace: Path) -> str | None:
403
+ result = _read_stable_text_file_result(path_text, workspace, MAX_FILE_BYTES)
404
+ if isinstance(result, _StableFile):
405
+ try:
406
+ return result.data.decode("utf-8")
407
+ except UnicodeError:
408
+ return None
409
+ target = Path(path_text).expanduser()
410
+ target = target if target.is_absolute() else workspace / target
411
+ if result is None and not target.exists() and not target.is_symlink():
412
+ return ""
413
+ return None
414
+
415
+
416
+ def _check_text_change(session_id: str, path_text: str, proposed: str, workspace: Path) -> dict[str, str] | None:
417
+ if not _path_is_reader_copy(path_text, workspace):
418
+ return None
419
+ if len(proposed.encode("utf-8")) > MAX_DETECT_BYTES:
420
+ _fail_open(session_id)
421
+ return None
422
+ previous = _read_previous(path_text, workspace)
423
+ if previous is None:
424
+ _fail_open(session_id)
425
+ return None
426
+ if len(previous.encode("utf-8")) > MAX_DETECT_BYTES:
427
+ _fail_open(session_id)
428
+ return None
429
+ changed = _changed_lines(previous, proposed)
430
+ if not changed:
431
+ return None
432
+ findings = _changed_findings(proposed, path_text, changed, session_id)
433
+ if findings is None:
434
+ _fail_open(session_id)
435
+ return None
436
+ _warn_if_needed(session_id, findings)
437
+ return _block_message(findings)
438
+
439
+
440
+ def _patch_added_chunks(patch_text: str) -> list[tuple[str, str]]:
441
+ chunks: list[tuple[str, str]] = []
442
+ path = ""
443
+ kind = ""
444
+ added: list[str] = []
445
+
446
+ def flush() -> None:
447
+ nonlocal added
448
+ if path and kind in {"Add", "Update"} and added:
449
+ chunks.append((path, "\n".join(added)))
450
+ added = []
451
+
452
+ for line in patch_text.splitlines():
453
+ header = _V4A_FILE.match(line)
454
+ if header:
455
+ flush()
456
+ kind, path = header.group(1), header.group(2).strip()
457
+ elif _V4A_MOVE.match(line):
458
+ flush()
459
+ elif line.startswith("+++") or line.startswith("---"):
460
+ flush()
461
+ elif line.startswith("+"):
462
+ added.append(line[1:])
463
+ else:
464
+ flush()
465
+ flush()
466
+ return chunks
467
+
468
+
469
+ def pre_tool_call(
470
+ tool_name: object,
471
+ args: object,
472
+ session_id: object,
473
+ *,
474
+ workspace: object = None,
475
+ ) -> dict[str, str] | None:
476
+ """Block block-tier findings before Hermes persists a supported text edit."""
477
+ name = str(tool_name or "")
478
+ payload = args if isinstance(args, dict) else {}
479
+ key = str(session_id or "")
480
+ if not key or name not in {"write_file", "patch"}:
481
+ return None
482
+ try:
483
+ root = Path(workspace or Path.cwd()).expanduser().resolve(strict=True)
484
+ except (OSError, RuntimeError):
485
+ _fail_open(key)
486
+ return None
487
+ if name == "write_file":
488
+ path_text = str(payload.get("path") or "")
489
+ content = payload.get("content")
490
+ if isinstance(content, str):
491
+ return _check_text_change(key, path_text, content, root)
492
+ return None
493
+ mode = str(payload.get("mode") or "replace").lower()
494
+ if mode == "replace":
495
+ path_text = str(payload.get("path") or "")
496
+ old_string = payload.get("old_string")
497
+ new_string = payload.get("new_string")
498
+ if not isinstance(old_string, str) or not isinstance(new_string, str):
499
+ return None
500
+ previous = _read_previous(path_text, root)
501
+ if previous is None or old_string not in previous:
502
+ _fail_open(key)
503
+ return None
504
+ proposed = previous.replace(old_string, new_string) if payload.get("replace_all") else previous.replace(old_string, new_string, 1)
505
+ return _check_text_change(key, path_text, proposed, root)
506
+ if mode == "patch" and isinstance(payload.get("patch"), str):
507
+ for path_text, added_text in _patch_added_chunks(payload["patch"]):
508
+ if not _path_is_reader_copy(path_text, root):
509
+ continue
510
+ findings = _changed_findings(added_text, path_text, set(range(1, len(added_text.splitlines()) + 1)), key)
511
+ if findings is None:
512
+ _fail_open(key)
513
+ continue
514
+ _warn_if_needed(key, findings)
515
+ denial = _block_message(findings)
516
+ if denial:
517
+ return denial
518
+ return None
519
+
520
+
521
+ def _extract_office(data: bytes, suffix: str) -> str:
522
+ try:
523
+ import humanizer_office
524
+ except ImportError:
525
+ from . import humanizer_office
526
+ if suffix == ".pdf":
527
+ return humanizer_office.extract_pdf_bytes(data)
528
+ return humanizer_office.extract_office_bytes(data, suffix)
529
+
530
+
485
531
  def observe_completed_paths(
486
532
  session_id: object,
487
533
  paths: Iterable[object],
488
534
  *,
489
535
  workspace: object = None,
490
536
  ) -> None:
537
+ """Advise after supported Office/PDF exports; this observer cannot deny."""
491
538
  key = str(session_id or "")
492
- skill_id = _ACTIVE_SKILLS.get(key)
493
- if not key or not skill_id:
494
- return
495
- try:
496
- contract = load_output_channel(skill_id)
497
- except (OSError, UnicodeError, ValueError):
498
- return
499
- if contract.artifact_genre in {"working_note", "no_artifact"}:
539
+ if not key:
500
540
  return
501
- bounded_paths = _bounded_artifact_paths(paths)
502
- if bounded_paths is None:
541
+ bounded = _bounded_artifact_paths(paths)
542
+ if bounded is None:
543
+ _fail_open(key)
503
544
  return
504
545
  try:
505
546
  root = Path(workspace or Path.cwd()).expanduser().resolve(strict=True)
506
547
  except (OSError, RuntimeError):
548
+ _fail_open(key)
507
549
  return
508
- buffered_text: list[str] = []
509
- remaining_bytes = MAX_AGGREGATE_FILE_BYTES
510
- for raw_path in bounded_paths:
511
- result = _read_stable_text_file_result(
512
- str(raw_path or ""),
513
- root,
514
- remaining_bytes,
515
- )
550
+ candidates: list[tuple[str, bytes]] = []
551
+ remaining = MAX_AGGREGATE_FILE_BYTES
552
+ for raw_path in bounded:
553
+ path_text = str(raw_path or "")
554
+ relative = _relative_artifact_path(path_text, root)
555
+ if relative is None or relative.suffix.lower() not in OFFICE_SUFFIXES:
556
+ continue
557
+ result = _read_stable_file_result(path_text, root, remaining)
516
558
  if result is _READ_BUDGET_EXCEEDED:
559
+ _fail_open(key)
517
560
  return
518
- if not isinstance(result, _StableText):
561
+ if not isinstance(result, _StableFile):
562
+ _fail_open(key)
563
+ continue
564
+ candidates.append((relative.suffix.lower(), result.data))
565
+ remaining -= result.byte_count
566
+ for suffix, data in candidates:
567
+ try:
568
+ text = _extract_office(data, suffix)
569
+ except (OSError, RuntimeError, ValueError, subprocess.TimeoutExpired, ImportError):
570
+ _fail_open(key)
571
+ continue
572
+ findings = _run_detector(text, "post-write" + suffix)
573
+ if findings is None:
574
+ _fail_open(key)
519
575
  continue
520
- buffered_text.append(result.text)
521
- remaining_bytes -= result.byte_count
522
-
523
- all_findings: list[Finding] = []
524
- file_count = 0
525
- for text in buffered_text:
526
- findings = scan_text(text, contract)
527
576
  if findings:
528
- file_count += 1
529
- all_findings.extend(findings)
530
- if not all_findings:
531
- return
532
- receipt = PendingReceipt(
533
- skill_id=skill_id,
534
- contract=contract,
535
- finding_count=min(len(all_findings), MAX_CONTEXT_FINDINGS),
536
- line_numbers=tuple(sorted({finding.line_number for finding in all_findings}))[
537
- :MAX_CONTEXT_FINDINGS
538
- ],
539
- file_count=file_count,
540
- )
541
- pending = list(_PENDING_RECEIPTS.get(key, ()))
542
- pending.append(receipt)
543
- _bounded_set(_PENDING_RECEIPTS, key, pending[-8:])
544
-
545
-
546
- def consume_context(session_id: object) -> str:
547
- key = str(session_id or "")
548
- receipts = _PENDING_RECEIPTS.pop(key, None)
549
- if not receipts:
550
- return ""
551
- lines = ['<lithermes-deliverable-hedge-guard event="completed-write">']
552
- for receipt in receipts:
553
- line_numbers = ",".join(str(number) for number in receipt.line_numbers)
554
- lines.append(
555
- "DELIVERABLE_HEDGE_VIOLATION "
556
- f"skill={receipt.skill_id} genre={receipt.contract.artifact_genre} "
557
- f"findings={receipt.finding_count} lines={line_numbers} files={receipt.file_count}. "
558
- f"Revise the artifact and place limitations in {receipt.contract.limitations_channel}."
559
- )
560
- lines.append("Artifact text and paths were omitted because they are untrusted data.")
561
- lines.append("</lithermes-deliverable-hedge-guard>")
562
- return "\n".join(lines)
577
+ blocks = sum(item["severity"] == "block" for item in findings)
578
+ warnings = sum(item["severity"] == "warn" for item in findings)
579
+ _queue_advisory(
580
+ key,
581
+ "LIT_HUMANIZER_POSTWRITE_ADVISORY: the completed Office/PDF export has "
582
+ f"{blocks} block-tier and {warnings} warning-tier finding(s). Edit the source and rebuild; Hermes cannot undo a completed export.",
583
+ )