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 @@
1
+ httpx>=0.27,<1.0
@@ -0,0 +1,664 @@
1
+ #!/usr/bin/env python3
2
+ """Generic LLM Chat MCP Server - Supports any OpenAI-compatible API
3
+
4
+ Environment Variables:
5
+ LLM_API_KEY - API key (required)
6
+ LLM_BASE_URL - API base URL (default: https://api.openai.com/v1)
7
+ LLM_MODEL - Model name (default: gpt-4o)
8
+ LLM_FALLBACK_MODEL - Fallback model on 504 timeout (default: gpt-4o)
9
+ LLM_SERVER_NAME - Server name for MCP (default: llm-chat)
10
+ LLM_REVIEW_FALLBACK_ENABLED
11
+ - Expose review/review_reply tools when true (default: false)
12
+
13
+ Supported Providers (examples):
14
+ OpenAI: LLM_BASE_URL=https://api.openai.com/v1 LLM_MODEL=gpt-4o
15
+ DeepSeek: LLM_BASE_URL=https://api.deepseek.com/v1 LLM_MODEL=deepseek-chat
16
+ Kimi: LLM_BASE_URL=https://api.moonshot.cn/v1 LLM_MODEL=moonshot-v1-32k
17
+ MiniMax: LLM_BASE_URL=https://api.minimax.io/v1 LLM_MODEL=MiniMax-M3
18
+ """
19
+
20
+ import datetime
21
+ import json
22
+ import os
23
+ import re
24
+ import sys
25
+ import tempfile
26
+ import uuid
27
+ from pathlib import Path
28
+ import httpx
29
+
30
+ _stdio_initialized = False
31
+
32
+
33
+ def _init_stdio():
34
+ """Rebind stdio to raw unbuffered binary streams for MCP framing.
35
+
36
+ Deferred into a function (called at the top of main()) so that merely
37
+ IMPORTING this module has no stdio side effects. os.fdopen(fileno) defaults
38
+ to closefd=True and thus seizes ownership of the fd; doing that at import
39
+ time under a test harness that captures stdio (pytest fd-capture) closes the
40
+ harness's capture fd and corrupts capture for every subsequent test. Real
41
+ server launch (python server.py) still calls this first via main(), so
42
+ runtime behavior is unchanged. Idempotent."""
43
+ global _stdio_initialized
44
+ if _stdio_initialized:
45
+ return
46
+ # Force unbuffered stdout/stdin
47
+ sys.stdout = os.fdopen(sys.stdout.fileno(), 'wb', buffering=0)
48
+ sys.stdin = os.fdopen(sys.stdin.fileno(), 'rb', buffering=0)
49
+ _stdio_initialized = True
50
+
51
+ # Configuration from environment
52
+ API_KEY = os.environ.get("LLM_API_KEY", "")
53
+ BASE_URL = os.environ.get("LLM_BASE_URL", "https://api.openai.com/v1")
54
+ DEFAULT_MODEL = os.environ.get("LLM_MODEL", "gpt-4o")
55
+ FALLBACK_MODEL = os.environ.get("LLM_FALLBACK_MODEL", "gpt-4o")
56
+ SERVER_NAME = os.environ.get("LLM_SERVER_NAME", "llm-chat")
57
+ REVIEW_FALLBACK_ENABLED = os.environ.get(
58
+ "LLM_REVIEW_FALLBACK_ENABLED", "false"
59
+ ).strip().lower() in {"1", "true", "yes", "on"}
60
+
61
+ # Debug logging
62
+ DEBUG_LOG = os.path.join(tempfile.gettempdir(), f"{SERVER_NAME}-mcp-debug.log")
63
+
64
+ def debug_log(msg):
65
+ try:
66
+ with open(DEBUG_LOG, "a") as f:
67
+ f.write(f"{datetime.datetime.now()}: {msg}\n")
68
+ f.flush()
69
+ except Exception:
70
+ pass
71
+
72
+ def log_error(msg):
73
+ try:
74
+ with open(DEBUG_LOG, "a") as f:
75
+ f.write(f"{datetime.datetime.now()}: ERROR: {msg}\n")
76
+ except Exception:
77
+ pass
78
+
79
+ debug_log(f"=== {SERVER_NAME} MCP Server Starting (v2.2) ===")
80
+ debug_log(f"BASE_URL: {BASE_URL}")
81
+ debug_log(f"MODEL: {DEFAULT_MODEL}")
82
+ debug_log(f"FALLBACK_MODEL: {FALLBACK_MODEL}")
83
+ debug_log(f"REVIEW_FALLBACK_ENABLED: {REVIEW_FALLBACK_ENABLED}")
84
+ debug_log(f"API_KEY set: {bool(API_KEY)}")
85
+
86
+ _use_ndjson = False
87
+ _review_threads = {}
88
+
89
+ def send_response(response):
90
+ global _use_ndjson
91
+ json_str = json.dumps(response, separators=(',', ':'))
92
+ json_bytes = json_str.encode('utf-8')
93
+
94
+ if _use_ndjson:
95
+ output = json_bytes + b'\n'
96
+ else:
97
+ header = f"Content-Length: {len(json_bytes)}\r\n\r\n".encode('utf-8')
98
+ output = header + json_bytes
99
+
100
+ sys.stdout.write(output)
101
+ sys.stdout.flush()
102
+
103
+ def _call_llm_detailed(messages, model=None):
104
+ """Call LLM Chat Completions API and return content, error, actual model."""
105
+ if not API_KEY:
106
+ return None, "LLM_API_KEY environment variable not set", None
107
+
108
+ use_model = model or DEFAULT_MODEL
109
+ url = f"{BASE_URL.rstrip('/')}/chat/completions"
110
+ headers = {
111
+ "Content-Type": "application/json",
112
+ "Authorization": f"Bearer {API_KEY}"
113
+ }
114
+
115
+ # Try: original model → retry same model → fallback model.
116
+ # This retrying behavior is intentionally legacy-chat-only. Verdict-bearing
117
+ # review/review_reply calls use _call_llm_review_once below so ambiguous
118
+ # failures can never duplicate a paid review or produce conflicting verdicts.
119
+ for attempt in range(3):
120
+ current_model = use_model if attempt < 2 else FALLBACK_MODEL
121
+ payload = {
122
+ "model": current_model,
123
+ "messages": messages,
124
+ "max_tokens": 4096
125
+ }
126
+
127
+ debug_log(f"Calling LLM API (attempt {attempt + 1}): model={current_model}")
128
+
129
+ try:
130
+ with httpx.Client(timeout=300.0) as client:
131
+ response = client.post(url, headers=headers, json=payload)
132
+
133
+ if response.status_code == 504:
134
+ debug_log(f"504 Gateway Timeout on attempt {attempt + 1} with model {current_model}")
135
+ if attempt < 2:
136
+ continue # retry or fallback
137
+
138
+ if response.status_code != 200:
139
+ error_msg = f"API error {response.status_code}: {response.text[:500]}"
140
+ debug_log(f"API error: {error_msg}")
141
+ return None, error_msg, None
142
+
143
+ data = response.json()
144
+ try:
145
+ content = data["choices"][0]["message"]["content"]
146
+ except (KeyError, IndexError, TypeError) as e:
147
+ return None, f"Unexpected API response structure: {e}", None
148
+
149
+ # Prefer the model identity reported by the provider. If absent,
150
+ # use the exact model id sent in this successful request.
151
+ actual_model = str(data.get("model") or current_model).strip()
152
+
153
+ if current_model != use_model:
154
+ fallback_note = f"\n\n[Note: Used fallback model {current_model} after 504 timeout with {use_model}]"
155
+ content = fallback_note + "\n" + content
156
+ debug_log(f"API success with fallback model {actual_model}, response length: {len(content)}")
157
+ elif attempt > 0:
158
+ debug_log(f"API success on retry (attempt {attempt + 1}), response length: {len(content)}")
159
+ else:
160
+ debug_log(f"API success, response length: {len(content)}")
161
+ return content, None, actual_model
162
+ except Exception as e:
163
+ debug_log(f"API exception on attempt {attempt + 1}: {str(e)}")
164
+ if attempt == 2:
165
+ return None, str(e), None
166
+
167
+ return None, "All attempts failed with 504 Gateway Timeout", None
168
+
169
+ def call_llm(messages, model=None):
170
+ """Backward-compatible two-value wrapper for the existing chat tool."""
171
+ content, error, _actual_model = _call_llm_detailed(messages, model)
172
+ return content, error
173
+
174
+
175
+ def _call_llm_review_once(messages, model=None):
176
+ """Single-attempt, fail-closed call for verdict-bearing reviewer tools.
177
+
178
+ Once the HTTP request is dispatched, a timeout, 504, malformed response, or
179
+ transport exception is ambiguous: the remote reviewer may already have run.
180
+ Never retry or switch to FALLBACK_MODEL here. Surface the error so the
181
+ orchestrator/gate records REVIEW_UNAVAILABLE instead of issuing a duplicate
182
+ paid review with a potentially conflicting verdict.
183
+ """
184
+ if not API_KEY:
185
+ return None, "LLM_API_KEY environment variable not set", None
186
+
187
+ use_model = model or DEFAULT_MODEL
188
+ url = f"{BASE_URL.rstrip('/')}/chat/completions"
189
+ headers = {
190
+ "Content-Type": "application/json",
191
+ "Authorization": f"Bearer {API_KEY}"
192
+ }
193
+ payload = {
194
+ "model": use_model,
195
+ "messages": messages,
196
+ "max_tokens": 4096
197
+ }
198
+
199
+ debug_log(f"Calling verdict-bearing LLM review once: model={use_model}")
200
+ try:
201
+ with httpx.Client(timeout=300.0) as client:
202
+ response = client.post(url, headers=headers, json=payload)
203
+ if response.status_code != 200:
204
+ error_msg = f"API error {response.status_code}: {response.text[:500]}"
205
+ debug_log(f"Review API error (no retry): {error_msg}")
206
+ return None, error_msg, None
207
+
208
+ try:
209
+ data = response.json()
210
+ except Exception as exc:
211
+ error_msg = f"Invalid API JSON response: {exc}"
212
+ debug_log(f"Review API parse error (no retry): {error_msg}")
213
+ return None, error_msg, None
214
+
215
+ try:
216
+ content = data["choices"][0]["message"]["content"]
217
+ except (KeyError, IndexError, TypeError) as exc:
218
+ error_msg = f"Unexpected API response structure: {exc}"
219
+ debug_log(f"Review API structure error (no retry): {error_msg}")
220
+ return None, error_msg, None
221
+
222
+ actual_model = str(data.get("model") or use_model).strip()
223
+ debug_log(
224
+ f"Verdict-bearing API success: model={actual_model}, "
225
+ f"response length={len(content)}"
226
+ )
227
+ return content, None, actual_model
228
+ except Exception as exc:
229
+ debug_log(f"Review API exception (no retry): {str(exc)}")
230
+ return None, str(exc), None
231
+
232
+
233
+ # Coarse model families used only by the opt-in verdict-bearing review tools.
234
+ _FAMILY = [
235
+ ("anthropic", ("claude", "opus", "sonnet", "haiku", "anthropic")),
236
+ ("openai", ("gpt", "codex", "chatgpt", "o1", "o3", "o4", "openai")),
237
+ ("google", ("gemini", "google", "palm", "bard")),
238
+ ("deepseek", ("deepseek",)),
239
+ ("zhipu", ("glm", "zhipu")),
240
+ ("minimax", ("minimax", "abab")),
241
+ ("moonshot", ("kimi", "moonshot")),
242
+ ("qwen", ("qwen", "tongyi")),
243
+ ("xiaomi", ("mimo", "xiaomi")),
244
+ ("bytedance", ("doubao", "bytedance", "volcengine")),
245
+ ("xai", ("grok",)),
246
+ ("meta", ("llama",)),
247
+ ("mistral", ("mistral", "mixtral")),
248
+ ]
249
+ _SHORT = {"o1", "o3", "o4"}
250
+
251
+ def model_family(name):
252
+ """Map a model id to a coarse family; collisions fail closed.
253
+
254
+ Match family needles at token boundaries, mirroring review_gate.py, so a
255
+ provider prefix such as ``ollama/deepseek-r1`` does not accidentally match
256
+ the ``llama`` model family inside ``ollama``.
257
+ """
258
+ n = str(name or "").strip().lower()
259
+ matched = set()
260
+ for family, needles in _FAMILY:
261
+ for needle in needles:
262
+ suffix = "" if needle in _SHORT else r"[0-9.]*"
263
+ pattern = rf"(^|[^a-z0-9]){re.escape(needle)}{suffix}([^a-z0-9]|$)"
264
+ if re.search(pattern, n):
265
+ matched.add(family)
266
+ break
267
+ return next(iter(matched)) if len(matched) == 1 else "unknown"
268
+
269
+ def _cross_family_error(executor_model, reviewer_model):
270
+ executor_family = model_family(executor_model)
271
+ reviewer_family = model_family(reviewer_model)
272
+ if executor_family == "unknown":
273
+ return (f"Cannot verify HTTP reviewer independence: executor_model is "
274
+ f"missing or unrecognized ({executor_model!r})")
275
+ if reviewer_family == "unknown":
276
+ return f"Cannot verify HTTP reviewer model family: {reviewer_model!r}"
277
+ if executor_family == reviewer_family:
278
+ return (f"HTTP reviewer must use a different model family: "
279
+ f"executor={executor_model} ({executor_family}), "
280
+ f"reviewer={reviewer_model} ({reviewer_family})")
281
+ return None
282
+
283
+ def _tool_success(request_id, payload):
284
+ return {
285
+ "jsonrpc": "2.0",
286
+ "id": request_id,
287
+ "result": {
288
+ "content": [{"type": "text", "text": json.dumps(payload, ensure_ascii=False)}]
289
+ }
290
+ }
291
+
292
+ def _tool_error(request_id, message):
293
+ return {
294
+ "jsonrpc": "2.0",
295
+ "id": request_id,
296
+ "result": {
297
+ "content": [{"type": "text", "text": json.dumps({"error": message}, ensure_ascii=False)}],
298
+ "isError": True
299
+ }
300
+ }
301
+
302
+ def _read_review_files(paths):
303
+ """Read explicit primary artifacts that will be sent to the HTTP endpoint."""
304
+ if paths is None:
305
+ return ""
306
+ if not isinstance(paths, list):
307
+ raise ValueError("files must be an array of file paths")
308
+
309
+ sections = []
310
+ for raw_path in paths:
311
+ path = Path(str(raw_path)).expanduser()
312
+ if not path.is_file():
313
+ raise ValueError(f"review file not found or not a regular file: {path}")
314
+ try:
315
+ text = path.read_text(encoding="utf-8", errors="replace")
316
+ except OSError as exc:
317
+ raise ValueError(f"cannot read review file {path}: {exc}") from exc
318
+ sections.append(
319
+ f"\n\n--- ARIS PRIMARY ARTIFACT: {path} ---\n{text}"
320
+ f"\n--- END ARIS PRIMARY ARTIFACT: {path} ---"
321
+ )
322
+ return "".join(sections)
323
+
324
+ def _review_user_content(prompt, files):
325
+ return prompt + _read_review_files(files)
326
+
327
+ def _review_messages(history, prompt, system=""):
328
+ messages = []
329
+ if system:
330
+ messages.append({"role": "system", "content": system})
331
+ messages.extend(history)
332
+ messages.append({"role": "user", "content": prompt})
333
+ return messages
334
+
335
+ def _handle_review(arguments, request_id):
336
+ prompt = str(arguments.get("prompt", "")).strip()
337
+ executor_model = str(arguments.get("executor_model", "")).strip()
338
+ model = str(arguments.get("model", DEFAULT_MODEL)).strip() or DEFAULT_MODEL
339
+ system = str(arguments.get("system", "")).strip()
340
+ files = arguments.get("files", [])
341
+
342
+ if not prompt:
343
+ return _tool_error(request_id, "prompt is required")
344
+ if not executor_model:
345
+ return _tool_error(request_id, "executor_model is required for cross-family review")
346
+
347
+ try:
348
+ user_content = _review_user_content(prompt, files)
349
+ except ValueError as exc:
350
+ return _tool_error(request_id, str(exc))
351
+
352
+ content, error, actual_model = _call_llm_review_once(
353
+ _review_messages([], user_content, system), model
354
+ )
355
+ if error:
356
+ return _tool_error(request_id, error)
357
+
358
+ independence_error = _cross_family_error(executor_model, actual_model)
359
+ if independence_error:
360
+ return _tool_error(request_id, independence_error)
361
+
362
+ thread_id = uuid.uuid4().hex[:12]
363
+ _review_threads[thread_id] = {
364
+ "messages": [
365
+ {"role": "user", "content": user_content},
366
+ {"role": "assistant", "content": content},
367
+ ],
368
+ "model": model,
369
+ "system": system,
370
+ "executor_model": executor_model,
371
+ }
372
+ return _tool_success(request_id, {
373
+ "threadId": thread_id,
374
+ "content": content,
375
+ "reviewer_model": actual_model,
376
+ "reviewer_family": model_family(actual_model),
377
+ "executor_model": executor_model,
378
+ "executor_family": model_family(executor_model),
379
+ "family_relation": "different",
380
+ "independence_verified": "unverified",
381
+ })
382
+
383
+ def _handle_review_reply(arguments, request_id):
384
+ thread_id = str(arguments.get("threadId", "")).strip()
385
+ prompt = str(arguments.get("prompt", "")).strip()
386
+ if not thread_id:
387
+ return _tool_error(request_id, "threadId is required")
388
+ if thread_id not in _review_threads:
389
+ return _tool_error(request_id, f"Unknown threadId: {thread_id}")
390
+ if not prompt:
391
+ return _tool_error(request_id, "prompt is required")
392
+
393
+ thread = _review_threads[thread_id]
394
+ executor_model = str(arguments.get("executor_model", thread["executor_model"])).strip()
395
+ if executor_model != thread["executor_model"]:
396
+ return _tool_error(request_id, "executor_model cannot change within a review thread")
397
+ model = str(arguments.get("model", thread["model"])).strip() or thread["model"]
398
+ if model != thread["model"]:
399
+ return _tool_error(request_id, "reviewer model cannot change within a review thread")
400
+ system = str(arguments.get("system", thread["system"])).strip()
401
+ files = arguments.get("files", [])
402
+
403
+ try:
404
+ user_content = _review_user_content(prompt, files)
405
+ except ValueError as exc:
406
+ return _tool_error(request_id, str(exc))
407
+
408
+ history = list(thread["messages"])
409
+ content, error, actual_model = _call_llm_review_once(
410
+ _review_messages(history, user_content, system), model
411
+ )
412
+ if error:
413
+ return _tool_error(request_id, error)
414
+
415
+ independence_error = _cross_family_error(executor_model, actual_model)
416
+ if independence_error:
417
+ return _tool_error(request_id, independence_error)
418
+
419
+ thread["messages"].extend([
420
+ {"role": "user", "content": user_content},
421
+ {"role": "assistant", "content": content},
422
+ ])
423
+ return _tool_success(request_id, {
424
+ "threadId": thread_id,
425
+ "content": content,
426
+ "reviewer_model": actual_model,
427
+ "reviewer_family": model_family(actual_model),
428
+ "executor_model": executor_model,
429
+ "executor_family": model_family(executor_model),
430
+ "family_relation": "different",
431
+ "independence_verified": "unverified",
432
+ })
433
+
434
+ def _review_tool_definitions():
435
+ common = {
436
+ "prompt": {"type": "string", "description": "The substantive ARIS review prompt"},
437
+ "executor_model": {
438
+ "type": "string",
439
+ "description": "Actual executor model id; required to enforce cross-family review"
440
+ },
441
+ "model": {"type": "string", "description": f"Reviewer model (default: {DEFAULT_MODEL})"},
442
+ "system": {"type": "string", "description": "Optional reviewer system prompt"},
443
+ "files": {
444
+ "type": "array",
445
+ "items": {"type": "string"},
446
+ "description": "Local primary-artifact paths to send verbatim to the HTTP reviewer"
447
+ },
448
+ }
449
+ return [
450
+ {
451
+ "name": "review",
452
+ "description": "Start an independent HTTP reviewer thread.",
453
+ "inputSchema": {
454
+ "type": "object",
455
+ "properties": dict(common),
456
+ "required": ["prompt", "executor_model"]
457
+ }
458
+ },
459
+ {
460
+ "name": "review_reply",
461
+ "description": "Continue an HTTP reviewer thread with prior message history.",
462
+ "inputSchema": {
463
+ "type": "object",
464
+ "properties": dict(common, threadId={
465
+ "type": "string",
466
+ "description": "threadId returned by review"
467
+ }),
468
+ "required": ["threadId", "prompt"]
469
+ }
470
+ }
471
+ ]
472
+
473
+ def handle_request(request):
474
+ """Handle a JSON-RPC request"""
475
+ method = request.get("method", "")
476
+ params = request.get("params", {})
477
+ request_id = request.get("id")
478
+
479
+ debug_log(f"Handling method: {method}, id: {request_id}")
480
+
481
+ # Handle notifications (no id, no response needed)
482
+ if request_id is None:
483
+ if method == "notifications/initialized":
484
+ debug_log("Client initialized successfully")
485
+ return None
486
+
487
+ if method == "initialize":
488
+ return {
489
+ "jsonrpc": "2.0",
490
+ "id": request_id,
491
+ "result": {
492
+ "protocolVersion": "2024-11-05",
493
+ "capabilities": {
494
+ "tools": {}
495
+ },
496
+ "serverInfo": {
497
+ "name": SERVER_NAME,
498
+ "version": "2.2.0"
499
+ }
500
+ }
501
+ }
502
+
503
+ elif method == "ping":
504
+ return {"jsonrpc": "2.0", "id": request_id, "result": {}}
505
+
506
+ elif method == "tools/list":
507
+ tools = [{
508
+ "name": "chat",
509
+ "description": f"Send a message to {DEFAULT_MODEL} and get a response. Use this for research reviews, code analysis, and general AI tasks.",
510
+ "inputSchema": {
511
+ "type": "object",
512
+ "properties": {
513
+ "prompt": {
514
+ "type": "string",
515
+ "description": "The prompt to send"
516
+ },
517
+ "model": {
518
+ "type": "string",
519
+ "description": f"Model to use (default: {DEFAULT_MODEL})"
520
+ },
521
+ "system": {
522
+ "type": "string",
523
+ "description": "Optional system prompt"
524
+ }
525
+ },
526
+ "required": ["prompt"]
527
+ }
528
+ }]
529
+ if REVIEW_FALLBACK_ENABLED:
530
+ tools.extend(_review_tool_definitions())
531
+ return {
532
+ "jsonrpc": "2.0",
533
+ "id": request_id,
534
+ "result": {"tools": tools}
535
+ }
536
+
537
+ elif method == "tools/call":
538
+ tool_name = params.get("name", "")
539
+ arguments = params.get("arguments", {})
540
+
541
+ if tool_name == "chat":
542
+ prompt = arguments.get("prompt", "")
543
+ model = arguments.get("model", DEFAULT_MODEL)
544
+ system = arguments.get("system", "")
545
+
546
+ messages = []
547
+ if system:
548
+ messages.append({"role": "system", "content": system})
549
+ messages.append({"role": "user", "content": prompt})
550
+
551
+ debug_log(f"Tool call: chat, prompt length: {len(prompt)}")
552
+ content, error = call_llm(messages, model)
553
+
554
+ if error:
555
+ return {
556
+ "jsonrpc": "2.0",
557
+ "id": request_id,
558
+ "result": {
559
+ "content": [{"type": "text", "text": f"Error: {error}"}],
560
+ "isError": True
561
+ }
562
+ }
563
+
564
+ return {
565
+ "jsonrpc": "2.0",
566
+ "id": request_id,
567
+ "result": {
568
+ "content": [{"type": "text", "text": content}]
569
+ }
570
+ }
571
+
572
+ if tool_name == "review":
573
+ if not REVIEW_FALLBACK_ENABLED:
574
+ return _tool_error(
575
+ request_id,
576
+ "HTTP reviewer fallback is disabled. Set "
577
+ "LLM_REVIEW_FALLBACK_ENABLED=true and restart the MCP server."
578
+ )
579
+ return _handle_review(arguments, request_id)
580
+
581
+ if tool_name == "review_reply":
582
+ if not REVIEW_FALLBACK_ENABLED:
583
+ return _tool_error(
584
+ request_id,
585
+ "HTTP reviewer fallback is disabled. Set "
586
+ "LLM_REVIEW_FALLBACK_ENABLED=true and restart the MCP server."
587
+ )
588
+ return _handle_review_reply(arguments, request_id)
589
+
590
+ return {
591
+ "jsonrpc": "2.0",
592
+ "id": request_id,
593
+ "error": {"code": -32601, "message": f"Unknown tool: {tool_name}"}
594
+ }
595
+
596
+ else:
597
+ return {
598
+ "jsonrpc": "2.0",
599
+ "id": request_id,
600
+ "error": {"code": -32601, "message": f"Unknown method: {method}"}
601
+ }
602
+
603
+ def read_message():
604
+ """Read a single JSON-RPC message from stdin."""
605
+ global _use_ndjson
606
+
607
+ line = sys.stdin.readline()
608
+ if not line:
609
+ return None
610
+
611
+ line = line.decode('utf-8').rstrip('\r\n')
612
+
613
+ if line.lower().startswith("content-length:"):
614
+ try:
615
+ content_length = int(line.split(":", 1)[1].strip())
616
+ except ValueError:
617
+ return None
618
+
619
+ while True:
620
+ hdr = sys.stdin.readline()
621
+ if not hdr:
622
+ return None
623
+ hdr = hdr.decode('utf-8').rstrip('\r\n')
624
+ if hdr == "":
625
+ break
626
+
627
+ body = sys.stdin.read(content_length)
628
+ try:
629
+ return json.loads(body.decode('utf-8'))
630
+ except Exception:
631
+ return None
632
+
633
+ elif line.startswith("{") or line.startswith("["):
634
+ _use_ndjson = True
635
+ try:
636
+ return json.loads(line)
637
+ except Exception:
638
+ return None
639
+
640
+ return None
641
+
642
+ def main():
643
+ """Main loop - read JSON-RPC messages from stdin"""
644
+ _init_stdio()
645
+ debug_log("Entering main loop")
646
+
647
+ while True:
648
+ try:
649
+ request = read_message()
650
+ if request is None:
651
+ debug_log("EOF, exiting")
652
+ break
653
+
654
+ response = handle_request(request)
655
+ if response:
656
+ send_response(response)
657
+
658
+ except Exception as e:
659
+ log_error(f"Exception: {e}")
660
+
661
+ debug_log("=== Server Exiting ===")
662
+
663
+ if __name__ == "__main__":
664
+ main()