@research-copilot/plugin 1.1.16 → 1.1.18

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 (799) hide show
  1. package/dist/.claude-plugin/plugin.json +1 -1
  2. package/dist/.codex-plugin/plugin.toml +1 -1
  3. package/dist/.cursor-plugin/plugin.json +1 -1
  4. package/dist/.gemini-plugin/plugin.json +1 -1
  5. package/dist/.opencode-plugin/plugin.json +1 -1
  6. package/dist/.windsurf-plugin/plugin.json +1 -1
  7. package/dist/skills/ablation-planner/SKILL.md +126 -0
  8. package/dist/skills/alphaxiv/SKILL.md +186 -0
  9. package/dist/skills/analyze-results/SKILL.md +45 -0
  10. package/dist/skills/arxiv/SKILL.md +210 -0
  11. package/dist/skills/auto-paper-improvement-loop/SKILL.md +574 -0
  12. package/dist/skills/auto-review-loop/SKILL.md +370 -0
  13. package/dist/skills/auto-review-loop-llm/SKILL.md +247 -0
  14. package/dist/skills/auto-review-loop-minimax/SKILL.md +290 -0
  15. package/dist/skills/benchmark-paper-template/SKILL.md +142 -0
  16. package/dist/skills/benchmark-paper-template/references/benchmark-design.md +180 -0
  17. package/dist/skills/benchmark-paper-template/references/checklist.md +113 -0
  18. package/dist/skills/benchmark-paper-template/references/construction-pipeline.md +127 -0
  19. package/dist/skills/benchmark-paper-template/references/experiments.md +159 -0
  20. package/dist/skills/benchmark-paper-template/references/gap-analysis.md +86 -0
  21. package/dist/skills/benchmark-paper-template/references/instantiation-template.md +194 -0
  22. package/dist/skills/benchmark-paper-template/references/orchestrator-notes.md +96 -0
  23. package/dist/skills/benchmark-paper-template/references/paper-structure.md +209 -0
  24. package/dist/skills/citation-audit/SKILL.md +494 -0
  25. package/dist/skills/claims-drafting/SKILL.md +239 -0
  26. package/dist/skills/comm-lit-review/SKILL.md +299 -0
  27. package/dist/skills/comm-lit-review/references/domain-taxonomy.md +57 -0
  28. package/dist/skills/comm-lit-review/references/output-template.md +37 -0
  29. package/dist/skills/comm-lit-review/references/source-policy.md +99 -0
  30. package/dist/skills/comm-lit-review/references/venue-tiering.md +112 -0
  31. package/dist/skills/composer/SKILL.md +840 -0
  32. package/dist/skills/composer/references/section_guides.md +675 -0
  33. package/dist/skills/composer/references/writing_standards.md +629 -0
  34. package/dist/skills/composer/scripts/chapter_quality_check.py +470 -0
  35. package/dist/skills/composer/scripts/final_evaluation.py +550 -0
  36. package/dist/skills/deepxiv/SKILL.md +142 -0
  37. package/dist/skills/dse-loop/SKILL.md +277 -0
  38. package/dist/skills/embodiment-description/SKILL.md +129 -0
  39. package/dist/skills/exa-search/SKILL.md +192 -0
  40. package/dist/skills/experiment-audit/SKILL.md +262 -0
  41. package/dist/skills/experiment-bridge/SKILL.md +316 -0
  42. package/dist/skills/experiment-plan/SKILL.md +249 -0
  43. package/dist/skills/experiment-queue/SKILL.md +380 -0
  44. package/dist/skills/experiment-queue/scripts/build_manifest.py +142 -0
  45. package/dist/skills/experiment-queue/scripts/queue_manager.py +426 -0
  46. package/dist/skills/feishu-notify/SKILL.md +155 -0
  47. package/dist/skills/figure-description/SKILL.md +138 -0
  48. package/dist/skills/figure-designer/SKILL.md +207 -0
  49. package/dist/skills/figure-designer/references/design-rules.md +99 -0
  50. package/dist/skills/figure-designer/references/experimental-results.md +127 -0
  51. package/dist/skills/figure-designer/references/motivated-example.md +138 -0
  52. package/dist/skills/figure-designer/references/solution-overview.md +145 -0
  53. package/dist/skills/figure-designer/references/tools.md +124 -0
  54. package/dist/skills/figure-spec/SKILL.md +252 -0
  55. package/dist/skills/figure-spec/scripts/figure_renderer.py +799 -0
  56. package/dist/skills/formula-derivation/SKILL.md +280 -0
  57. package/dist/skills/gemini-search/SKILL.md +205 -0
  58. package/dist/skills/grant-proposal/SKILL.md +625 -0
  59. package/dist/skills/humanizer/AGENTS.md +25 -0
  60. package/dist/skills/humanizer/SKILL.md +621 -0
  61. package/dist/skills/idea-creator/SKILL.md +311 -0
  62. package/dist/skills/idea-discovery/SKILL.md +340 -0
  63. package/dist/skills/idea-discovery-robot/SKILL.md +362 -0
  64. package/dist/skills/idea-evaluator/SKILL.md +265 -0
  65. package/dist/skills/idea-evaluator/references/fatal-flaws.md +192 -0
  66. package/dist/skills/idea-evaluator/references/five-dimensions.md +251 -0
  67. package/dist/skills/idea-evaluator/references/lifecycle-capability-matching.md +177 -0
  68. package/dist/skills/idea-evaluator/references/paradigm-elephant.md +112 -0
  69. package/dist/skills/idea-evaluator/references/paradigm-examples.md +107 -0
  70. package/dist/skills/idea-evaluator/references/paradigm-first-principles.md +115 -0
  71. package/dist/skills/idea-evaluator/references/paradigm-hamming.md +137 -0
  72. package/dist/skills/idea-evaluator/references/paradigm-shift-probe.md +160 -0
  73. package/dist/skills/idea-evaluator/references/paradigm-technology-cycle.md +116 -0
  74. package/dist/skills/idea-evaluator/references/worked-examples.md +206 -0
  75. package/dist/skills/interview-cheatsheet/SKILL.md +245 -0
  76. package/dist/skills/intro-drafter/SKILL.md +250 -0
  77. package/dist/skills/intro-drafter/references/contribution-patterns.md +116 -0
  78. package/dist/skills/intro-drafter/references/flowchart.md +204 -0
  79. package/dist/skills/intro-drafter/references/paper-types.md +155 -0
  80. package/dist/skills/intro-drafter/references/running-example.md +133 -0
  81. package/dist/skills/intro-drafter/references/worked-examples.md +161 -0
  82. package/dist/skills/invention-structuring/SKILL.md +188 -0
  83. package/dist/skills/jurisdiction-format/SKILL.md +192 -0
  84. package/dist/skills/kill-argument/SKILL.md +384 -0
  85. package/dist/skills/llm-wiki/.mise.toml +2 -0
  86. package/dist/skills/llm-wiki/.nvmrc +1 -0
  87. package/dist/skills/llm-wiki/AGENTS.md +132 -0
  88. package/dist/skills/llm-wiki/CHANGELOG.md +459 -0
  89. package/dist/skills/llm-wiki/CLAUDE.md +109 -0
  90. package/dist/skills/llm-wiki/HERMES.md +44 -0
  91. package/dist/skills/llm-wiki/SKILL.md +1133 -0
  92. package/dist/skills/llm-wiki/assets/graph-demo.gif +0 -0
  93. package/dist/skills/llm-wiki/assets/graph-preview.png +0 -0
  94. package/dist/skills/llm-wiki/deps/LICENSE-d3.txt +13 -0
  95. package/dist/skills/llm-wiki/deps/LICENSE-marked.txt +44 -0
  96. package/dist/skills/llm-wiki/deps/LICENSE-purify.txt +568 -0
  97. package/{LICENSE → dist/skills/llm-wiki/deps/LICENSE-roughjs.txt} +1 -1
  98. package/dist/skills/llm-wiki/deps/baoyu-url-to-markdown/SKILL.md +261 -0
  99. package/dist/skills/llm-wiki/deps/baoyu-url-to-markdown/references/config/first-time-setup.md +106 -0
  100. package/dist/skills/llm-wiki/deps/baoyu-url-to-markdown/scripts/cdp.ts +179 -0
  101. package/dist/skills/llm-wiki/deps/baoyu-url-to-markdown/scripts/constants.ts +13 -0
  102. package/dist/skills/llm-wiki/deps/baoyu-url-to-markdown/scripts/defuddle-converter.ts +58 -0
  103. package/dist/skills/llm-wiki/deps/baoyu-url-to-markdown/scripts/html-to-markdown.ts +135 -0
  104. package/dist/skills/llm-wiki/deps/baoyu-url-to-markdown/scripts/legacy-converter.ts +629 -0
  105. package/dist/skills/llm-wiki/deps/baoyu-url-to-markdown/scripts/main.ts +314 -0
  106. package/dist/skills/llm-wiki/deps/baoyu-url-to-markdown/scripts/markdown-conversion-shared.ts +305 -0
  107. package/dist/skills/llm-wiki/deps/baoyu-url-to-markdown/scripts/media-localizer.ts +317 -0
  108. package/dist/skills/llm-wiki/deps/baoyu-url-to-markdown/scripts/package.json +14 -0
  109. package/dist/skills/llm-wiki/deps/baoyu-url-to-markdown/scripts/paths.ts +29 -0
  110. package/dist/skills/llm-wiki/deps/baoyu-url-to-markdown/scripts/vendor/baoyu-chrome-cdp/package.json +9 -0
  111. package/dist/skills/llm-wiki/deps/baoyu-url-to-markdown/scripts/vendor/baoyu-chrome-cdp/src/index.test.ts +307 -0
  112. package/dist/skills/llm-wiki/deps/baoyu-url-to-markdown/scripts/vendor/baoyu-chrome-cdp/src/index.ts +523 -0
  113. package/dist/skills/llm-wiki/deps/d3.min.js +2 -0
  114. package/dist/skills/llm-wiki/deps/marked.min.js +6 -0
  115. package/dist/skills/llm-wiki/deps/purify.min.js +3 -0
  116. package/dist/skills/llm-wiki/deps/rough.min.js +7 -0
  117. package/dist/skills/llm-wiki/deps/youtube-transcript/SKILL.md +47 -0
  118. package/dist/skills/llm-wiki/deps/youtube-transcript/scripts/get_transcript.py +72 -0
  119. package/dist/skills/llm-wiki/docs/design/oriental-atlas/DESIGN.md +183 -0
  120. package/dist/skills/llm-wiki/docs/design/oriental-atlas/design-brief.md +170 -0
  121. package/dist/skills/llm-wiki/docs/design/oriental-atlas/oriental-editorial-atlas.html +1908 -0
  122. package/dist/skills/llm-wiki/docs/design/oriental-atlas/reviews/result-review.md +68 -0
  123. package/dist/skills/llm-wiki/docs/plans/2026-06-15-omp-tool-status-events-phased-plan.md +655 -0
  124. package/dist/skills/llm-wiki/docs/plans/2026-06-15-omp-tool-status-events-progress.json +913 -0
  125. package/dist/skills/llm-wiki/docs/spark/2026-06-15-omp-tool-status-events-design.md +174 -0
  126. package/dist/skills/llm-wiki/install.ps1 +87 -0
  127. package/dist/skills/llm-wiki/install.sh +722 -0
  128. package/dist/skills/llm-wiki/package-lock.json +10309 -0
  129. package/dist/skills/llm-wiki/package.json +24 -0
  130. package/dist/skills/llm-wiki/packages/graph-engine/package.json +33 -0
  131. package/dist/skills/llm-wiki/packages/graph-engine/src/anim/.gitkeep +1 -0
  132. package/dist/skills/llm-wiki/packages/graph-engine/src/anim/index.ts +179 -0
  133. package/dist/skills/llm-wiki/packages/graph-engine/src/diff.ts +121 -0
  134. package/dist/skills/llm-wiki/packages/graph-engine/src/graph-node.ts +37 -0
  135. package/dist/skills/llm-wiki/packages/graph-engine/src/index.ts +140 -0
  136. package/dist/skills/llm-wiki/packages/graph-engine/src/model/atlas.ts +18 -0
  137. package/dist/skills/llm-wiki/packages/graph-engine/src/model/index.ts +6 -0
  138. package/dist/skills/llm-wiki/packages/graph-engine/src/model/labels.ts +11 -0
  139. package/dist/skills/llm-wiki/packages/graph-engine/src/model/learning.ts +8 -0
  140. package/dist/skills/llm-wiki/packages/graph-engine/src/model/legacy-helpers.ts +1373 -0
  141. package/dist/skills/llm-wiki/packages/graph-engine/src/model/queue.ts +7 -0
  142. package/dist/skills/llm-wiki/packages/graph-engine/src/model/storage.ts +4 -0
  143. package/dist/skills/llm-wiki/packages/graph-engine/src/model/visibility.ts +9 -0
  144. package/dist/skills/llm-wiki/packages/graph-engine/src/render/.gitkeep +1 -0
  145. package/dist/skills/llm-wiki/packages/graph-engine/src/render/index.ts +59 -0
  146. package/dist/skills/llm-wiki/packages/graph-engine/src/render/legend.ts +25 -0
  147. package/dist/skills/llm-wiki/packages/graph-engine/src/render/model.ts +593 -0
  148. package/dist/skills/llm-wiki/packages/graph-engine/src/render/preview.ts +65 -0
  149. package/dist/skills/llm-wiki/packages/graph-engine/src/render/search.ts +48 -0
  150. package/dist/skills/llm-wiki/packages/graph-engine/src/render/static-renderer.ts +2783 -0
  151. package/dist/skills/llm-wiki/packages/graph-engine/src/render/toolbar.ts +40 -0
  152. package/dist/skills/llm-wiki/packages/graph-engine/src/render/viewport.ts +272 -0
  153. package/dist/skills/llm-wiki/packages/graph-engine/src/select/.gitkeep +1 -0
  154. package/dist/skills/llm-wiki/packages/graph-engine/src/select/index.ts +189 -0
  155. package/dist/skills/llm-wiki/packages/graph-engine/src/sim/index.ts +298 -0
  156. package/dist/skills/llm-wiki/packages/graph-engine/src/sim/pins.ts +96 -0
  157. package/dist/skills/llm-wiki/packages/graph-engine/src/themes/.gitkeep +1 -0
  158. package/dist/skills/llm-wiki/packages/graph-engine/src/themes/index.ts +8 -0
  159. package/dist/skills/llm-wiki/packages/graph-engine/src/themes/tokens.ts +107 -0
  160. package/dist/skills/llm-wiki/packages/graph-engine/src/types.ts +313 -0
  161. package/dist/skills/llm-wiki/packages/graph-engine/test/anim.test.ts +100 -0
  162. package/dist/skills/llm-wiki/packages/graph-engine/test/diff.test.ts +133 -0
  163. package/dist/skills/llm-wiki/packages/graph-engine/test/helpers.test.ts +275 -0
  164. package/dist/skills/llm-wiki/packages/graph-engine/test/learning.test.ts +259 -0
  165. package/dist/skills/llm-wiki/packages/graph-engine/test/preview.test.ts +56 -0
  166. package/dist/skills/llm-wiki/packages/graph-engine/test/queue.test.ts +114 -0
  167. package/dist/skills/llm-wiki/packages/graph-engine/test/render-model.test.ts +322 -0
  168. package/dist/skills/llm-wiki/packages/graph-engine/test/runtime-state.test.ts +281 -0
  169. package/dist/skills/llm-wiki/packages/graph-engine/test/search-and-legend.test.ts +111 -0
  170. package/dist/skills/llm-wiki/packages/graph-engine/test/select.test.ts +168 -0
  171. package/dist/skills/llm-wiki/packages/graph-engine/test/sim.test.ts +123 -0
  172. package/dist/skills/llm-wiki/packages/graph-engine/test/themes.test.ts +62 -0
  173. package/dist/skills/llm-wiki/packages/graph-engine/test/toolbar.test.ts +64 -0
  174. package/dist/skills/llm-wiki/packages/graph-engine/test/viewport.test.ts +167 -0
  175. package/dist/skills/llm-wiki/packages/graph-engine/tsconfig.json +17 -0
  176. package/dist/skills/llm-wiki/packages/graph-engine/vite.config.ts +15 -0
  177. package/dist/skills/llm-wiki/platforms/claude/CLAUDE.md +37 -0
  178. package/dist/skills/llm-wiki/platforms/claude/companions/llm-wiki-upgrade/SKILL.md +95 -0
  179. package/dist/skills/llm-wiki/platforms/codex/AGENTS.md +23 -0
  180. package/dist/skills/llm-wiki/scripts/adapter-state.sh +424 -0
  181. package/dist/skills/llm-wiki/scripts/build-graph-data.sh +395 -0
  182. package/dist/skills/llm-wiki/scripts/build-graph-html.sh +453 -0
  183. package/dist/skills/llm-wiki/scripts/cache.sh +352 -0
  184. package/dist/skills/llm-wiki/scripts/create-source-page.sh +100 -0
  185. package/dist/skills/llm-wiki/scripts/delete-helper.sh +68 -0
  186. package/dist/skills/llm-wiki/scripts/graph-analysis.js +732 -0
  187. package/dist/skills/llm-wiki/scripts/hook-session-start.sh +46 -0
  188. package/dist/skills/llm-wiki/scripts/init-wiki.sh +95 -0
  189. package/dist/skills/llm-wiki/scripts/lib/source-signal-eligibility.js +158 -0
  190. package/dist/skills/llm-wiki/scripts/lint-fix.sh +114 -0
  191. package/dist/skills/llm-wiki/scripts/lint-runner.sh +217 -0
  192. package/dist/skills/llm-wiki/scripts/runtime-context.sh +77 -0
  193. package/dist/skills/llm-wiki/scripts/shared-config.sh +83 -0
  194. package/dist/skills/llm-wiki/scripts/source-record-contract.tsv +10 -0
  195. package/dist/skills/llm-wiki/scripts/source-registry.sh +349 -0
  196. package/dist/skills/llm-wiki/scripts/source-registry.tsv +10 -0
  197. package/dist/skills/llm-wiki/scripts/source-signal-coverage.js +83 -0
  198. package/dist/skills/llm-wiki/scripts/validate-step1.sh +144 -0
  199. package/dist/skills/llm-wiki/scripts/wiki-compat.sh +267 -0
  200. package/dist/skills/llm-wiki/setup.sh +8 -0
  201. package/dist/skills/llm-wiki/templates/entity-template.md +30 -0
  202. package/dist/skills/llm-wiki/templates/graph-styles/wash/footer.html +27 -0
  203. package/dist/skills/llm-wiki/templates/graph-styles/wash/graph-wash-helpers.js +1326 -0
  204. package/dist/skills/llm-wiki/templates/graph-styles/wash/graph-wash.js +1009 -0
  205. package/dist/skills/llm-wiki/templates/graph-styles/wash/header.html +2002 -0
  206. package/dist/skills/llm-wiki/templates/index-en-template.md +51 -0
  207. package/dist/skills/llm-wiki/templates/index-template.md +51 -0
  208. package/dist/skills/llm-wiki/templates/log-en-template.md +11 -0
  209. package/dist/skills/llm-wiki/templates/log-template.md +11 -0
  210. package/dist/skills/llm-wiki/templates/overview-en-template.md +41 -0
  211. package/dist/skills/llm-wiki/templates/overview-template.md +41 -0
  212. package/dist/skills/llm-wiki/templates/purpose-en-template.md +16 -0
  213. package/dist/skills/llm-wiki/templates/purpose-template.md +16 -0
  214. package/dist/skills/llm-wiki/templates/query-template.md +19 -0
  215. package/dist/skills/llm-wiki/templates/schema-template.md +185 -0
  216. package/dist/skills/llm-wiki/templates/source-template.md +51 -0
  217. package/dist/skills/llm-wiki/templates/synthesis-template.md +25 -0
  218. package/dist/skills/llm-wiki/templates/topic-template.md +35 -0
  219. package/dist/skills/llm-wiki/tests/adapter-state.sh +338 -0
  220. package/dist/skills/llm-wiki/tests/browser/graph-density-preview.mjs +53 -0
  221. package/dist/skills/llm-wiki/tests/browser/graph-html-insights.mjs +41 -0
  222. package/dist/skills/llm-wiki/tests/browser/graph-node-slim.mjs +71 -0
  223. package/dist/skills/llm-wiki/tests/browser/graph-stage-4-5.mjs +717 -0
  224. package/dist/skills/llm-wiki/tests/expected/graph-data-empty.json +60 -0
  225. package/dist/skills/llm-wiki/tests/expected/graph-data-sample.json +396 -0
  226. package/dist/skills/llm-wiki/tests/expected/graph-interactive-basic.html +1736 -0
  227. package/dist/skills/llm-wiki/tests/expected/lint-output.txt +44 -0
  228. package/dist/skills/llm-wiki/tests/fixtures/coverage-sample-wiki/index.md +1 -0
  229. package/dist/skills/llm-wiki/tests/fixtures/coverage-sample-wiki/wiki/entities/Alpha.md +10 -0
  230. package/dist/skills/llm-wiki/tests/fixtures/coverage-sample-wiki/wiki/entities/Beta.md +7 -0
  231. package/dist/skills/llm-wiki/tests/fixtures/coverage-sample-wiki/wiki/entities/Delta.md +8 -0
  232. package/dist/skills/llm-wiki/tests/fixtures/coverage-sample-wiki/wiki/entities/Gamma.md +8 -0
  233. package/dist/skills/llm-wiki/tests/fixtures/coverage-sample-wiki/wiki/queries/20260422-abc.md +10 -0
  234. package/dist/skills/llm-wiki/tests/fixtures/coverage-sample-wiki/wiki/synthesis/Crystal.md +8 -0
  235. package/dist/skills/llm-wiki/tests/fixtures/coverage-sample-wiki/wiki/topics/Overview.md +9 -0
  236. package/dist/skills/llm-wiki/tests/fixtures/graph-data-empty-wiki/wiki/entities/.gitkeep +0 -0
  237. package/dist/skills/llm-wiki/tests/fixtures/graph-data-sample-wiki/purpose.md +3 -0
  238. package/dist/skills/llm-wiki/tests/fixtures/graph-data-sample-wiki/wiki/entities/Attention.md +7 -0
  239. package/dist/skills/llm-wiki/tests/fixtures/graph-data-sample-wiki/wiki/entities/Decoder.md +7 -0
  240. package/dist/skills/llm-wiki/tests/fixtures/graph-data-sample-wiki/wiki/entities/Encoder.md +7 -0
  241. package/dist/skills/llm-wiki/tests/fixtures/graph-data-sample-wiki/wiki/entities/GPT.md +7 -0
  242. package/dist/skills/llm-wiki/tests/fixtures/graph-data-sample-wiki/wiki/entities/Transformer.md +13 -0
  243. package/dist/skills/llm-wiki/tests/fixtures/graph-data-sample-wiki/wiki/sources/paper.md +9 -0
  244. package/dist/skills/llm-wiki/tests/fixtures/graph-data-sample-wiki/wiki/topics/arch.md +12 -0
  245. package/dist/skills/llm-wiki/tests/fixtures/graph-data-sample-wiki/wiki/topics/finetune.md +9 -0
  246. package/dist/skills/llm-wiki/tests/fixtures/graph-interactive-basic/wiki/graph-data.json +40 -0
  247. package/dist/skills/llm-wiki/tests/fixtures/graph-interactive-dense/wiki/graph-data.json +3965 -0
  248. package/dist/skills/llm-wiki/tests/fixtures/graph-interactive-multicomm/wiki/graph-data.json +212 -0
  249. package/dist/skills/llm-wiki/tests/fixtures/lint-sample-wiki/index.md +14 -0
  250. package/dist/skills/llm-wiki/tests/fixtures/lint-sample-wiki/wiki/entities/C++.md +6 -0
  251. package/dist/skills/llm-wiki/tests/fixtures/lint-sample-wiki/wiki/entities/Lonely.md +4 -0
  252. package/dist/skills/llm-wiki/tests/fixtures/lint-sample-wiki/wiki/entities/Other.md +8 -0
  253. package/dist/skills/llm-wiki/tests/fixtures/lint-sample-wiki/wiki/entities/Real.md +7 -0
  254. package/dist/skills/llm-wiki/tests/fixtures/lint-sample-wiki/wiki/sources/2026-01-01-test-source.md +15 -0
  255. package/dist/skills/llm-wiki/tests/fixtures/lint-sample-wiki/wiki/sources/2026-02-01-inline-img.md +12 -0
  256. package/dist/skills/llm-wiki/tests/fixtures/lint-sample-wiki/wiki/topics/AIbasic.md +3 -0
  257. package/dist/skills/llm-wiki/tests/graph-analysis-helper.regression-1.sh +237 -0
  258. package/dist/skills/llm-wiki/tests/graph-browser-stage-4-5.regression-1.sh +157 -0
  259. package/dist/skills/llm-wiki/tests/graph-build-failures.regression-1.sh +91 -0
  260. package/dist/skills/llm-wiki/tests/graph-data-confidence-merge.regression-1.sh +309 -0
  261. package/dist/skills/llm-wiki/tests/graph-data-source-paths.regression-1.sh +49 -0
  262. package/dist/skills/llm-wiki/tests/graph-html-a11y.regression-1.sh +47 -0
  263. package/dist/skills/llm-wiki/tests/graph-html-brand-link.regression-1.sh +47 -0
  264. package/dist/skills/llm-wiki/tests/graph-html-density.regression-1.sh +228 -0
  265. package/dist/skills/llm-wiki/tests/graph-html-drawer-neighbors.regression-1.sh +47 -0
  266. package/dist/skills/llm-wiki/tests/graph-html-insights.regression-1.sh +80 -0
  267. package/dist/skills/llm-wiki/tests/graph-html-long-label.regression-1.sh +92 -0
  268. package/dist/skills/llm-wiki/tests/graph-html-minimap.regression-1.sh +51 -0
  269. package/dist/skills/llm-wiki/tests/graph-html-mobile.regression-1.sh +48 -0
  270. package/dist/skills/llm-wiki/tests/graph-html-oriental-atlas-contract.regression-1.sh +94 -0
  271. package/dist/skills/llm-wiki/tests/graph-html-oriental-design-contract.regression-1.sh +82 -0
  272. package/dist/skills/llm-wiki/tests/graph-html-search.regression-1.sh +52 -0
  273. package/dist/skills/llm-wiki/tests/graph-html-styles.regression-1.sh +66 -0
  274. package/dist/skills/llm-wiki/tests/graph-html-toolbar.regression-1.sh +62 -0
  275. package/dist/skills/llm-wiki/tests/js/graph-wash-bootstrap.test.js +110 -0
  276. package/dist/skills/llm-wiki/tests/js/graph-wash-helpers.test.js +296 -0
  277. package/dist/skills/llm-wiki/tests/js/graph-wash-learning.test.js +260 -0
  278. package/dist/skills/llm-wiki/tests/js/graph-wash-queue.test.js +115 -0
  279. package/dist/skills/llm-wiki/tests/js/graph-wash-runtime-state.test.js +282 -0
  280. package/dist/skills/llm-wiki/tests/js/source-signal-coverage.test.js +48 -0
  281. package/dist/skills/llm-wiki/tests/js/source-signal-eligibility.test.js +202 -0
  282. package/dist/skills/llm-wiki/tests/lib/graph-html-engine-helpers.sh +110 -0
  283. package/dist/skills/llm-wiki/tests/lint-output.regression-1.sh +32 -0
  284. package/dist/skills/llm-wiki/tests/regression.sh +1754 -0
  285. package/dist/skills/llm-wiki/workbench/.claude/skills/.gitkeep +0 -0
  286. package/dist/skills/llm-wiki/workbench/.claude/skills/docx/SKILL.md +590 -0
  287. package/dist/skills/llm-wiki/workbench/.claude/skills/docx/scripts/__init__.py +1 -0
  288. package/dist/skills/llm-wiki/workbench/.claude/skills/docx/scripts/accept_changes.py +135 -0
  289. package/dist/skills/llm-wiki/workbench/.claude/skills/docx/scripts/comment.py +318 -0
  290. package/dist/skills/llm-wiki/workbench/.claude/skills/docx/scripts/office/helpers/__init__.py +0 -0
  291. package/dist/skills/llm-wiki/workbench/.claude/skills/docx/scripts/office/helpers/merge_runs.py +199 -0
  292. package/dist/skills/llm-wiki/workbench/.claude/skills/docx/scripts/office/helpers/simplify_redlines.py +197 -0
  293. package/dist/skills/llm-wiki/workbench/.claude/skills/docx/scripts/office/pack.py +159 -0
  294. package/dist/skills/llm-wiki/workbench/.claude/skills/docx/scripts/office/schemas/ISO-IEC29500-4_2016/dml-chart.xsd +1499 -0
  295. package/dist/skills/llm-wiki/workbench/.claude/skills/docx/scripts/office/schemas/ISO-IEC29500-4_2016/dml-chartDrawing.xsd +146 -0
  296. package/dist/skills/llm-wiki/workbench/.claude/skills/docx/scripts/office/schemas/ISO-IEC29500-4_2016/dml-diagram.xsd +1085 -0
  297. package/dist/skills/llm-wiki/workbench/.claude/skills/docx/scripts/office/schemas/ISO-IEC29500-4_2016/dml-lockedCanvas.xsd +11 -0
  298. package/dist/skills/llm-wiki/workbench/.claude/skills/docx/scripts/office/schemas/ISO-IEC29500-4_2016/dml-main.xsd +3081 -0
  299. package/dist/skills/llm-wiki/workbench/.claude/skills/docx/scripts/office/schemas/ISO-IEC29500-4_2016/dml-picture.xsd +23 -0
  300. package/dist/skills/llm-wiki/workbench/.claude/skills/docx/scripts/office/schemas/ISO-IEC29500-4_2016/dml-spreadsheetDrawing.xsd +185 -0
  301. package/dist/skills/llm-wiki/workbench/.claude/skills/docx/scripts/office/schemas/ISO-IEC29500-4_2016/dml-wordprocessingDrawing.xsd +287 -0
  302. package/dist/skills/llm-wiki/workbench/.claude/skills/docx/scripts/office/schemas/ISO-IEC29500-4_2016/pml.xsd +1676 -0
  303. package/dist/skills/llm-wiki/workbench/.claude/skills/docx/scripts/office/schemas/ISO-IEC29500-4_2016/shared-additionalCharacteristics.xsd +28 -0
  304. package/dist/skills/llm-wiki/workbench/.claude/skills/docx/scripts/office/schemas/ISO-IEC29500-4_2016/shared-bibliography.xsd +144 -0
  305. package/dist/skills/llm-wiki/workbench/.claude/skills/docx/scripts/office/schemas/ISO-IEC29500-4_2016/shared-commonSimpleTypes.xsd +174 -0
  306. package/dist/skills/llm-wiki/workbench/.claude/skills/docx/scripts/office/schemas/ISO-IEC29500-4_2016/shared-customXmlDataProperties.xsd +25 -0
  307. package/dist/skills/llm-wiki/workbench/.claude/skills/docx/scripts/office/schemas/ISO-IEC29500-4_2016/shared-customXmlSchemaProperties.xsd +18 -0
  308. package/dist/skills/llm-wiki/workbench/.claude/skills/docx/scripts/office/schemas/ISO-IEC29500-4_2016/shared-documentPropertiesCustom.xsd +59 -0
  309. package/dist/skills/llm-wiki/workbench/.claude/skills/docx/scripts/office/schemas/ISO-IEC29500-4_2016/shared-documentPropertiesExtended.xsd +56 -0
  310. package/dist/skills/llm-wiki/workbench/.claude/skills/docx/scripts/office/schemas/ISO-IEC29500-4_2016/shared-documentPropertiesVariantTypes.xsd +195 -0
  311. package/dist/skills/llm-wiki/workbench/.claude/skills/docx/scripts/office/schemas/ISO-IEC29500-4_2016/shared-math.xsd +582 -0
  312. package/dist/skills/llm-wiki/workbench/.claude/skills/docx/scripts/office/schemas/ISO-IEC29500-4_2016/shared-relationshipReference.xsd +25 -0
  313. package/dist/skills/llm-wiki/workbench/.claude/skills/docx/scripts/office/schemas/ISO-IEC29500-4_2016/sml.xsd +4439 -0
  314. package/dist/skills/llm-wiki/workbench/.claude/skills/docx/scripts/office/schemas/ISO-IEC29500-4_2016/vml-main.xsd +570 -0
  315. package/dist/skills/llm-wiki/workbench/.claude/skills/docx/scripts/office/schemas/ISO-IEC29500-4_2016/vml-officeDrawing.xsd +509 -0
  316. package/dist/skills/llm-wiki/workbench/.claude/skills/docx/scripts/office/schemas/ISO-IEC29500-4_2016/vml-presentationDrawing.xsd +12 -0
  317. package/dist/skills/llm-wiki/workbench/.claude/skills/docx/scripts/office/schemas/ISO-IEC29500-4_2016/vml-spreadsheetDrawing.xsd +108 -0
  318. package/dist/skills/llm-wiki/workbench/.claude/skills/docx/scripts/office/schemas/ISO-IEC29500-4_2016/vml-wordprocessingDrawing.xsd +96 -0
  319. package/dist/skills/llm-wiki/workbench/.claude/skills/docx/scripts/office/schemas/ISO-IEC29500-4_2016/wml.xsd +3646 -0
  320. package/dist/skills/llm-wiki/workbench/.claude/skills/docx/scripts/office/schemas/ISO-IEC29500-4_2016/xml.xsd +116 -0
  321. package/dist/skills/llm-wiki/workbench/.claude/skills/docx/scripts/office/schemas/ecma/fouth-edition/opc-contentTypes.xsd +42 -0
  322. package/dist/skills/llm-wiki/workbench/.claude/skills/docx/scripts/office/schemas/ecma/fouth-edition/opc-coreProperties.xsd +50 -0
  323. package/dist/skills/llm-wiki/workbench/.claude/skills/docx/scripts/office/schemas/ecma/fouth-edition/opc-digSig.xsd +49 -0
  324. package/dist/skills/llm-wiki/workbench/.claude/skills/docx/scripts/office/schemas/ecma/fouth-edition/opc-relationships.xsd +33 -0
  325. package/dist/skills/llm-wiki/workbench/.claude/skills/docx/scripts/office/schemas/mce/mc.xsd +75 -0
  326. package/dist/skills/llm-wiki/workbench/.claude/skills/docx/scripts/office/schemas/microsoft/wml-2010.xsd +560 -0
  327. package/dist/skills/llm-wiki/workbench/.claude/skills/docx/scripts/office/schemas/microsoft/wml-2012.xsd +67 -0
  328. package/dist/skills/llm-wiki/workbench/.claude/skills/docx/scripts/office/schemas/microsoft/wml-2018.xsd +14 -0
  329. package/dist/skills/llm-wiki/workbench/.claude/skills/docx/scripts/office/schemas/microsoft/wml-cex-2018.xsd +20 -0
  330. package/dist/skills/llm-wiki/workbench/.claude/skills/docx/scripts/office/schemas/microsoft/wml-cid-2016.xsd +13 -0
  331. package/dist/skills/llm-wiki/workbench/.claude/skills/docx/scripts/office/schemas/microsoft/wml-sdtdatahash-2020.xsd +4 -0
  332. package/dist/skills/llm-wiki/workbench/.claude/skills/docx/scripts/office/schemas/microsoft/wml-symex-2015.xsd +8 -0
  333. package/dist/skills/llm-wiki/workbench/.claude/skills/docx/scripts/office/soffice.py +183 -0
  334. package/dist/skills/llm-wiki/workbench/.claude/skills/docx/scripts/office/unpack.py +132 -0
  335. package/dist/skills/llm-wiki/workbench/.claude/skills/docx/scripts/office/validate.py +111 -0
  336. package/dist/skills/llm-wiki/workbench/.claude/skills/docx/scripts/office/validators/__init__.py +15 -0
  337. package/dist/skills/llm-wiki/workbench/.claude/skills/docx/scripts/office/validators/base.py +847 -0
  338. package/dist/skills/llm-wiki/workbench/.claude/skills/docx/scripts/office/validators/docx.py +446 -0
  339. package/dist/skills/llm-wiki/workbench/.claude/skills/docx/scripts/office/validators/pptx.py +275 -0
  340. package/dist/skills/llm-wiki/workbench/.claude/skills/docx/scripts/office/validators/redlining.py +247 -0
  341. package/dist/skills/llm-wiki/workbench/.claude/skills/docx/scripts/templates/comments.xml +3 -0
  342. package/dist/skills/llm-wiki/workbench/.claude/skills/docx/scripts/templates/commentsExtended.xml +3 -0
  343. package/dist/skills/llm-wiki/workbench/.claude/skills/docx/scripts/templates/commentsExtensible.xml +3 -0
  344. package/dist/skills/llm-wiki/workbench/.claude/skills/docx/scripts/templates/commentsIds.xml +3 -0
  345. package/dist/skills/llm-wiki/workbench/.claude/skills/docx/scripts/templates/people.xml +3 -0
  346. package/dist/skills/llm-wiki/workbench/.claude/skills/pdf/SKILL.md +314 -0
  347. package/dist/skills/llm-wiki/workbench/.claude/skills/pdf/forms.md +294 -0
  348. package/dist/skills/llm-wiki/workbench/.claude/skills/pdf/reference.md +612 -0
  349. package/dist/skills/llm-wiki/workbench/.claude/skills/pdf/scripts/check_bounding_boxes.py +65 -0
  350. package/dist/skills/llm-wiki/workbench/.claude/skills/pdf/scripts/check_fillable_fields.py +11 -0
  351. package/dist/skills/llm-wiki/workbench/.claude/skills/pdf/scripts/convert_pdf_to_images.py +33 -0
  352. package/dist/skills/llm-wiki/workbench/.claude/skills/pdf/scripts/create_validation_image.py +37 -0
  353. package/dist/skills/llm-wiki/workbench/.claude/skills/pdf/scripts/extract_form_field_info.py +122 -0
  354. package/dist/skills/llm-wiki/workbench/.claude/skills/pdf/scripts/extract_form_structure.py +115 -0
  355. package/dist/skills/llm-wiki/workbench/.claude/skills/pdf/scripts/fill_fillable_fields.py +98 -0
  356. package/dist/skills/llm-wiki/workbench/.claude/skills/pdf/scripts/fill_pdf_form_with_annotations.py +107 -0
  357. package/dist/skills/llm-wiki/workbench/.claude/skills/pptx/SKILL.md +232 -0
  358. package/dist/skills/llm-wiki/workbench/.claude/skills/pptx/editing.md +205 -0
  359. package/dist/skills/llm-wiki/workbench/.claude/skills/pptx/pptxgenjs.md +420 -0
  360. package/dist/skills/llm-wiki/workbench/.claude/skills/pptx/scripts/__init__.py +0 -0
  361. package/dist/skills/llm-wiki/workbench/.claude/skills/pptx/scripts/add_slide.py +195 -0
  362. package/dist/skills/llm-wiki/workbench/.claude/skills/pptx/scripts/clean.py +286 -0
  363. package/dist/skills/llm-wiki/workbench/.claude/skills/pptx/scripts/office/helpers/__init__.py +0 -0
  364. package/dist/skills/llm-wiki/workbench/.claude/skills/pptx/scripts/office/helpers/merge_runs.py +199 -0
  365. package/dist/skills/llm-wiki/workbench/.claude/skills/pptx/scripts/office/helpers/simplify_redlines.py +197 -0
  366. package/dist/skills/llm-wiki/workbench/.claude/skills/pptx/scripts/office/pack.py +159 -0
  367. package/dist/skills/llm-wiki/workbench/.claude/skills/pptx/scripts/office/schemas/ISO-IEC29500-4_2016/dml-chart.xsd +1499 -0
  368. package/dist/skills/llm-wiki/workbench/.claude/skills/pptx/scripts/office/schemas/ISO-IEC29500-4_2016/dml-chartDrawing.xsd +146 -0
  369. package/dist/skills/llm-wiki/workbench/.claude/skills/pptx/scripts/office/schemas/ISO-IEC29500-4_2016/dml-diagram.xsd +1085 -0
  370. package/dist/skills/llm-wiki/workbench/.claude/skills/pptx/scripts/office/schemas/ISO-IEC29500-4_2016/dml-lockedCanvas.xsd +11 -0
  371. package/dist/skills/llm-wiki/workbench/.claude/skills/pptx/scripts/office/schemas/ISO-IEC29500-4_2016/dml-main.xsd +3081 -0
  372. package/dist/skills/llm-wiki/workbench/.claude/skills/pptx/scripts/office/schemas/ISO-IEC29500-4_2016/dml-picture.xsd +23 -0
  373. package/dist/skills/llm-wiki/workbench/.claude/skills/pptx/scripts/office/schemas/ISO-IEC29500-4_2016/dml-spreadsheetDrawing.xsd +185 -0
  374. package/dist/skills/llm-wiki/workbench/.claude/skills/pptx/scripts/office/schemas/ISO-IEC29500-4_2016/dml-wordprocessingDrawing.xsd +287 -0
  375. package/dist/skills/llm-wiki/workbench/.claude/skills/pptx/scripts/office/schemas/ISO-IEC29500-4_2016/pml.xsd +1676 -0
  376. package/dist/skills/llm-wiki/workbench/.claude/skills/pptx/scripts/office/schemas/ISO-IEC29500-4_2016/shared-additionalCharacteristics.xsd +28 -0
  377. package/dist/skills/llm-wiki/workbench/.claude/skills/pptx/scripts/office/schemas/ISO-IEC29500-4_2016/shared-bibliography.xsd +144 -0
  378. package/dist/skills/llm-wiki/workbench/.claude/skills/pptx/scripts/office/schemas/ISO-IEC29500-4_2016/shared-commonSimpleTypes.xsd +174 -0
  379. package/dist/skills/llm-wiki/workbench/.claude/skills/pptx/scripts/office/schemas/ISO-IEC29500-4_2016/shared-customXmlDataProperties.xsd +25 -0
  380. package/dist/skills/llm-wiki/workbench/.claude/skills/pptx/scripts/office/schemas/ISO-IEC29500-4_2016/shared-customXmlSchemaProperties.xsd +18 -0
  381. package/dist/skills/llm-wiki/workbench/.claude/skills/pptx/scripts/office/schemas/ISO-IEC29500-4_2016/shared-documentPropertiesCustom.xsd +59 -0
  382. package/dist/skills/llm-wiki/workbench/.claude/skills/pptx/scripts/office/schemas/ISO-IEC29500-4_2016/shared-documentPropertiesExtended.xsd +56 -0
  383. package/dist/skills/llm-wiki/workbench/.claude/skills/pptx/scripts/office/schemas/ISO-IEC29500-4_2016/shared-documentPropertiesVariantTypes.xsd +195 -0
  384. package/dist/skills/llm-wiki/workbench/.claude/skills/pptx/scripts/office/schemas/ISO-IEC29500-4_2016/shared-math.xsd +582 -0
  385. package/dist/skills/llm-wiki/workbench/.claude/skills/pptx/scripts/office/schemas/ISO-IEC29500-4_2016/shared-relationshipReference.xsd +25 -0
  386. package/dist/skills/llm-wiki/workbench/.claude/skills/pptx/scripts/office/schemas/ISO-IEC29500-4_2016/sml.xsd +4439 -0
  387. package/dist/skills/llm-wiki/workbench/.claude/skills/pptx/scripts/office/schemas/ISO-IEC29500-4_2016/vml-main.xsd +570 -0
  388. package/dist/skills/llm-wiki/workbench/.claude/skills/pptx/scripts/office/schemas/ISO-IEC29500-4_2016/vml-officeDrawing.xsd +509 -0
  389. package/dist/skills/llm-wiki/workbench/.claude/skills/pptx/scripts/office/schemas/ISO-IEC29500-4_2016/vml-presentationDrawing.xsd +12 -0
  390. package/dist/skills/llm-wiki/workbench/.claude/skills/pptx/scripts/office/schemas/ISO-IEC29500-4_2016/vml-spreadsheetDrawing.xsd +108 -0
  391. package/dist/skills/llm-wiki/workbench/.claude/skills/pptx/scripts/office/schemas/ISO-IEC29500-4_2016/vml-wordprocessingDrawing.xsd +96 -0
  392. package/dist/skills/llm-wiki/workbench/.claude/skills/pptx/scripts/office/schemas/ISO-IEC29500-4_2016/wml.xsd +3646 -0
  393. package/dist/skills/llm-wiki/workbench/.claude/skills/pptx/scripts/office/schemas/ISO-IEC29500-4_2016/xml.xsd +116 -0
  394. package/dist/skills/llm-wiki/workbench/.claude/skills/pptx/scripts/office/schemas/ecma/fouth-edition/opc-contentTypes.xsd +42 -0
  395. package/dist/skills/llm-wiki/workbench/.claude/skills/pptx/scripts/office/schemas/ecma/fouth-edition/opc-coreProperties.xsd +50 -0
  396. package/dist/skills/llm-wiki/workbench/.claude/skills/pptx/scripts/office/schemas/ecma/fouth-edition/opc-digSig.xsd +49 -0
  397. package/dist/skills/llm-wiki/workbench/.claude/skills/pptx/scripts/office/schemas/ecma/fouth-edition/opc-relationships.xsd +33 -0
  398. package/dist/skills/llm-wiki/workbench/.claude/skills/pptx/scripts/office/schemas/mce/mc.xsd +75 -0
  399. package/dist/skills/llm-wiki/workbench/.claude/skills/pptx/scripts/office/schemas/microsoft/wml-2010.xsd +560 -0
  400. package/dist/skills/llm-wiki/workbench/.claude/skills/pptx/scripts/office/schemas/microsoft/wml-2012.xsd +67 -0
  401. package/dist/skills/llm-wiki/workbench/.claude/skills/pptx/scripts/office/schemas/microsoft/wml-2018.xsd +14 -0
  402. package/dist/skills/llm-wiki/workbench/.claude/skills/pptx/scripts/office/schemas/microsoft/wml-cex-2018.xsd +20 -0
  403. package/dist/skills/llm-wiki/workbench/.claude/skills/pptx/scripts/office/schemas/microsoft/wml-cid-2016.xsd +13 -0
  404. package/dist/skills/llm-wiki/workbench/.claude/skills/pptx/scripts/office/schemas/microsoft/wml-sdtdatahash-2020.xsd +4 -0
  405. package/dist/skills/llm-wiki/workbench/.claude/skills/pptx/scripts/office/schemas/microsoft/wml-symex-2015.xsd +8 -0
  406. package/dist/skills/llm-wiki/workbench/.claude/skills/pptx/scripts/office/soffice.py +183 -0
  407. package/dist/skills/llm-wiki/workbench/.claude/skills/pptx/scripts/office/unpack.py +132 -0
  408. package/dist/skills/llm-wiki/workbench/.claude/skills/pptx/scripts/office/validate.py +111 -0
  409. package/dist/skills/llm-wiki/workbench/.claude/skills/pptx/scripts/office/validators/__init__.py +15 -0
  410. package/dist/skills/llm-wiki/workbench/.claude/skills/pptx/scripts/office/validators/base.py +847 -0
  411. package/dist/skills/llm-wiki/workbench/.claude/skills/pptx/scripts/office/validators/docx.py +446 -0
  412. package/dist/skills/llm-wiki/workbench/.claude/skills/pptx/scripts/office/validators/pptx.py +275 -0
  413. package/dist/skills/llm-wiki/workbench/.claude/skills/pptx/scripts/office/validators/redlining.py +247 -0
  414. package/dist/skills/llm-wiki/workbench/.claude/skills/pptx/scripts/thumbnail.py +289 -0
  415. package/dist/skills/llm-wiki/workbench/.claude/skills/xlsx/SKILL.md +292 -0
  416. package/dist/skills/llm-wiki/workbench/.claude/skills/xlsx/scripts/office/helpers/__init__.py +0 -0
  417. package/dist/skills/llm-wiki/workbench/.claude/skills/xlsx/scripts/office/helpers/merge_runs.py +199 -0
  418. package/dist/skills/llm-wiki/workbench/.claude/skills/xlsx/scripts/office/helpers/simplify_redlines.py +197 -0
  419. package/dist/skills/llm-wiki/workbench/.claude/skills/xlsx/scripts/office/pack.py +159 -0
  420. package/dist/skills/llm-wiki/workbench/.claude/skills/xlsx/scripts/office/schemas/ISO-IEC29500-4_2016/dml-chart.xsd +1499 -0
  421. package/dist/skills/llm-wiki/workbench/.claude/skills/xlsx/scripts/office/schemas/ISO-IEC29500-4_2016/dml-chartDrawing.xsd +146 -0
  422. package/dist/skills/llm-wiki/workbench/.claude/skills/xlsx/scripts/office/schemas/ISO-IEC29500-4_2016/dml-diagram.xsd +1085 -0
  423. package/dist/skills/llm-wiki/workbench/.claude/skills/xlsx/scripts/office/schemas/ISO-IEC29500-4_2016/dml-lockedCanvas.xsd +11 -0
  424. package/dist/skills/llm-wiki/workbench/.claude/skills/xlsx/scripts/office/schemas/ISO-IEC29500-4_2016/dml-main.xsd +3081 -0
  425. package/dist/skills/llm-wiki/workbench/.claude/skills/xlsx/scripts/office/schemas/ISO-IEC29500-4_2016/dml-picture.xsd +23 -0
  426. package/dist/skills/llm-wiki/workbench/.claude/skills/xlsx/scripts/office/schemas/ISO-IEC29500-4_2016/dml-spreadsheetDrawing.xsd +185 -0
  427. package/dist/skills/llm-wiki/workbench/.claude/skills/xlsx/scripts/office/schemas/ISO-IEC29500-4_2016/dml-wordprocessingDrawing.xsd +287 -0
  428. package/dist/skills/llm-wiki/workbench/.claude/skills/xlsx/scripts/office/schemas/ISO-IEC29500-4_2016/pml.xsd +1676 -0
  429. package/dist/skills/llm-wiki/workbench/.claude/skills/xlsx/scripts/office/schemas/ISO-IEC29500-4_2016/shared-additionalCharacteristics.xsd +28 -0
  430. package/dist/skills/llm-wiki/workbench/.claude/skills/xlsx/scripts/office/schemas/ISO-IEC29500-4_2016/shared-bibliography.xsd +144 -0
  431. package/dist/skills/llm-wiki/workbench/.claude/skills/xlsx/scripts/office/schemas/ISO-IEC29500-4_2016/shared-commonSimpleTypes.xsd +174 -0
  432. package/dist/skills/llm-wiki/workbench/.claude/skills/xlsx/scripts/office/schemas/ISO-IEC29500-4_2016/shared-customXmlDataProperties.xsd +25 -0
  433. package/dist/skills/llm-wiki/workbench/.claude/skills/xlsx/scripts/office/schemas/ISO-IEC29500-4_2016/shared-customXmlSchemaProperties.xsd +18 -0
  434. package/dist/skills/llm-wiki/workbench/.claude/skills/xlsx/scripts/office/schemas/ISO-IEC29500-4_2016/shared-documentPropertiesCustom.xsd +59 -0
  435. package/dist/skills/llm-wiki/workbench/.claude/skills/xlsx/scripts/office/schemas/ISO-IEC29500-4_2016/shared-documentPropertiesExtended.xsd +56 -0
  436. package/dist/skills/llm-wiki/workbench/.claude/skills/xlsx/scripts/office/schemas/ISO-IEC29500-4_2016/shared-documentPropertiesVariantTypes.xsd +195 -0
  437. package/dist/skills/llm-wiki/workbench/.claude/skills/xlsx/scripts/office/schemas/ISO-IEC29500-4_2016/shared-math.xsd +582 -0
  438. package/dist/skills/llm-wiki/workbench/.claude/skills/xlsx/scripts/office/schemas/ISO-IEC29500-4_2016/shared-relationshipReference.xsd +25 -0
  439. package/dist/skills/llm-wiki/workbench/.claude/skills/xlsx/scripts/office/schemas/ISO-IEC29500-4_2016/sml.xsd +4439 -0
  440. package/dist/skills/llm-wiki/workbench/.claude/skills/xlsx/scripts/office/schemas/ISO-IEC29500-4_2016/vml-main.xsd +570 -0
  441. package/dist/skills/llm-wiki/workbench/.claude/skills/xlsx/scripts/office/schemas/ISO-IEC29500-4_2016/vml-officeDrawing.xsd +509 -0
  442. package/dist/skills/llm-wiki/workbench/.claude/skills/xlsx/scripts/office/schemas/ISO-IEC29500-4_2016/vml-presentationDrawing.xsd +12 -0
  443. package/dist/skills/llm-wiki/workbench/.claude/skills/xlsx/scripts/office/schemas/ISO-IEC29500-4_2016/vml-spreadsheetDrawing.xsd +108 -0
  444. package/dist/skills/llm-wiki/workbench/.claude/skills/xlsx/scripts/office/schemas/ISO-IEC29500-4_2016/vml-wordprocessingDrawing.xsd +96 -0
  445. package/dist/skills/llm-wiki/workbench/.claude/skills/xlsx/scripts/office/schemas/ISO-IEC29500-4_2016/wml.xsd +3646 -0
  446. package/dist/skills/llm-wiki/workbench/.claude/skills/xlsx/scripts/office/schemas/ISO-IEC29500-4_2016/xml.xsd +116 -0
  447. package/dist/skills/llm-wiki/workbench/.claude/skills/xlsx/scripts/office/schemas/ecma/fouth-edition/opc-contentTypes.xsd +42 -0
  448. package/dist/skills/llm-wiki/workbench/.claude/skills/xlsx/scripts/office/schemas/ecma/fouth-edition/opc-coreProperties.xsd +50 -0
  449. package/dist/skills/llm-wiki/workbench/.claude/skills/xlsx/scripts/office/schemas/ecma/fouth-edition/opc-digSig.xsd +49 -0
  450. package/dist/skills/llm-wiki/workbench/.claude/skills/xlsx/scripts/office/schemas/ecma/fouth-edition/opc-relationships.xsd +33 -0
  451. package/dist/skills/llm-wiki/workbench/.claude/skills/xlsx/scripts/office/schemas/mce/mc.xsd +75 -0
  452. package/dist/skills/llm-wiki/workbench/.claude/skills/xlsx/scripts/office/schemas/microsoft/wml-2010.xsd +560 -0
  453. package/dist/skills/llm-wiki/workbench/.claude/skills/xlsx/scripts/office/schemas/microsoft/wml-2012.xsd +67 -0
  454. package/dist/skills/llm-wiki/workbench/.claude/skills/xlsx/scripts/office/schemas/microsoft/wml-2018.xsd +14 -0
  455. package/dist/skills/llm-wiki/workbench/.claude/skills/xlsx/scripts/office/schemas/microsoft/wml-cex-2018.xsd +20 -0
  456. package/dist/skills/llm-wiki/workbench/.claude/skills/xlsx/scripts/office/schemas/microsoft/wml-cid-2016.xsd +13 -0
  457. package/dist/skills/llm-wiki/workbench/.claude/skills/xlsx/scripts/office/schemas/microsoft/wml-sdtdatahash-2020.xsd +4 -0
  458. package/dist/skills/llm-wiki/workbench/.claude/skills/xlsx/scripts/office/schemas/microsoft/wml-symex-2015.xsd +8 -0
  459. package/dist/skills/llm-wiki/workbench/.claude/skills/xlsx/scripts/office/soffice.py +183 -0
  460. package/dist/skills/llm-wiki/workbench/.claude/skills/xlsx/scripts/office/unpack.py +132 -0
  461. package/dist/skills/llm-wiki/workbench/.claude/skills/xlsx/scripts/office/validate.py +111 -0
  462. package/dist/skills/llm-wiki/workbench/.claude/skills/xlsx/scripts/office/validators/__init__.py +15 -0
  463. package/dist/skills/llm-wiki/workbench/.claude/skills/xlsx/scripts/office/validators/base.py +847 -0
  464. package/dist/skills/llm-wiki/workbench/.claude/skills/xlsx/scripts/office/validators/docx.py +446 -0
  465. package/dist/skills/llm-wiki/workbench/.claude/skills/xlsx/scripts/office/validators/pptx.py +275 -0
  466. package/dist/skills/llm-wiki/workbench/.claude/skills/xlsx/scripts/office/validators/redlining.py +247 -0
  467. package/dist/skills/llm-wiki/workbench/.claude/skills/xlsx/scripts/recalc.py +184 -0
  468. package/dist/skills/llm-wiki/workbench/AGENTS.md +110 -0
  469. package/dist/skills/llm-wiki/workbench/CLAUDE.md +54 -0
  470. package/dist/skills/llm-wiki/workbench/PRODUCT.md +1268 -0
  471. package/dist/skills/llm-wiki/workbench/docs/current-kb-retrieval-design.md +587 -0
  472. package/dist/skills/llm-wiki/workbench/docs/graph-evolution-1-design.md +210 -0
  473. package/dist/skills/llm-wiki/workbench/docs/stage-2-design.md +1139 -0
  474. package/dist/skills/llm-wiki/workbench/docs/stage-3-design.md +1269 -0
  475. package/dist/skills/llm-wiki/workbench/docs/stage-3.5-design.md +1164 -0
  476. package/dist/skills/llm-wiki/workbench/docs/stage-4-design.md +504 -0
  477. package/dist/skills/llm-wiki/workbench/docs/stage-4.5-design.md +195 -0
  478. package/dist/skills/llm-wiki/workbench/docs/superpowers/specs/2026-05-28-resizable-preview-layout-design.md +165 -0
  479. package/dist/skills/llm-wiki/workbench/docs/superpowers/specs/2026-05-28-settings-panel-scroll-fix.md +50 -0
  480. package/dist/skills/llm-wiki/workbench/server/package.json +29 -0
  481. package/dist/skills/llm-wiki/workbench/server/src/agent.ts +457 -0
  482. package/dist/skills/llm-wiki/workbench/server/src/artifacts.ts +248 -0
  483. package/dist/skills/llm-wiki/workbench/server/src/auth.ts +164 -0
  484. package/dist/skills/llm-wiki/workbench/server/src/config.ts +130 -0
  485. package/dist/skills/llm-wiki/workbench/server/src/conversations.test.ts +121 -0
  486. package/dist/skills/llm-wiki/workbench/server/src/conversations.ts +255 -0
  487. package/dist/skills/llm-wiki/workbench/server/src/digest/batch.ts +189 -0
  488. package/dist/skills/llm-wiki/workbench/server/src/digest/concurrency.test.ts +36 -0
  489. package/dist/skills/llm-wiki/workbench/server/src/digest/concurrency.ts +31 -0
  490. package/dist/skills/llm-wiki/workbench/server/src/digest/subagent.ts +91 -0
  491. package/dist/skills/llm-wiki/workbench/server/src/extensions/artifacts.ts +81 -0
  492. package/dist/skills/llm-wiki/workbench/server/src/extensions/knowledge-base.ts +263 -0
  493. package/dist/skills/llm-wiki/workbench/server/src/extensions/new-wiki.ts +42 -0
  494. package/dist/skills/llm-wiki/workbench/server/src/extensions/synthesis.ts +172 -0
  495. package/dist/skills/llm-wiki/workbench/server/src/graph-watcher.test.ts +196 -0
  496. package/dist/skills/llm-wiki/workbench/server/src/graph.test.ts +84 -0
  497. package/dist/skills/llm-wiki/workbench/server/src/graph.ts +379 -0
  498. package/dist/skills/llm-wiki/workbench/server/src/index.ts +1148 -0
  499. package/dist/skills/llm-wiki/workbench/server/src/knowledge-bases.test.ts +30 -0
  500. package/dist/skills/llm-wiki/workbench/server/src/knowledge-bases.ts +321 -0
  501. package/dist/skills/llm-wiki/workbench/server/src/pages.test.ts +16 -0
  502. package/dist/skills/llm-wiki/workbench/server/src/pages.ts +158 -0
  503. package/dist/skills/llm-wiki/workbench/server/src/retrieval.test.ts +151 -0
  504. package/dist/skills/llm-wiki/workbench/server/src/retrieval.ts +427 -0
  505. package/dist/skills/llm-wiki/workbench/server/src/tool-status-events.test.ts +363 -0
  506. package/dist/skills/llm-wiki/workbench/server/src/tool-status-events.ts +616 -0
  507. package/dist/skills/llm-wiki/workbench/server/src/wiki-init.test.ts +19 -0
  508. package/dist/skills/llm-wiki/workbench/server/src/wiki-init.ts +188 -0
  509. package/dist/skills/llm-wiki/workbench/server/tsconfig.json +10 -0
  510. package/dist/skills/llm-wiki/workbench/tsconfig.json +20 -0
  511. package/dist/skills/llm-wiki/workbench/web/components.json +21 -0
  512. package/dist/skills/llm-wiki/workbench/web/eslint.config.js +22 -0
  513. package/dist/skills/llm-wiki/workbench/web/index.html +13 -0
  514. package/dist/skills/llm-wiki/workbench/web/package.json +48 -0
  515. package/dist/skills/llm-wiki/workbench/web/src/App.tsx +749 -0
  516. package/dist/skills/llm-wiki/workbench/web/src/components/AddExternalDialog.tsx +373 -0
  517. package/dist/skills/llm-wiki/workbench/web/src/components/ArtifactView.tsx +15 -0
  518. package/dist/skills/llm-wiki/workbench/web/src/components/BatchDigestPanel.tsx +106 -0
  519. package/dist/skills/llm-wiki/workbench/web/src/components/ChatPanel.tsx +821 -0
  520. package/dist/skills/llm-wiki/workbench/web/src/components/CommandMenu.tsx +65 -0
  521. package/dist/skills/llm-wiki/workbench/web/src/components/ExportButtons.tsx +54 -0
  522. package/dist/skills/llm-wiki/workbench/web/src/components/GraphPanel.tsx +516 -0
  523. package/dist/skills/llm-wiki/workbench/web/src/components/GraphReader.tsx +48 -0
  524. package/dist/skills/llm-wiki/workbench/web/src/components/GraphSelection.tsx +100 -0
  525. package/dist/skills/llm-wiki/workbench/web/src/components/MarkdownView.tsx +56 -0
  526. package/dist/skills/llm-wiki/workbench/web/src/components/NewWikiDialog.tsx +101 -0
  527. package/dist/skills/llm-wiki/workbench/web/src/components/RefMenu.tsx +40 -0
  528. package/dist/skills/llm-wiki/workbench/web/src/components/RightDrawer.tsx +227 -0
  529. package/dist/skills/llm-wiki/workbench/web/src/components/SettingsPanel.tsx +331 -0
  530. package/dist/skills/llm-wiki/workbench/web/src/components/Sidebar.tsx +436 -0
  531. package/dist/skills/llm-wiki/workbench/web/src/components/ToolHistorySummary.tsx +123 -0
  532. package/dist/skills/llm-wiki/workbench/web/src/components/ToolStatusRunway.tsx +90 -0
  533. package/dist/skills/llm-wiki/workbench/web/src/components/renderers/DownloadOnlyRenderer.tsx +88 -0
  534. package/dist/skills/llm-wiki/workbench/web/src/components/renderers/HtmlRenderer.tsx +92 -0
  535. package/dist/skills/llm-wiki/workbench/web/src/components/ui/button.tsx +52 -0
  536. package/dist/skills/llm-wiki/workbench/web/src/components/ui/command.tsx +50 -0
  537. package/dist/skills/llm-wiki/workbench/web/src/components/ui/dialog.tsx +156 -0
  538. package/dist/skills/llm-wiki/workbench/web/src/components/ui/input.tsx +21 -0
  539. package/dist/skills/llm-wiki/workbench/web/src/components/ui/tooltip.tsx +57 -0
  540. package/dist/skills/llm-wiki/workbench/web/src/index.css +1737 -0
  541. package/dist/skills/llm-wiki/workbench/web/src/lib/api.ts +648 -0
  542. package/dist/skills/llm-wiki/workbench/web/src/lib/drawer-state.ts +79 -0
  543. package/dist/skills/llm-wiki/workbench/web/src/lib/graph-reader.ts +25 -0
  544. package/dist/skills/llm-wiki/workbench/web/src/lib/graph-selection-drawer.ts +35 -0
  545. package/dist/skills/llm-wiki/workbench/web/src/lib/graph-selection.ts +96 -0
  546. package/dist/skills/llm-wiki/workbench/web/src/lib/legacy-tool-status.ts +113 -0
  547. package/dist/skills/llm-wiki/workbench/web/src/lib/sse.ts +72 -0
  548. package/dist/skills/llm-wiki/workbench/web/src/lib/tool-status-format.ts +170 -0
  549. package/dist/skills/llm-wiki/workbench/web/src/lib/tool-status-model.ts +392 -0
  550. package/dist/skills/llm-wiki/workbench/web/src/lib/utils.ts +10 -0
  551. package/dist/skills/llm-wiki/workbench/web/src/lib/wiki-links.ts +32 -0
  552. package/dist/skills/llm-wiki/workbench/web/src/main.tsx +10 -0
  553. package/dist/skills/llm-wiki/workbench/web/test/api.test.ts +61 -0
  554. package/dist/skills/llm-wiki/workbench/web/test/chat-panel-tool-status.test.tsx +26 -0
  555. package/dist/skills/llm-wiki/workbench/web/test/graph-drawer-state.test.ts +78 -0
  556. package/dist/skills/llm-wiki/workbench/web/test/graph-reader-request.test.ts +32 -0
  557. package/dist/skills/llm-wiki/workbench/web/test/graph-reader.test.ts +62 -0
  558. package/dist/skills/llm-wiki/workbench/web/test/graph-selection-drawer.test.ts +56 -0
  559. package/dist/skills/llm-wiki/workbench/web/test/graph-selection.test.ts +83 -0
  560. package/dist/skills/llm-wiki/workbench/web/test/tool-history-summary.test.tsx +124 -0
  561. package/dist/skills/llm-wiki/workbench/web/test/tool-status-format.test.ts +107 -0
  562. package/dist/skills/llm-wiki/workbench/web/test/tool-status-model.test.ts +324 -0
  563. package/dist/skills/llm-wiki/workbench/web/test/tool-status-runway.test.ts +134 -0
  564. package/dist/skills/llm-wiki/workbench/web/test/wiki-links.test.ts +23 -0
  565. package/dist/skills/llm-wiki/workbench/web/tsconfig.app.json +30 -0
  566. package/dist/skills/llm-wiki/workbench/web/tsconfig.json +7 -0
  567. package/dist/skills/llm-wiki/workbench/web/tsconfig.node.json +24 -0
  568. package/dist/skills/llm-wiki/workbench/web/vite.config.ts +26 -0
  569. package/dist/skills/mean-reviewer/SECURITY.md +23 -0
  570. package/dist/skills/mean-reviewer/SKILL.md +203 -0
  571. package/dist/skills/mean-reviewer/examples/13446_1000_Layer_Networks_for_.pdf +0 -0
  572. package/dist/skills/mean-reviewer/examples/13446_mean_reviewer.md +116 -0
  573. package/dist/skills/mean-reviewer/examples/13446_mean_reviewer_author_rebuttal_simulated.md +282 -0
  574. package/dist/skills/mean-reviewer/examples/13446_mean_reviewer_reply.md +91 -0
  575. package/dist/skills/mean-reviewer/examples/13446_official_review.json +973 -0
  576. package/dist/skills/mean-reviewer/examples/ChatGPT_AC_Roleplay.jpeg +0 -0
  577. package/dist/skills/medical-imaging-review/SKILL.md +295 -0
  578. package/dist/skills/medical-imaging-review/references/CITATION_INTEGRITY.md +233 -0
  579. package/dist/skills/medical-imaging-review/references/DOMAINS.md +302 -0
  580. package/dist/skills/medical-imaging-review/references/HALLUCINATION_PATTERNS.md +211 -0
  581. package/dist/skills/medical-imaging-review/references/MCP_SETUP.md +216 -0
  582. package/dist/skills/medical-imaging-review/references/PARADIGM.md +221 -0
  583. package/dist/skills/medical-imaging-review/references/QUALITY_CHECKLIST.md +169 -0
  584. package/dist/skills/medical-imaging-review/references/TEMPLATES.md +291 -0
  585. package/dist/skills/medical-imaging-review/references/WORKFLOW.md +289 -0
  586. package/dist/skills/mermaid-diagram/SKILL.md +379 -0
  587. package/dist/skills/meta-apply/SKILL.md +137 -0
  588. package/dist/skills/meta-optimize/SKILL.md +253 -0
  589. package/dist/skills/monitor-experiment/SKILL.md +98 -0
  590. package/dist/skills/novelty-check/SKILL.md +89 -0
  591. package/dist/skills/openalex/SKILL.md +228 -0
  592. package/dist/skills/overleaf-sync/SKILL.md +220 -0
  593. package/dist/skills/paper-claim-audit/SKILL.md +340 -0
  594. package/dist/skills/paper-compile/SKILL.md +253 -0
  595. package/dist/skills/paper-figure/SKILL.md +279 -0
  596. package/dist/skills/paper-illustration/SKILL.md +690 -0
  597. package/dist/skills/paper-illustration-image2/SKILL.md +383 -0
  598. package/dist/skills/paper-illustration-image2/scripts/paper_illustration_image2.py +255 -0
  599. package/dist/skills/paper-plan/SKILL.md +278 -0
  600. package/dist/skills/paper-poster/SKILL.md +19 -0
  601. package/dist/skills/paper-poster-html/DESIGN_FINAL.md +176 -0
  602. package/dist/skills/paper-poster-html/IMPLEMENTATION_CONVENTIONS.md +161 -0
  603. package/dist/skills/paper-poster-html/LICENSES/posterly-MIT.txt +21 -0
  604. package/dist/skills/paper-poster-html/NOTICE.md +57 -0
  605. package/dist/skills/paper-poster-html/SKILL.md +357 -0
  606. package/dist/skills/paper-poster-html/scripts/_posterly/__init__.py +0 -0
  607. package/dist/skills/paper-poster-html/scripts/_posterly/canvas.py +200 -0
  608. package/dist/skills/paper-poster-html/scripts/_posterly/measure.py +588 -0
  609. package/dist/skills/paper-poster-html/scripts/_posterly/polish.py +498 -0
  610. package/dist/skills/paper-poster-html/scripts/_posterly/preflight.py +489 -0
  611. package/dist/skills/paper-poster-html/scripts/_posterly/render.py +215 -0
  612. package/dist/skills/paper-poster-html/scripts/_posterly/textutil.py +16 -0
  613. package/dist/skills/paper-poster-html/scripts/_posterly/verify_final.py +171 -0
  614. package/dist/skills/paper-poster-html/scripts/asset_check.py +897 -0
  615. package/dist/skills/paper-poster-html/scripts/extract_pdf_figures.py +666 -0
  616. package/dist/skills/paper-poster-html/scripts/poster_check.py +251 -0
  617. package/dist/skills/paper-poster-html/scripts/preprocess_figures.py +238 -0
  618. package/dist/skills/paper-poster-html/scripts/render_preview.py +217 -0
  619. package/dist/skills/paper-poster-html/scripts/run_gates.py +556 -0
  620. package/dist/skills/paper-poster-html/scripts/style_check.py +1324 -0
  621. package/dist/skills/paper-poster-html/templates/COMPONENTS.md +462 -0
  622. package/dist/skills/paper-poster-html/templates/landscape_4col.html +1032 -0
  623. package/dist/skills/paper-poster-html/templates/landscape_hero.html +1046 -0
  624. package/dist/skills/paper-poster-html/templates/portrait_2col.html +947 -0
  625. package/dist/skills/paper-poster-html/templates/tokens/acl.json +9 -0
  626. package/dist/skills/paper-poster-html/templates/tokens/cvpr.json +9 -0
  627. package/dist/skills/paper-poster-html/templates/tokens/generic.json +9 -0
  628. package/dist/skills/paper-poster-html/templates/tokens/iclr.json +9 -0
  629. package/dist/skills/paper-poster-html/templates/tokens/icml.json +9 -0
  630. package/dist/skills/paper-poster-html/templates/tokens/neurips.json +9 -0
  631. package/dist/skills/paper-slide-deck/SKILL.md +464 -0
  632. package/dist/skills/paper-slide-deck/references/analysis-framework.md +392 -0
  633. package/dist/skills/paper-slide-deck/references/base-prompt.md +70 -0
  634. package/dist/skills/paper-slide-deck/references/content-rules.md +95 -0
  635. package/dist/skills/paper-slide-deck/references/figure-container-template.md +177 -0
  636. package/dist/skills/paper-slide-deck/references/modification-guide.md +85 -0
  637. package/dist/skills/paper-slide-deck/references/outline-template.md +437 -0
  638. package/dist/skills/paper-slide-deck/references/styles/academic-paper.md +109 -0
  639. package/dist/skills/paper-slide-deck/references/styles/blueprint.md +67 -0
  640. package/dist/skills/paper-slide-deck/references/styles/bold-editorial.md +70 -0
  641. package/dist/skills/paper-slide-deck/references/styles/chalkboard.md +68 -0
  642. package/dist/skills/paper-slide-deck/references/styles/corporate.md +69 -0
  643. package/dist/skills/paper-slide-deck/references/styles/dark-atmospheric.md +69 -0
  644. package/dist/skills/paper-slide-deck/references/styles/editorial-infographic.md +73 -0
  645. package/dist/skills/paper-slide-deck/references/styles/fantasy-animation.md +69 -0
  646. package/dist/skills/paper-slide-deck/references/styles/intuition-machine.md +72 -0
  647. package/dist/skills/paper-slide-deck/references/styles/minimal.md +64 -0
  648. package/dist/skills/paper-slide-deck/references/styles/notion.md +69 -0
  649. package/dist/skills/paper-slide-deck/references/styles/pixel-art.md +67 -0
  650. package/dist/skills/paper-slide-deck/references/styles/scientific.md +73 -0
  651. package/dist/skills/paper-slide-deck/references/styles/sketch-notes.md +66 -0
  652. package/dist/skills/paper-slide-deck/references/styles/vector-illustration.md +72 -0
  653. package/dist/skills/paper-slide-deck/references/styles/vintage.md +73 -0
  654. package/dist/skills/paper-slide-deck/references/styles/watercolor.md +68 -0
  655. package/dist/skills/paper-slide-deck/scripts/apply-template.ts +282 -0
  656. package/dist/skills/paper-slide-deck/scripts/detect-figures.ts +283 -0
  657. package/dist/skills/paper-slide-deck/scripts/extract-figure.ts +140 -0
  658. package/dist/skills/paper-slide-deck/scripts/generate-slides.py +182 -0
  659. package/dist/skills/paper-slide-deck/scripts/merge-to-pdf.ts +116 -0
  660. package/dist/skills/paper-slide-deck/scripts/merge-to-pptx.ts +137 -0
  661. package/dist/skills/paper-slide-deck/scripts/package-lock.json +899 -0
  662. package/dist/skills/paper-slide-deck/scripts/package.json +8 -0
  663. package/dist/skills/paper-slides/SKILL.md +571 -0
  664. package/dist/skills/paper-talk/SKILL.md +381 -0
  665. package/dist/skills/paper-write/SKILL.md +411 -0
  666. package/dist/skills/paper-write/templates/IEEEtran.bst +2409 -0
  667. package/dist/skills/paper-write/templates/IEEEtran.cls +6347 -0
  668. package/dist/skills/paper-write/templates/aaai2026.bst +1493 -0
  669. package/dist/skills/paper-write/templates/aaai2026.sty +315 -0
  670. package/dist/skills/paper-write/templates/aaai2026.tex +952 -0
  671. package/dist/skills/paper-write/templates/acl.sty +312 -0
  672. package/dist/skills/paper-write/templates/acl2026.tex +377 -0
  673. package/dist/skills/paper-write/templates/acl_natbib.bst +1940 -0
  674. package/dist/skills/paper-write/templates/acm.bst +3081 -0
  675. package/dist/skills/paper-write/templates/acm_mm2026.tex +204 -0
  676. package/dist/skills/paper-write/templates/acmart.cls +3520 -0
  677. package/dist/skills/paper-write/templates/cvpr.bst +1448 -0
  678. package/dist/skills/paper-write/templates/cvpr.sty +508 -0
  679. package/dist/skills/paper-write/templates/cvpr2026.tex +63 -0
  680. package/dist/skills/paper-write/templates/iclr2026.tex +84 -0
  681. package/dist/skills/paper-write/templates/iclr2026_conference.bst +1440 -0
  682. package/dist/skills/paper-write/templates/iclr2026_conference.sty +246 -0
  683. package/dist/skills/paper-write/templates/icml2025.tex +87 -0
  684. package/dist/skills/paper-write/templates/icml2026.sty +767 -0
  685. package/dist/skills/paper-write/templates/icml2026.tex +662 -0
  686. package/dist/skills/paper-write/templates/ieee_conference.tex +89 -0
  687. package/dist/skills/paper-write/templates/ieee_journal.tex +93 -0
  688. package/dist/skills/paper-write/templates/math_commands.tex +48 -0
  689. package/dist/skills/paper-write/templates/neurips2025.tex +80 -0
  690. package/dist/skills/paper-write/templates/neurips2026.tex +493 -0
  691. package/dist/skills/paper-write/templates/neurips_2026.sty +437 -0
  692. package/dist/skills/paper-writing/SKILL.md +632 -0
  693. package/dist/skills/patent-novelty-check/SKILL.md +153 -0
  694. package/dist/skills/patent-pipeline/SKILL.md +344 -0
  695. package/dist/skills/patent-review/SKILL.md +202 -0
  696. package/dist/skills/pixel-art/SKILL.md +139 -0
  697. package/dist/skills/pre-submission-reviewer/SKILL.md +247 -0
  698. package/dist/skills/pre-submission-reviewer/references/forbidden-patterns.md +163 -0
  699. package/dist/skills/pre-submission-reviewer/references/grammar-rules.md +135 -0
  700. package/dist/skills/pre-submission-reviewer/references/latex-rules.md +158 -0
  701. package/dist/skills/pre-submission-reviewer/references/logic-and-structure.md +125 -0
  702. package/dist/skills/pre-submission-reviewer/references/section-guides.md +169 -0
  703. package/dist/skills/prior-art-search/SKILL.md +146 -0
  704. package/dist/skills/proof-checker/SKILL.md +499 -0
  705. package/dist/skills/proof-writer/SKILL.md +222 -0
  706. package/dist/skills/qzcli/SKILL.md +316 -0
  707. package/dist/skills/rebuttal/SKILL.md +304 -0
  708. package/dist/skills/render-html/SKILL.md +299 -0
  709. package/dist/skills/render-html/scripts/render_html.py +905 -0
  710. package/dist/skills/render-html/scripts/templates/academic.html +342 -0
  711. package/dist/skills/render-html/scripts/templates/dashboard.html +333 -0
  712. package/dist/skills/research-lit/SKILL.md +353 -0
  713. package/dist/skills/research-paper-writing/SKILL.md +99 -0
  714. package/dist/skills/research-paper-writing/agents/openai.yaml +4 -0
  715. package/dist/skills/research-paper-writing/references/abstract.md +102 -0
  716. package/dist/skills/research-paper-writing/references/conclusion.md +35 -0
  717. package/dist/skills/research-paper-writing/references/does-my-writing-flow-source.md +45 -0
  718. package/dist/skills/research-paper-writing/references/examples/abstract/template-a.md +21 -0
  719. package/dist/skills/research-paper-writing/references/examples/abstract/template-b.md +34 -0
  720. package/dist/skills/research-paper-writing/references/examples/abstract/template-c.md +28 -0
  721. package/dist/skills/research-paper-writing/references/examples/abstract-examples.md +13 -0
  722. package/dist/skills/research-paper-writing/references/examples/index.md +21 -0
  723. package/dist/skills/research-paper-writing/references/examples/introduction/novel-task-challenge-decomposition.md +18 -0
  724. package/dist/skills/research-paper-writing/references/examples/introduction/pipeline-not-recommended-abstract-only.md +30 -0
  725. package/dist/skills/research-paper-writing/references/examples/introduction/pipeline-version-1-one-contribution-multi-advantages.md +30 -0
  726. package/dist/skills/research-paper-writing/references/examples/introduction/pipeline-version-2-two-contributions.md +34 -0
  727. package/dist/skills/research-paper-writing/references/examples/introduction/pipeline-version-3-new-module-on-existing-pipeline.md +18 -0
  728. package/dist/skills/research-paper-writing/references/examples/introduction/pipeline-version-4-observation-driven.md +16 -0
  729. package/dist/skills/research-paper-writing/references/examples/introduction/technical-challenge-version-1-existing-task.md +32 -0
  730. package/dist/skills/research-paper-writing/references/examples/introduction/technical-challenge-version-2-existing-task-insight-backed-by-traditional.md +33 -0
  731. package/dist/skills/research-paper-writing/references/examples/introduction/technical-challenge-version-3-novel-task.md +21 -0
  732. package/dist/skills/research-paper-writing/references/examples/introduction/version-1-task-then-application.md +14 -0
  733. package/dist/skills/research-paper-writing/references/examples/introduction/version-2-application-first.md +10 -0
  734. package/dist/skills/research-paper-writing/references/examples/introduction/version-3-general-to-specific-setting.md +14 -0
  735. package/dist/skills/research-paper-writing/references/examples/introduction/version-4-open-with-challenge.md +20 -0
  736. package/dist/skills/research-paper-writing/references/examples/introduction-examples.md +25 -0
  737. package/dist/skills/research-paper-writing/references/examples/method/example-of-the-three-elements.md +67 -0
  738. package/dist/skills/research-paper-writing/references/examples/method/method-writing-common-issues-note.md +10 -0
  739. package/dist/skills/research-paper-writing/references/examples/method/module-design-instant-ngp.md +55 -0
  740. package/dist/skills/research-paper-writing/references/examples/method/module-motivation-patterns.md +15 -0
  741. package/dist/skills/research-paper-writing/references/examples/method/module-triad-neural-body.md +19 -0
  742. package/dist/skills/research-paper-writing/references/examples/method/neural-body-annotated-figure-text.md +66 -0
  743. package/dist/skills/research-paper-writing/references/examples/method/overview-template.md +30 -0
  744. package/dist/skills/research-paper-writing/references/examples/method/pre-writing-questions.md +17 -0
  745. package/dist/skills/research-paper-writing/references/examples/method/section-skeleton.md +9 -0
  746. package/dist/skills/research-paper-writing/references/examples/method-examples.md +24 -0
  747. package/dist/skills/research-paper-writing/references/experiments.md +102 -0
  748. package/dist/skills/research-paper-writing/references/introduction.md +408 -0
  749. package/dist/skills/research-paper-writing/references/method.md +196 -0
  750. package/dist/skills/research-paper-writing/references/paper-review.md +86 -0
  751. package/dist/skills/research-paper-writing/references/related-work.md +41 -0
  752. package/dist/skills/research-pipeline/SKILL.md +257 -0
  753. package/dist/skills/research-proposal/SKILL.md +573 -0
  754. package/dist/skills/research-proposal/assets/proposal_scaffold_en.md +323 -0
  755. package/dist/skills/research-proposal/assets/proposal_scaffold_zh.md +346 -0
  756. package/dist/skills/research-proposal/references/DOMAIN_TEMPLATES.md +518 -0
  757. package/dist/skills/research-proposal/references/LITERATURE_WORKFLOW.md +529 -0
  758. package/dist/skills/research-proposal/references/QUALITY_CHECKLIST.md +325 -0
  759. package/dist/skills/research-proposal/references/STRUCTURE_GUIDE.md +398 -0
  760. package/dist/skills/research-proposal/references/WRITING_STYLE_GUIDE.md +661 -0
  761. package/dist/skills/research-refine/SKILL.md +716 -0
  762. package/dist/skills/research-refine-pipeline/SKILL.md +186 -0
  763. package/dist/skills/research-review/SKILL.md +119 -0
  764. package/dist/skills/research-wiki/SKILL.md +373 -0
  765. package/dist/skills/resubmit-pipeline/SKILL.md +427 -0
  766. package/dist/skills/result-to-claim/SKILL.md +190 -0
  767. package/dist/skills/run-experiment/SKILL.md +227 -0
  768. package/dist/skills/scientific-figure-making/SKILL.md +38 -0
  769. package/dist/skills/scientific-figure-making/references/api.md +152 -0
  770. package/dist/skills/scientific-figure-making/references/common-patterns.md +74 -0
  771. package/dist/skills/scientific-figure-making/references/demos.md +30 -0
  772. package/dist/skills/scientific-figure-making/references/design-theory.md +138 -0
  773. package/dist/skills/scientific-figure-making/references/tutorials.md +135 -0
  774. package/dist/skills/semantic-scholar/SKILL.md +219 -0
  775. package/dist/skills/serverless-modal/SKILL.md +324 -0
  776. package/dist/skills/slides-polish/SKILL.md +563 -0
  777. package/dist/skills/specification-writing/SKILL.md +211 -0
  778. package/dist/skills/strategist/SKILL.md +670 -0
  779. package/dist/skills/strategist/references/quality_standards.md +336 -0
  780. package/dist/skills/strategist/references/search_strategy.md +459 -0
  781. package/dist/skills/strategist/scripts/evaluate_samples.py +300 -0
  782. package/dist/skills/strategist/scripts/gap_analysis.py +399 -0
  783. package/dist/skills/system-profile/SKILL.md +103 -0
  784. package/dist/skills/tech-paper-template/SKILL.md +192 -0
  785. package/dist/skills/tech-paper-template/references/consistency-checks.md +166 -0
  786. package/dist/skills/tech-paper-template/references/paper-types.md +127 -0
  787. package/dist/skills/tech-paper-template/references/thinking-template.md +194 -0
  788. package/dist/skills/tech-paper-template/references/worked-examples.md +124 -0
  789. package/dist/skills/training-check/SKILL.md +83 -0
  790. package/dist/skills/vast-gpu/SKILL.md +380 -0
  791. package/dist/skills/vibe-research-workflow/SKILL.md +189 -0
  792. package/dist/skills/vibe-research-workflow/references/behavior-guidelines.md +149 -0
  793. package/dist/skills/vibe-research-workflow/references/tool-selection.md +144 -0
  794. package/dist/skills/vibe-research-workflow/references/vibe-coding.md +154 -0
  795. package/dist/skills/vibe-research-workflow/references/vibe-figure.md +131 -0
  796. package/dist/skills/vibe-research-workflow/references/vibe-writing.md +181 -0
  797. package/dist/skills/wiki-enrich/SKILL.md +254 -0
  798. package/dist/skills/writing-systems-papers/SKILL.md +184 -0
  799. package/package.json +1 -1
