dsh-aris-panel 0.1.0

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 (442) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +98 -0
  3. package/README_CN.md +87 -0
  4. package/dsh/checkout.patch.yml +38 -0
  5. package/dsh/client.js +634 -0
  6. package/dsh/cordis.patch.yml +44 -0
  7. package/dsh/index.mjs +76 -0
  8. package/dsh/run-status.mjs +182 -0
  9. package/dsh/scope-limits.mjs +50 -0
  10. package/dsh/workbench.mjs +291 -0
  11. package/mcp-servers/claude-review/README.md +93 -0
  12. package/mcp-servers/claude-review/run_with_claude_aws.sh +49 -0
  13. package/mcp-servers/claude-review/server.py +718 -0
  14. package/mcp-servers/codex-image2/README.md +65 -0
  15. package/mcp-servers/codex-image2/server.py +893 -0
  16. package/mcp-servers/feishu-bridge/requirements.txt +1 -0
  17. package/mcp-servers/feishu-bridge/server.py +240 -0
  18. package/mcp-servers/gemini-review/README.md +171 -0
  19. package/mcp-servers/gemini-review/server.py +1856 -0
  20. package/mcp-servers/llm-chat/requirements.txt +1 -0
  21. package/mcp-servers/llm-chat/server.py +664 -0
  22. package/mcp-servers/manual-review/README.md +133 -0
  23. package/mcp-servers/manual-review/server.py +910 -0
  24. package/mcp-servers/manual-review/ui.html +279 -0
  25. package/mcp-servers/minimax-chat/requirements.txt +1 -0
  26. package/mcp-servers/minimax-chat/server.py +381 -0
  27. package/package.json +51 -0
  28. package/skills/ablation-planner/SKILL.md +123 -0
  29. package/skills/alphaxiv/SKILL.md +196 -0
  30. package/skills/analyze-results/SKILL.md +46 -0
  31. package/skills/arxiv/SKILL.md +248 -0
  32. package/skills/auto-paper-improvement-loop/SKILL.md +651 -0
  33. package/skills/auto-review-loop/SKILL.md +1137 -0
  34. package/skills/auto-review-loop-llm/SKILL.md +259 -0
  35. package/skills/auto-review-loop-minimax/SKILL.md +302 -0
  36. package/skills/citation-audit/SKILL.md +502 -0
  37. package/skills/claims-drafting/SKILL.md +227 -0
  38. package/skills/comm-lit-review/SKILL.md +297 -0
  39. package/skills/deepxiv/SKILL.md +263 -0
  40. package/skills/dse-loop/SKILL.md +296 -0
  41. package/skills/embodiment-description/SKILL.md +129 -0
  42. package/skills/exa-search/SKILL.md +205 -0
  43. package/skills/experiment-audit/SKILL.md +311 -0
  44. package/skills/experiment-bridge/SKILL.md +376 -0
  45. package/skills/experiment-plan/SKILL.md +249 -0
  46. package/skills/experiment-queue/SKILL.md +431 -0
  47. package/skills/experiment-queue/scripts/build_manifest.py +142 -0
  48. package/skills/experiment-queue/scripts/queue_manager.py +433 -0
  49. package/skills/feishu-notify/SKILL.md +156 -0
  50. package/skills/figure-description/SKILL.md +138 -0
  51. package/skills/figure-spec/SKILL.md +262 -0
  52. package/skills/figure-spec/scripts/figure_renderer.py +799 -0
  53. package/skills/formula-derivation/SKILL.md +280 -0
  54. package/skills/gemini-search/SKILL.md +231 -0
  55. package/skills/grant-proposal/SKILL.md +698 -0
  56. package/skills/idea-creator/SKILL.md +542 -0
  57. package/skills/idea-discovery/SKILL.md +521 -0
  58. package/skills/idea-discovery-robot/SKILL.md +363 -0
  59. package/skills/integrity-forensics/SKILL.md +284 -0
  60. package/skills/interview-cheatsheet/SKILL.md +245 -0
  61. package/skills/invention-structuring/SKILL.md +188 -0
  62. package/skills/jurisdiction-format/SKILL.md +192 -0
  63. package/skills/kill-argument/SKILL.md +437 -0
  64. package/skills/mermaid-diagram/SKILL.md +419 -0
  65. package/skills/meta-apply/SKILL.md +141 -0
  66. package/skills/meta-optimize/SKILL.md +437 -0
  67. package/skills/monitor-experiment/SKILL.md +140 -0
  68. package/skills/novelty-check/SKILL.md +101 -0
  69. package/skills/openalex/SKILL.md +237 -0
  70. package/skills/overleaf-sync/SKILL.md +220 -0
  71. package/skills/paper-claim-audit/SKILL.md +348 -0
  72. package/skills/paper-compile/SKILL.md +266 -0
  73. package/skills/paper-figure/SKILL.md +312 -0
  74. package/skills/paper-illustration/SKILL.md +736 -0
  75. package/skills/paper-illustration-image2/SKILL.md +391 -0
  76. package/skills/paper-illustration-image2/scripts/paper_illustration_image2.py +255 -0
  77. package/skills/paper-plan/SKILL.md +386 -0
  78. package/skills/paper-poster/SKILL.md +19 -0
  79. package/skills/paper-poster-html/DESIGN_FINAL.md +176 -0
  80. package/skills/paper-poster-html/IMPLEMENTATION_CONVENTIONS.md +161 -0
  81. package/skills/paper-poster-html/LICENSES/posterly-MIT.txt +21 -0
  82. package/skills/paper-poster-html/NOTICE.md +57 -0
  83. package/skills/paper-poster-html/SKILL.md +323 -0
  84. package/skills/paper-poster-html/scripts/_posterly/__init__.py +0 -0
  85. package/skills/paper-poster-html/scripts/_posterly/canvas.py +200 -0
  86. package/skills/paper-poster-html/scripts/_posterly/measure.py +588 -0
  87. package/skills/paper-poster-html/scripts/_posterly/polish.py +498 -0
  88. package/skills/paper-poster-html/scripts/_posterly/preflight.py +489 -0
  89. package/skills/paper-poster-html/scripts/_posterly/render.py +215 -0
  90. package/skills/paper-poster-html/scripts/_posterly/textutil.py +16 -0
  91. package/skills/paper-poster-html/scripts/_posterly/verify_final.py +171 -0
  92. package/skills/paper-poster-html/scripts/asset_check.py +897 -0
  93. package/skills/paper-poster-html/scripts/extract_pdf_figures.py +666 -0
  94. package/skills/paper-poster-html/scripts/poster_check.py +251 -0
  95. package/skills/paper-poster-html/scripts/preprocess_figures.py +238 -0
  96. package/skills/paper-poster-html/scripts/render_preview.py +217 -0
  97. package/skills/paper-poster-html/scripts/run_gates.py +556 -0
  98. package/skills/paper-poster-html/scripts/style_check.py +1324 -0
  99. package/skills/paper-poster-html/templates/COMPONENTS.md +462 -0
  100. package/skills/paper-poster-html/templates/README.md +170 -0
  101. package/skills/paper-poster-html/templates/landscape_4col.html +1032 -0
  102. package/skills/paper-poster-html/templates/landscape_hero.html +1046 -0
  103. package/skills/paper-poster-html/templates/portrait_2col.html +947 -0
  104. package/skills/paper-poster-html/templates/tokens/acl.json +9 -0
  105. package/skills/paper-poster-html/templates/tokens/cvpr.json +9 -0
  106. package/skills/paper-poster-html/templates/tokens/generic.json +9 -0
  107. package/skills/paper-poster-html/templates/tokens/iclr.json +9 -0
  108. package/skills/paper-poster-html/templates/tokens/icml.json +9 -0
  109. package/skills/paper-poster-html/templates/tokens/neurips.json +9 -0
  110. package/skills/paper-slides/SKILL.md +635 -0
  111. package/skills/paper-talk/SKILL.md +381 -0
  112. package/skills/paper-write/SKILL.md +604 -0
  113. package/skills/paper-write/templates/IEEEtran.bst +2409 -0
  114. package/skills/paper-write/templates/IEEEtran.cls +6347 -0
  115. package/skills/paper-write/templates/iclr2026.tex +84 -0
  116. package/skills/paper-write/templates/icml2025.tex +87 -0
  117. package/skills/paper-write/templates/ieee_conference.tex +89 -0
  118. package/skills/paper-write/templates/ieee_journal.tex +93 -0
  119. package/skills/paper-write/templates/math_commands.tex +48 -0
  120. package/skills/paper-write/templates/neurips2025.tex +80 -0
  121. package/skills/paper-writing/SKILL.md +916 -0
  122. package/skills/patent-novelty-check/SKILL.md +153 -0
  123. package/skills/patent-pipeline/SKILL.md +344 -0
  124. package/skills/patent-review/SKILL.md +203 -0
  125. package/skills/pixel-art/SKILL.md +137 -0
  126. package/skills/prior-art-search/SKILL.md +146 -0
  127. package/skills/proof-checker/SKILL.md +866 -0
  128. package/skills/proof-orchestrator/NOTICE.md +24 -0
  129. package/skills/proof-orchestrator/SKILL.md +254 -0
  130. package/skills/proof-orchestrator/references/audit-output-contract.md +126 -0
  131. package/skills/proof-orchestrator/references/deepseek-routing.md +74 -0
  132. package/skills/proof-orchestrator/references/dispatch-prompts.md +227 -0
  133. package/skills/proof-orchestrator/references/notation-audit.md +135 -0
  134. package/skills/proof-orchestrator/references/proof-audit-rubric.md +70 -0
  135. package/skills/proof-orchestrator/references/stress-tests.md +38 -0
  136. package/skills/proof-writer/SKILL.md +223 -0
  137. package/skills/qzcli/SKILL.md +324 -0
  138. package/skills/rebuttal/SKILL.md +376 -0
  139. package/skills/render-html/SKILL.md +316 -0
  140. package/skills/render-html/scripts/render_html.py +1006 -0
  141. package/skills/render-html/scripts/templates/academic.html +703 -0
  142. package/skills/render-html/scripts/templates/dashboard.html +333 -0
  143. package/skills/research-lit/SKILL.md +756 -0
  144. package/skills/research-pipeline/SKILL.md +384 -0
  145. package/skills/research-refine/SKILL.md +770 -0
  146. package/skills/research-refine-pipeline/SKILL.md +186 -0
  147. package/skills/research-review/SKILL.md +198 -0
  148. package/skills/research-wiki/SKILL.md +461 -0
  149. package/skills/resubmit-pipeline/SKILL.md +447 -0
  150. package/skills/result-to-claim/SKILL.md +311 -0
  151. package/skills/run-experiment/SKILL.md +313 -0
  152. package/skills/semantic-scholar/SKILL.md +236 -0
  153. package/skills/serverless-modal/SKILL.md +335 -0
  154. package/skills/shared-references/acceptance-gate.md +324 -0
  155. package/skills/shared-references/assurance-contract.md +248 -0
  156. package/skills/shared-references/capture-antipatterns.md +78 -0
  157. package/skills/shared-references/citation-discipline.md +583 -0
  158. package/skills/shared-references/compute-env-contract.md +163 -0
  159. package/skills/shared-references/effort-contract.md +183 -0
  160. package/skills/shared-references/evidence-precheck.md +65 -0
  161. package/skills/shared-references/experiment-integrity.md +49 -0
  162. package/skills/shared-references/external-cadence.md +326 -0
  163. package/skills/shared-references/fan-out-pattern.md +366 -0
  164. package/skills/shared-references/injection-hygiene.md +127 -0
  165. package/skills/shared-references/integration-contract.md +461 -0
  166. package/skills/shared-references/output-composition.md +93 -0
  167. package/skills/shared-references/output-language.md +45 -0
  168. package/skills/shared-references/output-manifest.md +49 -0
  169. package/skills/shared-references/output-versioning.md +111 -0
  170. package/skills/shared-references/patent-format-cn.md +199 -0
  171. package/skills/shared-references/patent-format-ep.md +173 -0
  172. package/skills/shared-references/patent-format-us.md +161 -0
  173. package/skills/shared-references/patent-writing-principles.md +197 -0
  174. package/skills/shared-references/prior-art-databases.md +141 -0
  175. package/skills/shared-references/resumable-runs.md +109 -0
  176. package/skills/shared-references/review-scope-limits.md +81 -0
  177. package/skills/shared-references/review-tracing.md +391 -0
  178. package/skills/shared-references/reviewer-independence.md +79 -0
  179. package/skills/shared-references/reviewer-routing.md +852 -0
  180. package/skills/shared-references/skill-governance.md +104 -0
  181. package/skills/shared-references/taste-calibration.md +85 -0
  182. package/skills/shared-references/venue-checklists.md +114 -0
  183. package/skills/shared-references/wiki-helper-resolution.md +134 -0
  184. package/skills/shared-references/writing-principles.md +525 -0
  185. package/skills/skills-codex/README.md +102 -0
  186. package/skills/skills-codex/README_CN.md +100 -0
  187. package/skills/skills-codex/ablation-planner/SKILL.md +126 -0
  188. package/skills/skills-codex/alphaxiv/SKILL.md +186 -0
  189. package/skills/skills-codex/analyze-results/SKILL.md +45 -0
  190. package/skills/skills-codex/arxiv/SKILL.md +210 -0
  191. package/skills/skills-codex/auto-paper-improvement-loop/SKILL.md +574 -0
  192. package/skills/skills-codex/auto-review-loop/SKILL.md +500 -0
  193. package/skills/skills-codex/auto-review-loop-llm/SKILL.md +247 -0
  194. package/skills/skills-codex/auto-review-loop-minimax/SKILL.md +290 -0
  195. package/skills/skills-codex/citation-audit/SKILL.md +504 -0
  196. package/skills/skills-codex/claims-drafting/SKILL.md +239 -0
  197. package/skills/skills-codex/comm-lit-review/SKILL.md +299 -0
  198. package/skills/skills-codex/comm-lit-review/references/domain-taxonomy.md +57 -0
  199. package/skills/skills-codex/comm-lit-review/references/output-template.md +37 -0
  200. package/skills/skills-codex/comm-lit-review/references/source-policy.md +99 -0
  201. package/skills/skills-codex/comm-lit-review/references/venue-tiering.md +112 -0
  202. package/skills/skills-codex/deepxiv/SKILL.md +142 -0
  203. package/skills/skills-codex/dse-loop/SKILL.md +285 -0
  204. package/skills/skills-codex/embodiment-description/SKILL.md +129 -0
  205. package/skills/skills-codex/exa-search/SKILL.md +192 -0
  206. package/skills/skills-codex/experiment-audit/SKILL.md +286 -0
  207. package/skills/skills-codex/experiment-bridge/SKILL.md +356 -0
  208. package/skills/skills-codex/experiment-plan/SKILL.md +249 -0
  209. package/skills/skills-codex/experiment-queue/SKILL.md +401 -0
  210. package/skills/skills-codex/feishu-notify/SKILL.md +155 -0
  211. package/skills/skills-codex/figure-description/SKILL.md +138 -0
  212. package/skills/skills-codex/figure-spec/SKILL.md +252 -0
  213. package/skills/skills-codex/formula-derivation/SKILL.md +280 -0
  214. package/skills/skills-codex/gemini-search/SKILL.md +205 -0
  215. package/skills/skills-codex/grant-proposal/SKILL.md +626 -0
  216. package/skills/skills-codex/idea-creator/SKILL.md +405 -0
  217. package/skills/skills-codex/idea-discovery/SKILL.md +475 -0
  218. package/skills/skills-codex/idea-discovery-robot/SKILL.md +362 -0
  219. package/skills/skills-codex/integrity-forensics/SKILL.md +106 -0
  220. package/skills/skills-codex/interview-cheatsheet/SKILL.md +245 -0
  221. package/skills/skills-codex/invention-structuring/SKILL.md +188 -0
  222. package/skills/skills-codex/jurisdiction-format/SKILL.md +192 -0
  223. package/skills/skills-codex/kill-argument/SKILL.md +403 -0
  224. package/skills/skills-codex/mermaid-diagram/SKILL.md +379 -0
  225. package/skills/skills-codex/meta-apply/SKILL.md +154 -0
  226. package/skills/skills-codex/meta-optimize/SKILL.md +348 -0
  227. package/skills/skills-codex/monitor-experiment/SKILL.md +98 -0
  228. package/skills/skills-codex/novelty-check/SKILL.md +89 -0
  229. package/skills/skills-codex/openalex/SKILL.md +228 -0
  230. package/skills/skills-codex/overleaf-sync/SKILL.md +220 -0
  231. package/skills/skills-codex/paper-claim-audit/SKILL.md +350 -0
  232. package/skills/skills-codex/paper-compile/SKILL.md +253 -0
  233. package/skills/skills-codex/paper-figure/SKILL.md +311 -0
  234. package/skills/skills-codex/paper-illustration/SKILL.md +690 -0
  235. package/skills/skills-codex/paper-illustration-image2/SKILL.md +383 -0
  236. package/skills/skills-codex/paper-illustration-image2/scripts/paper_illustration_image2.py +255 -0
  237. package/skills/skills-codex/paper-plan/SKILL.md +278 -0
  238. package/skills/skills-codex/paper-poster/SKILL.md +19 -0
  239. package/skills/skills-codex/paper-poster-html/SKILL.md +377 -0
  240. package/skills/skills-codex/paper-slides/SKILL.md +571 -0
  241. package/skills/skills-codex/paper-talk/SKILL.md +381 -0
  242. package/skills/skills-codex/paper-write/SKILL.md +411 -0
  243. package/skills/skills-codex/paper-write/templates/IEEEtran.bst +2409 -0
  244. package/skills/skills-codex/paper-write/templates/IEEEtran.cls +6347 -0
  245. package/skills/skills-codex/paper-write/templates/aaai2026.bst +1493 -0
  246. package/skills/skills-codex/paper-write/templates/aaai2026.sty +315 -0
  247. package/skills/skills-codex/paper-write/templates/aaai2026.tex +952 -0
  248. package/skills/skills-codex/paper-write/templates/acl.sty +312 -0
  249. package/skills/skills-codex/paper-write/templates/acl2026.tex +377 -0
  250. package/skills/skills-codex/paper-write/templates/acl_natbib.bst +1940 -0
  251. package/skills/skills-codex/paper-write/templates/acm.bst +3081 -0
  252. package/skills/skills-codex/paper-write/templates/acm_mm2026.tex +204 -0
  253. package/skills/skills-codex/paper-write/templates/acmart.cls +3520 -0
  254. package/skills/skills-codex/paper-write/templates/cvpr.bst +1448 -0
  255. package/skills/skills-codex/paper-write/templates/cvpr.sty +508 -0
  256. package/skills/skills-codex/paper-write/templates/cvpr2026.tex +63 -0
  257. package/skills/skills-codex/paper-write/templates/iclr2026.tex +84 -0
  258. package/skills/skills-codex/paper-write/templates/iclr2026_conference.bst +1440 -0
  259. package/skills/skills-codex/paper-write/templates/iclr2026_conference.sty +246 -0
  260. package/skills/skills-codex/paper-write/templates/icml2026.sty +767 -0
  261. package/skills/skills-codex/paper-write/templates/icml2026.tex +662 -0
  262. package/skills/skills-codex/paper-write/templates/ieee_conference.tex +89 -0
  263. package/skills/skills-codex/paper-write/templates/ieee_journal.tex +93 -0
  264. package/skills/skills-codex/paper-write/templates/math_commands.tex +48 -0
  265. package/skills/skills-codex/paper-write/templates/neurips2026.tex +493 -0
  266. package/skills/skills-codex/paper-write/templates/neurips_2026.sty +437 -0
  267. package/skills/skills-codex/paper-writing/SKILL.md +731 -0
  268. package/skills/skills-codex/patent-novelty-check/SKILL.md +153 -0
  269. package/skills/skills-codex/patent-pipeline/SKILL.md +344 -0
  270. package/skills/skills-codex/patent-review/SKILL.md +202 -0
  271. package/skills/skills-codex/pixel-art/SKILL.md +139 -0
  272. package/skills/skills-codex/prior-art-search/SKILL.md +146 -0
  273. package/skills/skills-codex/proof-checker/SKILL.md +554 -0
  274. package/skills/skills-codex/proof-orchestrator/SKILL.md +260 -0
  275. package/skills/skills-codex/proof-orchestrator/references/audit-output-contract.md +126 -0
  276. package/skills/skills-codex/proof-orchestrator/references/deepseek-routing.md +76 -0
  277. package/skills/skills-codex/proof-orchestrator/references/dispatch-prompts.md +227 -0
  278. package/skills/skills-codex/proof-orchestrator/references/notation-audit.md +135 -0
  279. package/skills/skills-codex/proof-orchestrator/references/proof-audit-rubric.md +70 -0
  280. package/skills/skills-codex/proof-orchestrator/references/stress-tests.md +38 -0
  281. package/skills/skills-codex/proof-writer/SKILL.md +222 -0
  282. package/skills/skills-codex/qzcli/SKILL.md +324 -0
  283. package/skills/skills-codex/rebuttal/SKILL.md +305 -0
  284. package/skills/skills-codex/render-html/SKILL.md +305 -0
  285. package/skills/skills-codex/render-html/scripts/__pycache__/render_html.cpython-314.pyc +0 -0
  286. package/skills/skills-codex/render-html/scripts/render_html.py +909 -0
  287. package/skills/skills-codex/render-html/scripts/templates/academic.html +342 -0
  288. package/skills/skills-codex/render-html/scripts/templates/dashboard.html +333 -0
  289. package/skills/skills-codex/research-lit/SKILL.md +464 -0
  290. package/skills/skills-codex/research-pipeline/SKILL.md +340 -0
  291. package/skills/skills-codex/research-refine/SKILL.md +721 -0
  292. package/skills/skills-codex/research-refine-pipeline/SKILL.md +186 -0
  293. package/skills/skills-codex/research-review/SKILL.md +135 -0
  294. package/skills/skills-codex/research-wiki/SKILL.md +421 -0
  295. package/skills/skills-codex/resubmit-pipeline/SKILL.md +444 -0
  296. package/skills/skills-codex/result-to-claim/SKILL.md +246 -0
  297. package/skills/skills-codex/run-experiment/SKILL.md +236 -0
  298. package/skills/skills-codex/semantic-scholar/SKILL.md +219 -0
  299. package/skills/skills-codex/serverless-modal/SKILL.md +335 -0
  300. package/skills/skills-codex/shared-references/acceptance-gate.md +336 -0
  301. package/skills/skills-codex/shared-references/assurance-contract.md +139 -0
  302. package/skills/skills-codex/shared-references/capture-antipatterns.md +84 -0
  303. package/skills/skills-codex/shared-references/citation-discipline.md +452 -0
  304. package/skills/skills-codex/shared-references/compute-env-contract.md +163 -0
  305. package/skills/skills-codex/shared-references/effort-contract.md +143 -0
  306. package/skills/skills-codex/shared-references/evidence-precheck.md +73 -0
  307. package/skills/skills-codex/shared-references/experiment-integrity.md +49 -0
  308. package/skills/skills-codex/shared-references/external-cadence.md +334 -0
  309. package/skills/skills-codex/shared-references/fan-out-pattern.md +375 -0
  310. package/skills/skills-codex/shared-references/injection-hygiene.md +132 -0
  311. package/skills/skills-codex/shared-references/integration-contract.md +372 -0
  312. package/skills/skills-codex/shared-references/output-composition.md +98 -0
  313. package/skills/skills-codex/shared-references/output-language.md +45 -0
  314. package/skills/skills-codex/shared-references/output-manifest.md +40 -0
  315. package/skills/skills-codex/shared-references/output-versioning.md +111 -0
  316. package/skills/skills-codex/shared-references/patent-format-cn.md +199 -0
  317. package/skills/skills-codex/shared-references/patent-format-ep.md +173 -0
  318. package/skills/skills-codex/shared-references/patent-format-us.md +161 -0
  319. package/skills/skills-codex/shared-references/patent-writing-principles.md +197 -0
  320. package/skills/skills-codex/shared-references/prior-art-databases.md +141 -0
  321. package/skills/skills-codex/shared-references/resumable-runs.md +125 -0
  322. package/skills/skills-codex/shared-references/review-scope-limits.md +81 -0
  323. package/skills/skills-codex/shared-references/review-tracing.md +144 -0
  324. package/skills/skills-codex/shared-references/reviewer-independence.md +66 -0
  325. package/skills/skills-codex/shared-references/reviewer-routing.md +128 -0
  326. package/skills/skills-codex/shared-references/skill-governance.md +119 -0
  327. package/skills/skills-codex/shared-references/taste-calibration.md +90 -0
  328. package/skills/skills-codex/shared-references/venue-checklists.md +73 -0
  329. package/skills/skills-codex/shared-references/wiki-helper-resolution.md +69 -0
  330. package/skills/skills-codex/shared-references/writing-principles.md +525 -0
  331. package/skills/skills-codex/slides-polish/SKILL.md +563 -0
  332. package/skills/skills-codex/specification-writing/SKILL.md +211 -0
  333. package/skills/skills-codex/system-profile/SKILL.md +103 -0
  334. package/skills/skills-codex/training-check/SKILL.md +83 -0
  335. package/skills/skills-codex/vast-gpu/SKILL.md +394 -0
  336. package/skills/skills-codex/web-debug-search/SKILL.md +334 -0
  337. package/skills/skills-codex/wiki-enrich/SKILL.md +255 -0
  338. package/skills/skills-codex/writing-systems-papers/SKILL.md +184 -0
  339. package/skills/skills-codex-claude-review/README.md +79 -0
  340. package/skills/skills-codex-claude-review/README_CN.md +78 -0
  341. package/skills/skills-codex-claude-review/auto-paper-improvement-loop/SKILL.md +581 -0
  342. package/skills/skills-codex-claude-review/auto-review-loop/SKILL.md +510 -0
  343. package/skills/skills-codex-claude-review/novelty-check/SKILL.md +102 -0
  344. package/skills/skills-codex-claude-review/paper-figure/SKILL.md +319 -0
  345. package/skills/skills-codex-claude-review/paper-plan/SKILL.md +287 -0
  346. package/skills/skills-codex-claude-review/paper-write/SKILL.md +420 -0
  347. package/skills/skills-codex-claude-review/research-refine/SKILL.md +732 -0
  348. package/skills/skills-codex-claude-review/research-review/SKILL.md +149 -0
  349. package/skills/skills-codex-gemini-review/README.md +176 -0
  350. package/skills/skills-codex-gemini-review/README_CN.md +175 -0
  351. package/skills/skills-codex-gemini-review/auto-paper-improvement-loop/SKILL.md +331 -0
  352. package/skills/skills-codex-gemini-review/auto-review-loop/SKILL.md +304 -0
  353. package/skills/skills-codex-gemini-review/grant-proposal/SKILL.md +630 -0
  354. package/skills/skills-codex-gemini-review/idea-creator/SKILL.md +263 -0
  355. package/skills/skills-codex-gemini-review/idea-discovery/SKILL.md +275 -0
  356. package/skills/skills-codex-gemini-review/idea-discovery-robot/SKILL.md +365 -0
  357. package/skills/skills-codex-gemini-review/novelty-check/SKILL.md +92 -0
  358. package/skills/skills-codex-gemini-review/paper-figure/SKILL.md +289 -0
  359. package/skills/skills-codex-gemini-review/paper-plan/SKILL.md +265 -0
  360. package/skills/skills-codex-gemini-review/paper-poster-html/SKILL.md +102 -0
  361. package/skills/skills-codex-gemini-review/paper-slides/SKILL.md +582 -0
  362. package/skills/skills-codex-gemini-review/paper-write/SKILL.md +346 -0
  363. package/skills/skills-codex-gemini-review/paper-writing/SKILL.md +312 -0
  364. package/skills/skills-codex-gemini-review/research-refine/SKILL.md +674 -0
  365. package/skills/skills-codex-gemini-review/research-review/SKILL.md +112 -0
  366. package/skills/slides-polish/SKILL.md +565 -0
  367. package/skills/specification-writing/SKILL.md +211 -0
  368. package/skills/system-profile/SKILL.md +103 -0
  369. package/skills/training-check/SKILL.md +132 -0
  370. package/skills/vast-gpu/SKILL.md +394 -0
  371. package/skills/web-debug-search/SKILL.md +334 -0
  372. package/skills/wiki-enrich/SKILL.md +257 -0
  373. package/skills/writing-systems-papers/SKILL.md +184 -0
  374. package/templates/CLAUDE_MD_TEMPLATE.md +29 -0
  375. package/templates/EXPERIMENT_LOG_TEMPLATE.md +47 -0
  376. package/templates/EXPERIMENT_PLAN_TEMPLATE.md +51 -0
  377. package/templates/EXPERIMENT_PLAN_TEMPLATE_CN.md +53 -0
  378. package/templates/FINDINGS_TEMPLATE.md +52 -0
  379. package/templates/IDEA_CANDIDATES_TEMPLATE.md +47 -0
  380. package/templates/IDEA_CANDIDATES_TEMPLATE_CN.md +47 -0
  381. package/templates/INVENTION_BRIEF_TEMPLATE.md +87 -0
  382. package/templates/MANIFEST_TEMPLATE.md +7 -0
  383. package/templates/NARRATIVE_REPORT_TEMPLATE.md +49 -0
  384. package/templates/PAPER_PLAN_TEMPLATE.md +47 -0
  385. package/templates/PATENT_CLAIMS_TEMPLATE.md +78 -0
  386. package/templates/PATENT_SPECIFICATION_TEMPLATE.md +68 -0
  387. package/templates/README.md +57 -0
  388. package/templates/RESEARCH_BRIEF_TEMPLATE.md +35 -0
  389. package/templates/RESEARCH_BRIEF_TEMPLATE_CN.md +41 -0
  390. package/templates/RESEARCH_CONTRACT_TEMPLATE.md +60 -0
  391. package/templates/claude-hooks/corpus_write_guard.json +16 -0
  392. package/templates/claude-hooks/corpus_write_guard.py +85 -0
  393. package/templates/claude-hooks/meta_logging.json +74 -0
  394. package/templates/gitignore-trace.txt +3 -0
  395. package/tools/__pycache__/check_skills_inventory.cpython-314.pyc +0 -0
  396. package/tools/arxiv_fetch.py +311 -0
  397. package/tools/capture_filter.py +126 -0
  398. package/tools/check_skills_inventory.py +273 -0
  399. package/tools/convert_skills_to_llm_chat.py +282 -0
  400. package/tools/copilot_native_evidence.py +818 -0
  401. package/tools/deepxiv_fetch.py +213 -0
  402. package/tools/evidence_check.py +212 -0
  403. package/tools/exa_search.py +425 -0
  404. package/tools/experiment_queue/README.md +118 -0
  405. package/tools/experiment_queue/build_manifest.py +44 -0
  406. package/tools/experiment_queue/queue_manager.py +44 -0
  407. package/tools/extract_paper_style.py +560 -0
  408. package/tools/figure_renderer.py +69 -0
  409. package/tools/forensics_gate.py +669 -0
  410. package/tools/generate_codex_claude_review_overrides.py +299 -0
  411. package/tools/idea_discovery_gate.py +256 -0
  412. package/tools/install_aris.ps1 +1372 -0
  413. package/tools/install_aris.sh +1370 -0
  414. package/tools/install_aris_codex.sh +1023 -0
  415. package/tools/install_aris_copilot.sh +1052 -0
  416. package/tools/iteration_log.py +143 -0
  417. package/tools/lint_skills_helpers.sh +84 -0
  418. package/tools/meta_opt/check_ready.sh +80 -0
  419. package/tools/meta_opt/log_event.sh +91 -0
  420. package/tools/meta_opt/trigger_eval.py +280 -0
  421. package/tools/meta_opt/trigger_evals.sample.json +28 -0
  422. package/tools/openalex_fetch.py +326 -0
  423. package/tools/overleaf_audit.sh +104 -0
  424. package/tools/overleaf_setup.sh +150 -0
  425. package/tools/paper_illustration_image2.py +62 -0
  426. package/tools/provenance.py +294 -0
  427. package/tools/research_wiki.py +1720 -0
  428. package/tools/review_gate.py +502 -0
  429. package/tools/run_state.py +399 -0
  430. package/tools/save_trace.sh +477 -0
  431. package/tools/semantic_scholar_fetch.py +438 -0
  432. package/tools/skill-groups.tsv +116 -0
  433. package/tools/skill_picker.py +238 -0
  434. package/tools/smart_update.ps1 +521 -0
  435. package/tools/smart_update.sh +591 -0
  436. package/tools/smart_update_codex.sh +419 -0
  437. package/tools/smart_update_copilot.sh +605 -0
  438. package/tools/threat_scan.py +222 -0
  439. package/tools/verify_paper_audits.sh +487 -0
  440. package/tools/verify_papers.py +613 -0
  441. package/tools/verify_wiki_coverage.sh +176 -0
  442. package/tools/watchdog.py +485 -0
