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.
- package/LICENSE +21 -0
- package/README.md +98 -0
- package/README_CN.md +87 -0
- package/dsh/checkout.patch.yml +38 -0
- package/dsh/client.js +634 -0
- package/dsh/cordis.patch.yml +44 -0
- package/dsh/index.mjs +76 -0
- package/dsh/run-status.mjs +182 -0
- package/dsh/scope-limits.mjs +50 -0
- package/dsh/workbench.mjs +291 -0
- package/mcp-servers/claude-review/README.md +93 -0
- package/mcp-servers/claude-review/run_with_claude_aws.sh +49 -0
- package/mcp-servers/claude-review/server.py +718 -0
- package/mcp-servers/codex-image2/README.md +65 -0
- package/mcp-servers/codex-image2/server.py +893 -0
- package/mcp-servers/feishu-bridge/requirements.txt +1 -0
- package/mcp-servers/feishu-bridge/server.py +240 -0
- package/mcp-servers/gemini-review/README.md +171 -0
- package/mcp-servers/gemini-review/server.py +1856 -0
- package/mcp-servers/llm-chat/requirements.txt +1 -0
- package/mcp-servers/llm-chat/server.py +664 -0
- package/mcp-servers/manual-review/README.md +133 -0
- package/mcp-servers/manual-review/server.py +910 -0
- package/mcp-servers/manual-review/ui.html +279 -0
- package/mcp-servers/minimax-chat/requirements.txt +1 -0
- package/mcp-servers/minimax-chat/server.py +381 -0
- package/package.json +51 -0
- package/skills/ablation-planner/SKILL.md +123 -0
- package/skills/alphaxiv/SKILL.md +196 -0
- package/skills/analyze-results/SKILL.md +46 -0
- package/skills/arxiv/SKILL.md +248 -0
- package/skills/auto-paper-improvement-loop/SKILL.md +651 -0
- package/skills/auto-review-loop/SKILL.md +1137 -0
- package/skills/auto-review-loop-llm/SKILL.md +259 -0
- package/skills/auto-review-loop-minimax/SKILL.md +302 -0
- package/skills/citation-audit/SKILL.md +502 -0
- package/skills/claims-drafting/SKILL.md +227 -0
- package/skills/comm-lit-review/SKILL.md +297 -0
- package/skills/deepxiv/SKILL.md +263 -0
- package/skills/dse-loop/SKILL.md +296 -0
- package/skills/embodiment-description/SKILL.md +129 -0
- package/skills/exa-search/SKILL.md +205 -0
- package/skills/experiment-audit/SKILL.md +311 -0
- package/skills/experiment-bridge/SKILL.md +376 -0
- package/skills/experiment-plan/SKILL.md +249 -0
- package/skills/experiment-queue/SKILL.md +431 -0
- package/skills/experiment-queue/scripts/build_manifest.py +142 -0
- package/skills/experiment-queue/scripts/queue_manager.py +433 -0
- package/skills/feishu-notify/SKILL.md +156 -0
- package/skills/figure-description/SKILL.md +138 -0
- package/skills/figure-spec/SKILL.md +262 -0
- package/skills/figure-spec/scripts/figure_renderer.py +799 -0
- package/skills/formula-derivation/SKILL.md +280 -0
- package/skills/gemini-search/SKILL.md +231 -0
- package/skills/grant-proposal/SKILL.md +698 -0
- package/skills/idea-creator/SKILL.md +542 -0
- package/skills/idea-discovery/SKILL.md +521 -0
- package/skills/idea-discovery-robot/SKILL.md +363 -0
- package/skills/integrity-forensics/SKILL.md +284 -0
- package/skills/interview-cheatsheet/SKILL.md +245 -0
- package/skills/invention-structuring/SKILL.md +188 -0
- package/skills/jurisdiction-format/SKILL.md +192 -0
- package/skills/kill-argument/SKILL.md +437 -0
- package/skills/mermaid-diagram/SKILL.md +419 -0
- package/skills/meta-apply/SKILL.md +141 -0
- package/skills/meta-optimize/SKILL.md +437 -0
- package/skills/monitor-experiment/SKILL.md +140 -0
- package/skills/novelty-check/SKILL.md +101 -0
- package/skills/openalex/SKILL.md +237 -0
- package/skills/overleaf-sync/SKILL.md +220 -0
- package/skills/paper-claim-audit/SKILL.md +348 -0
- package/skills/paper-compile/SKILL.md +266 -0
- package/skills/paper-figure/SKILL.md +312 -0
- package/skills/paper-illustration/SKILL.md +736 -0
- package/skills/paper-illustration-image2/SKILL.md +391 -0
- package/skills/paper-illustration-image2/scripts/paper_illustration_image2.py +255 -0
- package/skills/paper-plan/SKILL.md +386 -0
- package/skills/paper-poster/SKILL.md +19 -0
- package/skills/paper-poster-html/DESIGN_FINAL.md +176 -0
- package/skills/paper-poster-html/IMPLEMENTATION_CONVENTIONS.md +161 -0
- package/skills/paper-poster-html/LICENSES/posterly-MIT.txt +21 -0
- package/skills/paper-poster-html/NOTICE.md +57 -0
- package/skills/paper-poster-html/SKILL.md +323 -0
- package/skills/paper-poster-html/scripts/_posterly/__init__.py +0 -0
- package/skills/paper-poster-html/scripts/_posterly/canvas.py +200 -0
- package/skills/paper-poster-html/scripts/_posterly/measure.py +588 -0
- package/skills/paper-poster-html/scripts/_posterly/polish.py +498 -0
- package/skills/paper-poster-html/scripts/_posterly/preflight.py +489 -0
- package/skills/paper-poster-html/scripts/_posterly/render.py +215 -0
- package/skills/paper-poster-html/scripts/_posterly/textutil.py +16 -0
- package/skills/paper-poster-html/scripts/_posterly/verify_final.py +171 -0
- package/skills/paper-poster-html/scripts/asset_check.py +897 -0
- package/skills/paper-poster-html/scripts/extract_pdf_figures.py +666 -0
- package/skills/paper-poster-html/scripts/poster_check.py +251 -0
- package/skills/paper-poster-html/scripts/preprocess_figures.py +238 -0
- package/skills/paper-poster-html/scripts/render_preview.py +217 -0
- package/skills/paper-poster-html/scripts/run_gates.py +556 -0
- package/skills/paper-poster-html/scripts/style_check.py +1324 -0
- package/skills/paper-poster-html/templates/COMPONENTS.md +462 -0
- package/skills/paper-poster-html/templates/README.md +170 -0
- package/skills/paper-poster-html/templates/landscape_4col.html +1032 -0
- package/skills/paper-poster-html/templates/landscape_hero.html +1046 -0
- package/skills/paper-poster-html/templates/portrait_2col.html +947 -0
- package/skills/paper-poster-html/templates/tokens/acl.json +9 -0
- package/skills/paper-poster-html/templates/tokens/cvpr.json +9 -0
- package/skills/paper-poster-html/templates/tokens/generic.json +9 -0
- package/skills/paper-poster-html/templates/tokens/iclr.json +9 -0
- package/skills/paper-poster-html/templates/tokens/icml.json +9 -0
- package/skills/paper-poster-html/templates/tokens/neurips.json +9 -0
- package/skills/paper-slides/SKILL.md +635 -0
- package/skills/paper-talk/SKILL.md +381 -0
- package/skills/paper-write/SKILL.md +604 -0
- package/skills/paper-write/templates/IEEEtran.bst +2409 -0
- package/skills/paper-write/templates/IEEEtran.cls +6347 -0
- package/skills/paper-write/templates/iclr2026.tex +84 -0
- package/skills/paper-write/templates/icml2025.tex +87 -0
- package/skills/paper-write/templates/ieee_conference.tex +89 -0
- package/skills/paper-write/templates/ieee_journal.tex +93 -0
- package/skills/paper-write/templates/math_commands.tex +48 -0
- package/skills/paper-write/templates/neurips2025.tex +80 -0
- package/skills/paper-writing/SKILL.md +916 -0
- package/skills/patent-novelty-check/SKILL.md +153 -0
- package/skills/patent-pipeline/SKILL.md +344 -0
- package/skills/patent-review/SKILL.md +203 -0
- package/skills/pixel-art/SKILL.md +137 -0
- package/skills/prior-art-search/SKILL.md +146 -0
- package/skills/proof-checker/SKILL.md +866 -0
- package/skills/proof-orchestrator/NOTICE.md +24 -0
- package/skills/proof-orchestrator/SKILL.md +254 -0
- package/skills/proof-orchestrator/references/audit-output-contract.md +126 -0
- package/skills/proof-orchestrator/references/deepseek-routing.md +74 -0
- package/skills/proof-orchestrator/references/dispatch-prompts.md +227 -0
- package/skills/proof-orchestrator/references/notation-audit.md +135 -0
- package/skills/proof-orchestrator/references/proof-audit-rubric.md +70 -0
- package/skills/proof-orchestrator/references/stress-tests.md +38 -0
- package/skills/proof-writer/SKILL.md +223 -0
- package/skills/qzcli/SKILL.md +324 -0
- package/skills/rebuttal/SKILL.md +376 -0
- package/skills/render-html/SKILL.md +316 -0
- package/skills/render-html/scripts/render_html.py +1006 -0
- package/skills/render-html/scripts/templates/academic.html +703 -0
- package/skills/render-html/scripts/templates/dashboard.html +333 -0
- package/skills/research-lit/SKILL.md +756 -0
- package/skills/research-pipeline/SKILL.md +384 -0
- package/skills/research-refine/SKILL.md +770 -0
- package/skills/research-refine-pipeline/SKILL.md +186 -0
- package/skills/research-review/SKILL.md +198 -0
- package/skills/research-wiki/SKILL.md +461 -0
- package/skills/resubmit-pipeline/SKILL.md +447 -0
- package/skills/result-to-claim/SKILL.md +311 -0
- package/skills/run-experiment/SKILL.md +313 -0
- package/skills/semantic-scholar/SKILL.md +236 -0
- package/skills/serverless-modal/SKILL.md +335 -0
- package/skills/shared-references/acceptance-gate.md +324 -0
- package/skills/shared-references/assurance-contract.md +248 -0
- package/skills/shared-references/capture-antipatterns.md +78 -0
- package/skills/shared-references/citation-discipline.md +583 -0
- package/skills/shared-references/compute-env-contract.md +163 -0
- package/skills/shared-references/effort-contract.md +183 -0
- package/skills/shared-references/evidence-precheck.md +65 -0
- package/skills/shared-references/experiment-integrity.md +49 -0
- package/skills/shared-references/external-cadence.md +326 -0
- package/skills/shared-references/fan-out-pattern.md +366 -0
- package/skills/shared-references/injection-hygiene.md +127 -0
- package/skills/shared-references/integration-contract.md +461 -0
- package/skills/shared-references/output-composition.md +93 -0
- package/skills/shared-references/output-language.md +45 -0
- package/skills/shared-references/output-manifest.md +49 -0
- package/skills/shared-references/output-versioning.md +111 -0
- package/skills/shared-references/patent-format-cn.md +199 -0
- package/skills/shared-references/patent-format-ep.md +173 -0
- package/skills/shared-references/patent-format-us.md +161 -0
- package/skills/shared-references/patent-writing-principles.md +197 -0
- package/skills/shared-references/prior-art-databases.md +141 -0
- package/skills/shared-references/resumable-runs.md +109 -0
- package/skills/shared-references/review-scope-limits.md +81 -0
- package/skills/shared-references/review-tracing.md +391 -0
- package/skills/shared-references/reviewer-independence.md +79 -0
- package/skills/shared-references/reviewer-routing.md +852 -0
- package/skills/shared-references/skill-governance.md +104 -0
- package/skills/shared-references/taste-calibration.md +85 -0
- package/skills/shared-references/venue-checklists.md +114 -0
- package/skills/shared-references/wiki-helper-resolution.md +134 -0
- package/skills/shared-references/writing-principles.md +525 -0
- package/skills/skills-codex/README.md +102 -0
- package/skills/skills-codex/README_CN.md +100 -0
- package/skills/skills-codex/ablation-planner/SKILL.md +126 -0
- package/skills/skills-codex/alphaxiv/SKILL.md +186 -0
- package/skills/skills-codex/analyze-results/SKILL.md +45 -0
- package/skills/skills-codex/arxiv/SKILL.md +210 -0
- package/skills/skills-codex/auto-paper-improvement-loop/SKILL.md +574 -0
- package/skills/skills-codex/auto-review-loop/SKILL.md +500 -0
- package/skills/skills-codex/auto-review-loop-llm/SKILL.md +247 -0
- package/skills/skills-codex/auto-review-loop-minimax/SKILL.md +290 -0
- package/skills/skills-codex/citation-audit/SKILL.md +504 -0
- package/skills/skills-codex/claims-drafting/SKILL.md +239 -0
- package/skills/skills-codex/comm-lit-review/SKILL.md +299 -0
- package/skills/skills-codex/comm-lit-review/references/domain-taxonomy.md +57 -0
- package/skills/skills-codex/comm-lit-review/references/output-template.md +37 -0
- package/skills/skills-codex/comm-lit-review/references/source-policy.md +99 -0
- package/skills/skills-codex/comm-lit-review/references/venue-tiering.md +112 -0
- package/skills/skills-codex/deepxiv/SKILL.md +142 -0
- package/skills/skills-codex/dse-loop/SKILL.md +285 -0
- package/skills/skills-codex/embodiment-description/SKILL.md +129 -0
- package/skills/skills-codex/exa-search/SKILL.md +192 -0
- package/skills/skills-codex/experiment-audit/SKILL.md +286 -0
- package/skills/skills-codex/experiment-bridge/SKILL.md +356 -0
- package/skills/skills-codex/experiment-plan/SKILL.md +249 -0
- package/skills/skills-codex/experiment-queue/SKILL.md +401 -0
- package/skills/skills-codex/feishu-notify/SKILL.md +155 -0
- package/skills/skills-codex/figure-description/SKILL.md +138 -0
- package/skills/skills-codex/figure-spec/SKILL.md +252 -0
- package/skills/skills-codex/formula-derivation/SKILL.md +280 -0
- package/skills/skills-codex/gemini-search/SKILL.md +205 -0
- package/skills/skills-codex/grant-proposal/SKILL.md +626 -0
- package/skills/skills-codex/idea-creator/SKILL.md +405 -0
- package/skills/skills-codex/idea-discovery/SKILL.md +475 -0
- package/skills/skills-codex/idea-discovery-robot/SKILL.md +362 -0
- package/skills/skills-codex/integrity-forensics/SKILL.md +106 -0
- package/skills/skills-codex/interview-cheatsheet/SKILL.md +245 -0
- package/skills/skills-codex/invention-structuring/SKILL.md +188 -0
- package/skills/skills-codex/jurisdiction-format/SKILL.md +192 -0
- package/skills/skills-codex/kill-argument/SKILL.md +403 -0
- package/skills/skills-codex/mermaid-diagram/SKILL.md +379 -0
- package/skills/skills-codex/meta-apply/SKILL.md +154 -0
- package/skills/skills-codex/meta-optimize/SKILL.md +348 -0
- package/skills/skills-codex/monitor-experiment/SKILL.md +98 -0
- package/skills/skills-codex/novelty-check/SKILL.md +89 -0
- package/skills/skills-codex/openalex/SKILL.md +228 -0
- package/skills/skills-codex/overleaf-sync/SKILL.md +220 -0
- package/skills/skills-codex/paper-claim-audit/SKILL.md +350 -0
- package/skills/skills-codex/paper-compile/SKILL.md +253 -0
- package/skills/skills-codex/paper-figure/SKILL.md +311 -0
- package/skills/skills-codex/paper-illustration/SKILL.md +690 -0
- package/skills/skills-codex/paper-illustration-image2/SKILL.md +383 -0
- package/skills/skills-codex/paper-illustration-image2/scripts/paper_illustration_image2.py +255 -0
- package/skills/skills-codex/paper-plan/SKILL.md +278 -0
- package/skills/skills-codex/paper-poster/SKILL.md +19 -0
- package/skills/skills-codex/paper-poster-html/SKILL.md +377 -0
- package/skills/skills-codex/paper-slides/SKILL.md +571 -0
- package/skills/skills-codex/paper-talk/SKILL.md +381 -0
- package/skills/skills-codex/paper-write/SKILL.md +411 -0
- package/skills/skills-codex/paper-write/templates/IEEEtran.bst +2409 -0
- package/skills/skills-codex/paper-write/templates/IEEEtran.cls +6347 -0
- package/skills/skills-codex/paper-write/templates/aaai2026.bst +1493 -0
- package/skills/skills-codex/paper-write/templates/aaai2026.sty +315 -0
- package/skills/skills-codex/paper-write/templates/aaai2026.tex +952 -0
- package/skills/skills-codex/paper-write/templates/acl.sty +312 -0
- package/skills/skills-codex/paper-write/templates/acl2026.tex +377 -0
- package/skills/skills-codex/paper-write/templates/acl_natbib.bst +1940 -0
- package/skills/skills-codex/paper-write/templates/acm.bst +3081 -0
- package/skills/skills-codex/paper-write/templates/acm_mm2026.tex +204 -0
- package/skills/skills-codex/paper-write/templates/acmart.cls +3520 -0
- package/skills/skills-codex/paper-write/templates/cvpr.bst +1448 -0
- package/skills/skills-codex/paper-write/templates/cvpr.sty +508 -0
- package/skills/skills-codex/paper-write/templates/cvpr2026.tex +63 -0
- package/skills/skills-codex/paper-write/templates/iclr2026.tex +84 -0
- package/skills/skills-codex/paper-write/templates/iclr2026_conference.bst +1440 -0
- package/skills/skills-codex/paper-write/templates/iclr2026_conference.sty +246 -0
- package/skills/skills-codex/paper-write/templates/icml2026.sty +767 -0
- package/skills/skills-codex/paper-write/templates/icml2026.tex +662 -0
- package/skills/skills-codex/paper-write/templates/ieee_conference.tex +89 -0
- package/skills/skills-codex/paper-write/templates/ieee_journal.tex +93 -0
- package/skills/skills-codex/paper-write/templates/math_commands.tex +48 -0
- package/skills/skills-codex/paper-write/templates/neurips2026.tex +493 -0
- package/skills/skills-codex/paper-write/templates/neurips_2026.sty +437 -0
- package/skills/skills-codex/paper-writing/SKILL.md +731 -0
- package/skills/skills-codex/patent-novelty-check/SKILL.md +153 -0
- package/skills/skills-codex/patent-pipeline/SKILL.md +344 -0
- package/skills/skills-codex/patent-review/SKILL.md +202 -0
- package/skills/skills-codex/pixel-art/SKILL.md +139 -0
- package/skills/skills-codex/prior-art-search/SKILL.md +146 -0
- package/skills/skills-codex/proof-checker/SKILL.md +554 -0
- package/skills/skills-codex/proof-orchestrator/SKILL.md +260 -0
- package/skills/skills-codex/proof-orchestrator/references/audit-output-contract.md +126 -0
- package/skills/skills-codex/proof-orchestrator/references/deepseek-routing.md +76 -0
- package/skills/skills-codex/proof-orchestrator/references/dispatch-prompts.md +227 -0
- package/skills/skills-codex/proof-orchestrator/references/notation-audit.md +135 -0
- package/skills/skills-codex/proof-orchestrator/references/proof-audit-rubric.md +70 -0
- package/skills/skills-codex/proof-orchestrator/references/stress-tests.md +38 -0
- package/skills/skills-codex/proof-writer/SKILL.md +222 -0
- package/skills/skills-codex/qzcli/SKILL.md +324 -0
- package/skills/skills-codex/rebuttal/SKILL.md +305 -0
- package/skills/skills-codex/render-html/SKILL.md +305 -0
- package/skills/skills-codex/render-html/scripts/__pycache__/render_html.cpython-314.pyc +0 -0
- package/skills/skills-codex/render-html/scripts/render_html.py +909 -0
- package/skills/skills-codex/render-html/scripts/templates/academic.html +342 -0
- package/skills/skills-codex/render-html/scripts/templates/dashboard.html +333 -0
- package/skills/skills-codex/research-lit/SKILL.md +464 -0
- package/skills/skills-codex/research-pipeline/SKILL.md +340 -0
- package/skills/skills-codex/research-refine/SKILL.md +721 -0
- package/skills/skills-codex/research-refine-pipeline/SKILL.md +186 -0
- package/skills/skills-codex/research-review/SKILL.md +135 -0
- package/skills/skills-codex/research-wiki/SKILL.md +421 -0
- package/skills/skills-codex/resubmit-pipeline/SKILL.md +444 -0
- package/skills/skills-codex/result-to-claim/SKILL.md +246 -0
- package/skills/skills-codex/run-experiment/SKILL.md +236 -0
- package/skills/skills-codex/semantic-scholar/SKILL.md +219 -0
- package/skills/skills-codex/serverless-modal/SKILL.md +335 -0
- package/skills/skills-codex/shared-references/acceptance-gate.md +336 -0
- package/skills/skills-codex/shared-references/assurance-contract.md +139 -0
- package/skills/skills-codex/shared-references/capture-antipatterns.md +84 -0
- package/skills/skills-codex/shared-references/citation-discipline.md +452 -0
- package/skills/skills-codex/shared-references/compute-env-contract.md +163 -0
- package/skills/skills-codex/shared-references/effort-contract.md +143 -0
- package/skills/skills-codex/shared-references/evidence-precheck.md +73 -0
- package/skills/skills-codex/shared-references/experiment-integrity.md +49 -0
- package/skills/skills-codex/shared-references/external-cadence.md +334 -0
- package/skills/skills-codex/shared-references/fan-out-pattern.md +375 -0
- package/skills/skills-codex/shared-references/injection-hygiene.md +132 -0
- package/skills/skills-codex/shared-references/integration-contract.md +372 -0
- package/skills/skills-codex/shared-references/output-composition.md +98 -0
- package/skills/skills-codex/shared-references/output-language.md +45 -0
- package/skills/skills-codex/shared-references/output-manifest.md +40 -0
- package/skills/skills-codex/shared-references/output-versioning.md +111 -0
- package/skills/skills-codex/shared-references/patent-format-cn.md +199 -0
- package/skills/skills-codex/shared-references/patent-format-ep.md +173 -0
- package/skills/skills-codex/shared-references/patent-format-us.md +161 -0
- package/skills/skills-codex/shared-references/patent-writing-principles.md +197 -0
- package/skills/skills-codex/shared-references/prior-art-databases.md +141 -0
- package/skills/skills-codex/shared-references/resumable-runs.md +125 -0
- package/skills/skills-codex/shared-references/review-scope-limits.md +81 -0
- package/skills/skills-codex/shared-references/review-tracing.md +144 -0
- package/skills/skills-codex/shared-references/reviewer-independence.md +66 -0
- package/skills/skills-codex/shared-references/reviewer-routing.md +128 -0
- package/skills/skills-codex/shared-references/skill-governance.md +119 -0
- package/skills/skills-codex/shared-references/taste-calibration.md +90 -0
- package/skills/skills-codex/shared-references/venue-checklists.md +73 -0
- package/skills/skills-codex/shared-references/wiki-helper-resolution.md +69 -0
- package/skills/skills-codex/shared-references/writing-principles.md +525 -0
- package/skills/skills-codex/slides-polish/SKILL.md +563 -0
- package/skills/skills-codex/specification-writing/SKILL.md +211 -0
- package/skills/skills-codex/system-profile/SKILL.md +103 -0
- package/skills/skills-codex/training-check/SKILL.md +83 -0
- package/skills/skills-codex/vast-gpu/SKILL.md +394 -0
- package/skills/skills-codex/web-debug-search/SKILL.md +334 -0
- package/skills/skills-codex/wiki-enrich/SKILL.md +255 -0
- package/skills/skills-codex/writing-systems-papers/SKILL.md +184 -0
- package/skills/skills-codex-claude-review/README.md +79 -0
- package/skills/skills-codex-claude-review/README_CN.md +78 -0
- package/skills/skills-codex-claude-review/auto-paper-improvement-loop/SKILL.md +581 -0
- package/skills/skills-codex-claude-review/auto-review-loop/SKILL.md +510 -0
- package/skills/skills-codex-claude-review/novelty-check/SKILL.md +102 -0
- package/skills/skills-codex-claude-review/paper-figure/SKILL.md +319 -0
- package/skills/skills-codex-claude-review/paper-plan/SKILL.md +287 -0
- package/skills/skills-codex-claude-review/paper-write/SKILL.md +420 -0
- package/skills/skills-codex-claude-review/research-refine/SKILL.md +732 -0
- package/skills/skills-codex-claude-review/research-review/SKILL.md +149 -0
- package/skills/skills-codex-gemini-review/README.md +176 -0
- package/skills/skills-codex-gemini-review/README_CN.md +175 -0
- package/skills/skills-codex-gemini-review/auto-paper-improvement-loop/SKILL.md +331 -0
- package/skills/skills-codex-gemini-review/auto-review-loop/SKILL.md +304 -0
- package/skills/skills-codex-gemini-review/grant-proposal/SKILL.md +630 -0
- package/skills/skills-codex-gemini-review/idea-creator/SKILL.md +263 -0
- package/skills/skills-codex-gemini-review/idea-discovery/SKILL.md +275 -0
- package/skills/skills-codex-gemini-review/idea-discovery-robot/SKILL.md +365 -0
- package/skills/skills-codex-gemini-review/novelty-check/SKILL.md +92 -0
- package/skills/skills-codex-gemini-review/paper-figure/SKILL.md +289 -0
- package/skills/skills-codex-gemini-review/paper-plan/SKILL.md +265 -0
- package/skills/skills-codex-gemini-review/paper-poster-html/SKILL.md +102 -0
- package/skills/skills-codex-gemini-review/paper-slides/SKILL.md +582 -0
- package/skills/skills-codex-gemini-review/paper-write/SKILL.md +346 -0
- package/skills/skills-codex-gemini-review/paper-writing/SKILL.md +312 -0
- package/skills/skills-codex-gemini-review/research-refine/SKILL.md +674 -0
- package/skills/skills-codex-gemini-review/research-review/SKILL.md +112 -0
- package/skills/slides-polish/SKILL.md +565 -0
- package/skills/specification-writing/SKILL.md +211 -0
- package/skills/system-profile/SKILL.md +103 -0
- package/skills/training-check/SKILL.md +132 -0
- package/skills/vast-gpu/SKILL.md +394 -0
- package/skills/web-debug-search/SKILL.md +334 -0
- package/skills/wiki-enrich/SKILL.md +257 -0
- package/skills/writing-systems-papers/SKILL.md +184 -0
- package/templates/CLAUDE_MD_TEMPLATE.md +29 -0
- package/templates/EXPERIMENT_LOG_TEMPLATE.md +47 -0
- package/templates/EXPERIMENT_PLAN_TEMPLATE.md +51 -0
- package/templates/EXPERIMENT_PLAN_TEMPLATE_CN.md +53 -0
- package/templates/FINDINGS_TEMPLATE.md +52 -0
- package/templates/IDEA_CANDIDATES_TEMPLATE.md +47 -0
- package/templates/IDEA_CANDIDATES_TEMPLATE_CN.md +47 -0
- package/templates/INVENTION_BRIEF_TEMPLATE.md +87 -0
- package/templates/MANIFEST_TEMPLATE.md +7 -0
- package/templates/NARRATIVE_REPORT_TEMPLATE.md +49 -0
- package/templates/PAPER_PLAN_TEMPLATE.md +47 -0
- package/templates/PATENT_CLAIMS_TEMPLATE.md +78 -0
- package/templates/PATENT_SPECIFICATION_TEMPLATE.md +68 -0
- package/templates/README.md +57 -0
- package/templates/RESEARCH_BRIEF_TEMPLATE.md +35 -0
- package/templates/RESEARCH_BRIEF_TEMPLATE_CN.md +41 -0
- package/templates/RESEARCH_CONTRACT_TEMPLATE.md +60 -0
- package/templates/claude-hooks/corpus_write_guard.json +16 -0
- package/templates/claude-hooks/corpus_write_guard.py +85 -0
- package/templates/claude-hooks/meta_logging.json +74 -0
- package/templates/gitignore-trace.txt +3 -0
- package/tools/__pycache__/check_skills_inventory.cpython-314.pyc +0 -0
- package/tools/arxiv_fetch.py +311 -0
- package/tools/capture_filter.py +126 -0
- package/tools/check_skills_inventory.py +273 -0
- package/tools/convert_skills_to_llm_chat.py +282 -0
- package/tools/copilot_native_evidence.py +818 -0
- package/tools/deepxiv_fetch.py +213 -0
- package/tools/evidence_check.py +212 -0
- package/tools/exa_search.py +425 -0
- package/tools/experiment_queue/README.md +118 -0
- package/tools/experiment_queue/build_manifest.py +44 -0
- package/tools/experiment_queue/queue_manager.py +44 -0
- package/tools/extract_paper_style.py +560 -0
- package/tools/figure_renderer.py +69 -0
- package/tools/forensics_gate.py +669 -0
- package/tools/generate_codex_claude_review_overrides.py +299 -0
- package/tools/idea_discovery_gate.py +256 -0
- package/tools/install_aris.ps1 +1372 -0
- package/tools/install_aris.sh +1370 -0
- package/tools/install_aris_codex.sh +1023 -0
- package/tools/install_aris_copilot.sh +1052 -0
- package/tools/iteration_log.py +143 -0
- package/tools/lint_skills_helpers.sh +84 -0
- package/tools/meta_opt/check_ready.sh +80 -0
- package/tools/meta_opt/log_event.sh +91 -0
- package/tools/meta_opt/trigger_eval.py +280 -0
- package/tools/meta_opt/trigger_evals.sample.json +28 -0
- package/tools/openalex_fetch.py +326 -0
- package/tools/overleaf_audit.sh +104 -0
- package/tools/overleaf_setup.sh +150 -0
- package/tools/paper_illustration_image2.py +62 -0
- package/tools/provenance.py +294 -0
- package/tools/research_wiki.py +1720 -0
- package/tools/review_gate.py +502 -0
- package/tools/run_state.py +399 -0
- package/tools/save_trace.sh +477 -0
- package/tools/semantic_scholar_fetch.py +438 -0
- package/tools/skill-groups.tsv +116 -0
- package/tools/skill_picker.py +238 -0
- package/tools/smart_update.ps1 +521 -0
- package/tools/smart_update.sh +591 -0
- package/tools/smart_update_codex.sh +419 -0
- package/tools/smart_update_copilot.sh +605 -0
- package/tools/threat_scan.py +222 -0
- package/tools/verify_paper_audits.sh +487 -0
- package/tools/verify_papers.py +613 -0
- package/tools/verify_wiki_coverage.sh +176 -0
- package/tools/watchdog.py +485 -0
|
@@ -0,0 +1,215 @@
|
|
|
1
|
+
"""Shared Playwright launch + page-settle helpers.
|
|
2
|
+
|
|
3
|
+
Used by ``measure``, ``polish``, and ``render_preview``. Centralises:
|
|
4
|
+
|
|
5
|
+
1. Print-emulated Chromium context at the correct viewport.
|
|
6
|
+
2. MathJax detection + bounded typeset wait (so a stuck CDN can't
|
|
7
|
+
hang the script forever).
|
|
8
|
+
3. ``document.fonts.ready`` + two RAFs + a fixed settle ms — so
|
|
9
|
+
the layout is locked before any geometry is read.
|
|
10
|
+
4. A sanity check that catches the "page has ``$…$`` TeX in body text
|
|
11
|
+
but no rendered ``<mjx-container>``" case — MathJax never ran
|
|
12
|
+
(CDN blocked, script error, …). Measurement / polish must NOT
|
|
13
|
+
silently pass against a raw-TeX layout.
|
|
14
|
+
|
|
15
|
+
The ``settle_page`` helper returns a :class:`SettleResult` with the raw
|
|
16
|
+
status flags. ``measure``/``polish`` treat MathJax issues as hard fails;
|
|
17
|
+
``render_preview`` warns and continues (rendering raw-TeX is at least
|
|
18
|
+
visible to the user, whereas a silent measure PASS isn't).
|
|
19
|
+
"""
|
|
20
|
+
from __future__ import annotations
|
|
21
|
+
|
|
22
|
+
import sys
|
|
23
|
+
from dataclasses import dataclass
|
|
24
|
+
from pathlib import Path
|
|
25
|
+
from typing import Any
|
|
26
|
+
|
|
27
|
+
from .textutil import ascii_safe
|
|
28
|
+
|
|
29
|
+
|
|
30
|
+
def _eprint(*args: Any, **kw: Any) -> None:
|
|
31
|
+
print(*args, file=sys.stderr, **kw)
|
|
32
|
+
|
|
33
|
+
|
|
34
|
+
@dataclass
|
|
35
|
+
class SettleResult:
|
|
36
|
+
mathjax_intended: bool
|
|
37
|
+
"""The page intended to load MathJax — either a ``<script src=…mathjax…>``
|
|
38
|
+
tag is present or ``window.MathJax`` config was set. Used to gate the
|
|
39
|
+
``tex_without_mathjax`` failure: a poster that documents TeX syntax in
|
|
40
|
+
prose without ever loading MathJax is a perfectly valid use case and
|
|
41
|
+
must NOT trip the sanity check."""
|
|
42
|
+
|
|
43
|
+
has_mathjax: bool
|
|
44
|
+
"""``window.MathJax.startup.promise`` was defined at settle time
|
|
45
|
+
(MathJax actually initialized)."""
|
|
46
|
+
|
|
47
|
+
mathjax_status: str
|
|
48
|
+
"""One of ``'ok'``, ``'timeout'``, ``'error'``, ``'not-needed'``."""
|
|
49
|
+
|
|
50
|
+
mathjax_error: str | None
|
|
51
|
+
"""Exception message if ``mathjax_status == 'error'``, else None."""
|
|
52
|
+
|
|
53
|
+
tex_without_mathjax: bool
|
|
54
|
+
"""Body innerText has TeX delimiters but no ``<mjx-container>`` rendered.
|
|
55
|
+
Only counted as a failure when ``mathjax_intended`` is True (otherwise
|
|
56
|
+
the ``$…$`` is most likely prose, not math)."""
|
|
57
|
+
|
|
58
|
+
|
|
59
|
+
def open_print_emulated_page(p, viewport_px: tuple[int, int]):
|
|
60
|
+
"""Launch headless Chromium, open a context+page at the viewport,
|
|
61
|
+
emulate print media. Returns ``(browser, ctx, page)``.
|
|
62
|
+
|
|
63
|
+
Print emulation is set BEFORE navigation by the caller (via
|
|
64
|
+
``page.emulate_media``), so MathJax typesets against ``@media print``
|
|
65
|
+
layout from the start. Without that, the screen-mode ``--u`` value
|
|
66
|
+
leaks in and measurement is unreliable.
|
|
67
|
+
"""
|
|
68
|
+
w, h = viewport_px
|
|
69
|
+
browser = p.chromium.launch()
|
|
70
|
+
ctx = browser.new_context(viewport={"width": w, "height": h})
|
|
71
|
+
page = ctx.new_page()
|
|
72
|
+
page.emulate_media(media="print")
|
|
73
|
+
page.set_viewport_size({"width": w, "height": h})
|
|
74
|
+
return browser, ctx, page
|
|
75
|
+
|
|
76
|
+
|
|
77
|
+
def settle_page(
|
|
78
|
+
page,
|
|
79
|
+
*,
|
|
80
|
+
mathjax_timeout_ms: int = 15000,
|
|
81
|
+
settle_ms: int = 500,
|
|
82
|
+
) -> SettleResult:
|
|
83
|
+
"""Wait for MathJax, fonts, two RAFs, and an extra fixed ms.
|
|
84
|
+
|
|
85
|
+
Returns a :class:`SettleResult` rather than raising — the caller
|
|
86
|
+
decides whether each flag is a hard fail or a soft warning.
|
|
87
|
+
Idempotent on math-free pages: detection is synchronous and the
|
|
88
|
+
typeset wait is skipped when MathJax wasn't loaded.
|
|
89
|
+
"""
|
|
90
|
+
# 1a) Did the page INTEND to load MathJax? A <script src="…mathjax…">
|
|
91
|
+
# tag OR a window.MathJax config object counts. Used to decide
|
|
92
|
+
# whether stray `$…$` in body text is "math that failed to render"
|
|
93
|
+
# (intended) vs "prose that happens to mention TeX" (not intended).
|
|
94
|
+
try:
|
|
95
|
+
mathjax_intended = bool(page.evaluate(
|
|
96
|
+
"() => !!(document.querySelector('script[src*=\"mathjax\" i]') "
|
|
97
|
+
"|| (window.MathJax && Object.keys(window.MathJax).length > 0))"
|
|
98
|
+
))
|
|
99
|
+
except Exception:
|
|
100
|
+
mathjax_intended = False
|
|
101
|
+
|
|
102
|
+
# 1b) Did MathJax actually initialise?
|
|
103
|
+
try:
|
|
104
|
+
has_mj = bool(page.evaluate(
|
|
105
|
+
"() => !!(window.MathJax && window.MathJax.startup "
|
|
106
|
+
"&& window.MathJax.startup.promise)"
|
|
107
|
+
))
|
|
108
|
+
except Exception:
|
|
109
|
+
has_mj = False
|
|
110
|
+
|
|
111
|
+
mj_status = "not-needed"
|
|
112
|
+
mj_error: str | None = None
|
|
113
|
+
|
|
114
|
+
# 2) If present, bound the typeset wait with Promise.race so a
|
|
115
|
+
# stuck MathJax can't hang us.
|
|
116
|
+
if has_mj:
|
|
117
|
+
mj_js = (
|
|
118
|
+
f"() => Promise.race(["
|
|
119
|
+
f" MathJax.startup.promise"
|
|
120
|
+
f" .then(() => (MathJax.typesetPromise"
|
|
121
|
+
f" ? MathJax.typesetPromise() : null))"
|
|
122
|
+
f" .then(() => 'ok'),"
|
|
123
|
+
f" new Promise(r => setTimeout("
|
|
124
|
+
f" () => r('timeout'), {mathjax_timeout_ms}))"
|
|
125
|
+
f"])"
|
|
126
|
+
)
|
|
127
|
+
try:
|
|
128
|
+
mj_status = page.evaluate(mj_js) or "timeout"
|
|
129
|
+
except Exception as e:
|
|
130
|
+
mj_status = "error"
|
|
131
|
+
mj_error = str(e)
|
|
132
|
+
|
|
133
|
+
# 3) Fonts (best-effort) + two RAFs + fixed settle ms.
|
|
134
|
+
try:
|
|
135
|
+
page.evaluate(
|
|
136
|
+
"() => document.fonts && document.fonts.ready "
|
|
137
|
+
"? document.fonts.ready : null"
|
|
138
|
+
)
|
|
139
|
+
except Exception:
|
|
140
|
+
pass
|
|
141
|
+
page.evaluate(
|
|
142
|
+
"() => new Promise(r => "
|
|
143
|
+
"requestAnimationFrame(() => requestAnimationFrame(r)))"
|
|
144
|
+
)
|
|
145
|
+
page.wait_for_timeout(settle_ms)
|
|
146
|
+
|
|
147
|
+
# 4) Sanity check for the silent-fail case: page has TeX in body
|
|
148
|
+
# text but no rendered mjx-container. Covers all four delimiter
|
|
149
|
+
# pairs the templates configure (`$...$`, `$$...$$`, `\(...\)`,
|
|
150
|
+
# `\[...\]`). No length bound — earlier `{1,1500}` regex limits
|
|
151
|
+
# were Codex-flagged for letting long raw-TeX paste slip past.
|
|
152
|
+
# `[^$\n]+` (inline) and `[\s\S]+?` (display, non-greedy) avoid
|
|
153
|
+
# catastrophic backtracking even on multi-paragraph segments.
|
|
154
|
+
try:
|
|
155
|
+
sanity = page.evaluate(
|
|
156
|
+
"() => {"
|
|
157
|
+
" const has_mjx = "
|
|
158
|
+
" document.querySelectorAll('mjx-container').length > 0;"
|
|
159
|
+
" const txt = document.body && document.body.innerText || '';"
|
|
160
|
+
" const has_dollar = /\\$[^$\\n]+\\$/.test(txt);"
|
|
161
|
+
" const has_ddollar = /\\$\\$[\\s\\S]+?\\$\\$/.test(txt);"
|
|
162
|
+
" const has_paren = /\\\\\\([\\s\\S]+?\\\\\\)/.test(txt);"
|
|
163
|
+
" const has_brack = /\\\\\\[[\\s\\S]+?\\\\\\]/.test(txt);"
|
|
164
|
+
" return {has_mjx, has_tex: has_dollar || has_ddollar "
|
|
165
|
+
" || has_paren || has_brack};"
|
|
166
|
+
"}"
|
|
167
|
+
)
|
|
168
|
+
tex_without_mathjax = bool(
|
|
169
|
+
sanity.get("has_tex") and not sanity.get("has_mjx")
|
|
170
|
+
)
|
|
171
|
+
except Exception:
|
|
172
|
+
tex_without_mathjax = False
|
|
173
|
+
|
|
174
|
+
return SettleResult(
|
|
175
|
+
mathjax_intended=mathjax_intended,
|
|
176
|
+
has_mathjax=has_mj,
|
|
177
|
+
mathjax_status=mj_status,
|
|
178
|
+
mathjax_error=mj_error,
|
|
179
|
+
tex_without_mathjax=tex_without_mathjax,
|
|
180
|
+
)
|
|
181
|
+
|
|
182
|
+
|
|
183
|
+
def hard_fail_on_settle_problems(
|
|
184
|
+
result: SettleResult,
|
|
185
|
+
*,
|
|
186
|
+
mathjax_timeout_ms: int,
|
|
187
|
+
) -> str | None:
|
|
188
|
+
"""Return a one-line failure message if ``measure`` / ``polish``
|
|
189
|
+
must hard-fail given a settle result, else None.
|
|
190
|
+
|
|
191
|
+
Centralised so the two strict gates agree on what counts as a fail.
|
|
192
|
+
"""
|
|
193
|
+
if result.mathjax_status == "error":
|
|
194
|
+
return (
|
|
195
|
+
f"MathJax typeset error: {ascii_safe(result.mathjax_error)}. "
|
|
196
|
+
f"Refusing to measure a broken-script page."
|
|
197
|
+
)
|
|
198
|
+
if result.mathjax_status == "timeout":
|
|
199
|
+
return (
|
|
200
|
+
f"MathJax typeset did not finish within "
|
|
201
|
+
f"{mathjax_timeout_ms} ms. Refusing to measure a "
|
|
202
|
+
f"partially typeset poster."
|
|
203
|
+
)
|
|
204
|
+
# Only fail when MathJax was INTENDED to load (script tag or config
|
|
205
|
+
# present) but didn't render anything. A poster that documents TeX
|
|
206
|
+
# syntax in prose without ever loading MathJax is a valid use case.
|
|
207
|
+
if result.mathjax_intended and result.tex_without_mathjax:
|
|
208
|
+
return (
|
|
209
|
+
"page intended to load MathJax (script/config present) "
|
|
210
|
+
"but no rendered <mjx-container> was found despite TeX "
|
|
211
|
+
"delimiters in body text. MathJax likely failed to load "
|
|
212
|
+
"(CDN block? script error?). Refusing to measure raw-TeX "
|
|
213
|
+
"layout."
|
|
214
|
+
)
|
|
215
|
+
return None
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
"""Make a string safe to print to a terminal / CI log / pasted issue.
|
|
2
|
+
|
|
3
|
+
Runtime output is otherwise all-ASCII (rounds 7-9), but USER-derived
|
|
4
|
+
fragments -- orphan text, an image src, a MathJax error, raw pdfinfo
|
|
5
|
+
output -- can re-inject Unicode that source-level grep can't catch.
|
|
6
|
+
Escape it at the output boundary so terminal output never mojibakes.
|
|
7
|
+
"""
|
|
8
|
+
from __future__ import annotations
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
def ascii_safe(s: object) -> str:
|
|
12
|
+
r"""Backslash-escape any non-ASCII char.
|
|
13
|
+
|
|
14
|
+
``ascii_safe("1.18-1.30× ↑")`` -> ``"1.18-1.30\\xd7 \\u2191"``.
|
|
15
|
+
"""
|
|
16
|
+
return str(s).encode("ascii", "backslashreplace").decode("ascii")
|
|
@@ -0,0 +1,171 @@
|
|
|
1
|
+
"""Final-PDF sanity check via ``pdfinfo``.
|
|
2
|
+
|
|
3
|
+
Checks the rendered PDF is exactly what was asked for:
|
|
4
|
+
|
|
5
|
+
- **page count == 1** (a multi-page export almost always means the
|
|
6
|
+
canvas size and ``@page { size }`` disagreed)
|
|
7
|
+
- **dimensions match the expected canvas** within ±0.05 in
|
|
8
|
+
(default; ``--dim-tol-in`` to tune)
|
|
9
|
+
- **file size <= --max-size-mb** (overlarge PDFs often mean an
|
|
10
|
+
accidentally embedded raw image or 600 dpi figure)
|
|
11
|
+
|
|
12
|
+
The expected canvas can come from:
|
|
13
|
+
|
|
14
|
+
- ``--canvas '<W>x<H><unit>'`` (e.g. ``60x36in`` / ``A0 portrait``)
|
|
15
|
+
- ``--from-html poster.html`` (parses the same ``@page`` rule the
|
|
16
|
+
HTML uses, so the verification can't drift from the source)
|
|
17
|
+
|
|
18
|
+
Exactly one of those must be supplied — no hardcoded landscape default.
|
|
19
|
+
"""
|
|
20
|
+
from __future__ import annotations
|
|
21
|
+
|
|
22
|
+
import argparse
|
|
23
|
+
import os
|
|
24
|
+
import re
|
|
25
|
+
import subprocess
|
|
26
|
+
import sys
|
|
27
|
+
from pathlib import Path
|
|
28
|
+
from typing import Any
|
|
29
|
+
|
|
30
|
+
from . import canvas as _canvas
|
|
31
|
+
from .textutil import ascii_safe
|
|
32
|
+
|
|
33
|
+
|
|
34
|
+
def _eprint(*args: Any, **kw: Any) -> None:
|
|
35
|
+
print(*args, file=sys.stderr, **kw)
|
|
36
|
+
|
|
37
|
+
|
|
38
|
+
def cmd_verify_final(args: argparse.Namespace) -> int:
|
|
39
|
+
pdf = Path(args.pdf).resolve()
|
|
40
|
+
if not pdf.exists():
|
|
41
|
+
_eprint(f"ERROR: PDF not found: {ascii_safe(pdf)}")
|
|
42
|
+
return 2
|
|
43
|
+
|
|
44
|
+
# Resolve expected canvas.
|
|
45
|
+
if args.canvas is None and args.from_html is None:
|
|
46
|
+
_eprint(
|
|
47
|
+
"ERROR: verify-final needs either `--canvas <W>x<H><unit>` "
|
|
48
|
+
"(e.g. '60x36in' or 'A0 portrait') or `--from-html "
|
|
49
|
+
"<poster.html>` so the expected size can't be wrong by "
|
|
50
|
+
"default."
|
|
51
|
+
)
|
|
52
|
+
return 2
|
|
53
|
+
if args.canvas is not None and args.from_html is not None:
|
|
54
|
+
_eprint(
|
|
55
|
+
"ERROR: --canvas and --from-html are mutually exclusive; "
|
|
56
|
+
"pick one."
|
|
57
|
+
)
|
|
58
|
+
return 2
|
|
59
|
+
if args.canvas is not None:
|
|
60
|
+
exp_w, exp_h = args.canvas
|
|
61
|
+
src = "--canvas"
|
|
62
|
+
else:
|
|
63
|
+
html_path = Path(args.from_html).resolve()
|
|
64
|
+
if not html_path.exists():
|
|
65
|
+
_eprint(f"ERROR: --from-html path not found: {ascii_safe(html_path)}")
|
|
66
|
+
return 2
|
|
67
|
+
parsed = _canvas.read_canvas_from_html(html_path)
|
|
68
|
+
if parsed is None:
|
|
69
|
+
_eprint(
|
|
70
|
+
f"ERROR: no `@page {{ size }}` found in "
|
|
71
|
+
f"{ascii_safe(html_path)}. Fall back to --canvas."
|
|
72
|
+
)
|
|
73
|
+
return 2
|
|
74
|
+
exp_w, exp_h = parsed
|
|
75
|
+
src = f"--from-html ({ascii_safe(html_path.name)})"
|
|
76
|
+
|
|
77
|
+
# Preserve user PATH (Homebrew/conda/etc.) but force C locale so
|
|
78
|
+
# pdfinfo number formatting is consistent across systems.
|
|
79
|
+
env = os.environ.copy()
|
|
80
|
+
env["LC_ALL"] = "C"
|
|
81
|
+
env["LANG"] = "C"
|
|
82
|
+
try:
|
|
83
|
+
out = subprocess.check_output(
|
|
84
|
+
["pdfinfo", str(pdf)],
|
|
85
|
+
text=True, stderr=subprocess.STDOUT, env=env,
|
|
86
|
+
)
|
|
87
|
+
except FileNotFoundError:
|
|
88
|
+
_eprint(
|
|
89
|
+
"ERROR: pdfinfo not installed. Install poppler:\n"
|
|
90
|
+
" Linux: apt install poppler-utils "
|
|
91
|
+
"(or `dnf install poppler-utils`)\n"
|
|
92
|
+
" macOS: brew install poppler\n"
|
|
93
|
+
" Windows: choco install poppler (or download from "
|
|
94
|
+
"poppler-windows)"
|
|
95
|
+
)
|
|
96
|
+
return 2
|
|
97
|
+
except subprocess.CalledProcessError as e:
|
|
98
|
+
_eprint(f"ERROR: pdfinfo failed: {ascii_safe(e.output)}")
|
|
99
|
+
return 2
|
|
100
|
+
|
|
101
|
+
info: dict[str, str] = {}
|
|
102
|
+
for line in out.splitlines():
|
|
103
|
+
if ":" in line:
|
|
104
|
+
k, v = line.split(":", 1)
|
|
105
|
+
info[k.strip()] = v.strip()
|
|
106
|
+
|
|
107
|
+
pages = int(info.get("Pages", "0"))
|
|
108
|
+
page_size = info.get("Page size", "")
|
|
109
|
+
page_rot = int(info.get("Page rot", "0") or "0")
|
|
110
|
+
file_size_b = pdf.stat().st_size
|
|
111
|
+
file_size_mb = file_size_b / (1024 * 1024)
|
|
112
|
+
|
|
113
|
+
print(f"[verify-final] {ascii_safe(pdf)}")
|
|
114
|
+
print(f" expected canvas = {exp_w:.2f}in x {exp_h:.2f}in "
|
|
115
|
+
f"(from {src})")
|
|
116
|
+
print(f" pages = {pages}")
|
|
117
|
+
print(f" page size = {ascii_safe(page_size)}")
|
|
118
|
+
print(f" page rot = {page_rot}")
|
|
119
|
+
print(f" file size = {file_size_mb:.2f} MB")
|
|
120
|
+
|
|
121
|
+
problems: list[str] = []
|
|
122
|
+
|
|
123
|
+
if pages != 1:
|
|
124
|
+
problems.append(f"page count = {pages}, expected 1")
|
|
125
|
+
|
|
126
|
+
# pdfinfo's Page size is in points (1pt = 1/72 in).
|
|
127
|
+
m = re.search(r"([\d.]+)\s*x\s*([\d.]+)\s*pts", page_size)
|
|
128
|
+
if not m:
|
|
129
|
+
problems.append(
|
|
130
|
+
f"could not parse pdfinfo `Page size`: {ascii_safe(page_size)!r}"
|
|
131
|
+
)
|
|
132
|
+
else:
|
|
133
|
+
w_in = float(m.group(1)) / 72.0
|
|
134
|
+
h_in = float(m.group(2)) / 72.0
|
|
135
|
+
print(f" -> {w_in:.2f}in x {h_in:.2f}in")
|
|
136
|
+
tol = args.dim_tol_in
|
|
137
|
+
direct_ok = (
|
|
138
|
+
abs(w_in - exp_w) <= tol and abs(h_in - exp_h) <= tol
|
|
139
|
+
)
|
|
140
|
+
swap_ok = (
|
|
141
|
+
abs(w_in - exp_h) <= tol and abs(h_in - exp_w) <= tol
|
|
142
|
+
)
|
|
143
|
+
allow_swap = args.allow_rotated or page_rot in (90, 270)
|
|
144
|
+
if direct_ok:
|
|
145
|
+
pass
|
|
146
|
+
elif swap_ok and allow_swap:
|
|
147
|
+
print(
|
|
148
|
+
f" (swapped dimensions accepted -- page rot = "
|
|
149
|
+
f"{page_rot}deg"
|
|
150
|
+
+ (" + --allow-rotated" if args.allow_rotated else "")
|
|
151
|
+
+ ")"
|
|
152
|
+
)
|
|
153
|
+
else:
|
|
154
|
+
problems.append(
|
|
155
|
+
f"dimensions {w_in:.2f}x{h_in:.2f}in "
|
|
156
|
+
f"do not match canvas {exp_w}x{exp_h}in "
|
|
157
|
+
f"(tol +/-{tol}in, page rot {page_rot}deg)"
|
|
158
|
+
)
|
|
159
|
+
|
|
160
|
+
if file_size_mb > args.max_size_mb:
|
|
161
|
+
problems.append(
|
|
162
|
+
f"file {file_size_mb:.2f} MB > limit "
|
|
163
|
+
f"{args.max_size_mb} MB"
|
|
164
|
+
)
|
|
165
|
+
|
|
166
|
+
for p in problems:
|
|
167
|
+
_eprint(f" FAIL: {p}")
|
|
168
|
+
if problems:
|
|
169
|
+
return 1
|
|
170
|
+
print("[verify-final] PASS")
|
|
171
|
+
return 0
|