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,1023 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
# install_aris_codex.sh -- Project-local ARIS Codex skill installation.
|
|
3
|
+
#
|
|
4
|
+
# This installer manages a flat Codex project layout:
|
|
5
|
+
# <project>/.agents/skills/<skill-name> -> <aris-repo>/skills/<package>/<skill-name>
|
|
6
|
+
#
|
|
7
|
+
# Managed entries are tracked in:
|
|
8
|
+
# <project>/.aris/installed-skills-codex.txt
|
|
9
|
+
#
|
|
10
|
+
# Default package set:
|
|
11
|
+
# - skills/skills-codex
|
|
12
|
+
#
|
|
13
|
+
# Optional overlays:
|
|
14
|
+
# --with-claude-review-overlay
|
|
15
|
+
# --with-gemini-review-overlay
|
|
16
|
+
#
|
|
17
|
+
# Usage:
|
|
18
|
+
# bash tools/install_aris_codex.sh [project_path] [options]
|
|
19
|
+
#
|
|
20
|
+
# Actions (mutually exclusive, default: auto):
|
|
21
|
+
# default install if no manifest, else reconcile
|
|
22
|
+
# --reconcile explicit reconcile; refuse if no manifest
|
|
23
|
+
# --uninstall remove only entries in manifest; delete manifest
|
|
24
|
+
#
|
|
25
|
+
# Selection (catalog: tools/skill-groups.tsv in the aris-repo):
|
|
26
|
+
# --groups A,B install only these skill groups (see --list-groups)
|
|
27
|
+
# --skills X,Y additionally install these skills (clears declined mark)
|
|
28
|
+
# --exclude X,Y never install these skills (recorded as declined)
|
|
29
|
+
# --all install every upstream skill (legacy default)
|
|
30
|
+
# --add-new reconcile: accept all upstream skills not yet installed
|
|
31
|
+
# --skip-new reconcile: skip new upstream skills without prompting
|
|
32
|
+
# --list-groups print the group catalog and exit
|
|
33
|
+
# With no selection flags: fresh install on a TTY opens a full-screen
|
|
34
|
+
# checkbox picker (Space toggles a skill / a whole group, Enter confirms;
|
|
35
|
+
# ARIS_NO_PICKER=1 or missing python3/curses falls back to per-group
|
|
36
|
+
# Y/n/e prompts); fresh install with --quiet/no TTY installs everything (old behavior).
|
|
37
|
+
# Reconcile keeps exactly what the manifest says is installed; NEW upstream
|
|
38
|
+
# skills need per-skill confirmation (declined ones are remembered in
|
|
39
|
+
# .aris/skills-declined-codex.txt and never re-asked).
|
|
40
|
+
#
|
|
41
|
+
# Options:
|
|
42
|
+
# --aris-repo PATH override repo discovery
|
|
43
|
+
# --with-claude-review-overlay install skills-codex-claude-review on top
|
|
44
|
+
# --with-gemini-review-overlay install skills-codex-gemini-review on top
|
|
45
|
+
# --dry-run show plan, no writes
|
|
46
|
+
# --quiet no prompts
|
|
47
|
+
# --no-doc skip AGENTS.md managed block update
|
|
48
|
+
# --replace-link NAME replace a conflicting symlink for NAME
|
|
49
|
+
# --clear-stale-lock clear a stale installer lock
|
|
50
|
+
|
|
51
|
+
set -euo pipefail
|
|
52
|
+
|
|
53
|
+
MANIFEST_VERSION="1"
|
|
54
|
+
MANIFEST_NAME="installed-skills-codex.txt"
|
|
55
|
+
MANIFEST_PREV_NAME="installed-skills-codex.txt.prev"
|
|
56
|
+
DECLINED_NAME="skills-declined-codex.txt"
|
|
57
|
+
CATALOG_REL="tools/skill-groups.tsv"
|
|
58
|
+
GLOBAL_POINTER="$HOME/.aris/repo"
|
|
59
|
+
ARIS_DIR_NAME=".aris"
|
|
60
|
+
LOCK_DIR_NAME=".install-codex.lock.d"
|
|
61
|
+
SKILLS_REL=".agents/skills"
|
|
62
|
+
DOC_FILE_NAME="AGENTS.md"
|
|
63
|
+
BLOCK_BEGIN="<!-- ARIS-CODEX:BEGIN -->"
|
|
64
|
+
BLOCK_END="<!-- ARIS-CODEX:END -->"
|
|
65
|
+
SAFE_NAME_REGEX='^[A-Za-z0-9][A-Za-z0-9._-]*$'
|
|
66
|
+
BASE_PACKAGE="skills-codex"
|
|
67
|
+
|
|
68
|
+
PROJECT_PATH=""
|
|
69
|
+
ARIS_REPO_OVERRIDE=""
|
|
70
|
+
ACTION="auto"
|
|
71
|
+
DRY_RUN=false
|
|
72
|
+
QUIET=false
|
|
73
|
+
NO_DOC=false
|
|
74
|
+
CLEAR_STALE_LOCK=false
|
|
75
|
+
WITH_CLAUDE_OVERLAY=false
|
|
76
|
+
WITH_GEMINI_OVERLAY=false
|
|
77
|
+
REPLACE_LINK_NAMES=()
|
|
78
|
+
SELECT_GROUPS="" # comma list from --groups
|
|
79
|
+
SELECT_SKILLS="" # comma list from --skills
|
|
80
|
+
EXCLUDE_SKILLS="" # comma list from --exclude
|
|
81
|
+
SELECT_ALL=false
|
|
82
|
+
NEW_POLICY="" # "" (prompt) | add | skip
|
|
83
|
+
LIST_GROUPS=false
|
|
84
|
+
|
|
85
|
+
usage() { sed -n '2,49p' "$0" | sed 's/^# \?//'; }
|
|
86
|
+
|
|
87
|
+
while [[ $# -gt 0 ]]; do
|
|
88
|
+
case "$1" in
|
|
89
|
+
--reconcile) ACTION="reconcile"; shift ;;
|
|
90
|
+
--uninstall) ACTION="uninstall"; shift ;;
|
|
91
|
+
--aris-repo) ARIS_REPO_OVERRIDE="${2:?--aris-repo requires path}"; shift 2 ;;
|
|
92
|
+
--with-claude-review-overlay) WITH_CLAUDE_OVERLAY=true; shift ;;
|
|
93
|
+
--with-gemini-review-overlay) WITH_GEMINI_OVERLAY=true; shift ;;
|
|
94
|
+
--dry-run) DRY_RUN=true; shift ;;
|
|
95
|
+
--quiet) QUIET=true; shift ;;
|
|
96
|
+
--no-doc) NO_DOC=true; shift ;;
|
|
97
|
+
--replace-link) REPLACE_LINK_NAMES+=("${2:?--replace-link requires NAME}"); shift 2 ;;
|
|
98
|
+
--clear-stale-lock) CLEAR_STALE_LOCK=true; shift ;;
|
|
99
|
+
--groups) SELECT_GROUPS="${SELECT_GROUPS:+$SELECT_GROUPS,}${2:?--groups requires A,B,...}"; shift 2 ;;
|
|
100
|
+
--skills) SELECT_SKILLS="${SELECT_SKILLS:+$SELECT_SKILLS,}${2:?--skills requires X,Y,...}"; shift 2 ;;
|
|
101
|
+
--exclude) EXCLUDE_SKILLS="${EXCLUDE_SKILLS:+$EXCLUDE_SKILLS,}${2:?--exclude requires X,Y,...}"; shift 2 ;;
|
|
102
|
+
--all) SELECT_ALL=true; shift ;;
|
|
103
|
+
--add-new) NEW_POLICY="add"; shift ;;
|
|
104
|
+
--skip-new) NEW_POLICY="skip"; shift ;;
|
|
105
|
+
--list-groups) LIST_GROUPS=true; shift ;;
|
|
106
|
+
-h|--help) usage; exit 0 ;;
|
|
107
|
+
--*) echo "Unknown option: $1" >&2; exit 2 ;;
|
|
108
|
+
*)
|
|
109
|
+
if [[ -z "$PROJECT_PATH" ]]; then
|
|
110
|
+
PROJECT_PATH="$1"
|
|
111
|
+
else
|
|
112
|
+
echo "Error: unexpected positional argument: $1" >&2
|
|
113
|
+
exit 2
|
|
114
|
+
fi
|
|
115
|
+
shift
|
|
116
|
+
;;
|
|
117
|
+
esac
|
|
118
|
+
done
|
|
119
|
+
|
|
120
|
+
if $SELECT_ALL && [[ -n "$SELECT_GROUPS$SELECT_SKILLS" ]]; then
|
|
121
|
+
echo "Error: --all cannot be combined with --groups/--skills (only --exclude)" >&2; exit 2
|
|
122
|
+
fi
|
|
123
|
+
|
|
124
|
+
log() { $QUIET && return 0; echo "$@"; }
|
|
125
|
+
warn() { echo "warning: $*" >&2; }
|
|
126
|
+
die() { echo "error: $*" >&2; exit 1; }
|
|
127
|
+
prompt() { $QUIET && return 0; printf "%s " "$1" >&2; read -r REPLY; [[ "$REPLY" =~ ^[Yy]$ ]]; }
|
|
128
|
+
abs_path() { ( cd "$1" 2>/dev/null && pwd ) || return 1; }
|
|
129
|
+
is_safe_name() { [[ "$1" =~ $SAFE_NAME_REGEX ]]; }
|
|
130
|
+
is_symlink() { [[ -L "$1" ]]; }
|
|
131
|
+
name_in_replace_allowlist() {
|
|
132
|
+
local needle="$1"
|
|
133
|
+
local item
|
|
134
|
+
# bash 3.2: empty-array "${ARR[@]}" trips `set -u`; no --replace-link = empty allowlist
|
|
135
|
+
[[ ${#REPLACE_LINK_NAMES[@]} -gt 0 ]] || return 1
|
|
136
|
+
for item in "${REPLACE_LINK_NAMES[@]}"; do
|
|
137
|
+
[[ "$item" == "$needle" ]] && return 0
|
|
138
|
+
done
|
|
139
|
+
return 1
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
read_link_target() {
|
|
143
|
+
if command -v greadlink >/dev/null 2>&1; then greadlink "$1"
|
|
144
|
+
else readlink "$1"; fi
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
canonicalize() {
|
|
148
|
+
if command -v greadlink >/dev/null 2>&1; then greadlink -f "$1" 2>/dev/null || true
|
|
149
|
+
elif readlink -f "$1" 2>/dev/null; then :
|
|
150
|
+
else
|
|
151
|
+
local d f
|
|
152
|
+
if [[ -d "$1" ]]; then
|
|
153
|
+
( cd "$1" && pwd )
|
|
154
|
+
else
|
|
155
|
+
d="$(dirname "$1")"
|
|
156
|
+
f="$(basename "$1")"
|
|
157
|
+
( cd "$d" 2>/dev/null && echo "$(pwd)/$f" )
|
|
158
|
+
fi
|
|
159
|
+
fi
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
resolve_aris_repo() {
|
|
163
|
+
local p
|
|
164
|
+
if [[ -n "$ARIS_REPO_OVERRIDE" ]]; then
|
|
165
|
+
p="$(abs_path "$ARIS_REPO_OVERRIDE")" || die "--aris-repo path not found: $ARIS_REPO_OVERRIDE"
|
|
166
|
+
else
|
|
167
|
+
local script_dir parent guess
|
|
168
|
+
script_dir="$(cd "$(dirname "$0")" && pwd)"
|
|
169
|
+
parent="$(cd "$script_dir/.." && pwd)"
|
|
170
|
+
if [[ -d "$parent/skills/$BASE_PACKAGE" ]]; then
|
|
171
|
+
p="$parent"
|
|
172
|
+
elif [[ -n "${ARIS_REPO:-}" && -d "$ARIS_REPO/skills/$BASE_PACKAGE" ]]; then
|
|
173
|
+
p="$(abs_path "$ARIS_REPO")"
|
|
174
|
+
else
|
|
175
|
+
for guess in \
|
|
176
|
+
"$HOME/Desktop/Auto-claude-code-research-in-sleep" \
|
|
177
|
+
"$HOME/Auto-claude-code-research-in-sleep" \
|
|
178
|
+
"$HOME/aris_repo" \
|
|
179
|
+
"$HOME/.codex/Auto-claude-code-research-in-sleep"; do
|
|
180
|
+
if [[ -d "$guess/skills/$BASE_PACKAGE" ]]; then
|
|
181
|
+
p="$(abs_path "$guess")"
|
|
182
|
+
break
|
|
183
|
+
fi
|
|
184
|
+
done
|
|
185
|
+
fi
|
|
186
|
+
fi
|
|
187
|
+
[[ -n "${p:-}" ]] || die "cannot find ARIS repo with skills/$BASE_PACKAGE. Use --aris-repo PATH."
|
|
188
|
+
[[ -d "$p/skills/$BASE_PACKAGE" ]] || die "repo missing skills/$BASE_PACKAGE: $p"
|
|
189
|
+
echo "$p"
|
|
190
|
+
}
|
|
191
|
+
|
|
192
|
+
selected_packages() {
|
|
193
|
+
local packages=("$BASE_PACKAGE")
|
|
194
|
+
$WITH_CLAUDE_OVERLAY && packages+=("skills-codex-claude-review")
|
|
195
|
+
$WITH_GEMINI_OVERLAY && packages+=("skills-codex-gemini-review")
|
|
196
|
+
printf "%s\n" "${packages[@]}"
|
|
197
|
+
}
|
|
198
|
+
|
|
199
|
+
build_upstream_inventory() {
|
|
200
|
+
local repo="$1" out="$2"
|
|
201
|
+
local package package_dir d name kind source_rel tmp
|
|
202
|
+
tmp="$(mktemp -t aris-codex-upstream-raw.XXXX)"
|
|
203
|
+
: > "$out"
|
|
204
|
+
: > "$tmp"
|
|
205
|
+
|
|
206
|
+
while IFS= read -r package; do
|
|
207
|
+
[[ -z "$package" ]] && continue
|
|
208
|
+
package_dir="$repo/skills/$package"
|
|
209
|
+
[[ -d "$package_dir" ]] || die "selected package missing: $package_dir"
|
|
210
|
+
for d in "$package_dir"/*; do
|
|
211
|
+
[[ -d "$d" ]] || continue
|
|
212
|
+
name="$(basename "$d")"
|
|
213
|
+
is_safe_name "$name" || { warn "skipping unsafe upstream name: $name"; continue; }
|
|
214
|
+
if [[ "$name" == "shared-references" ]]; then
|
|
215
|
+
kind="support"
|
|
216
|
+
elif [[ -f "$d/SKILL.md" ]]; then
|
|
217
|
+
kind="skill"
|
|
218
|
+
else
|
|
219
|
+
continue
|
|
220
|
+
fi
|
|
221
|
+
source_rel="skills/$package/$name"
|
|
222
|
+
printf "%s|%s|%s\n" "$kind" "$name" "$source_rel" >> "$tmp"
|
|
223
|
+
done
|
|
224
|
+
done < <(selected_packages)
|
|
225
|
+
|
|
226
|
+
if [[ ! -s "$tmp" ]]; then
|
|
227
|
+
rm -f "$tmp"
|
|
228
|
+
die "upstream inventory empty"
|
|
229
|
+
fi
|
|
230
|
+
|
|
231
|
+
# Keep the last entry for duplicate names so overlays override the base
|
|
232
|
+
# package, then sort by skill/support name for deterministic plans.
|
|
233
|
+
awk -F'|' '{row[$2]=$0} END {for (name in row) print row[name]}' "$tmp" | sort -t'|' -k2,2 > "$out"
|
|
234
|
+
rm -f "$tmp"
|
|
235
|
+
}
|
|
236
|
+
|
|
237
|
+
# --- Selective install (#366, ported from install_aris.sh) ---
|
|
238
|
+
# Upstream rows here are 3-field (kind|name|source_rel) because a name may be
|
|
239
|
+
# sourced from the base package or an overlay; catalog skill names match the
|
|
240
|
+
# mainline skill names 1:1 (mirror directories share names with skills/<name>).
|
|
241
|
+
|
|
242
|
+
catalog_ok() { [[ -n "${CATALOG_PATH:-}" && -f "$CATALOG_PATH" ]]; }
|
|
243
|
+
catalog_groups() { awk -F'\t' '$1=="group"{print $2 "\t" $3 "\t" $4}' "$CATALOG_PATH"; }
|
|
244
|
+
catalog_group_of() { awk -F'\t' -v s="$1" '$1=="skill" && $2==s {print $3; exit}' "$CATALOG_PATH"; }
|
|
245
|
+
catalog_desc_of() { awk -F'\t' -v s="$1" '$1=="skill" && $2==s {print (NF>=5?$5:""); exit}' "$CATALOG_PATH"; }
|
|
246
|
+
catalog_requires() { awk -F'\t' -v s="$1" '$1=="skill" && $2==s && $4!="-" {print $4; exit}' "$CATALOG_PATH" | tr ',' '\n'; }
|
|
247
|
+
catalog_skills_in_group() { awk -F'\t' -v g="$1" '$1=="skill" && $3==g {print $2}' "$CATALOG_PATH"; }
|
|
248
|
+
catalog_has_skill() { awk -F'\t' -v s="$1" '$1=="skill" && $2==s {found=1; exit} END{exit !found}' "$CATALOG_PATH"; }
|
|
249
|
+
|
|
250
|
+
in_file() { grep -qxF "$1" "$2" 2>/dev/null; }
|
|
251
|
+
upstream_has_skill() { grep -q "^skill|$1|" "$2"; }
|
|
252
|
+
|
|
253
|
+
print_group_catalog() {
|
|
254
|
+
catalog_ok || die "skill catalog not found: ${CATALOG_PATH:-<unset>}"
|
|
255
|
+
echo "Skill groups (from $CATALOG_PATH):"
|
|
256
|
+
local gid display desc n
|
|
257
|
+
while IFS=$'\t' read -r gid display desc; do
|
|
258
|
+
n=$(catalog_skills_in_group "$gid" | wc -l | tr -d ' ')
|
|
259
|
+
printf "\n %-14s %s — %s [%s skills]\n" "$gid" "$display" "$desc" "$n"
|
|
260
|
+
catalog_skills_in_group "$gid" | sed 's/^/ /'
|
|
261
|
+
done < <(catalog_groups)
|
|
262
|
+
}
|
|
263
|
+
|
|
264
|
+
load_declined() { # $1 = out file
|
|
265
|
+
: > "$1"
|
|
266
|
+
[[ -f "$DECLINED_PATH" ]] || return 0
|
|
267
|
+
grep -v '^[[:space:]]*$' "$DECLINED_PATH" >> "$1" || true
|
|
268
|
+
}
|
|
269
|
+
|
|
270
|
+
save_declined() { # $1 = candidates file, $2 = selected file
|
|
271
|
+
$DRY_RUN && return 0
|
|
272
|
+
mkdir -p "$PROJECT_ARIS_DIR"
|
|
273
|
+
local tmp="$DECLINED_PATH.tmp.$$"
|
|
274
|
+
sort -u "$1" | grep -v '^$' | grep -vxF -f "$2" > "$tmp" || true
|
|
275
|
+
if [[ -s "$tmp" || -f "$DECLINED_PATH" ]]; then
|
|
276
|
+
mv -f "$tmp" "$DECLINED_PATH"
|
|
277
|
+
else
|
|
278
|
+
rm -f "$tmp"
|
|
279
|
+
fi
|
|
280
|
+
}
|
|
281
|
+
|
|
282
|
+
# Auto-include hard pipeline deps (catalog `requires` column, transitively).
|
|
283
|
+
expand_deps() { # $1 = selected file, $2 = excludes file, $3 = upstream file
|
|
284
|
+
catalog_ok || return 0
|
|
285
|
+
local changed=1 name dep
|
|
286
|
+
while (( changed )); do
|
|
287
|
+
changed=0
|
|
288
|
+
for name in $(cat "$1"); do
|
|
289
|
+
for dep in $(catalog_requires "$name"); do
|
|
290
|
+
in_file "$dep" "$1" && continue
|
|
291
|
+
if in_file "$dep" "$2"; then
|
|
292
|
+
warn "'$name' requires '$dep' but it is excluded — that pipeline phase will break"
|
|
293
|
+
continue
|
|
294
|
+
fi
|
|
295
|
+
upstream_has_skill "$dep" "$3" || continue
|
|
296
|
+
echo "$dep" >> "$1"
|
|
297
|
+
log " ↳ auto-including '$dep' (required by '$name')"
|
|
298
|
+
changed=1
|
|
299
|
+
done
|
|
300
|
+
done
|
|
301
|
+
done
|
|
302
|
+
}
|
|
303
|
+
|
|
304
|
+
# Interactive selection (fresh install on a TTY, no selection flags).
|
|
305
|
+
# Preferred UI: full-screen checkbox picker (tools/skill_picker.py, curses) —
|
|
306
|
+
# Space toggles a skill / a whole group, Enter confirms, q aborts. Falls back
|
|
307
|
+
# to the classic per-group Y/n/e prompts when python3/curses/tty are
|
|
308
|
+
# unavailable or ARIS_NO_PICKER=1 is set.
|
|
309
|
+
interactive_select() { # $1 = upstream file, $2 = out (selected) file
|
|
310
|
+
if [[ "${ARIS_NO_PICKER:-0}" != "1" ]] && command -v python3 >/dev/null 2>&1 \
|
|
311
|
+
&& [[ -f "$ARIS_REPO/tools/skill_picker.py" ]]; then
|
|
312
|
+
local avail_f rc=0
|
|
313
|
+
avail_f="$(mktemp -t aris-avail.XXXX)"
|
|
314
|
+
grep '^skill|' "$1" | cut -d'|' -f2 > "$avail_f" || true
|
|
315
|
+
python3 "$ARIS_REPO/tools/skill_picker.py" \
|
|
316
|
+
--catalog "$CATALOG_PATH" --available "$avail_f" --out "$2" \
|
|
317
|
+
</dev/tty >/dev/tty || rc=$?
|
|
318
|
+
rm -f "$avail_f"
|
|
319
|
+
if [[ $rc -eq 0 ]]; then return 0
|
|
320
|
+
elif [[ $rc -eq 1 ]]; then die "interactive selection aborted"
|
|
321
|
+
fi
|
|
322
|
+
# rc=2 (or unexpected): picker unusable — fall through to prompts.
|
|
323
|
+
warn "checkbox picker unavailable — using per-group prompts"
|
|
324
|
+
fi
|
|
325
|
+
log ""
|
|
326
|
+
log "Interactive skill selection — per group: Y=install all, n=skip, e=pick per skill."
|
|
327
|
+
local gid display desc n reply r2 name glist
|
|
328
|
+
glist="$(mktemp -t aris-codex-glist.XXXX)"
|
|
329
|
+
while IFS=$'\t' read -r gid display desc; do
|
|
330
|
+
catalog_skills_in_group "$gid" | while read -r name; do
|
|
331
|
+
upstream_has_skill "$name" "$1" && echo "$name"
|
|
332
|
+
done > "$glist" || true
|
|
333
|
+
n=$(wc -l < "$glist" | tr -d ' ')
|
|
334
|
+
(( n == 0 )) && continue
|
|
335
|
+
printf "\n%s (%s) — %s\n" "$display" "$gid" "$desc" >&2
|
|
336
|
+
sed 's/^/ /' "$glist" >&2
|
|
337
|
+
printf "Install group '%s' (%s skills)? [Y/n/e] " "$gid" "$n" >&2
|
|
338
|
+
read -r reply </dev/tty
|
|
339
|
+
case "$reply" in
|
|
340
|
+
[nN]*) : ;;
|
|
341
|
+
[eE]*)
|
|
342
|
+
while read -r name; do
|
|
343
|
+
printf " install %-30s [Y/n] " "$name" >&2
|
|
344
|
+
read -r r2 </dev/tty
|
|
345
|
+
[[ "$r2" =~ ^[nN] ]] || echo "$name" >> "$2"
|
|
346
|
+
done < "$glist"
|
|
347
|
+
;;
|
|
348
|
+
*) cat "$glist" >> "$2" ;;
|
|
349
|
+
esac
|
|
350
|
+
done < <(catalog_groups)
|
|
351
|
+
# Upstream skills the catalog doesn't know yet (catalog drift): never drop silently.
|
|
352
|
+
local ungrouped; ungrouped="$(mktemp -t aris-codex-ungrouped.XXXX)"
|
|
353
|
+
grep '^skill|' "$1" | cut -d'|' -f2 | while read -r name; do
|
|
354
|
+
catalog_has_skill "$name" || echo "$name"
|
|
355
|
+
done > "$ungrouped" || true
|
|
356
|
+
if [[ -s "$ungrouped" ]]; then
|
|
357
|
+
printf "\nSkills not in the catalog yet:\n" >&2
|
|
358
|
+
sed 's/^/ /' "$ungrouped" >&2
|
|
359
|
+
while read -r name; do
|
|
360
|
+
printf " install %-30s [Y/n] " "$name" >&2
|
|
361
|
+
read -r r2 </dev/tty
|
|
362
|
+
[[ "$r2" =~ ^[nN] ]] || echo "$name" >> "$2"
|
|
363
|
+
done < "$ungrouped"
|
|
364
|
+
fi
|
|
365
|
+
rm -f "$glist" "$ungrouped"
|
|
366
|
+
}
|
|
367
|
+
|
|
368
|
+
# Validate --groups/--skills names against catalog + upstream.
|
|
369
|
+
validate_selection_flags() { # $1 = upstream file
|
|
370
|
+
local g s
|
|
371
|
+
if [[ -n "$SELECT_GROUPS" ]]; then
|
|
372
|
+
catalog_ok || die "--groups needs the catalog at $CATALOG_PATH (update your aris-repo clone)"
|
|
373
|
+
for g in $(echo "$SELECT_GROUPS" | tr ',' ' '); do
|
|
374
|
+
catalog_groups | cut -f1 | grep -qxF "$g" \
|
|
375
|
+
|| die "unknown group '$g' — run with --list-groups to see valid ids"
|
|
376
|
+
done
|
|
377
|
+
fi
|
|
378
|
+
for s in $(echo "$SELECT_SKILLS" | tr ',' ' '); do
|
|
379
|
+
upstream_has_skill "$s" "$1" || die "unknown skill '$s' (not an upstream skill)"
|
|
380
|
+
done
|
|
381
|
+
}
|
|
382
|
+
|
|
383
|
+
# Build the selected-skill set (one name per line in $3).
|
|
384
|
+
build_selection() { # $1 = upstream file, $2 = declined-candidates out file, $3 = selected out file
|
|
385
|
+
local upstream="$1" declined_out="$2" out="$3"
|
|
386
|
+
: > "$out"
|
|
387
|
+
load_declined "$declined_out"
|
|
388
|
+
|
|
389
|
+
local excl; excl="$(mktemp -t aris-codex-excl.XXXX)"
|
|
390
|
+
echo "$EXCLUDE_SKILLS" | tr ',' '\n' | grep -v '^$' > "$excl" || true
|
|
391
|
+
cat "$excl" >> "$declined_out"
|
|
392
|
+
|
|
393
|
+
validate_selection_flags "$upstream"
|
|
394
|
+
|
|
395
|
+
local has_selection_flags=false
|
|
396
|
+
[[ -n "$SELECT_GROUPS$SELECT_SKILLS" ]] && has_selection_flags=true
|
|
397
|
+
local fresh=true
|
|
398
|
+
[[ -f "$MANIFEST_PATH" ]] && fresh=false
|
|
399
|
+
|
|
400
|
+
local name g subset_choice=false
|
|
401
|
+
if $fresh; then
|
|
402
|
+
if $SELECT_ALL || { ! $has_selection_flags && { $QUIET || [[ ! -t 0 ]]; }; }; then
|
|
403
|
+
grep '^skill|' "$upstream" | cut -d'|' -f2 > "$out"
|
|
404
|
+
elif $has_selection_flags; then
|
|
405
|
+
subset_choice=true
|
|
406
|
+
for g in $(echo "$SELECT_GROUPS" | tr ',' ' '); do
|
|
407
|
+
catalog_skills_in_group "$g" | while read -r name; do
|
|
408
|
+
upstream_has_skill "$name" "$upstream" && echo "$name"
|
|
409
|
+
done >> "$out" || true
|
|
410
|
+
done
|
|
411
|
+
echo "$SELECT_SKILLS" | tr ',' '\n' | grep -v '^$' >> "$out" || true
|
|
412
|
+
elif catalog_ok; then
|
|
413
|
+
subset_choice=true
|
|
414
|
+
interactive_select "$upstream" "$out"
|
|
415
|
+
else
|
|
416
|
+
warn "catalog missing at $CATALOG_PATH — falling back to full install"
|
|
417
|
+
grep '^skill|' "$upstream" | cut -d'|' -f2 > "$out"
|
|
418
|
+
fi
|
|
419
|
+
# Explicit subset choice ⇒ remember the rest as declined (won't re-ask).
|
|
420
|
+
if $subset_choice; then
|
|
421
|
+
grep '^skill|' "$upstream" | cut -d'|' -f2 | grep -vxF -f "$out" >> "$declined_out" 2>/dev/null || true
|
|
422
|
+
fi
|
|
423
|
+
else
|
|
424
|
+
# Reconcile: installed set = manifest ∩ upstream (auto-detected).
|
|
425
|
+
manifest_names "$MANIFEST_DATA" | while read -r name; do
|
|
426
|
+
[[ "$(manifest_kind_of "$MANIFEST_DATA" "$name")" == "skill" ]] || continue
|
|
427
|
+
upstream_has_skill "$name" "$upstream" && echo "$name"
|
|
428
|
+
done >> "$out" || true
|
|
429
|
+
# Flag-based additions re-enable previously declined skills.
|
|
430
|
+
for g in $(echo "$SELECT_GROUPS" | tr ',' ' '); do
|
|
431
|
+
catalog_skills_in_group "$g" | while read -r name; do
|
|
432
|
+
upstream_has_skill "$name" "$upstream" && echo "$name"
|
|
433
|
+
done >> "$out" || true
|
|
434
|
+
done
|
|
435
|
+
echo "$SELECT_SKILLS" | tr ',' '\n' | grep -v '^$' >> "$out" || true
|
|
436
|
+
# NEW upstream skills: not installed, not declined, not just selected.
|
|
437
|
+
local new_file; new_file="$(mktemp -t aris-codex-new.XXXX)"
|
|
438
|
+
grep '^skill|' "$upstream" | cut -d'|' -f2 | while read -r name; do
|
|
439
|
+
in_file "$name" "$out" && continue
|
|
440
|
+
in_file "$name" "$declined_out" && continue
|
|
441
|
+
echo "$name"
|
|
442
|
+
done > "$new_file" || true
|
|
443
|
+
if [[ -s "$new_file" ]]; then
|
|
444
|
+
if $SELECT_ALL || [[ "$NEW_POLICY" == "add" ]]; then
|
|
445
|
+
cat "$new_file" >> "$out"
|
|
446
|
+
log "→ adding $(wc -l < "$new_file" | tr -d ' ') new upstream skill(s) (--all/--add-new)"
|
|
447
|
+
elif [[ "$NEW_POLICY" == "skip" ]] || $QUIET || [[ ! -t 0 ]]; then
|
|
448
|
+
log ""
|
|
449
|
+
log "New upstream skills NOT installed (rerun without --skip-new/--quiet to be asked,"
|
|
450
|
+
log "or pass --add-new / --skills NAME):"
|
|
451
|
+
sed 's/^/ /' "$new_file" | while read -r l; do log "$l"; done
|
|
452
|
+
else
|
|
453
|
+
log ""
|
|
454
|
+
log "New skills appeared upstream since your last install:"
|
|
455
|
+
local reply grp sdesc
|
|
456
|
+
while read -r name; do
|
|
457
|
+
grp="$(catalog_group_of "$name")"
|
|
458
|
+
sdesc="$(catalog_desc_of "$name")"
|
|
459
|
+
printf " install new skill %-30s (group: %s)%s [y/N] " "$name" "${grp:-?}" "${sdesc:+ — $sdesc}" >&2
|
|
460
|
+
read -r reply </dev/tty
|
|
461
|
+
if [[ "$reply" =~ ^[yY] ]]; then echo "$name" >> "$out"
|
|
462
|
+
else echo "$name" >> "$declined_out"
|
|
463
|
+
fi
|
|
464
|
+
done < "$new_file"
|
|
465
|
+
fi
|
|
466
|
+
fi
|
|
467
|
+
rm -f "$new_file"
|
|
468
|
+
fi
|
|
469
|
+
|
|
470
|
+
# Excludes beat every other source (manifest, groups, deps, new skills).
|
|
471
|
+
local pruned
|
|
472
|
+
if [[ -s "$excl" ]]; then
|
|
473
|
+
pruned="$(mktemp -t aris-codex-pruned.XXXX)"
|
|
474
|
+
grep -vxF -f "$excl" "$out" > "$pruned" || true
|
|
475
|
+
mv -f "$pruned" "$out"
|
|
476
|
+
fi
|
|
477
|
+
expand_deps "$out" "$excl" "$upstream"
|
|
478
|
+
sort -u -o "$out" "$out"
|
|
479
|
+
rm -f "$excl"
|
|
480
|
+
[[ -s "$out" ]] || die "selection is empty — nothing to install (use --all or --groups/--skills)"
|
|
481
|
+
}
|
|
482
|
+
|
|
483
|
+
# Keep support entries + selected skills only (upstream rows stay 3-field).
|
|
484
|
+
filter_upstream_by_selection() { # $1 = upstream file, $2 = selected file, $3 = out
|
|
485
|
+
awk -F'|' -v sel="$2" '
|
|
486
|
+
BEGIN { while ((getline line < sel) > 0) picked[line]=1 }
|
|
487
|
+
$1=="support" { print; next }
|
|
488
|
+
$1=="skill" && picked[$2] { print }
|
|
489
|
+
' "$1" > "$3"
|
|
490
|
+
}
|
|
491
|
+
|
|
492
|
+
# Layer-4 helper resolution (#366): a global pointer file lets globally/copy-
|
|
493
|
+
# installed skills find $ARIS_REPO/tools without a per-project install.
|
|
494
|
+
ensure_global_pointer() {
|
|
495
|
+
$DRY_RUN && return 0
|
|
496
|
+
mkdir -p "$(dirname "$GLOBAL_POINTER")" 2>/dev/null || { warn "cannot create $(dirname "$GLOBAL_POINTER") — skipping global pointer"; return 0; }
|
|
497
|
+
local cur=""
|
|
498
|
+
[[ -f "$GLOBAL_POINTER" ]] && cur="$(cat "$GLOBAL_POINTER" 2>/dev/null || true)"
|
|
499
|
+
[[ "$cur" == "$ARIS_REPO" ]] && return 0
|
|
500
|
+
printf '%s\n' "$ARIS_REPO" > "$GLOBAL_POINTER.tmp.$$" && mv -f "$GLOBAL_POINTER.tmp.$$" "$GLOBAL_POINTER"
|
|
501
|
+
log " + global pointer $GLOBAL_POINTER -> $ARIS_REPO"
|
|
502
|
+
}
|
|
503
|
+
|
|
504
|
+
load_manifest() {
|
|
505
|
+
local path="$1" out="$2"
|
|
506
|
+
: > "$out"
|
|
507
|
+
[[ -f "$path" ]] || return 0
|
|
508
|
+
local ver
|
|
509
|
+
ver="$(awk -F'\t' '$1=="version"{print $2}' "$path" | head -1)"
|
|
510
|
+
[[ "$ver" == "$MANIFEST_VERSION" ]] || die "manifest version mismatch (got: ${ver:-none}, expected: $MANIFEST_VERSION)"
|
|
511
|
+
awk -F'\t' '
|
|
512
|
+
BEGIN { in_body=0 }
|
|
513
|
+
/^kind\tname\tsource_rel\ttarget_rel\tmode$/ { in_body=1; next }
|
|
514
|
+
in_body && NF==5 { print }
|
|
515
|
+
' "$path" > "$out"
|
|
516
|
+
}
|
|
517
|
+
|
|
518
|
+
manifest_lookup_target() { awk -F'\t' -v n="$2" '$2==n {print $4; exit}' "$1"; }
|
|
519
|
+
manifest_lookup_source() { awk -F'\t' -v n="$2" '$2==n {print $3; exit}' "$1"; }
|
|
520
|
+
manifest_repo_root() { awk -F'\t' '$1=="repo_root" {print $2; exit}' "$1"; }
|
|
521
|
+
manifest_names() { awk -F'\t' '{print $2}' "$1"; }
|
|
522
|
+
manifest_kind_of() { awk -F'\t' -v n="$2" '$2==n {print $1; exit}' "$1"; }
|
|
523
|
+
|
|
524
|
+
PROJECT_PATH="${PROJECT_PATH:-$(pwd)}"
|
|
525
|
+
[[ -d "$PROJECT_PATH" ]] || die "project path does not exist: $PROJECT_PATH"
|
|
526
|
+
PROJECT_PATH="$(abs_path "$PROJECT_PATH")"
|
|
527
|
+
ARIS_REPO="$(resolve_aris_repo)"
|
|
528
|
+
PROJECT_SKILLS_DIR="$PROJECT_PATH/$SKILLS_REL"
|
|
529
|
+
PROJECT_ARIS_DIR="$PROJECT_PATH/$ARIS_DIR_NAME"
|
|
530
|
+
MANIFEST_PATH="$PROJECT_ARIS_DIR/$MANIFEST_NAME"
|
|
531
|
+
MANIFEST_PREV="$PROJECT_ARIS_DIR/$MANIFEST_PREV_NAME"
|
|
532
|
+
LOCK_DIR="$PROJECT_ARIS_DIR/$LOCK_DIR_NAME"
|
|
533
|
+
DOC_FILE="$PROJECT_PATH/$DOC_FILE_NAME"
|
|
534
|
+
LEGACY_NESTED="$PROJECT_PATH/.agents/skills/aris"
|
|
535
|
+
CATALOG_PATH="$ARIS_REPO/$CATALOG_REL"
|
|
536
|
+
DECLINED_PATH="$PROJECT_ARIS_DIR/$DECLINED_NAME"
|
|
537
|
+
|
|
538
|
+
if $LIST_GROUPS; then
|
|
539
|
+
print_group_catalog
|
|
540
|
+
exit 0
|
|
541
|
+
fi
|
|
542
|
+
|
|
543
|
+
check_no_symlinked_parents() {
|
|
544
|
+
local p
|
|
545
|
+
for p in "$PROJECT_ARIS_DIR" "$PROJECT_PATH/.agents" "$PROJECT_SKILLS_DIR"; do
|
|
546
|
+
if is_symlink "$p"; then
|
|
547
|
+
die "$p is a symlink; refusing to mutate symlinked parent directories"
|
|
548
|
+
fi
|
|
549
|
+
done
|
|
550
|
+
}
|
|
551
|
+
|
|
552
|
+
check_legacy_nested_install() {
|
|
553
|
+
if [[ -e "$LEGACY_NESTED" || -L "$LEGACY_NESTED" ]]; then
|
|
554
|
+
die "legacy nested Codex install detected at $LEGACY_NESTED. Remove or migrate it before using the flat .agents/skills/<name> layout."
|
|
555
|
+
fi
|
|
556
|
+
}
|
|
557
|
+
|
|
558
|
+
write_lock_metadata() {
|
|
559
|
+
cat > "$LOCK_DIR/owner.json" <<EOF
|
|
560
|
+
{"host":"$(hostname)","pid":$$,"started_at":"$(date -u +%Y-%m-%dT%H:%M:%SZ)","tool":"install_aris_codex.sh"}
|
|
561
|
+
EOF
|
|
562
|
+
echo "$$" > "$LOCK_DIR/owner.pid"
|
|
563
|
+
echo "$(hostname)" > "$LOCK_DIR/owner.host"
|
|
564
|
+
}
|
|
565
|
+
|
|
566
|
+
release_lock() {
|
|
567
|
+
[[ -d "$LOCK_DIR" ]] || return 0
|
|
568
|
+
if [[ -f "$LOCK_DIR/owner.pid" && -f "$LOCK_DIR/owner.host" ]]; then
|
|
569
|
+
local pid host
|
|
570
|
+
pid="$(cat "$LOCK_DIR/owner.pid" 2>/dev/null || echo "")"
|
|
571
|
+
host="$(cat "$LOCK_DIR/owner.host" 2>/dev/null || echo "")"
|
|
572
|
+
if [[ "$pid" == "$$" && "$host" == "$(hostname)" ]]; then
|
|
573
|
+
rm -rf "$LOCK_DIR"
|
|
574
|
+
fi
|
|
575
|
+
fi
|
|
576
|
+
}
|
|
577
|
+
|
|
578
|
+
acquire_lock() {
|
|
579
|
+
mkdir -p "$PROJECT_ARIS_DIR"
|
|
580
|
+
if mkdir "$LOCK_DIR" 2>/dev/null; then
|
|
581
|
+
write_lock_metadata
|
|
582
|
+
trap release_lock EXIT INT TERM
|
|
583
|
+
return 0
|
|
584
|
+
fi
|
|
585
|
+
if $CLEAR_STALE_LOCK; then
|
|
586
|
+
warn "removing stale lock: $LOCK_DIR"
|
|
587
|
+
rm -rf "$LOCK_DIR"
|
|
588
|
+
mkdir "$LOCK_DIR" || die "cannot acquire lock after stale clear"
|
|
589
|
+
write_lock_metadata
|
|
590
|
+
trap release_lock EXIT INT TERM
|
|
591
|
+
return 0
|
|
592
|
+
fi
|
|
593
|
+
local owner=""
|
|
594
|
+
[[ -f "$LOCK_DIR/owner.json" ]] && owner="$(cat "$LOCK_DIR/owner.json")"
|
|
595
|
+
die "another install_aris_codex.sh appears to be running (lock: $LOCK_DIR, owner: $owner)"
|
|
596
|
+
}
|
|
597
|
+
|
|
598
|
+
compute_plan() {
|
|
599
|
+
local upstream_file="$1" manifest_data="$2" out="$3"
|
|
600
|
+
local kind name source_rel target_path expected_target current_target in_manifest
|
|
601
|
+
: > "$out"
|
|
602
|
+
|
|
603
|
+
while IFS='|' read -r kind name source_rel; do
|
|
604
|
+
[[ -z "$name" ]] && continue
|
|
605
|
+
target_path="$PROJECT_SKILLS_DIR/$name"
|
|
606
|
+
expected_target="$ARIS_REPO/$source_rel"
|
|
607
|
+
in_manifest=false
|
|
608
|
+
[[ -n "$(manifest_lookup_target "$manifest_data" "$name")" ]] && in_manifest=true
|
|
609
|
+
|
|
610
|
+
if [[ -L "$target_path" ]]; then
|
|
611
|
+
current_target="$(read_link_target "$target_path")"
|
|
612
|
+
[[ "$current_target" != /* ]] && current_target="$(canonicalize "$(dirname "$target_path")/$current_target")"
|
|
613
|
+
if [[ "$current_target" == "$expected_target" ]]; then
|
|
614
|
+
if $in_manifest; then
|
|
615
|
+
printf "REUSE|%s|%s|%s|\n" "$kind" "$name" "$source_rel" >> "$out"
|
|
616
|
+
else
|
|
617
|
+
printf "ADOPT|%s|%s|%s|\n" "$kind" "$name" "$source_rel" >> "$out"
|
|
618
|
+
fi
|
|
619
|
+
elif $in_manifest || name_in_replace_allowlist "$name"; then
|
|
620
|
+
printf "UPDATE_TARGET|%s|%s|%s|%s\n" "$kind" "$name" "$source_rel" "$current_target" >> "$out"
|
|
621
|
+
else
|
|
622
|
+
printf "CONFLICT|%s|%s|%s|symlink_to:%s\n" "$kind" "$name" "$source_rel" "$current_target" >> "$out"
|
|
623
|
+
fi
|
|
624
|
+
elif [[ -e "$target_path" ]]; then
|
|
625
|
+
printf "CONFLICT|%s|%s|%s|real_path\n" "$kind" "$name" "$source_rel" >> "$out"
|
|
626
|
+
else
|
|
627
|
+
printf "CREATE|%s|%s|%s|\n" "$kind" "$name" "$source_rel" >> "$out"
|
|
628
|
+
fi
|
|
629
|
+
done < "$upstream_file"
|
|
630
|
+
|
|
631
|
+
local recorded_repo_root
|
|
632
|
+
recorded_repo_root="$(manifest_repo_root "$MANIFEST_PATH" 2>/dev/null || true)"
|
|
633
|
+
local mkind mname msource mtarget mmode
|
|
634
|
+
while IFS=$'\t' read -r mkind mname msource mtarget mmode; do
|
|
635
|
+
[[ -z "$mname" ]] && continue
|
|
636
|
+
if awk -F'|' -v n="$mname" '$2==n {found=1} END{exit found?0:1}' "$upstream_file"; then
|
|
637
|
+
continue
|
|
638
|
+
fi
|
|
639
|
+
[[ -n "$recorded_repo_root" ]] || die "manifest missing repo_root: $MANIFEST_PATH"
|
|
640
|
+
printf "REMOVE|%s|%s|%s|%s/%s\n" "$mkind" "$mname" "$msource" "$recorded_repo_root" "$msource" >> "$out"
|
|
641
|
+
done < "$manifest_data"
|
|
642
|
+
}
|
|
643
|
+
|
|
644
|
+
print_plan() {
|
|
645
|
+
local plan="$1"
|
|
646
|
+
local action
|
|
647
|
+
log ""
|
|
648
|
+
log "Plan summary:"
|
|
649
|
+
for action in CREATE ADOPT UPDATE_TARGET REUSE REMOVE CONFLICT; do
|
|
650
|
+
log " $action: $(grep -c "^$action|" "$plan" || true)"
|
|
651
|
+
done
|
|
652
|
+
if grep -q '^CONFLICT|' "$plan"; then
|
|
653
|
+
log ""
|
|
654
|
+
log "Conflicts:"
|
|
655
|
+
while IFS='|' read -r _ kind name _source extra; do
|
|
656
|
+
log " - $name ($kind): $extra"
|
|
657
|
+
done < <(grep '^CONFLICT|' "$plan")
|
|
658
|
+
fi
|
|
659
|
+
}
|
|
660
|
+
|
|
661
|
+
write_manifest_tmp() {
|
|
662
|
+
local plan="$1" out="$2"
|
|
663
|
+
{
|
|
664
|
+
printf "version\t%s\n" "$MANIFEST_VERSION"
|
|
665
|
+
printf "repo_root\t%s\n" "$ARIS_REPO"
|
|
666
|
+
printf "project_root\t%s\n" "$PROJECT_PATH"
|
|
667
|
+
printf "generated\t%s\n" "$(date -u +%Y-%m-%dT%H:%M:%SZ)"
|
|
668
|
+
printf "packages\t%s\n" "$(selected_packages | paste -sd, -)"
|
|
669
|
+
printf "kind\tname\tsource_rel\ttarget_rel\tmode\n"
|
|
670
|
+
awk -F'|' '$1=="REUSE"||$1=="ADOPT"||$1=="CREATE"||$1=="UPDATE_TARGET"{print}' "$plan" \
|
|
671
|
+
| while IFS='|' read -r _ kind name source_rel _extra; do
|
|
672
|
+
printf "%s\t%s\t%s\t%s/%s\tsymlink\n" "$kind" "$name" "$source_rel" "$SKILLS_REL" "$name"
|
|
673
|
+
done
|
|
674
|
+
} > "$out"
|
|
675
|
+
}
|
|
676
|
+
|
|
677
|
+
apply_plan() {
|
|
678
|
+
local plan="$1"
|
|
679
|
+
local action kind name source_rel extra target_path expected_target current_target
|
|
680
|
+
mkdir -p "$PROJECT_SKILLS_DIR"
|
|
681
|
+
while IFS='|' read -r action kind name source_rel extra; do
|
|
682
|
+
[[ -z "$name" ]] && continue
|
|
683
|
+
target_path="$PROJECT_SKILLS_DIR/$name"
|
|
684
|
+
expected_target="$ARIS_REPO/$source_rel"
|
|
685
|
+
case "$action" in
|
|
686
|
+
REUSE|ADOPT)
|
|
687
|
+
:
|
|
688
|
+
;;
|
|
689
|
+
CREATE)
|
|
690
|
+
if [[ -e "$target_path" || -L "$target_path" ]]; then
|
|
691
|
+
die "path appeared during install: $target_path"
|
|
692
|
+
fi
|
|
693
|
+
if $DRY_RUN; then
|
|
694
|
+
log " (dry-run) ln -s $expected_target $target_path"
|
|
695
|
+
else
|
|
696
|
+
ln -s "$expected_target" "$target_path"
|
|
697
|
+
log " + $name"
|
|
698
|
+
fi
|
|
699
|
+
;;
|
|
700
|
+
UPDATE_TARGET)
|
|
701
|
+
if [[ -L "$target_path" ]]; then
|
|
702
|
+
current_target="$(read_link_target "$target_path")"
|
|
703
|
+
[[ "$current_target" != /* ]] && current_target="$(canonicalize "$(dirname "$target_path")/$current_target")"
|
|
704
|
+
else
|
|
705
|
+
current_target=""
|
|
706
|
+
fi
|
|
707
|
+
if [[ "$current_target" != "$extra" ]]; then
|
|
708
|
+
die "symlink target changed during install for $name (expected: $extra, got: ${current_target:-missing})"
|
|
709
|
+
fi
|
|
710
|
+
if $DRY_RUN; then
|
|
711
|
+
log " (dry-run) relink $target_path -> $expected_target"
|
|
712
|
+
else
|
|
713
|
+
rm -f "$target_path"
|
|
714
|
+
ln -s "$expected_target" "$target_path"
|
|
715
|
+
log " ↻ $name"
|
|
716
|
+
fi
|
|
717
|
+
;;
|
|
718
|
+
REMOVE)
|
|
719
|
+
[[ -n "$extra" ]] || die "remove action missing recorded target for $name"
|
|
720
|
+
if [[ -L "$target_path" ]]; then
|
|
721
|
+
current_target="$(read_link_target "$target_path")"
|
|
722
|
+
[[ "$current_target" != /* ]] && current_target="$(canonicalize "$(dirname "$target_path")/$current_target")"
|
|
723
|
+
if [[ "$current_target" == "$extra" ]]; then
|
|
724
|
+
if $DRY_RUN; then
|
|
725
|
+
log " (dry-run) rm $target_path"
|
|
726
|
+
else
|
|
727
|
+
rm -f "$target_path"
|
|
728
|
+
log " - $name"
|
|
729
|
+
fi
|
|
730
|
+
else
|
|
731
|
+
die "refusing to remove $name; target changed during reconcile (expected: $extra, got: $current_target)"
|
|
732
|
+
fi
|
|
733
|
+
elif [[ -e "$target_path" ]]; then
|
|
734
|
+
die "refusing to remove $name; target path is no longer a symlink"
|
|
735
|
+
else
|
|
736
|
+
log " - $name (already removed)"
|
|
737
|
+
fi
|
|
738
|
+
;;
|
|
739
|
+
CONFLICT)
|
|
740
|
+
die "conflict reached apply phase for $name"
|
|
741
|
+
;;
|
|
742
|
+
esac
|
|
743
|
+
done < "$plan"
|
|
744
|
+
}
|
|
745
|
+
|
|
746
|
+
commit_manifest() {
|
|
747
|
+
local manifest_tmp="$1"
|
|
748
|
+
if $DRY_RUN; then
|
|
749
|
+
log " (dry-run) would commit manifest"
|
|
750
|
+
return 0
|
|
751
|
+
fi
|
|
752
|
+
mkdir -p "$PROJECT_ARIS_DIR"
|
|
753
|
+
if [[ -f "$MANIFEST_PATH" ]]; then
|
|
754
|
+
cp -p "$MANIFEST_PATH" "$MANIFEST_PREV.tmp"
|
|
755
|
+
mv -f "$MANIFEST_PREV.tmp" "$MANIFEST_PREV"
|
|
756
|
+
fi
|
|
757
|
+
mv -f "$manifest_tmp" "$MANIFEST_PATH"
|
|
758
|
+
}
|
|
759
|
+
|
|
760
|
+
update_agents_doc() {
|
|
761
|
+
local installed_names_file="$1"
|
|
762
|
+
$NO_DOC && return 0
|
|
763
|
+
local original=""
|
|
764
|
+
[[ -f "$DOC_FILE" ]] && original="$(cat "$DOC_FILE")"
|
|
765
|
+
local count packages_csv new_block new_content tmp current
|
|
766
|
+
count="$(wc -l < "$installed_names_file" | tr -d ' ')"
|
|
767
|
+
packages_csv="$(selected_packages | paste -sd, -)"
|
|
768
|
+
local repo_lookup_cmd
|
|
769
|
+
repo_lookup_cmd="ARIS_REPO=\$(awk -F'\\t' '\$1==\"repo_root\"{print \$2; exit}' \"$PROJECT_PATH/$ARIS_DIR_NAME/$MANIFEST_NAME\")"
|
|
770
|
+
new_block="$BLOCK_BEGIN
|
|
771
|
+
## ARIS Codex Skill Scope
|
|
772
|
+
ARIS Codex packages installed in this project: $packages_csv
|
|
773
|
+
Managed entries: $count
|
|
774
|
+
Manifest: \`$ARIS_DIR_NAME/$MANIFEST_NAME\`
|
|
775
|
+
ARIS repo root: \`$ARIS_REPO\`
|
|
776
|
+
Project skill path: \`$SKILLS_REL/<skill-name>\`
|
|
777
|
+
For ARIS Codex workflows, prefer the project-local skills under \`$SKILLS_REL/\`.
|
|
778
|
+
When a skill needs ARIS helper scripts, resolve the repo root from the manifest or set it explicitly:
|
|
779
|
+
\`$repo_lookup_cmd\`
|
|
780
|
+
Do not edit or delete symlinked skills in place; update upstream or rerun:
|
|
781
|
+
\`bash $ARIS_REPO/tools/install_aris_codex.sh \"$PROJECT_PATH\" --reconcile\`
|
|
782
|
+
For copied Codex installs, use:
|
|
783
|
+
\`bash $ARIS_REPO/tools/smart_update_codex.sh --project \"$PROJECT_PATH\"\`
|
|
784
|
+
$BLOCK_END"
|
|
785
|
+
|
|
786
|
+
if printf '%s' "$original" | grep -qF "$BLOCK_BEGIN"; then
|
|
787
|
+
new_content="$(python3 - "$DOC_FILE" "$BLOCK_BEGIN" "$BLOCK_END" "$new_block" <<'PYEOF'
|
|
788
|
+
import pathlib
|
|
789
|
+
import re
|
|
790
|
+
import sys
|
|
791
|
+
|
|
792
|
+
path, begin, end, body = sys.argv[1], sys.argv[2], sys.argv[3], sys.argv[4]
|
|
793
|
+
text = pathlib.Path(path).read_text() if pathlib.Path(path).exists() else ""
|
|
794
|
+
pattern = re.compile(re.escape(begin) + r".*?" + re.escape(end), re.DOTALL)
|
|
795
|
+
matches = pattern.findall(text)
|
|
796
|
+
if len(matches) > 1:
|
|
797
|
+
sys.stderr.write("ARIS-CODEX:WARN multiple managed blocks found; skipping update\n")
|
|
798
|
+
sys.stdout.write(text)
|
|
799
|
+
else:
|
|
800
|
+
sys.stdout.write(pattern.sub(body, text))
|
|
801
|
+
PYEOF
|
|
802
|
+
)" || { warn "AGENTS.md update failed; continuing"; return 0; }
|
|
803
|
+
else
|
|
804
|
+
new_content="$original"
|
|
805
|
+
[[ -n "$new_content" && "${new_content: -1}" != $'\n' ]] && new_content="${new_content}"$'\n'
|
|
806
|
+
new_content="${new_content}${new_block}"$'\n'
|
|
807
|
+
fi
|
|
808
|
+
|
|
809
|
+
if $DRY_RUN; then
|
|
810
|
+
log " (dry-run) would update AGENTS.md managed block"
|
|
811
|
+
return 0
|
|
812
|
+
fi
|
|
813
|
+
|
|
814
|
+
tmp="$DOC_FILE.aris-codex-tmp.$$"
|
|
815
|
+
printf '%s' "$new_content" > "$tmp"
|
|
816
|
+
current=""
|
|
817
|
+
[[ -f "$DOC_FILE" ]] && current="$(cat "$DOC_FILE")"
|
|
818
|
+
if [[ "$current" != "$original" ]]; then
|
|
819
|
+
rm -f "$tmp"
|
|
820
|
+
warn "AGENTS.md changed during install; skipping managed block update"
|
|
821
|
+
return 0
|
|
822
|
+
fi
|
|
823
|
+
mv -f "$tmp" "$DOC_FILE"
|
|
824
|
+
log " ✓ updated AGENTS.md"
|
|
825
|
+
}
|
|
826
|
+
|
|
827
|
+
remove_agents_doc_block() {
|
|
828
|
+
$NO_DOC && return 0
|
|
829
|
+
[[ -f "$DOC_FILE" ]] || return 0
|
|
830
|
+
|
|
831
|
+
local original new_content tmp current
|
|
832
|
+
original="$(cat "$DOC_FILE")"
|
|
833
|
+
if ! printf '%s' "$original" | grep -qF "$BLOCK_BEGIN"; then
|
|
834
|
+
return 0
|
|
835
|
+
fi
|
|
836
|
+
|
|
837
|
+
new_content="$(python3 - "$DOC_FILE" "$BLOCK_BEGIN" "$BLOCK_END" <<'PYEOF'
|
|
838
|
+
import pathlib
|
|
839
|
+
import re
|
|
840
|
+
import sys
|
|
841
|
+
|
|
842
|
+
path, begin, end = sys.argv[1], sys.argv[2], sys.argv[3]
|
|
843
|
+
text = pathlib.Path(path).read_text()
|
|
844
|
+
pattern = re.compile(r"\n?" + re.escape(begin) + r".*?" + re.escape(end) + r"\n?", re.DOTALL)
|
|
845
|
+
matches = pattern.findall(text)
|
|
846
|
+
if len(matches) > 1:
|
|
847
|
+
sys.stderr.write("ARIS-CODEX:WARN multiple managed blocks found; skipping removal\n")
|
|
848
|
+
sys.stdout.write(text)
|
|
849
|
+
else:
|
|
850
|
+
updated = pattern.sub("\n", text)
|
|
851
|
+
sys.stdout.write(updated.lstrip("\n"))
|
|
852
|
+
PYEOF
|
|
853
|
+
)" || { warn "AGENTS.md managed block removal failed; continuing"; return 0; }
|
|
854
|
+
|
|
855
|
+
if $DRY_RUN; then
|
|
856
|
+
log " (dry-run) would remove AGENTS.md managed block"
|
|
857
|
+
return 0
|
|
858
|
+
fi
|
|
859
|
+
|
|
860
|
+
tmp="$DOC_FILE.aris-codex-tmp.$$"
|
|
861
|
+
printf '%s' "$new_content" > "$tmp"
|
|
862
|
+
current="$(cat "$DOC_FILE")"
|
|
863
|
+
if [[ "$current" != "$original" ]]; then
|
|
864
|
+
rm -f "$tmp"
|
|
865
|
+
warn "AGENTS.md changed during uninstall; skipping managed block removal"
|
|
866
|
+
return 0
|
|
867
|
+
fi
|
|
868
|
+
mv -f "$tmp" "$DOC_FILE"
|
|
869
|
+
log " ✓ removed AGENTS.md managed block"
|
|
870
|
+
}
|
|
871
|
+
|
|
872
|
+
do_uninstall() {
|
|
873
|
+
[[ -f "$MANIFEST_PATH" ]] || die "no manifest at $MANIFEST_PATH; nothing to uninstall"
|
|
874
|
+
local manifest_data
|
|
875
|
+
manifest_data="$(mktemp -t aris-codex-manifest.XXXX)"
|
|
876
|
+
load_manifest "$MANIFEST_PATH" "$manifest_data"
|
|
877
|
+
log ""
|
|
878
|
+
log "Uninstall plan:"
|
|
879
|
+
while IFS=$'\t' read -r kind name _source _target _mode; do
|
|
880
|
+
[[ -z "$name" ]] && continue
|
|
881
|
+
log " - $name ($kind)"
|
|
882
|
+
done < "$manifest_data"
|
|
883
|
+
if ! $DRY_RUN; then
|
|
884
|
+
prompt "Proceed?" || { log "aborted"; exit 0; }
|
|
885
|
+
fi
|
|
886
|
+
local kind name source_rel target_rel mode target_path expected_target current_target
|
|
887
|
+
local recorded_repo_root
|
|
888
|
+
recorded_repo_root="$(manifest_repo_root "$MANIFEST_PATH")"
|
|
889
|
+
[[ -n "$recorded_repo_root" ]] || die "manifest missing repo_root: $MANIFEST_PATH"
|
|
890
|
+
while IFS=$'\t' read -r kind name source_rel target_rel mode; do
|
|
891
|
+
[[ -z "$name" ]] && continue
|
|
892
|
+
target_path="$PROJECT_PATH/$target_rel"
|
|
893
|
+
expected_target="$recorded_repo_root/$source_rel"
|
|
894
|
+
if [[ -L "$target_path" ]]; then
|
|
895
|
+
current_target="$(read_link_target "$target_path")"
|
|
896
|
+
[[ "$current_target" != /* ]] && current_target="$(canonicalize "$(dirname "$target_path")/$current_target")"
|
|
897
|
+
if [[ "$current_target" == "$expected_target" ]]; then
|
|
898
|
+
if $DRY_RUN; then
|
|
899
|
+
log " (dry-run) rm $target_path"
|
|
900
|
+
else
|
|
901
|
+
rm -f "$target_path"
|
|
902
|
+
log " - removed $name"
|
|
903
|
+
fi
|
|
904
|
+
else
|
|
905
|
+
warn "skipping $name during uninstall; target changed to $current_target"
|
|
906
|
+
fi
|
|
907
|
+
else
|
|
908
|
+
warn "skipping $name during uninstall; not a symlink"
|
|
909
|
+
fi
|
|
910
|
+
done < "$manifest_data"
|
|
911
|
+
rm -f "$manifest_data"
|
|
912
|
+
if ! $DRY_RUN; then
|
|
913
|
+
mv -f "$MANIFEST_PATH" "$MANIFEST_PREV"
|
|
914
|
+
log " ✓ uninstalled (manifest preserved as $MANIFEST_PREV)"
|
|
915
|
+
fi
|
|
916
|
+
remove_agents_doc_block
|
|
917
|
+
}
|
|
918
|
+
|
|
919
|
+
log ""
|
|
920
|
+
log "ARIS Codex Project Install"
|
|
921
|
+
log " Project: $PROJECT_PATH"
|
|
922
|
+
log " Repo: $ARIS_REPO"
|
|
923
|
+
log " Packages: $(selected_packages | paste -sd, -)"
|
|
924
|
+
log " Action: $ACTION$($DRY_RUN && echo ' (dry-run)')"
|
|
925
|
+
log ""
|
|
926
|
+
|
|
927
|
+
check_no_symlinked_parents
|
|
928
|
+
check_legacy_nested_install
|
|
929
|
+
if ! $DRY_RUN; then
|
|
930
|
+
acquire_lock
|
|
931
|
+
fi
|
|
932
|
+
|
|
933
|
+
if [[ "$ACTION" == "uninstall" ]]; then
|
|
934
|
+
do_uninstall
|
|
935
|
+
exit 0
|
|
936
|
+
fi
|
|
937
|
+
|
|
938
|
+
if [[ "$ACTION" == "reconcile" && ! -f "$MANIFEST_PATH" ]]; then
|
|
939
|
+
die "--reconcile requires existing manifest; none found at $MANIFEST_PATH"
|
|
940
|
+
fi
|
|
941
|
+
|
|
942
|
+
UPSTREAM_FILE="$(mktemp -t aris-codex-upstream.XXXX)"
|
|
943
|
+
build_upstream_inventory "$ARIS_REPO" "$UPSTREAM_FILE"
|
|
944
|
+
|
|
945
|
+
MANIFEST_DATA="$(mktemp -t aris-codex-manifest.XXXX)"
|
|
946
|
+
load_manifest "$MANIFEST_PATH" "$MANIFEST_DATA"
|
|
947
|
+
|
|
948
|
+
# Selective install (#366): build the selected set, then plan against it.
|
|
949
|
+
SELECTED_FILE="$(mktemp -t aris-codex-selected.XXXX)"
|
|
950
|
+
DECLINED_CANDIDATES="$(mktemp -t aris-codex-declined.XXXX)"
|
|
951
|
+
build_selection "$UPSTREAM_FILE" "$DECLINED_CANDIDATES" "$SELECTED_FILE"
|
|
952
|
+
SELECTED_UPSTREAM="$(mktemp -t aris-codex-upstream-sel.XXXX)"
|
|
953
|
+
filter_upstream_by_selection "$UPSTREAM_FILE" "$SELECTED_FILE" "$SELECTED_UPSTREAM"
|
|
954
|
+
N_SELECTED=$(grep -c '^skill|' "$SELECTED_UPSTREAM" || true)
|
|
955
|
+
N_UPSTREAM=$(grep -c '^skill|' "$UPSTREAM_FILE" || true)
|
|
956
|
+
log ""
|
|
957
|
+
log "Selection: $N_SELECTED of $N_UPSTREAM upstream skills"
|
|
958
|
+
|
|
959
|
+
PLAN_FILE="$(mktemp -t aris-codex-plan.XXXX)"
|
|
960
|
+
compute_plan "$SELECTED_UPSTREAM" "$MANIFEST_DATA" "$PLAN_FILE"
|
|
961
|
+
print_plan "$PLAN_FILE"
|
|
962
|
+
|
|
963
|
+
if grep -q '^CONFLICT|' "$PLAN_FILE"; then
|
|
964
|
+
log ""
|
|
965
|
+
log "Aborting due to unresolved conflicts."
|
|
966
|
+
log "Use --replace-link NAME for a symlink you intentionally want to replace."
|
|
967
|
+
exit 1
|
|
968
|
+
fi
|
|
969
|
+
|
|
970
|
+
if $DRY_RUN; then
|
|
971
|
+
log ""
|
|
972
|
+
log "(dry-run) no changes made"
|
|
973
|
+
rm -f "$UPSTREAM_FILE" "$MANIFEST_DATA" "$PLAN_FILE" "$SELECTED_FILE" "$SELECTED_UPSTREAM" "$DECLINED_CANDIDATES"
|
|
974
|
+
exit 0
|
|
975
|
+
fi
|
|
976
|
+
|
|
977
|
+
N_CHANGES="$(awk -F'|' '$1=="CREATE"||$1=="UPDATE_TARGET"||$1=="REMOVE"{n++} END{print n+0}' "$PLAN_FILE")"
|
|
978
|
+
if (( N_CHANGES > 0 )); then
|
|
979
|
+
prompt "Apply these $N_CHANGES changes?" || { log "aborted"; exit 0; }
|
|
980
|
+
fi
|
|
981
|
+
|
|
982
|
+
MANIFEST_TMP="$MANIFEST_PATH.tmp.$$"
|
|
983
|
+
write_manifest_tmp "$PLAN_FILE" "$MANIFEST_TMP"
|
|
984
|
+
log ""
|
|
985
|
+
log "Applying:"
|
|
986
|
+
apply_plan "$PLAN_FILE"
|
|
987
|
+
commit_manifest "$MANIFEST_TMP"
|
|
988
|
+
|
|
989
|
+
# #366: persist declined skills + global repo pointer (best-effort, after
|
|
990
|
+
# manifest commit for the same reason as install_aris.sh).
|
|
991
|
+
save_declined "$DECLINED_CANDIDATES" "$SELECTED_FILE"
|
|
992
|
+
ensure_global_pointer
|
|
993
|
+
|
|
994
|
+
INSTALLED_NAMES="$(mktemp -t aris-codex-names.XXXX)"
|
|
995
|
+
awk -F'|' '$1=="REUSE"||$1=="ADOPT"||$1=="CREATE"||$1=="UPDATE_TARGET"{print $3}' "$PLAN_FILE" > "$INSTALLED_NAMES"
|
|
996
|
+
update_agents_doc "$INSTALLED_NAMES"
|
|
997
|
+
|
|
998
|
+
if ! $DRY_RUN; then
|
|
999
|
+
local_bad=0
|
|
1000
|
+
while IFS=$'\t' read -r kind name source_rel target_rel mode; do
|
|
1001
|
+
[[ -z "$name" ]] && continue
|
|
1002
|
+
target_path="$PROJECT_PATH/$target_rel"
|
|
1003
|
+
expected_target="$ARIS_REPO/$source_rel"
|
|
1004
|
+
if [[ ! -L "$target_path" ]]; then
|
|
1005
|
+
warn "verify: missing symlink $target_path"
|
|
1006
|
+
local_bad=$((local_bad + 1))
|
|
1007
|
+
continue
|
|
1008
|
+
fi
|
|
1009
|
+
current_target="$(read_link_target "$target_path")"
|
|
1010
|
+
[[ "$current_target" != /* ]] && current_target="$(canonicalize "$(dirname "$target_path")/$current_target")"
|
|
1011
|
+
if [[ "$current_target" != "$expected_target" ]]; then
|
|
1012
|
+
warn "verify: wrong target for $target_path -> $current_target"
|
|
1013
|
+
local_bad=$((local_bad + 1))
|
|
1014
|
+
fi
|
|
1015
|
+
done < <(awk -F'\t' '
|
|
1016
|
+
BEGIN { in_body=0 }
|
|
1017
|
+
/^kind\tname\tsource_rel\ttarget_rel\tmode$/ { in_body=1; next }
|
|
1018
|
+
in_body && NF==5 { print }
|
|
1019
|
+
' "$MANIFEST_PATH")
|
|
1020
|
+
(( local_bad == 0 )) && log "" && log "✓ Codex install complete. $N_CHANGES changes applied."
|
|
1021
|
+
fi
|
|
1022
|
+
|
|
1023
|
+
rm -f "$UPSTREAM_FILE" "$MANIFEST_DATA" "$PLAN_FILE" "$INSTALLED_NAMES" "$SELECTED_FILE" "$SELECTED_UPSTREAM" "$DECLINED_CANDIDATES"
|