@@ -0,0 +1,560 @@
1
+ #!/usr/bin/env python3
2
+ """
3
+ extract_paper_style.py — extract a *skeleton-only* style profile from a
4
+ reference paper, for opt-in use by writer skills via the `--style-ref` flag.
5
+
6
+ ================================================================
7
+ CONTRACT (read this before consuming the output in a writer skill)
8
+ ================================================================
9
+
10
+ Purpose
11
+ -------
12
+ Some users want a generated paper / poster / slide / grant draft to *match
13
+ the structural style* of a reference paper they admire (section ordering,
14
+ section name conventions, sentence-length cadence, theorem density, figure
15
+ density, bibliography style, etc.) — *without* copying the reference's prose
16
+ or claims. This helper resolves the reference, derives a compact, neutral
17
+ "style profile", and writes it to a deterministic cache path.
18
+
19
+ Writer skills that accept `--style-ref <source>`:
20
+ - paper-write, paper-plan, paper-writing
21
+ - paper-illustration, paper-slides
22
+ - grant-proposal, auto-paper-improvement-loop
23
+
24
+ Strict rules for the calling skill
25
+ ----------------------------------
26
+ 1. **Opt-in only.** When the user does NOT pass `--style-ref`, behavior is
27
+ unchanged. Do not auto-discover reference papers from the working tree.
28
+
29
+ 2. **Run this script first**, before drafting:
30
+ python3 tools/extract_paper_style.py --source <SRC> [--out <DIR>]
31
+ On exit code 0, read the printed cache directory and consume:
32
+ <cache>/source_manifest.json (provenance)
33
+ <cache>/style_profile.md (the style guidance)
34
+ On exit code 2 (missing optional dep), print a one-line warning and
35
+ continue without style guidance.
36
+ On exit code 3 (source failure), print the error and FAIL the writer
37
+ step — do NOT silently fall back, the user explicitly asked for a ref.
38
+
39
+ 3. **Use the profile as STRUCTURAL guidance only.** Do not copy sentences,
40
+ phrases, claim bullets, or any concrete content from anything reachable
41
+ through the cache. The profile is intentionally aggregate / statistical;
42
+ if you find yourself reaching for copied prose, stop.
43
+
44
+ 4. **Never pass `--style-ref` to reviewer / auditor sub-agents.**
45
+ Cross-model review independence (`shared-references/reviewer-independence.md`)
46
+ requires reviewers see only the artifact and the user's prompt, not the
47
+ author's stylistic context. Style ref is a *writer-side* affordance.
48
+
49
+ 5. **Cache is deterministic.** Same source → same cache dir. The calling
50
+ skill should pass the resolved cache path explicitly when invoking
51
+ sub-tools that need it; it should NOT mutate the cache.
52
+
53
+ Source types accepted
54
+ ---------------------
55
+ - Local directory: /path/to/paper/ (scans *.tex)
56
+ - Local TeX file: /path/to/paper.tex
57
+ - Local PDF file: /path/to/paper.pdf (uses pdftotext if installed)
58
+ - arXiv ID: arxiv:2501.12345 (fetches abstract HTML)
59
+ (also: 2501.12345 alone is auto-detected)
60
+ - HTTP/HTTPS URL: https://... (PDF or HTML)
61
+ - Overleaf URL/ID: https://www.overleaf.com/project/<id>
62
+ ↑ rejected with guidance: clone via overleaf-sync
63
+ first, then pass the local clone path.
64
+
65
+ Output schema
66
+ -------------
67
+ <cache>/source_manifest.json:
68
+ {
69
+ "source_input": "<original argument>",
70
+ "source_type": "local_dir|local_tex|local_pdf|arxiv|http",
71
+ "resolved_path": "<absolute path or URL>",
72
+ "fetched_at": "<ISO 8601 UTC>",
73
+ "content_sha256": "<hex>",
74
+ "tool_version": "1"
75
+ }
76
+
77
+ <cache>/style_profile.md:
78
+ Compact markdown (≤ ~200 lines). Sections:
79
+ - Section structure (ordered list of sec names)
80
+ - Length distribution (per-section approx word counts)
81
+ - Theorem-environment density
82
+ - Figure / table density
83
+ - Citation density and style (numeric vs author-year, if detectable)
84
+ - Sentence cadence (mean/median/p90 word count)
85
+ - Math display ratio (inline vs display)
86
+ - Captioning conventions (caption length stats)
87
+ - Notable structural patterns (e.g., "Contributions" bullet block,
88
+ "Setup → Result → Interpretation" theorem rhythm)
89
+ Explicitly NOT included: any copied sentences, claim text, author names,
90
+ affiliations, acknowledgements, or specific numerical results.
91
+
92
+ Cache layout
93
+ ------------
94
+ Default cache root: $ARIS_STYLE_REF_CACHE (env) or `~/.cache/aris-style-refs/`
95
+ (XDG-friendly; avoids polluting the user's project repo
96
+ when the user runs the writer skill from inside their
97
+ paper directory)
98
+ Per-source dir: <root>/<sha256(source_input)[:16]>/
99
+ source_manifest.json
100
+ style_profile.md
101
+
102
+ Exit codes
103
+ ----------
104
+ 0 — success (cache written; cache path printed to stdout, last line)
105
+ 2 — missing optional Python dep; nothing written (caller may continue)
106
+ 3 — source resolution / network / parse failure (caller should fail)
107
+ 1 — generic runtime error
108
+ """
109
+
110
+ from __future__ import annotations
111
+
112
+ import argparse
113
+ import datetime as _dt
114
+ import hashlib
115
+ import io
116
+ import json
117
+ import os
118
+ import re
119
+ import shutil
120
+ import statistics
121
+ import subprocess
122
+ import sys
123
+ from pathlib import Path
124
+ from typing import Any
125
+
126
+ TOOL_VERSION = "1"
127
+ ARXIV_ID_RE = re.compile(r"^\d{4}\.\d{4,5}(v\d+)?$")
128
+ # Match any URL whose host is overleaf.com (or *.overleaf.com) AND whose path
129
+ # contains "/project/...". Rejects regardless of trailing slash, query string,
130
+ # fragment, or extra path segments like "/file/main.tex".
131
+ OVERLEAF_URL_RE = re.compile(
132
+ r"^https?://([A-Za-z0-9-]+\.)*overleaf\.com(:\d+)?/project(/|$)",
133
+ re.IGNORECASE,
134
+ )
135
+ # Bare hex blob that looks like an Overleaf project id (24+ hex chars, no path).
136
+ OVERLEAF_BARE_ID_RE = re.compile(r"^[A-Fa-f0-9]{24,}$")
137
+
138
+
139
+ # ---------------------------------------------------------------------------
140
+ # Source resolution
141
+ # ---------------------------------------------------------------------------
142
+
143
+ def _classify_source(src: str) -> str:
144
+ if OVERLEAF_URL_RE.match(src) or OVERLEAF_BARE_ID_RE.match(src):
145
+ return "overleaf"
146
+ if src.startswith("arxiv:"):
147
+ return "arxiv"
148
+ if ARXIV_ID_RE.match(src):
149
+ return "arxiv"
150
+ if src.startswith("http://") or src.startswith("https://"):
151
+ return "http"
152
+ p = Path(src).expanduser()
153
+ if p.is_dir():
154
+ return "local_dir"
155
+ if p.is_file():
156
+ if p.suffix.lower() == ".pdf":
157
+ return "local_pdf"
158
+ return "local_tex"
159
+ return "unknown"
160
+
161
+
162
+ def _read_local_dir(p: Path) -> str:
163
+ parts: list[str] = []
164
+ tex_files = sorted(p.rglob("*.tex"))
165
+ if not tex_files:
166
+ raise SourceError(f"No .tex files under {p}")
167
+ for f in tex_files:
168
+ try:
169
+ parts.append(f.read_text(encoding="utf-8", errors="replace"))
170
+ except Exception:
171
+ continue
172
+ return "\n\n% --- file boundary ---\n\n".join(parts)
173
+
174
+
175
+ def _read_local_tex(p: Path) -> str:
176
+ return p.read_text(encoding="utf-8", errors="replace")
177
+
178
+
179
+ def _read_local_pdf(p: Path) -> str:
180
+ if not shutil.which("pdftotext"):
181
+ raise MissingDep("pdftotext (poppler) is required to read PDFs")
182
+ out = subprocess.run(
183
+ ["pdftotext", "-layout", str(p), "-"],
184
+ capture_output=True,
185
+ timeout=120,
186
+ )
187
+ if out.returncode != 0:
188
+ raise SourceError(f"pdftotext failed: {out.stderr.decode(errors='replace')[:200]}")
189
+ return out.stdout.decode("utf-8", errors="replace")
190
+
191
+
192
+ def _read_arxiv(arxiv_id: str) -> str:
193
+ try:
194
+ import requests
195
+ except ImportError:
196
+ raise MissingDep("requests (pip install requests) needed for arXiv fetch")
197
+ arxiv_id = arxiv_id.removeprefix("arxiv:")
198
+ url = f"https://export.arxiv.org/abs/{arxiv_id}"
199
+ try:
200
+ r = requests.get(url, timeout=20, headers={"User-Agent": "aris-extract-paper-style/1"})
201
+ except Exception as e:
202
+ raise SourceError(f"arXiv fetch failed: {e}")
203
+ if r.status_code != 200:
204
+ raise SourceError(f"arXiv fetch returned HTTP {r.status_code}")
205
+ return r.text
206
+
207
+
208
+ def _read_http(url: str) -> str:
209
+ try:
210
+ import requests
211
+ except ImportError:
212
+ raise MissingDep("requests (pip install requests) needed for HTTP fetch")
213
+ try:
214
+ r = requests.get(url, timeout=30, headers={"User-Agent": "aris-extract-paper-style/1"})
215
+ except Exception as e:
216
+ raise SourceError(f"HTTP fetch failed: {e}")
217
+ if r.status_code != 200:
218
+ raise SourceError(f"HTTP fetch returned HTTP {r.status_code}")
219
+ ctype = r.headers.get("content-type", "").lower()
220
+ if "pdf" in ctype or url.lower().endswith(".pdf"):
221
+ if not shutil.which("pdftotext"):
222
+ raise MissingDep("pdftotext (poppler) needed to parse downloaded PDF")
223
+ with subprocess.Popen(
224
+ ["pdftotext", "-layout", "-", "-"],
225
+ stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.PIPE,
226
+ ) as proc:
227
+ stdout, _ = proc.communicate(input=r.content, timeout=120)
228
+ if proc.returncode != 0:
229
+ raise SourceError("pdftotext failed on downloaded PDF")
230
+ return stdout.decode("utf-8", errors="replace")
231
+ return r.text
232
+
233
+
234
+ # ---------------------------------------------------------------------------
235
+ # Style extraction
236
+ # ---------------------------------------------------------------------------
237
+
238
+ SECTION_RE = re.compile(r"\\section\*?\{([^}]*)\}")
239
+ SUBSECTION_RE = re.compile(r"\\subsection\*?\{([^}]*)\}")
240
+ THM_RE = re.compile(
241
+ r"\\begin\{(theorem|lemma|proposition|corollary|definition|assumption|remark)\}",
242
+ re.IGNORECASE,
243
+ )
244
+ FIG_RE = re.compile(r"\\begin\{figure\*?\}")
245
+ TAB_RE = re.compile(r"\\begin\{table\*?\}")
246
+ CAPTION_RE = re.compile(r"\\caption\{([^{}]*(?:\{[^{}]*\}[^{}]*)*)\}")
247
+ CITE_RE = re.compile(r"\\cite[a-zA-Z]*\*?\{([^}]+)\}")
248
+ DISPLAY_MATH_RE = re.compile(r"\\begin\{(equation|align|gather|multline)\*?\}")
249
+ INLINE_MATH_RE = re.compile(r"(?<!\\)\$[^$]+?(?<!\\)\$")
250
+
251
+
252
+ def _strip_tex(text: str) -> str:
253
+ """Strip TeX commands to leave roughly natural-language prose for sentence stats."""
254
+ text = re.sub(r"\\begin\{[^}]+\}.*?\\end\{[^}]+\}", " ", text, flags=re.DOTALL)
255
+ text = re.sub(r"%.*", " ", text)
256
+ text = re.sub(r"\\[a-zA-Z]+\*?(\[[^\]]*\])?(\{[^}]*\})*", " ", text)
257
+ text = re.sub(r"[{}]", " ", text)
258
+ text = re.sub(r"\$[^$]*\$", " MATHEXPR ", text)
259
+ text = re.sub(r"\s+", " ", text)
260
+ return text
261
+
262
+
263
+ def _sentence_stats(prose: str) -> dict[str, Any]:
264
+ sentences = re.split(r"(?<=[.!?])\s+", prose.strip())
265
+ sentences = [s for s in sentences if len(s) > 4]
266
+ if not sentences:
267
+ return {"count": 0, "mean_words": 0, "median_words": 0, "p90_words": 0}
268
+ word_counts = [len(s.split()) for s in sentences]
269
+ word_counts_sorted = sorted(word_counts)
270
+ p90_idx = max(0, int(0.9 * len(word_counts_sorted)) - 1)
271
+ return {
272
+ "count": len(sentences),
273
+ "mean_words": round(statistics.mean(word_counts), 1),
274
+ "median_words": int(statistics.median(word_counts)),
275
+ "p90_words": word_counts_sorted[p90_idx],
276
+ }
277
+
278
+
279
+ def _build_profile(src_kind: str, raw: str) -> str:
280
+ """Generate a markdown style profile. Skeleton-only; no copied prose."""
281
+ if src_kind in ("local_dir", "local_tex"):
282
+ return _profile_from_tex(raw)
283
+ return _profile_from_text(raw)
284
+
285
+
286
+ def _profile_from_tex(tex: str) -> str:
287
+ sections = SECTION_RE.findall(tex)
288
+ subsecs = SUBSECTION_RE.findall(tex)
289
+ thm_kinds = THM_RE.findall(tex)
290
+ n_fig = len(FIG_RE.findall(tex))
291
+ n_tab = len(TAB_RE.findall(tex))
292
+ captions = CAPTION_RE.findall(tex)
293
+ citations = CITE_RE.findall(tex)
294
+ n_display = len(DISPLAY_MATH_RE.findall(tex))
295
+ n_inline = len(INLINE_MATH_RE.findall(tex))
296
+
297
+ cite_keys: list[str] = []
298
+ for c in citations:
299
+ for k in c.split(","):
300
+ cite_keys.append(k.strip())
301
+
302
+ prose = _strip_tex(tex)
303
+ sstats = _sentence_stats(prose)
304
+
305
+ section_word_counts: list[tuple[str, int]] = []
306
+ parts = re.split(SECTION_RE, tex)
307
+ if len(parts) >= 3:
308
+ for i in range(1, len(parts) - 1, 2):
309
+ name = parts[i]
310
+ body = parts[i + 1] if i + 1 < len(parts) else ""
311
+ wc = len(_strip_tex(body).split())
312
+ section_word_counts.append((name, wc))
313
+
314
+ caption_lens = [len(c.split()) for c in captions] if captions else []
315
+ caption_summary = ""
316
+ if caption_lens:
317
+ caption_summary = (
318
+ f"- Captions: {len(caption_lens)} captions, "
319
+ f"mean {round(statistics.mean(caption_lens), 1)} words, "
320
+ f"median {int(statistics.median(caption_lens))} words"
321
+ )
322
+
323
+ thm_counter: dict[str, int] = {}
324
+ for k in thm_kinds:
325
+ thm_counter[k.lower()] = thm_counter.get(k.lower(), 0) + 1
326
+
327
+ md = ["# Style profile (skeleton-only)\n"]
328
+ md.append("**Use as structural guidance for the writer agent. Do NOT copy prose.**\n")
329
+
330
+ md.append("\n## Top-level section structure\n")
331
+ if sections:
332
+ for i, s in enumerate(sections, 1):
333
+ md.append(f"{i}. {s}")
334
+ else:
335
+ md.append("- (no `\\section{...}` markers detected — treat as freeform prose)")
336
+
337
+ if subsecs:
338
+ md.append(f"\n- Subsection density: {len(subsecs)} subsections / {max(1,len(sections))} sections "
339
+ f"= {round(len(subsecs)/max(1,len(sections)), 2)} per section")
340
+
341
+ md.append("\n## Approximate length per section (words after TeX strip)\n")
342
+ if section_word_counts:
343
+ for name, wc in section_word_counts:
344
+ md.append(f"- {name}: ~{wc} words")
345
+ else:
346
+ md.append("- (not measurable)")
347
+
348
+ md.append("\n## Theorem-environment density\n")
349
+ if thm_counter:
350
+ for k, v in sorted(thm_counter.items(), key=lambda kv: -kv[1]):
351
+ md.append(f"- {k}: {v}")
352
+ md.append(f"- Total proof-style env: {sum(thm_counter.values())}")
353
+ else:
354
+ md.append("- (no theorem-style environments)")
355
+
356
+ md.append("\n## Figures / tables\n")
357
+ md.append(f"- Figures: {n_fig}")
358
+ md.append(f"- Tables: {n_tab}")
359
+ if caption_summary:
360
+ md.append(caption_summary)
361
+
362
+ md.append("\n## Math density\n")
363
+ md.append(f"- Display equations (equation/align/gather/multline): {n_display}")
364
+ md.append(f"- Inline math `$...$`: {n_inline}")
365
+ if n_inline + n_display > 0:
366
+ ratio = n_display / (n_inline + n_display)
367
+ md.append(f"- Display-math share: {round(ratio*100, 1)}%")
368
+
369
+ md.append("\n## Citation usage\n")
370
+ md.append(f"- Total `\\cite*{{...}}` invocations: {len(citations)}")
371
+ md.append(f"- Distinct cite keys: {len(set(cite_keys))}")
372
+ bib_hint = "unknown"
373
+ if re.search(r"\\bibliographystyle\{(plainnat|abbrvnat|authoryear)", tex):
374
+ bib_hint = "author-year (natbib-style)"
375
+ elif re.search(r"\\bibliographystyle\{(plain|unsrt|ieee|alpha)", tex):
376
+ bib_hint = "numeric"
377
+ md.append(f"- Bibliography style hint: {bib_hint}")
378
+
379
+ md.append("\n## Sentence cadence (after TeX strip)\n")
380
+ md.append(f"- Sentence count: {sstats['count']}")
381
+ md.append(f"- Mean words/sentence: {sstats['mean_words']}")
382
+ md.append(f"- Median words/sentence: {sstats['median_words']}")
383
+ md.append(f"- p90 words/sentence: {sstats['p90_words']}")
384
+
385
+ md.append("\n## Notable structural cues\n")
386
+ cues: list[str] = []
387
+ if any(re.search(r"contribution", s, re.IGNORECASE) for s in sections + subsecs):
388
+ cues.append("- Has explicit \"Contributions\" subsection")
389
+ if any(re.search(r"related work|prior work", s, re.IGNORECASE) for s in sections):
390
+ cues.append("- Has dedicated \"Related Work\" section")
391
+ if any(re.search(r"limitation|broader impact", s, re.IGNORECASE) for s in sections + subsecs):
392
+ cues.append("- Has explicit Limitations / Broader Impact discussion")
393
+ if "\\paragraph{" in tex:
394
+ n_para = tex.count("\\paragraph{")
395
+ cues.append(f"- Uses `\\paragraph{{...}}` headings ({n_para} occurrences) — implies short titled paragraphs")
396
+ if cues:
397
+ md.extend(cues)
398
+ else:
399
+ md.append("- (no salient cues detected)")
400
+
401
+ md.append("\n## Reminder to the writer\n")
402
+ md.append("- Match *structural* tendencies above (section count, theorem density, ")
403
+ md.append(" caption length, sentence cadence, math display ratio).")
404
+ md.append("- Do **not** copy prose, claims, examples, or terminology unique to the reference.")
405
+ md.append("- This profile is intentionally aggregate; if you need substance, use the user's own outline.\n")
406
+
407
+ return "\n".join(md) + "\n"
408
+
409
+
410
+ def _profile_from_text(text: str) -> str:
411
+ """Best-effort profile from non-TeX text (PDF text dump or HTML)."""
412
+ sentences = re.split(r"(?<=[.!?])\s+", text)
413
+ sentences = [s for s in sentences if 8 < len(s) < 1000]
414
+ word_counts = [len(s.split()) for s in sentences] if sentences else [0]
415
+ headings = re.findall(r"^([A-Z][A-Za-z ]{2,40})$", text, re.MULTILINE)
416
+ headings = [h.strip() for h in headings if 3 <= len(h.split()) <= 6][:30]
417
+
418
+ md = ["# Style profile (skeleton-only, from non-TeX source)\n"]
419
+ md.append("**Use as structural guidance for the writer agent. Do NOT copy prose.**\n")
420
+ md.append("\n## Heuristic section-name candidates (best effort)\n")
421
+ if headings:
422
+ for h in headings[:20]:
423
+ md.append(f"- {h}")
424
+ else:
425
+ md.append("- (no headings recovered)")
426
+ md.append("\n## Sentence cadence\n")
427
+ if word_counts:
428
+ md.append(f"- Sentence count (heuristic): {len(sentences)}")
429
+ md.append(f"- Mean words/sentence: {round(statistics.mean(word_counts), 1)}")
430
+ md.append(f"- Median words/sentence: {int(statistics.median(word_counts))}")
431
+ md.append("\n## Caveat\n")
432
+ md.append("- Source is not LaTeX, so theorem density, citation style, and figure")
433
+ md.append(" density cannot be measured. Treat the section list as a hint only.\n")
434
+ return "\n".join(md) + "\n"
435
+
436
+
437
+ # ---------------------------------------------------------------------------
438
+ # Errors
439
+ # ---------------------------------------------------------------------------
440
+
441
+ class MissingDep(RuntimeError):
442
+ """Optional Python or system dependency is unavailable. Caller may skip."""
443
+
444
+
445
+ class SourceError(RuntimeError):
446
+ """Source could not be resolved or parsed. Caller should fail."""
447
+
448
+
449
+ # ---------------------------------------------------------------------------
450
+ # Main
451
+ # ---------------------------------------------------------------------------
452
+
453
+ def _cache_root() -> Path:
454
+ env = os.environ.get("ARIS_STYLE_REF_CACHE")
455
+ if env:
456
+ return Path(env).expanduser().resolve()
457
+ xdg = os.environ.get("XDG_CACHE_HOME")
458
+ base = Path(xdg).expanduser() if xdg else Path.home() / ".cache"
459
+ return base / "aris-style-refs"
460
+
461
+
462
+ def main() -> int:
463
+ ap = argparse.ArgumentParser(
464
+ description="Extract a skeleton-only style profile from a reference paper "
465
+ "for opt-in use by ARIS writer skills via --style-ref.",
466
+ )
467
+ ap.add_argument("--source", required=True,
468
+ help="Local path, arXiv ID, http(s) URL, or 'arxiv:<id>'. "
469
+ "Overleaf URLs are rejected — clone via overleaf-sync first "
470
+ "and pass the local clone path instead.")
471
+ ap.add_argument("--out", default=None,
472
+ help="Override cache root (default: $ARIS_STYLE_REF_CACHE, "
473
+ "$XDG_CACHE_HOME/aris-style-refs/, or ~/.cache/aris-style-refs/)")
474
+ ap.add_argument("--force", action="store_true",
475
+ help="Refetch and overwrite even if cache hit exists.")
476
+ args = ap.parse_args()
477
+
478
+ src = args.source.strip()
479
+ if not src:
480
+ print("error: --source is required", file=sys.stderr)
481
+ return 1
482
+
483
+ kind = _classify_source(src)
484
+ if kind == "overleaf":
485
+ print(
486
+ "Overleaf URLs / project IDs are rejected by design (private content).\n"
487
+ "Workflow: clone the project locally first via `/overleaf-sync setup <id>`,\n"
488
+ "then re-run with --source <local-clone-path>.",
489
+ file=sys.stderr,
490
+ )
491
+ return 3
492
+ if kind == "unknown":
493
+ print(f"error: could not classify source '{src}'. "
494
+ f"Pass a local path, arXiv id, or http(s) URL.", file=sys.stderr)
495
+ return 3
496
+
497
+ digest = hashlib.sha256(src.encode("utf-8")).hexdigest()[:16]
498
+ cache_root = Path(args.out).expanduser().resolve() if args.out else _cache_root()
499
+ cache_dir = cache_root / digest
500
+ manifest_path = cache_dir / "source_manifest.json"
501
+ profile_path = cache_dir / "style_profile.md"
502
+
503
+ if manifest_path.exists() and profile_path.exists() and not args.force:
504
+ print(f"# cache hit: {cache_dir}", file=sys.stderr)
505
+ print(str(cache_dir))
506
+ return 0
507
+
508
+ try:
509
+ if kind == "local_dir":
510
+ raw = _read_local_dir(Path(src).expanduser())
511
+ resolved = str(Path(src).expanduser().resolve())
512
+ elif kind == "local_tex":
513
+ raw = _read_local_tex(Path(src).expanduser())
514
+ resolved = str(Path(src).expanduser().resolve())
515
+ elif kind == "local_pdf":
516
+ raw = _read_local_pdf(Path(src).expanduser())
517
+ resolved = str(Path(src).expanduser().resolve())
518
+ elif kind == "arxiv":
519
+ raw = _read_arxiv(src)
520
+ resolved = src
521
+ elif kind == "http":
522
+ raw = _read_http(src)
523
+ resolved = src
524
+ else:
525
+ print(f"error: unsupported source kind '{kind}'", file=sys.stderr)
526
+ return 3
527
+ except MissingDep as e:
528
+ print(f"warning: missing optional dependency: {e}", file=sys.stderr)
529
+ return 2
530
+ except SourceError as e:
531
+ print(f"error: source could not be resolved: {e}", file=sys.stderr)
532
+ return 3
533
+ except Exception as e:
534
+ print(f"error: unexpected failure: {type(e).__name__}: {e}", file=sys.stderr)
535
+ return 1
536
+
537
+ profile_md = _build_profile(kind, raw)
538
+
539
+ cache_dir.mkdir(parents=True, exist_ok=True)
540
+ content_sha = hashlib.sha256(raw.encode("utf-8", errors="replace")).hexdigest()
541
+ manifest = {
542
+ "source_input": src,
543
+ "source_type": kind,
544
+ "resolved_path": resolved,
545
+ "fetched_at": _dt.datetime.now(_dt.timezone.utc).replace(microsecond=0).isoformat().replace("+00:00", "Z"),
546
+ "content_sha256": content_sha,
547
+ "tool_version": TOOL_VERSION,
548
+ }
549
+ manifest_path.write_text(json.dumps(manifest, indent=2) + "\n", encoding="utf-8")
550
+ profile_path.write_text(profile_md, encoding="utf-8")
551
+
552
+ print(str(cache_dir))
553
+ return 0
554
+
555
+
556
+ if __name__ == "__main__":
557
+ try:
558
+ sys.exit(main())
559
+ except KeyboardInterrupt:
560
+ sys.exit(130)
@@ -0,0 +1,69 @@
1
+ #!/usr/bin/env python3
2
+ """Legacy entry point — forwards to the canonical figure_renderer.
3
+
4
+ The canonical implementation now lives at
5
+ skills/figure-spec/scripts/figure_renderer.py
6
+ (Phase 3.1 — Arch C — self-contained single-owner helper).
7
+
8
+ This shim exists so existing users keep working without re-running
9
+ install_aris.sh. The four legacy resolver layers all still hit a
10
+ valid Python module:
11
+
12
+ layer 1 <project>/.aris/tools/figure_renderer.py
13
+ → symlink to $ARIS_REPO/tools/figure_renderer.py
14
+ → this file (shim)
15
+ → $ARIS_REPO/skills/figure-spec/scripts/figure_renderer.py
16
+
17
+ layer 2 <project>/tools/figure_renderer.py
18
+ → this file (when running from inside the ARIS repo)
19
+
20
+ layer 3 $ARIS_REPO/tools/figure_renderer.py
21
+ → this file (when ARIS_REPO env var or manifest sets it)
22
+
23
+ layer 4 $ARIS_REPO/tools/figure_renderer.py
24
+ → this file (when ARIS_REPO is resolved from the global
25
+ pointer file ~/.aris/repo, #366 — no project manifest needed)
26
+
27
+ Shim semantics: `os.execv` replaces the current Python process with
28
+ the real helper, so the helper sees its own `__file__`, `sys.path[0]`,
29
+ and argv exactly as if it had been invoked directly. No extra
30
+ process layer, no environment pollution.
31
+
32
+ The shim itself is kept minimal so a Python 3.6+ interpreter on any
33
+ platform (including older macOS system python) can run it.
34
+ """
35
+
36
+ from __future__ import annotations
37
+
38
+ import os
39
+ import sys
40
+ from pathlib import Path
41
+
42
+ HERE = Path(__file__).resolve().parent
43
+ REPO_ROOT = HERE.parent
44
+ REAL = REPO_ROOT / "skills" / "figure-spec" / "scripts" / "figure_renderer.py"
45
+
46
+
47
+ def _fail(msg: str) -> int:
48
+ sys.stderr.write(msg + "\n")
49
+ return 1
50
+
51
+
52
+ def main() -> int:
53
+ if not REAL.is_file():
54
+ return _fail(
55
+ f"ERROR: canonical figure_renderer.py not found at {REAL}.\n"
56
+ " The Phase 3.1 migration moved this helper into the\n"
57
+ " /figure-spec SKILL ('skills/figure-spec/scripts/'). Your\n"
58
+ " local checkout may be incomplete — try `git pull` from the\n"
59
+ " ARIS repo, or rerun `bash tools/install_aris.sh` to refresh\n"
60
+ " the project-local symlink chain."
61
+ )
62
+ # os.execv replaces this Python process; argv[0] is the real path so
63
+ # the helper sees its own __file__ and computes paths correctly.
64
+ os.execv(sys.executable, [sys.executable, str(REAL), *sys.argv[1:]])
65
+ return 0 # unreachable; os.execv does not return on success
66
+
67
+
68
+ if __name__ == "__main__":
69
+ sys.exit(main())