@@ -0,0 +1,897 @@
1
+ #!/usr/bin/env python3
2
+ """asset_check - the "real-figure provenance" gate (DESIGN_FINAL.md §4).
3
+
4
+ A poster passes this gate only when its paper figures are genuinely
5
+ sourced from the paper and rendered large/sharp enough to read:
6
+
7
+ 1. Provenance. Every ``<img data-source="paper">`` must carry a
8
+ ``data-asset-id`` that resolves to a FIGURE_MANIFEST.json entry
9
+ with ``from_paper: true`` and ALL required fields (§D schema).
10
+ The referenced file must exist and its sha256 must match the
11
+ manifest -- so a swapped/edited PNG can't masquerade as the
12
+ vetted figure.
13
+
14
+ 2. Count. At least ``--min-paper-figs`` such figures (default 2):
15
+ a poster with one tiny figure or none is the failure mode we
16
+ are guarding against.
17
+
18
+ 3. Per-figure rendered area >= ``--min-fig-area`` of the poster
19
+ (default 1.5%), and total paper-image area >= ``--min-total-area``
20
+ of the body (default 12%). The 12% total rule is the only one
21
+ ``--waive-total-area`` can waive (pure-theory posters; §12.5 nit 2).
22
+
23
+ 4. Resolution. A raster's natural pixel size must be >= 1.5x its
24
+ rendered size (HARD below 1.5x, WARN between 1.5x and 2x; aim 2x).
25
+ Catches up-scaled low-res crops that print blurry.
26
+
27
+ Rendered-area + rendered-resolution checks (3, 4) need real geometry,
28
+ which requires print-emulating the poster in Chromium via Playwright.
29
+ Playwright is lazy-imported INSIDE the render path: when it is missing
30
+ (or ``--no-render`` is passed), those checks degrade to an estimate
31
+ computed from ``natural_px`` and CSS ``width`` hints, are marked
32
+ ESTIMATED in the output, and do NOT hard-fail on the area thresholds
33
+ (a NOTICE is printed instead). The provenance/count/manifest checks
34
+ (1, 2, and the field/file/sha256 parts) are pure-static and always run.
35
+
36
+ JSON output (``--json``):
37
+ {"gate": "asset", "status": "PASS|FAIL|WARN", "checks": [ ... ]}
38
+ where each check is
39
+ {"id": "...", "severity": "hard|warn", "status": "PASS|FAIL|WARN|
40
+ NOTICE|ESTIMATED", "detail": "..."}
41
+
42
+ Exit code: 0 = pass (no hard failures), 1 = hard fail, 2 = usage /
43
+ environment error (bad args, missing file, unparseable manifest).
44
+ """
45
+ from __future__ import annotations
46
+
47
+ import argparse
48
+ import hashlib
49
+ import json
50
+ import os
51
+ import re
52
+ import sys
53
+ from html.parser import HTMLParser
54
+ from pathlib import Path
55
+
56
+ # Make `_posterly` importable when run directly via
57
+ # `python asset_check.py …`, mirroring poster_check.py / render_preview.py.
58
+ _THIS_DIR = os.path.dirname(os.path.abspath(__file__))
59
+ if _THIS_DIR not in sys.path:
60
+ sys.path.insert(0, _THIS_DIR)
61
+
62
+ from _posterly import canvas as _canvas # noqa: E402
63
+ from _posterly.textutil import ascii_safe # noqa: E402
64
+
65
+
66
+ # Required manifest fields per figure (§D schema). ``from_paper`` is
67
+ # validated separately (it must be exactly True), so it is not in the
68
+ # "presence" list but IS required to exist -- see _validate_manifest.
69
+ _REQUIRED_FIG_FIELDS: tuple[str, ...] = (
70
+ "asset_id", "file", "from_paper", "page", "bbox", "dpi",
71
+ "sha256", "natural_px",
72
+ )
73
+
74
+ # Resolution thresholds (§4): natural >= 1.5x rendered is the HARD floor;
75
+ # between 1.5x and 2.0x is a WARN (target is 2x).
76
+ _RES_HARD_FACTOR = 1.5
77
+ _RES_WARN_FACTOR = 2.0
78
+
79
+
80
+ def _eprint(*args: object, **kw: object) -> None:
81
+ print(*args, file=sys.stderr, **kw) # type: ignore[arg-type]
82
+
83
+
84
+ # --------------------------------------------------------------------------
85
+ # HTML parsing: collect <img> elements (esp. data-source="paper").
86
+ # --------------------------------------------------------------------------
87
+ class _ImgCollector(HTMLParser):
88
+ """Collect every ``<img>``'s attributes as a flat dict.
89
+
90
+ Why a real parser and not a regex: the AR-opt-out path lets a paper
91
+ image carry ``style="width: NN%"`` (the one inline-style exception in
92
+ §B), and attribute order is free-form. HTMLParser hands us a clean
93
+ ``{attr: value}`` map regardless of quoting/order, and lower-cases the
94
+ keys, so downstream lookups (``data-source``, ``data-asset-id``,
95
+ ``class``, ``style``, ``width``) are robust.
96
+ """
97
+
98
+ def __init__(self) -> None:
99
+ super().__init__(convert_charrefs=True)
100
+ # One dict per <img>, in source order. Keys are lower-cased attr
101
+ # names; missing attrs simply absent.
102
+ self.imgs: list[dict[str, str]] = []
103
+
104
+ def _record_img(self, attrs: list[tuple[str, str | None]]) -> None:
105
+ d: dict[str, str] = {}
106
+ for k, v in attrs:
107
+ d[k.lower()] = "" if v is None else v
108
+ d["_line"] = str(self.getpos()[0])
109
+ self.imgs.append(d)
110
+
111
+ def handle_starttag(self, tag: str,
112
+ attrs: list[tuple[str, str | None]]) -> None:
113
+ if tag.lower() == "img":
114
+ self._record_img(attrs)
115
+
116
+ def handle_startendtag(self, tag: str,
117
+ attrs: list[tuple[str, str | None]]) -> None:
118
+ # `<img ... />` self-closing form: identical handling.
119
+ if tag.lower() == "img":
120
+ self._record_img(attrs)
121
+
122
+
123
+ def collect_imgs(html: str) -> list[dict[str, str]]:
124
+ """Return one attr-dict per ``<img>`` in source order. Pure function
125
+ so the provenance rules are unit-testable without a browser."""
126
+ p = _ImgCollector()
127
+ p.feed(html)
128
+ p.close()
129
+ return p.imgs
130
+
131
+
132
+ def paper_imgs(imgs: list[dict[str, str]]) -> list[dict[str, str]]:
133
+ """Filter to images tagged as sourced from the paper.
134
+
135
+ The contract (§B) is ``data-source="paper"``; we match
136
+ case-insensitively on the value but the attribute name is fixed.
137
+ """
138
+ return [d for d in imgs if d.get("data-source", "").strip().lower()
139
+ == "paper"]
140
+
141
+
142
+ # --------------------------------------------------------------------------
143
+ # Manifest loading + schema validation (§D).
144
+ # --------------------------------------------------------------------------
145
+ def load_manifest(path: Path) -> dict:
146
+ """Parse FIGURE_MANIFEST.json. Raises ``ValueError`` (caught by the
147
+ caller -> exit 2) on missing file or bad JSON, with a readable msg."""
148
+ if not path.exists():
149
+ raise ValueError(f"manifest not found: {ascii_safe(path)}")
150
+ try:
151
+ data = json.loads(path.read_text(encoding="utf-8"))
152
+ except json.JSONDecodeError as e:
153
+ raise ValueError(
154
+ f"manifest is not valid JSON: {ascii_safe(e)}"
155
+ ) from e
156
+ if not isinstance(data, dict):
157
+ raise ValueError("manifest top-level must be a JSON object")
158
+ return data
159
+
160
+
161
+ def index_figures(manifest: dict) -> dict[str, dict]:
162
+ """Map ``asset_id`` -> figure entry. Entries without an ``asset_id``
163
+ are skipped here (the missing-field check reports them per-image)."""
164
+ figs = manifest.get("figures")
165
+ out: dict[str, dict] = {}
166
+ if isinstance(figs, list):
167
+ for f in figs:
168
+ if isinstance(f, dict) and isinstance(f.get("asset_id"), str):
169
+ out[f["asset_id"]] = f
170
+ return out
171
+
172
+
173
+ def _missing_fields(fig: dict) -> list[str]:
174
+ """Required §D fields absent from a figure entry (presence only)."""
175
+ return [k for k in _REQUIRED_FIG_FIELDS if k not in fig]
176
+
177
+
178
+ def _sha256_of(path: Path) -> str:
179
+ h = hashlib.sha256()
180
+ with path.open("rb") as fh:
181
+ for chunk in iter(lambda: fh.read(1 << 16), b""):
182
+ h.update(chunk)
183
+ return h.hexdigest()
184
+
185
+
186
+ # --------------------------------------------------------------------------
187
+ # Check accumulation. A "check" is one row in the JSON ``checks`` array.
188
+ # --------------------------------------------------------------------------
189
+ class Checks:
190
+ """Accumulate check rows and derive the overall gate status.
191
+
192
+ Status semantics:
193
+ - any ``hard`` check FAIL -> gate FAIL (exit 1)
194
+ - else any WARN -> gate WARN (exit 0)
195
+ - else -> gate PASS (exit 0)
196
+ NOTICE / ESTIMATED are informational (degraded render path) and
197
+ never by themselves flip the gate.
198
+ """
199
+
200
+ def __init__(self) -> None:
201
+ self.rows: list[dict[str, str]] = []
202
+
203
+ def add(self, cid: str, severity: str, status: str, detail: str
204
+ ) -> None:
205
+ self.rows.append({
206
+ "id": cid,
207
+ "severity": severity,
208
+ "status": status,
209
+ "detail": ascii_safe(detail),
210
+ })
211
+
212
+ def overall(self) -> str:
213
+ if any(r["severity"] == "hard" and r["status"] == "FAIL"
214
+ for r in self.rows):
215
+ return "FAIL"
216
+ if any(r["status"] == "WARN" for r in self.rows):
217
+ return "WARN"
218
+ return "PASS"
219
+
220
+
221
+ # --------------------------------------------------------------------------
222
+ # Static provenance + manifest checks (always run).
223
+ # --------------------------------------------------------------------------
224
+ def check_provenance(
225
+ checks: Checks,
226
+ p_imgs: list[dict[str, str]],
227
+ fig_index: dict[str, dict],
228
+ manifest_dir: Path,
229
+ min_paper_figs: int,
230
+ ) -> list[tuple[dict[str, str], dict]]:
231
+ """Validate count + per-image manifest linkage (id resolves,
232
+ from_paper True, fields present, file exists, sha256 matches).
233
+
234
+ Returns the list of ``(img_attrs, manifest_entry)`` pairs that fully
235
+ validated -- callers use these for the area/resolution checks.
236
+ """
237
+ # 2) Count gate.
238
+ n = len(p_imgs)
239
+ if n >= min_paper_figs:
240
+ checks.add(
241
+ "paper_fig_count", "hard", "PASS",
242
+ f"{n} img[data-source=paper] (>= {min_paper_figs} required)",
243
+ )
244
+ else:
245
+ checks.add(
246
+ "paper_fig_count", "hard", "FAIL",
247
+ f"only {n} img[data-source=paper]; need >= {min_paper_figs}. "
248
+ f"Pull at least {min_paper_figs} real figures from the paper "
249
+ f"(or use a human-checkpoint waiver per DESIGN_FINAL §4).",
250
+ )
251
+
252
+ validated: list[tuple[dict[str, str], dict]] = []
253
+ for img in p_imgs:
254
+ line = img.get("_line", "?")
255
+ asset_id = img.get("data-asset-id", "").strip()
256
+ tag = f"L{line} src={ascii_safe(img.get('src', '?'))}"
257
+
258
+ # 1a) data-asset-id present?
259
+ if not asset_id:
260
+ checks.add(
261
+ "asset_id_present", "hard", "FAIL",
262
+ f"{tag}: data-source=paper without data-asset-id; "
263
+ f"cannot trace to the manifest.",
264
+ )
265
+ continue
266
+ # 1b) Resolves to a manifest entry?
267
+ entry = fig_index.get(asset_id)
268
+ if entry is None:
269
+ checks.add(
270
+ "asset_id_resolves", "hard", "FAIL",
271
+ f"{tag}: data-asset-id={ascii_safe(asset_id)!r} not found "
272
+ f"in manifest figures[].",
273
+ )
274
+ continue
275
+ # 1c) from_paper exactly True?
276
+ if entry.get("from_paper") is not True:
277
+ checks.add(
278
+ "from_paper", "hard", "FAIL",
279
+ f"asset {ascii_safe(asset_id)}: from_paper is "
280
+ f"{ascii_safe(entry.get('from_paper'))!r}, must be true.",
281
+ )
282
+ continue
283
+ # 1d) All required §D fields present?
284
+ missing = _missing_fields(entry)
285
+ if missing:
286
+ checks.add(
287
+ "manifest_fields", "hard", "FAIL",
288
+ f"asset {ascii_safe(asset_id)}: missing required field(s) "
289
+ f"{missing}.",
290
+ )
291
+ continue
292
+ # 1e) Referenced file exists? `file` is relative to the manifest
293
+ # directory (the manifest lives alongside the poster output).
294
+ rel = str(entry.get("file", ""))
295
+ fpath = (manifest_dir / rel).resolve()
296
+ if not fpath.exists():
297
+ checks.add(
298
+ "asset_file_exists", "hard", "FAIL",
299
+ f"asset {ascii_safe(asset_id)}: file {ascii_safe(rel)} "
300
+ f"does not exist at {ascii_safe(fpath)}.",
301
+ )
302
+ continue
303
+ # 1f) sha256 matches the manifest? A mismatch means the on-disk
304
+ # bytes are NOT the vetted figure (re-saved, edited, swapped).
305
+ want = str(entry.get("sha256", "")).strip().lower()
306
+ got = _sha256_of(fpath).lower()
307
+ if want != got:
308
+ checks.add(
309
+ "asset_sha256", "hard", "FAIL",
310
+ f"asset {ascii_safe(asset_id)}: sha256 mismatch "
311
+ f"(manifest {want[:12]}..., file {got[:12]}...). The "
312
+ f"on-disk file is not the manifested figure.",
313
+ )
314
+ continue
315
+
316
+ checks.add(
317
+ "asset_provenance", "hard", "PASS",
318
+ f"asset {ascii_safe(asset_id)}: resolves, from_paper, fields "
319
+ f"complete, file exists, sha256 matches.",
320
+ )
321
+ validated.append((img, entry))
322
+
323
+ return validated
324
+
325
+
326
+ # --------------------------------------------------------------------------
327
+ # CSS width hint extraction (for the --no-render estimate).
328
+ # --------------------------------------------------------------------------
329
+ def _width_fraction_hint(img: dict[str, str]) -> float | None:
330
+ """Best-effort fraction-of-container width for an <img>, from CSS hints.
331
+
332
+ Sources, in priority order:
333
+ 1. ``style="width: NN%"`` (the one allowed inline-style, §B).
334
+ 2. A ``w-NN`` utility class (``.w-45 … .w-100``, §B): NN percent.
335
+ Returns the fraction in [0, 1], or None when no width hint is present.
336
+ This is only an ESTIMATE input -- the real number comes from render.
337
+ """
338
+ style = img.get("style", "")
339
+ m = re.search(r"width\s*:\s*([\d.]+)\s*%", style, re.IGNORECASE)
340
+ if m:
341
+ try:
342
+ return max(0.0, min(1.0, float(m.group(1)) / 100.0))
343
+ except ValueError:
344
+ pass
345
+ cls = img.get("class", "")
346
+ m = re.search(r"\bw-(\d{2,3})\b", cls)
347
+ if m:
348
+ try:
349
+ return max(0.0, min(1.0, float(m.group(1)) / 100.0))
350
+ except ValueError:
351
+ pass
352
+ return None
353
+
354
+
355
+ # --------------------------------------------------------------------------
356
+ # Rendered-geometry path (Playwright). Lazy import inside.
357
+ # --------------------------------------------------------------------------
358
+ def measure_rendered(
359
+ html_path: Path,
360
+ viewport: tuple[int, int],
361
+ asset_ids: list[str],
362
+ mathjax_timeout_ms: int,
363
+ ) -> dict[str, dict[str, float]] | None:
364
+ """Print-emulate the poster and read each paper image's rendered box
365
+ plus the poster + body boxes. Returns a dict keyed by asset_id:
366
+
367
+ {asset_id: {"w": px, "h": px, "area": px2}}
368
+ plus pseudo-keys "__poster__" and "__body__" with their areas.
369
+
370
+ Returns ``None`` when Playwright is unavailable -- the caller then
371
+ falls back to the ESTIMATED path. Playwright is imported HERE (not at
372
+ module top) so the static checks run even while playwright is still
373
+ installing / absent.
374
+ """
375
+ try:
376
+ from playwright.sync_api import sync_playwright
377
+ from playwright.sync_api import TimeoutError as PWTimeoutError
378
+ except ImportError:
379
+ _eprint(
380
+ "[asset_check] NOTICE: playwright not available; cannot "
381
+ "measure rendered figure areas. Falling back to a "
382
+ "natural_px + CSS-width ESTIMATE. To get the real geometry "
383
+ "gate, install it once:\n"
384
+ " python -m pip install playwright\n"
385
+ " python -m playwright install chromium\n"
386
+ "...or re-run with --no-render to silence this notice."
387
+ )
388
+ return None
389
+
390
+ from _posterly import render as _render # local: needs playwright too
391
+
392
+ w, h = viewport
393
+ result: dict[str, dict[str, float]] = {}
394
+ with sync_playwright() as p_:
395
+ browser, _ctx, page = _render.open_print_emulated_page(p_, (w, h))
396
+ try:
397
+ page.goto(html_path.as_uri(), timeout=mathjax_timeout_ms)
398
+ except PWTimeoutError:
399
+ _eprint(
400
+ f"[asset_check] WARN: page.goto did not reach `load` "
401
+ f"within {mathjax_timeout_ms} ms; measuring whatever "
402
+ f"loaded (a CDN/external resource is likely blocked)."
403
+ )
404
+ # Settle fonts/layout (best-effort) so image boxes are final.
405
+ _render.settle_page(
406
+ page, mathjax_timeout_ms=mathjax_timeout_ms, settle_ms=300,
407
+ )
408
+ # One round-trip: collect every paper image's box + the poster
409
+ # and body boxes. We key on data-asset-id.
410
+ boxes = page.evaluate(
411
+ """(ids) => {
412
+ const out = {};
413
+ const poster = document.querySelector(
414
+ '[data-measure-role="poster"]')
415
+ || document.querySelector('.poster')
416
+ || document.body;
417
+ const body = document.querySelector(
418
+ '[data-measure-role="body"]') || poster;
419
+ const rp = poster.getBoundingClientRect();
420
+ const rb = body.getBoundingClientRect();
421
+ out["__poster__"] = {w: rp.width, h: rp.height,
422
+ area: rp.width * rp.height};
423
+ out["__body__"] = {w: rb.width, h: rb.height,
424
+ area: rb.width * rb.height};
425
+ for (const id of ids) {
426
+ const el = document.querySelector(
427
+ 'img[data-source="paper"][data-asset-id="'
428
+ + id.replace(/"/g, '\\\\"') + '"]');
429
+ if (!el) continue;
430
+ const r = el.getBoundingClientRect();
431
+ out[id] = {w: r.width, h: r.height,
432
+ area: r.width * r.height};
433
+ }
434
+ return out;
435
+ }""",
436
+ asset_ids,
437
+ )
438
+ browser.close()
439
+ for k, v in boxes.items():
440
+ result[k] = {kk: float(vv) for kk, vv in v.items()}
441
+ return result
442
+
443
+
444
+ # --------------------------------------------------------------------------
445
+ # Area + resolution checks. Two code paths: rendered vs estimated.
446
+ # --------------------------------------------------------------------------
447
+ def check_areas_rendered(
448
+ checks: Checks,
449
+ validated: list[tuple[dict[str, str], dict]],
450
+ boxes: dict[str, dict[str, float]],
451
+ min_fig_area: float,
452
+ min_total_area: float,
453
+ waive_total_area: bool,
454
+ warn_fig_area: float = 0.10,
455
+ max_fig_area: float = 0.13,
456
+ warn_total_area: float = 0.24,
457
+ max_total_area: float = 0.28,
458
+ ) -> None:
459
+ """Per-figure area (min AND max bands), total area (min AND max
460
+ bands), and natural>=1.5x rendered checks using REAL geometry from
461
+ ``measure_rendered``. Upper bands exist because the failure mode is
462
+ symmetric: too-small figures read as decoration, too-big figures
463
+ crowd out the content (user-reported regression, 2026-06-05).
464
+ Mins stay poster-based for back-compat; maxes are body-based per the
465
+ codex-converged density bands (target total 14-22%% of body)."""
466
+ poster_area = boxes.get("__poster__", {}).get("area", 0.0)
467
+ body_area = boxes.get("__body__", {}).get("area", 0.0) or poster_area
468
+
469
+ total_fig_area = 0.0
470
+ for img, entry in validated:
471
+ asset_id = str(entry.get("asset_id"))
472
+ box = boxes.get(asset_id)
473
+ if box is None:
474
+ # Image validated statically but not found in the DOM render
475
+ # (e.g. display:none, off-canvas). Treat as a HARD fail: it
476
+ # is not actually contributing a visible figure.
477
+ checks.add(
478
+ "fig_area", "hard", "FAIL",
479
+ f"asset {ascii_safe(asset_id)}: not found / zero-size in "
480
+ f"the rendered poster (hidden or detached?).",
481
+ )
482
+ continue
483
+ area = box["area"]
484
+ total_fig_area += area
485
+ frac = (area / poster_area) if poster_area > 0 else 0.0
486
+ if frac >= min_fig_area:
487
+ checks.add(
488
+ "fig_area", "hard", "PASS",
489
+ f"asset {ascii_safe(asset_id)}: {frac * 100:.2f}% of "
490
+ f"poster (>= {min_fig_area * 100:.2f}%).",
491
+ )
492
+ else:
493
+ checks.add(
494
+ "fig_area", "hard", "FAIL",
495
+ f"asset {ascii_safe(asset_id)}: only {frac * 100:.2f}% of "
496
+ f"poster (need >= {min_fig_area * 100:.2f}%). Widen the "
497
+ f"figure (.w-NN / style=width) or move it to a larger card.",
498
+ )
499
+ body_frac = (area / body_area) if body_area > 0 else 0.0
500
+ if body_frac > max_fig_area:
501
+ checks.add(
502
+ "fig_area_max", "hard", "FAIL",
503
+ f"asset {ascii_safe(asset_id)}: {body_frac * 100:.2f}% of "
504
+ f"body (> {max_fig_area * 100:.0f}% hard max). A figure "
505
+ f"this dominant crowds out content: shrink (.w-NN), merge "
506
+ f"siblings into a .figure--duo, or use the hero template "
507
+ f"(--hero).",
508
+ )
509
+ elif body_frac > warn_fig_area:
510
+ checks.add(
511
+ "fig_area_max", "warn", "WARN",
512
+ f"asset {ascii_safe(asset_id)}: {body_frac * 100:.2f}% of "
513
+ f"body (> {warn_fig_area * 100:.0f}%); target per-figure "
514
+ f"band is 4-8%. Consider shrinking or pairing.",
515
+ )
516
+ _check_resolution(checks, entry, box["w"], box["h"], estimated=False)
517
+
518
+ # Total paper-image area vs body. The ONLY rule --waive-total-area
519
+ # affects (§12.5 nit 2).
520
+ total_frac = (total_fig_area / body_area) if body_area > 0 else 0.0
521
+ if waive_total_area:
522
+ checks.add(
523
+ "total_fig_area", "hard", "NOTICE",
524
+ f"total paper-image area = {total_frac * 100:.2f}% of body; "
525
+ f"WAIVED via --waive-total-area (pure-theory poster).",
526
+ )
527
+ elif total_frac >= min_total_area:
528
+ checks.add(
529
+ "total_fig_area", "hard", "PASS",
530
+ f"total paper-image area = {total_frac * 100:.2f}% of body "
531
+ f"(>= {min_total_area * 100:.2f}%).",
532
+ )
533
+ else:
534
+ checks.add(
535
+ "total_fig_area", "hard", "FAIL",
536
+ f"total paper-image area = {total_frac * 100:.2f}% of body "
537
+ f"(need >= {min_total_area * 100:.2f}%). Add/enlarge real "
538
+ f"figures, or --waive-total-area for a pure-theory poster.",
539
+ )
540
+ if total_frac > max_total_area:
541
+ checks.add(
542
+ "total_fig_area_max", "hard", "FAIL",
543
+ f"total paper-image area = {total_frac * 100:.2f}% of body "
544
+ f"(> {max_total_area * 100:.0f}% hard max). Figures are "
545
+ f"crowding out content: shrink, merge into .figure--duo, or "
546
+ f"switch to the hero template (--hero).",
547
+ )
548
+ elif total_frac > warn_total_area:
549
+ checks.add(
550
+ "total_fig_area_max", "warn", "WARN",
551
+ f"total paper-image area = {total_frac * 100:.2f}% of body "
552
+ f"(> {warn_total_area * 100:.0f}%); target band is 14-22%.",
553
+ )
554
+
555
+
556
+ def check_areas_estimated(
557
+ checks: Checks,
558
+ validated: list[tuple[dict[str, str], dict]],
559
+ canvas_in: tuple[float, float],
560
+ min_fig_area: float,
561
+ min_total_area: float,
562
+ waive_total_area: bool,
563
+ ) -> None:
564
+ """Degraded area + resolution checks for the ``--no-render`` (or
565
+ no-playwright) path.
566
+
567
+ We have no real layout, so we ESTIMATE each figure's rendered box from
568
+ its ``natural_px`` aspect ratio scaled by a CSS width hint applied to
569
+ a coarse column-width assumption. These estimates are reported with
570
+ status ESTIMATED and DO NOT hard-fail the area thresholds -- a NOTICE
571
+ is emitted when an estimate is below threshold so the human knows to
572
+ re-run with rendering. The resolution check still runs (HARD/WARN),
573
+ but against the ESTIMATED rendered size, so it is reported ESTIMATED.
574
+ """
575
+ checks.add(
576
+ "render_mode", "warn", "NOTICE",
577
+ "no rendering available (--no-render or playwright missing); "
578
+ "area + resolution checks are ESTIMATED and not enforced as hard "
579
+ "gates. Re-run with rendering for the real geometry gate.",
580
+ )
581
+
582
+ # Coarse layout model: assume a typical 3-column body, so a figure at
583
+ # 100% width spans ~1/3 of poster WIDTH. width-hint scales that. This
584
+ # is intentionally rough -- it only flags figures that are obviously
585
+ # too small even under generous assumptions.
586
+ poster_w_px, poster_h_px = _canvas.viewport_for(canvas_in)
587
+ poster_area = float(poster_w_px * poster_h_px)
588
+ assumed_col_frac = 1.0 / 3.0 # column ~1/3 poster width
589
+
590
+ total_est_area = 0.0
591
+ any_below = False
592
+ for img, entry in validated:
593
+ asset_id = str(entry.get("asset_id"))
594
+ nat = entry.get("natural_px")
595
+ if not (isinstance(nat, (list, tuple)) and len(nat) == 2):
596
+ checks.add(
597
+ "fig_area", "warn", "ESTIMATED",
598
+ f"asset {ascii_safe(asset_id)}: natural_px missing/invalid; "
599
+ f"cannot estimate area.",
600
+ )
601
+ continue
602
+ nat_w, nat_h = float(nat[0]), float(nat[1])
603
+ aspect = (nat_h / nat_w) if nat_w > 0 else 1.0
604
+ wfrac = _width_fraction_hint(img)
605
+ if wfrac is None:
606
+ wfrac = 0.95 # template default for paper figures (.w-95)
607
+ # Estimated rendered width/height in px.
608
+ rend_w = poster_w_px * assumed_col_frac * wfrac
609
+ rend_h = rend_w * aspect
610
+ est_area = rend_w * rend_h
611
+ total_est_area += est_area
612
+ frac = (est_area / poster_area) if poster_area > 0 else 0.0
613
+ below = frac < min_fig_area
614
+ any_below = any_below or below
615
+ checks.add(
616
+ "fig_area", "warn", "ESTIMATED",
617
+ f"asset {ascii_safe(asset_id)}: ~{frac * 100:.2f}% of poster "
618
+ f"(threshold {min_fig_area * 100:.2f}%, "
619
+ f"{'BELOW' if below else 'ok'}; estimate from natural_px + "
620
+ f"width hint).",
621
+ )
622
+ _check_resolution(checks, entry, rend_w, rend_h, estimated=True)
623
+
624
+ total_frac = (total_est_area / poster_area) if poster_area > 0 else 0.0
625
+ if waive_total_area:
626
+ checks.add(
627
+ "total_fig_area", "warn", "NOTICE",
628
+ f"total paper-image area ~{total_frac * 100:.2f}% of poster "
629
+ f"(ESTIMATED); WAIVED via --waive-total-area.",
630
+ )
631
+ else:
632
+ below_total = total_frac < min_total_area
633
+ any_below = any_below or below_total
634
+ checks.add(
635
+ "total_fig_area", "warn", "ESTIMATED",
636
+ f"total paper-image area ~{total_frac * 100:.2f}% of poster "
637
+ f"(threshold {min_total_area * 100:.2f}% of body, "
638
+ f"{'BELOW' if below_total else 'ok'}; estimate -- not enforced "
639
+ f"without rendering).",
640
+ )
641
+
642
+ if any_below:
643
+ checks.add(
644
+ "area_estimate_notice", "warn", "NOTICE",
645
+ "one or more ESTIMATED areas are below threshold; this is NOT "
646
+ "a hard failure (no rendering). Re-run WITHOUT --no-render (and "
647
+ "with playwright installed) to enforce the real area gate.",
648
+ )
649
+
650
+
651
+ def _check_resolution(
652
+ checks: Checks,
653
+ entry: dict,
654
+ rendered_w: float,
655
+ rendered_h: float,
656
+ *,
657
+ estimated: bool,
658
+ ) -> None:
659
+ """natural_px vs rendered px: HARD below 1.5x, WARN in [1.5x, 2x).
660
+
661
+ We compare on the larger dimension's ratio (a figure can be scaled
662
+ differently per axis only if its aspect is distorted, which the
663
+ template AR rules already discourage; the min-axis ratio is the
664
+ binding constraint for sharpness). The status carries an ESTIMATED
665
+ suffix in the detail when ``estimated`` -- and crucially, in the
666
+ estimated path the rule is reported as a WARN-severity row so a
667
+ rough estimate can never HARD-fail the gate.
668
+ """
669
+ asset_id = str(entry.get("asset_id"))
670
+ nat = entry.get("natural_px")
671
+ if not (isinstance(nat, (list, tuple)) and len(nat) == 2):
672
+ checks.add(
673
+ "fig_resolution", "warn", "ESTIMATED" if estimated else "WARN",
674
+ f"asset {ascii_safe(asset_id)}: natural_px missing/invalid; "
675
+ f"cannot check resolution.",
676
+ )
677
+ return
678
+ nat_w, nat_h = float(nat[0]), float(nat[1])
679
+ # Per-axis ratio; the minimum is what governs perceived sharpness.
680
+ rx = (nat_w / rendered_w) if rendered_w > 0 else float("inf")
681
+ ry = (nat_h / rendered_h) if rendered_h > 0 else float("inf")
682
+ ratio = min(rx, ry)
683
+ src = "estimated rendered" if estimated else "rendered"
684
+
685
+ if ratio >= _RES_WARN_FACTOR:
686
+ status = "ESTIMATED" if estimated else "PASS"
687
+ checks.add(
688
+ "fig_resolution", "warn" if estimated else "hard", status,
689
+ f"asset {ascii_safe(asset_id)}: natural {nat_w:.0f}x{nat_h:.0f} "
690
+ f"= {ratio:.2f}x {src} ({rendered_w:.0f}x{rendered_h:.0f}); "
691
+ f">= {_RES_WARN_FACTOR}x target.",
692
+ )
693
+ elif ratio >= _RES_HARD_FACTOR:
694
+ # In [1.5x, 2x): WARN in both paths (target not met but readable).
695
+ checks.add(
696
+ "fig_resolution", "warn",
697
+ "ESTIMATED" if estimated else "WARN",
698
+ f"asset {ascii_safe(asset_id)}: natural {nat_w:.0f}x{nat_h:.0f} "
699
+ f"= {ratio:.2f}x {src} ({rendered_w:.0f}x{rendered_h:.0f}); "
700
+ f">= {_RES_HARD_FACTOR}x floor but below {_RES_WARN_FACTOR}x "
701
+ f"target -- consider a higher-DPI crop.",
702
+ )
703
+ else:
704
+ # Below 1.5x: HARD when rendered for real; WARN-severity (reported
705
+ # ESTIMATED) when only estimated, so the estimate never hard-fails.
706
+ if estimated:
707
+ checks.add(
708
+ "fig_resolution", "warn", "ESTIMATED",
709
+ f"asset {ascii_safe(asset_id)}: natural "
710
+ f"{nat_w:.0f}x{nat_h:.0f} = {ratio:.2f}x {src} "
711
+ f"({rendered_w:.0f}x{rendered_h:.0f}); below "
712
+ f"{_RES_HARD_FACTOR}x floor (ESTIMATED -- re-render to "
713
+ f"enforce).",
714
+ )
715
+ else:
716
+ checks.add(
717
+ "fig_resolution", "hard", "FAIL",
718
+ f"asset {ascii_safe(asset_id)}: natural "
719
+ f"{nat_w:.0f}x{nat_h:.0f} = {ratio:.2f}x {src} "
720
+ f"({rendered_w:.0f}x{rendered_h:.0f}); below "
721
+ f"{_RES_HARD_FACTOR}x floor -- prints blurry. Re-crop at "
722
+ f"higher DPI (target {_RES_WARN_FACTOR}x).",
723
+ )
724
+
725
+
726
+ # --------------------------------------------------------------------------
727
+ # CLI.
728
+ # --------------------------------------------------------------------------
729
+ def build_parser() -> argparse.ArgumentParser:
730
+ p = argparse.ArgumentParser(
731
+ prog="asset_check",
732
+ description="Real-figure provenance + area + resolution gate "
733
+ "for HTML academic posters (DESIGN_FINAL.md §4).",
734
+ )
735
+ p.add_argument("html", metavar="POSTER.html", help="path to poster.html")
736
+ p.add_argument(
737
+ "--manifest", required=True, metavar="FIGURE_MANIFEST.json",
738
+ help="path to FIGURE_MANIFEST.json (schema: DESIGN_FINAL §D)",
739
+ )
740
+ p.add_argument(
741
+ "--json", default=None, metavar="OUT.json",
742
+ help="write the {gate, status, checks} report to this JSON file",
743
+ )
744
+ p.add_argument(
745
+ "--min-paper-figs", type=int, default=2,
746
+ help="min number of img[data-source=paper] (default 2)",
747
+ )
748
+ p.add_argument(
749
+ "--min-fig-area", type=float, default=0.015,
750
+ help="min rendered area per figure, fraction of poster "
751
+ "(default 0.015 = 1.5%%)",
752
+ )
753
+ p.add_argument(
754
+ "--min-total-area", type=float, default=0.12,
755
+ help="min total paper-image area, fraction of body "
756
+ "(default 0.12 = 12%%)",
757
+ )
758
+ p.add_argument(
759
+ "--warn-fig-area", type=float, default=0.10,
760
+ help="WARN when a single figure exceeds this fraction of body "
761
+ "(default 0.10); figure-dominance early warning",
762
+ )
763
+ p.add_argument(
764
+ "--max-fig-area", type=float, default=0.13,
765
+ help="HARD max per-figure rendered area, fraction of body "
766
+ "(default 0.13). Raised to 0.42 by --hero.",
767
+ )
768
+ p.add_argument(
769
+ "--warn-total-area", type=float, default=0.24,
770
+ help="WARN when total paper-image area exceeds this fraction of "
771
+ "body (default 0.24); target band is 0.14-0.22",
772
+ )
773
+ p.add_argument(
774
+ "--max-total-area", type=float, default=0.28,
775
+ help="HARD max total paper-image area, fraction of body "
776
+ "(default 0.28). Figures should illustrate, not crowd out "
777
+ "the content (non-hero templates).",
778
+ )
779
+ p.add_argument(
780
+ "--hero", action="store_true",
781
+ help="hero-template mode: the hero figure may legitimately take "
782
+ "30-40%% of body, so per-figure maxes relax (warn 0.40, "
783
+ "hard 0.42) and the total hard max rises to 0.50",
784
+ )
785
+ p.add_argument(
786
+ "--waive-total-area", action="store_true",
787
+ help="waive ONLY the total-area (>=12%% of body) rule for "
788
+ "pure-theory posters (DESIGN_FINAL §12.5 nit 2)",
789
+ )
790
+ p.add_argument(
791
+ "--no-render", action="store_true",
792
+ help="skip Playwright; estimate areas from natural_px + CSS "
793
+ "width hints. Area checks become ESTIMATED and are not "
794
+ "enforced as hard gates (a NOTICE is printed instead).",
795
+ )
796
+ p.add_argument(
797
+ "--mathjax-timeout-ms", type=int, default=15000,
798
+ help="render path: bound on page load / MathJax settle "
799
+ "(default 15000); only used when actually rendering",
800
+ )
801
+ return p
802
+
803
+
804
+ def run(args: argparse.Namespace) -> int:
805
+ html_path = Path(args.html).resolve()
806
+ if not html_path.exists():
807
+ _eprint(f"ERROR: HTML not found: {ascii_safe(html_path)}")
808
+ return 2
809
+
810
+ manifest_path = Path(args.manifest).resolve()
811
+ try:
812
+ manifest = load_manifest(manifest_path)
813
+ except ValueError as e:
814
+ _eprint(f"ERROR: {ascii_safe(e)}")
815
+ return 2
816
+ # Manifest `file` paths are resolved relative to the manifest's dir
817
+ # (the poster output dir holds both the manifest and assets/).
818
+ manifest_dir = manifest_path.parent
819
+ fig_index = index_figures(manifest)
820
+
821
+ html_text = html_path.read_text(encoding="utf-8", errors="ignore")
822
+ all_imgs = collect_imgs(html_text)
823
+ p_imgs = paper_imgs(all_imgs)
824
+
825
+ checks = Checks()
826
+
827
+ # 1+2) Static provenance + count + manifest (always run).
828
+ validated = check_provenance(
829
+ checks, p_imgs, fig_index, manifest_dir, args.min_paper_figs,
830
+ )
831
+
832
+ # 3+4) Area + resolution. Real geometry if rendering; else estimate.
833
+ canvas_in = _canvas.read_canvas_from_html(html_path)
834
+ if canvas_in is None:
835
+ # Without @page we cannot derive poster area for the estimate, and
836
+ # render would also fail to size. Refuse silently-wrong areas.
837
+ checks.add(
838
+ "canvas", "hard", "FAIL",
839
+ "could not parse @page { size } from the poster HTML; cannot "
840
+ "determine poster area for figure-area checks. Add an @page "
841
+ "rule (DESIGN_FINAL §A unit contract).",
842
+ )
843
+ else:
844
+ boxes = None
845
+ if not args.no_render:
846
+ asset_ids = [str(e.get("asset_id")) for _i, e in validated]
847
+ viewport = _canvas.viewport_for(canvas_in)
848
+ boxes = measure_rendered(
849
+ html_path, viewport, asset_ids, args.mathjax_timeout_ms,
850
+ )
851
+ if boxes is not None:
852
+ # --hero: a hero-template centerpiece legitimately dominates.
853
+ warn_fig = 0.40 if args.hero else args.warn_fig_area
854
+ max_fig = 0.42 if args.hero else args.max_fig_area
855
+ max_total = 0.50 if args.hero else args.max_total_area
856
+ check_areas_rendered(
857
+ checks, validated, boxes,
858
+ args.min_fig_area, args.min_total_area,
859
+ args.waive_total_area,
860
+ warn_fig_area=warn_fig, max_fig_area=max_fig,
861
+ warn_total_area=args.warn_total_area,
862
+ max_total_area=max_total,
863
+ )
864
+ else:
865
+ # --no-render OR playwright unavailable: degrade to estimate.
866
+ check_areas_estimated(
867
+ checks, validated, canvas_in,
868
+ args.min_fig_area, args.min_total_area,
869
+ args.waive_total_area,
870
+ )
871
+
872
+ status = checks.overall()
873
+ report = {"gate": "asset", "status": status, "checks": checks.rows}
874
+
875
+ # Human-readable summary to stdout.
876
+ print(f"[asset_check] gate=asset status={status} "
877
+ f"({len(checks.rows)} checks)")
878
+ for r in checks.rows:
879
+ print(f" [{r['status']:9s}] {r['severity']:4s} {r['id']}: "
880
+ f"{r['detail']}")
881
+
882
+ if args.json:
883
+ out = Path(args.json)
884
+ out.write_text(json.dumps(report, indent=2) + "\n",
885
+ encoding="utf-8")
886
+ print(f"[asset_check] report -> {ascii_safe(out)}")
887
+
888
+ return 1 if status == "FAIL" else 0
889
+
890
+
891
+ def main(argv: list[str] | None = None) -> int:
892
+ args = build_parser().parse_args(argv)
893
+ return run(args)
894
+
895
+
896
+ if __name__ == "__main__":
897
+ sys.exit(main())