devrites 5.10.1 → 5.11.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/CHANGELOG.md +13 -0
- package/README.md +24 -10
- package/bin/devrites.mjs +2 -0
- package/docs/cli.md +4 -1
- package/docs/command-map.md +7 -5
- package/docs/engine/commands.md +7 -5
- package/docs/orchestration.md +5 -2
- package/docs/skills.md +10 -4
- package/docs/usage.md +3 -1
- package/engine/commands.go +3 -0
- package/engine/help.go +190 -0
- package/engine/help_test.go +98 -0
- package/engine/internal/devritespaths/paths.go +2 -0
- package/engine/internal/hostpack/hostpack.go +39 -5
- package/engine/internal/hostpack/hostpack_test.go +27 -13
- package/engine/internal/install/apply.go +17 -4
- package/engine/internal/install/install.go +9 -2
- package/engine/internal/install/install_test.go +15 -2
- package/engine/internal/install/preflight.go +8 -2
- package/engine/internal/install/update.go +1 -1
- package/engine/internal/parallel/cli.go +90 -32
- package/engine/internal/parallel/cli_test.go +32 -0
- package/engine/main.go +15 -8
- package/engine/root_routing_test.go +4 -0
- package/install.sh +4 -1
- package/pack/.claude/skills/devrites-lib/reference/standards/afk-hitl.md +15 -8
- package/pack/.claude/skills/rite-autocomplete/SKILL.md +10 -5
- package/pack/.claude/skills/rite-autocomplete/reference/loop.md +12 -7
- package/pack/.claude/skills/rite-build/SKILL.md +3 -1
- package/pack/.claude/skills/rite-build/reference/afk-discipline.md +4 -3
- package/pack/.claude/skills/rite-build/reference/parallel-batch.md +3 -1
- package/pack/.claude/skills/rite-define/reference/plan-template.md +1 -1
- package/pack/generated/README.md +4 -2
- package/pack/generated/claude/skills/devrites-lib/reference/standards/afk-hitl.md +15 -8
- package/pack/generated/claude/skills/rite-autocomplete/SKILL.md +10 -5
- package/pack/generated/claude/skills/rite-autocomplete/reference/loop.md +12 -7
- package/pack/generated/claude/skills/rite-build/SKILL.md +3 -1
- package/pack/generated/claude/skills/rite-build/reference/afk-discipline.md +4 -3
- package/pack/generated/claude/skills/rite-build/reference/parallel-batch.md +3 -1
- package/pack/generated/claude/skills/rite-define/reference/plan-template.md +1 -1
- package/pack/generated/codex/skills/devrites-lib/reference/standards/afk-hitl.md +15 -8
- package/pack/generated/codex/skills/rite-autocomplete/SKILL.md +10 -5
- package/pack/generated/codex/skills/rite-autocomplete/reference/loop.md +12 -7
- package/pack/generated/codex/skills/rite-build/SKILL.md +3 -1
- package/pack/generated/codex/skills/rite-build/reference/afk-discipline.md +4 -3
- package/pack/generated/codex/skills/rite-build/reference/parallel-batch.md +3 -1
- package/pack/generated/codex/skills/rite-define/reference/plan-template.md +1 -1
- package/pack/generated/devin/AGENTS.md +23 -0
- package/pack/generated/devin/agents/devrites-code-reviewer.md +145 -0
- package/pack/generated/devin/agents/devrites-devex-reviewer.md +126 -0
- package/pack/generated/devin/agents/devrites-doubt-reviewer.md +91 -0
- package/pack/generated/devin/agents/devrites-evidence-scout.md +77 -0
- package/pack/generated/devin/agents/devrites-frontend-reviewer.md +119 -0
- package/pack/generated/devin/agents/devrites-performance-reviewer.md +117 -0
- package/pack/generated/devin/agents/devrites-plan-drafter.md +102 -0
- package/pack/generated/devin/agents/devrites-plan-reviewer.md +144 -0
- package/pack/generated/devin/agents/devrites-proof-runner.md +76 -0
- package/pack/generated/devin/agents/devrites-retrospector.md +64 -0
- package/pack/generated/devin/agents/devrites-security-auditor.md +112 -0
- package/pack/generated/devin/agents/devrites-simplifier-reviewer.md +97 -0
- package/pack/generated/devin/agents/devrites-slice-wright.md +219 -0
- package/pack/generated/devin/agents/devrites-spec-reviewer.md +99 -0
- package/pack/generated/devin/agents/devrites-strategy-reviewer.md +102 -0
- package/pack/generated/devin/agents/devrites-test-analyst.md +97 -0
- package/pack/generated/devin/agents/devrites-upgrade-planner.md +91 -0
- package/pack/generated/devin/skills/devrites-api-interface/SKILL.md +64 -0
- package/pack/generated/devin/skills/devrites-audit/SKILL.md +51 -0
- package/pack/generated/devin/skills/devrites-browser-proof/SKILL.md +77 -0
- package/pack/generated/devin/skills/devrites-browser-proof/reference/browser-performance.md +15 -0
- package/pack/generated/devin/skills/devrites-browser-proof/reference/visual-verdict.md +34 -0
- package/pack/generated/devin/skills/devrites-debug-recovery/SKILL.md +97 -0
- package/pack/generated/devin/skills/devrites-debug-recovery/reference/build-the-loop.md +58 -0
- package/pack/generated/devin/skills/devrites-debug-recovery/reference/cleanup-and-classify.md +34 -0
- package/pack/generated/devin/skills/devrites-debug-recovery/reference/hypotheses.md +17 -0
- package/pack/generated/devin/skills/devrites-debug-recovery/reference/instrumentation.md +21 -0
- package/pack/generated/devin/skills/devrites-debug-recovery/reference/regression-test.md +30 -0
- package/pack/generated/devin/skills/devrites-debug-recovery/reference/trace.md +25 -0
- package/pack/generated/devin/skills/devrites-doubt/SKILL.md +80 -0
- package/pack/generated/devin/skills/devrites-frontend-craft/SKILL.md +87 -0
- package/pack/generated/devin/skills/devrites-frontend-craft/reference/craft.md +63 -0
- package/pack/generated/devin/skills/devrites-frontend-craft/reference/design-references.md +116 -0
- package/pack/generated/devin/skills/devrites-frontend-craft/reference/fullstack.md +46 -0
- package/pack/generated/devin/skills/devrites-frontend-craft/reference/quality-standards.md +294 -0
- package/pack/generated/devin/skills/devrites-frontend-craft/reference/reuse-first.md +53 -0
- package/pack/generated/devin/skills/devrites-frontend-craft/reference/shape.md +56 -0
- package/pack/generated/devin/skills/devrites-interview/SKILL.md +103 -0
- package/pack/generated/devin/skills/devrites-lib/SKILL.md +57 -0
- package/pack/generated/devin/skills/devrites-lib/reference/candidate-integrity.md +42 -0
- package/pack/generated/devin/skills/devrites-lib/reference/intent-map.md +64 -0
- package/pack/generated/devin/skills/devrites-lib/reference/orchestration-profiles.md +27 -0
- package/pack/generated/devin/skills/devrites-lib/reference/parallel-dispatch.md +73 -0
- package/pack/generated/devin/skills/devrites-lib/reference/reply-contract.md +88 -0
- package/pack/generated/devin/skills/devrites-lib/reference/standards/README.md +60 -0
- package/pack/generated/devin/skills/devrites-lib/reference/standards/acceptance-preserving-reslice.md +30 -0
- package/pack/generated/devin/skills/devrites-lib/reference/standards/afk-hitl.md +415 -0
- package/pack/generated/devin/skills/devrites-lib/reference/standards/agents.md +99 -0
- package/pack/generated/devin/skills/devrites-lib/reference/standards/anti-patterns.md +48 -0
- package/pack/generated/devin/skills/devrites-lib/reference/standards/browser-proof-checklist.md +24 -0
- package/pack/generated/devin/skills/devrites-lib/reference/standards/ci-cd.md +50 -0
- package/pack/generated/devin/skills/devrites-lib/reference/standards/code-navigation.md +43 -0
- package/pack/generated/devin/skills/devrites-lib/reference/standards/code-review.md +108 -0
- package/pack/generated/devin/skills/devrites-lib/reference/standards/coding-style.md +48 -0
- package/pack/generated/devin/skills/devrites-lib/reference/standards/context-hygiene.md +109 -0
- package/pack/generated/devin/skills/devrites-lib/reference/standards/core.md +167 -0
- package/pack/generated/devin/skills/devrites-lib/reference/standards/data-integrity.md +118 -0
- package/pack/generated/devin/skills/devrites-lib/reference/standards/debug-recovery.md +28 -0
- package/pack/generated/devin/skills/devrites-lib/reference/standards/definition-of-done.md +19 -0
- package/pack/generated/devin/skills/devrites-lib/reference/standards/deprecation.md +31 -0
- package/pack/generated/devin/skills/devrites-lib/reference/standards/developer-experience.md +119 -0
- package/pack/generated/devin/skills/devrites-lib/reference/standards/development-workflow.md +29 -0
- package/pack/generated/devin/skills/devrites-lib/reference/standards/documentation.md +43 -0
- package/pack/generated/devin/skills/devrites-lib/reference/standards/edge-case-trace.md +92 -0
- package/pack/generated/devin/skills/devrites-lib/reference/standards/elicitation.md +85 -0
- package/pack/generated/devin/skills/devrites-lib/reference/standards/error-handling.md +47 -0
- package/pack/generated/devin/skills/devrites-lib/reference/standards/git-workflow.md +49 -0
- package/pack/generated/devin/skills/devrites-lib/reference/standards/hooks.md +25 -0
- package/pack/generated/devin/skills/devrites-lib/reference/standards/integration-reliability.md +102 -0
- package/pack/generated/devin/skills/devrites-lib/reference/standards/loop-operations.md +85 -0
- package/pack/generated/devin/skills/devrites-lib/reference/standards/observability.md +88 -0
- package/pack/generated/devin/skills/devrites-lib/reference/standards/one-shot-actions.md +97 -0
- package/pack/generated/devin/skills/devrites-lib/reference/standards/patterns.md +68 -0
- package/pack/generated/devin/skills/devrites-lib/reference/standards/performance.md +51 -0
- package/pack/generated/devin/skills/devrites-lib/reference/standards/principles.md +42 -0
- package/pack/generated/devin/skills/devrites-lib/reference/standards/prose-style.md +123 -0
- package/pack/generated/devin/skills/devrites-lib/reference/standards/release/ship-checklist.md +8 -0
- package/pack/generated/devin/skills/devrites-lib/reference/standards/repository-topology.md +80 -0
- package/pack/generated/devin/skills/devrites-lib/reference/standards/review-checklist.md +12 -0
- package/pack/generated/devin/skills/devrites-lib/reference/standards/security-checklist.md +25 -0
- package/pack/generated/devin/skills/devrites-lib/reference/standards/security.md +202 -0
- package/pack/generated/devin/skills/devrites-lib/reference/standards/skill-authoring.md +209 -0
- package/pack/generated/devin/skills/devrites-lib/reference/standards/spec-grammar.md +197 -0
- package/pack/generated/devin/skills/devrites-lib/reference/standards/test-proof-checklist.md +13 -0
- package/pack/generated/devin/skills/devrites-lib/reference/standards/testing.md +212 -0
- package/pack/generated/devin/skills/devrites-lib/reference/standards/tooling.md +92 -0
- package/pack/generated/devin/skills/devrites-lib/reference/standards/workflow-artifacts.md +427 -0
- package/pack/generated/devin/skills/devrites-lib/reference/visual-playbooks/code.md +44 -0
- package/pack/generated/devin/skills/devrites-lib/reference/visual-playbooks/comparison.md +42 -0
- package/pack/generated/devin/skills/devrites-lib/reference/visual-playbooks/diagram.md +51 -0
- package/pack/generated/devin/skills/devrites-lib/reference/visual-playbooks/index.md +66 -0
- package/pack/generated/devin/skills/devrites-lib/reference/visual-playbooks/input.md +46 -0
- package/pack/generated/devin/skills/devrites-lib/reference/visual-playbooks/outline-template.md +106 -0
- package/pack/generated/devin/skills/devrites-lib/reference/visual-playbooks/plan.md +48 -0
- package/pack/generated/devin/skills/devrites-lib/reference/visual-playbooks/slides.md +40 -0
- package/pack/generated/devin/skills/devrites-lib/reference/visual-playbooks/table.md +42 -0
- package/pack/generated/devin/skills/devrites-lib/reference/workspace-artifact-schema.md +267 -0
- package/pack/generated/devin/skills/devrites-prose-craft/SKILL.md +74 -0
- package/pack/generated/devin/skills/devrites-prose-craft/reference/banned-phrases.md +132 -0
- package/pack/generated/devin/skills/devrites-prose-craft/reference/examples.md +131 -0
- package/pack/generated/devin/skills/devrites-prose-craft/reference/structures.md +196 -0
- package/pack/generated/devin/skills/devrites-source-driven/SKILL.md +53 -0
- package/pack/generated/devin/skills/devrites-ux-shape/SKILL.md +135 -0
- package/pack/generated/devin/skills/devrites-ux-shape/reference/brief-template.md +108 -0
- package/pack/generated/devin/skills/devrites-ux-shape/reference/visual-direction-probe.md +48 -0
- package/pack/generated/devin/skills/rite/SKILL.md +148 -0
- package/pack/generated/devin/skills/rite/reference/menu.md +48 -0
- package/pack/generated/devin/skills/rite-adopt/SKILL.md +51 -0
- package/pack/generated/devin/skills/rite-adopt/reference/adoption.md +19 -0
- package/pack/generated/devin/skills/rite-adopt/reference/anti-patterns.md +19 -0
- package/pack/generated/devin/skills/rite-autocomplete/SKILL.md +142 -0
- package/pack/generated/devin/skills/rite-autocomplete/reference/decision-policy.md +43 -0
- package/pack/generated/devin/skills/rite-autocomplete/reference/loop.md +151 -0
- package/pack/generated/devin/skills/rite-autocomplete/reference/stop-conditions.md +97 -0
- package/pack/generated/devin/skills/rite-build/SKILL.md +102 -0
- package/pack/generated/devin/skills/rite-build/reference/afk-discipline.md +148 -0
- package/pack/generated/devin/skills/rite-build/reference/anti-patterns.md +27 -0
- package/pack/generated/devin/skills/rite-build/reference/checkpoint-protocol.md +120 -0
- package/pack/generated/devin/skills/rite-build/reference/checkpoint.md +56 -0
- package/pack/generated/devin/skills/rite-build/reference/frontend-trigger.md +39 -0
- package/pack/generated/devin/skills/rite-build/reference/one-slice-cycle.md +51 -0
- package/pack/generated/devin/skills/rite-build/reference/output.md +33 -0
- package/pack/generated/devin/skills/rite-build/reference/parallel-batch.md +214 -0
- package/pack/generated/devin/skills/rite-build/reference/phase-contract.md +89 -0
- package/pack/generated/devin/skills/rite-build/reference/spec-drift-guard.md +84 -0
- package/pack/generated/devin/skills/rite-build/reference/tdd.md +27 -0
- package/pack/generated/devin/skills/rite-build/reference/wright-dispatch.md +96 -0
- package/pack/generated/devin/skills/rite-clarify/SKILL.md +98 -0
- package/pack/generated/devin/skills/rite-clarify/reference/anti-patterns.md +24 -0
- package/pack/generated/devin/skills/rite-clarify/reference/decision-coverage.md +55 -0
- package/pack/generated/devin/skills/rite-converge/SKILL.md +144 -0
- package/pack/generated/devin/skills/rite-converge/reference/anti-patterns.md +35 -0
- package/pack/generated/devin/skills/rite-converge/reference/convergence-assessment.md +65 -0
- package/pack/generated/devin/skills/rite-customize/SKILL.md +60 -0
- package/pack/generated/devin/skills/rite-define/SKILL.md +168 -0
- package/pack/generated/devin/skills/rite-define/reference/anti-patterns.md +26 -0
- package/pack/generated/devin/skills/rite-define/reference/gates.md +159 -0
- package/pack/generated/devin/skills/rite-define/reference/plan-template.md +149 -0
- package/pack/generated/devin/skills/rite-doctor/SKILL.md +68 -0
- package/pack/generated/devin/skills/rite-dogfood/SKILL.md +55 -0
- package/pack/generated/devin/skills/rite-explain/SKILL.md +152 -0
- package/pack/generated/devin/skills/rite-explain/reference/intake.md +89 -0
- package/pack/generated/devin/skills/rite-frame/SKILL.md +114 -0
- package/pack/generated/devin/skills/rite-frame/reference/failure-modes.md +66 -0
- package/pack/generated/devin/skills/rite-handoff/SKILL.md +97 -0
- package/pack/generated/devin/skills/rite-handoff/reference/handoff-template.md +44 -0
- package/pack/generated/devin/skills/rite-learn/SKILL.md +72 -0
- package/pack/generated/devin/skills/rite-plan/SKILL.md +185 -0
- package/pack/generated/devin/skills/rite-plan/reference/anti-patterns.md +34 -0
- package/pack/generated/devin/skills/rite-plan/reference/dependency-graph.md +48 -0
- package/pack/generated/devin/skills/rite-plan/reference/replan-and-repair.md +105 -0
- package/pack/generated/devin/skills/rite-plan/reference/slicing.md +168 -0
- package/pack/generated/devin/skills/rite-plan/reference/task-breakdown.md +42 -0
- package/pack/generated/devin/skills/rite-polish/SKILL.md +105 -0
- package/pack/generated/devin/skills/rite-polish/reference/adr-promotion.md +11 -0
- package/pack/generated/devin/skills/rite-polish/reference/anti-ai-slop.md +187 -0
- package/pack/generated/devin/skills/rite-polish/reference/anti-patterns.md +30 -0
- package/pack/generated/devin/skills/rite-polish/reference/backend-polish.md +80 -0
- package/pack/generated/devin/skills/rite-polish/reference/browser-polish-evidence.md +33 -0
- package/pack/generated/devin/skills/rite-polish/reference/code.md +82 -0
- package/pack/generated/devin/skills/rite-polish/reference/design-memory.md +117 -0
- package/pack/generated/devin/skills/rite-polish/reference/design-system-discovery.md +8 -0
- package/pack/generated/devin/skills/rite-polish/reference/harden-checklist.md +109 -0
- package/pack/generated/devin/skills/rite-polish/reference/ledger.md +65 -0
- package/pack/generated/devin/skills/rite-polish/reference/ui.md +137 -0
- package/pack/generated/devin/skills/rite-pov/SKILL.md +57 -0
- package/pack/generated/devin/skills/rite-pr-feedback/SKILL.md +54 -0
- package/pack/generated/devin/skills/rite-pressure-test/SKILL.md +66 -0
- package/pack/generated/devin/skills/rite-prototype/SKILL.md +104 -0
- package/pack/generated/devin/skills/rite-prove/SKILL.md +122 -0
- package/pack/generated/devin/skills/rite-prove/reference/acceptance-proof.md +88 -0
- package/pack/generated/devin/skills/rite-prove/reference/anti-patterns.md +25 -0
- package/pack/generated/devin/skills/rite-prove/reference/browser-proof.md +51 -0
- package/pack/generated/devin/skills/rite-prove/reference/failure-triage.md +43 -0
- package/pack/generated/devin/skills/rite-prove/reference/proof-ladder.md +28 -0
- package/pack/generated/devin/skills/rite-prove/reference/test-command-discovery.md +30 -0
- package/pack/generated/devin/skills/rite-quick/SKILL.md +81 -0
- package/pack/generated/devin/skills/rite-resolve/SKILL.md +98 -0
- package/pack/generated/devin/skills/rite-resolve/reference/answer-protocol.md +118 -0
- package/pack/generated/devin/skills/rite-review/SKILL.md +171 -0
- package/pack/generated/devin/skills/rite-review/reference/anti-patterns.md +32 -0
- package/pack/generated/devin/skills/rite-review/reference/cognitive-load.md +90 -0
- package/pack/generated/devin/skills/rite-review/reference/feature-scoped-review.md +26 -0
- package/pack/generated/devin/skills/rite-review/reference/five-axis-review.md +66 -0
- package/pack/generated/devin/skills/rite-review/reference/nielsen-heuristics.md +126 -0
- package/pack/generated/devin/skills/rite-review/reference/performance-checklist.md +80 -0
- package/pack/generated/devin/skills/rite-review/reference/performance-review.md +14 -0
- package/pack/generated/devin/skills/rite-review/reference/security-review.md +42 -0
- package/pack/generated/devin/skills/rite-seal/SKILL.md +74 -0
- package/pack/generated/devin/skills/rite-seal/reference/anti-patterns.md +29 -0
- package/pack/generated/devin/skills/rite-seal/reference/final-evidence.md +41 -0
- package/pack/generated/devin/skills/rite-seal/reference/go-no-go.md +29 -0
- package/pack/generated/devin/skills/rite-seal/reference/output.md +5 -0
- package/pack/generated/devin/skills/rite-seal/reference/phase-contract.md +47 -0
- package/pack/generated/devin/skills/rite-seal/reference/risk-and-rollback.md +56 -0
- package/pack/generated/devin/skills/rite-seal/reference/seal-template.md +27 -0
- package/pack/generated/devin/skills/rite-ship/SKILL.md +87 -0
- package/pack/generated/devin/skills/rite-ship/reference/anti-patterns.md +28 -0
- package/pack/generated/devin/skills/rite-ship/reference/close-out.md +68 -0
- package/pack/generated/devin/skills/rite-ship/reference/git-ship.md +120 -0
- package/pack/generated/devin/skills/rite-ship/reference/rollout.md +62 -0
- package/pack/generated/devin/skills/rite-ship/reference/ship-template.md +39 -0
- package/pack/generated/devin/skills/rite-spec/SKILL.md +149 -0
- package/pack/generated/devin/skills/rite-spec/reference/acceptance-criteria.md +31 -0
- package/pack/generated/devin/skills/rite-spec/reference/ai-spec-template.md +40 -0
- package/pack/generated/devin/skills/rite-spec/reference/anti-patterns.md +27 -0
- package/pack/generated/devin/skills/rite-spec/reference/interview-patterns.md +56 -0
- package/pack/generated/devin/skills/rite-spec/reference/investigation.md +83 -0
- package/pack/generated/devin/skills/rite-spec/reference/question-protocol.md +36 -0
- package/pack/generated/devin/skills/rite-spec/reference/references-intake.md +62 -0
- package/pack/generated/devin/skills/rite-spec/reference/spec-checklists.md +89 -0
- package/pack/generated/devin/skills/rite-spec/reference/spec-template.md +154 -0
- package/pack/generated/devin/skills/rite-spec/reference/state-workspace.md +227 -0
- package/pack/generated/devin/skills/rite-status/SKILL.md +57 -0
- package/pack/generated/devin/skills/rite-temper/SKILL.md +129 -0
- package/pack/generated/devin/skills/rite-temper/reference/anti-patterns.md +30 -0
- package/pack/generated/devin/skills/rite-temper/reference/review-dimensions.md +66 -0
- package/pack/generated/devin/skills/rite-temper/reference/scope-modes.md +53 -0
- package/pack/generated/devin/skills/rite-temper/reference/significance.md +46 -0
- package/pack/generated/devin/skills/rite-temper/reference/strategy-template.md +90 -0
- package/pack/generated/devin/skills/rite-upgrade/SKILL.md +121 -0
- package/pack/generated/devin/skills/rite-vet/SKILL.md +192 -0
- package/pack/generated/devin/skills/rite-vet/reference/anti-patterns.md +43 -0
- package/pack/generated/devin/skills/rite-vet/reference/artifacts.md +202 -0
- package/pack/generated/devin/skills/rite-vet/reference/cross-model.md +19 -0
- package/pack/generated/devin/skills/rite-vet/reference/depth.md +59 -0
- package/pack/generated/devin/skills/rite-vet/reference/eng-lenses.md +48 -0
- package/pack/generated/devin/skills/rite-vet/reference/review-axes.md +201 -0
- package/pack/generated/devin/skills/rite-watch-pr/SKILL.md +84 -0
- package/pack/generated/devin/skills/rite-zoom-out/SKILL.md +69 -0
- package/pack/generated/omp/skills/devrites-lib/reference/standards/afk-hitl.md +15 -8
- package/pack/generated/omp/skills/rite-autocomplete/SKILL.md +10 -5
- package/pack/generated/omp/skills/rite-autocomplete/reference/loop.md +12 -7
- package/pack/generated/omp/skills/rite-build/SKILL.md +3 -1
- package/pack/generated/omp/skills/rite-build/reference/afk-discipline.md +4 -3
- package/pack/generated/omp/skills/rite-build/reference/parallel-batch.md +3 -1
- package/pack/generated/omp/skills/rite-define/reference/plan-template.md +1 -1
- package/pack/generated/pi/skills/devrites-lib/reference/standards/afk-hitl.md +15 -8
- package/pack/generated/pi/skills/rite-autocomplete/SKILL.md +10 -5
- package/pack/generated/pi/skills/rite-autocomplete/reference/loop.md +12 -7
- package/pack/generated/pi/skills/rite-build/SKILL.md +3 -1
- package/pack/generated/pi/skills/rite-build/reference/afk-discipline.md +4 -3
- package/pack/generated/pi/skills/rite-build/reference/parallel-batch.md +3 -1
- package/pack/generated/pi/skills/rite-define/reference/plan-template.md +1 -1
- package/package.json +4 -2
- package/scripts/build-host-artifacts.sh +48 -5
- package/scripts/devin-generate.sh +222 -0
- package/update.sh +2 -1
|
@@ -18,10 +18,12 @@ const (
|
|
|
18
18
|
CodexSkillsTarget = devritespaths.CodexSkillsTarget
|
|
19
19
|
OmpSkillsTarget = devritespaths.OmpSkillsTarget
|
|
20
20
|
PiSkillsTarget = devritespaths.PiSkillsTarget
|
|
21
|
+
DevinSkillsTarget = devritespaths.DevinSkillsTarget
|
|
21
22
|
ClaudeAgentsTarget = devritespaths.ClaudeAgentsTarget
|
|
22
23
|
CodexAgentsTarget = devritespaths.CodexAgentsTarget
|
|
23
24
|
OmpAgentsTarget = devritespaths.OmpAgentsTarget
|
|
24
25
|
PiAgentsTarget = devritespaths.PiAgentsTarget
|
|
26
|
+
DevinAgentsTarget = devritespaths.DevinAgentsTarget
|
|
25
27
|
PiPromptsTarget = devritespaths.PiPromptsTarget
|
|
26
28
|
ClaudeWorkflowsTarget = devritespaths.ClaudeWorkflowsTarget
|
|
27
29
|
)
|
|
@@ -99,6 +101,15 @@ var PiAgentsMerge = MarkerMerge{
|
|
|
99
101
|
MarkerText: "AGENTS.md contains a DevRites managed block between BEGIN/END DEVRITES PI markers.",
|
|
100
102
|
}
|
|
101
103
|
|
|
104
|
+
var DevinAgentsMerge = MarkerMerge{
|
|
105
|
+
TargetRel: "AGENTS.md",
|
|
106
|
+
PayloadRel: "devin/AGENTS.md",
|
|
107
|
+
Begin: "<!-- BEGIN DEVRITES DEVIN -->",
|
|
108
|
+
End: "<!-- END DEVRITES DEVIN -->",
|
|
109
|
+
MarkerRel: ".claude/devrites.devin-agents-merge",
|
|
110
|
+
MarkerText: "AGENTS.md contains a DevRites managed block between BEGIN/END DEVRITES DEVIN markers.",
|
|
111
|
+
}
|
|
112
|
+
|
|
102
113
|
var CodexConfigMerge = MarkerMerge{
|
|
103
114
|
TargetRel: ".codex/config.toml",
|
|
104
115
|
PayloadRel: "codex/config.toml",
|
|
@@ -129,6 +140,13 @@ var managedMerges = []ManagedMerge{
|
|
|
129
140
|
End: PiAgentsMerge.End,
|
|
130
141
|
DryRun: "AGENTS.md DevRites pi block",
|
|
131
142
|
},
|
|
143
|
+
{
|
|
144
|
+
MarkerRel: DevinAgentsMerge.MarkerRel,
|
|
145
|
+
TargetRel: DevinAgentsMerge.TargetRel,
|
|
146
|
+
Begin: DevinAgentsMerge.Begin,
|
|
147
|
+
End: DevinAgentsMerge.End,
|
|
148
|
+
DryRun: "AGENTS.md DevRites Devin block",
|
|
149
|
+
},
|
|
132
150
|
{
|
|
133
151
|
MarkerRel: CodexConfigMerge.MarkerRel,
|
|
134
152
|
TargetRel: CodexConfigMerge.TargetRel,
|
|
@@ -144,7 +162,7 @@ var managedMerges = []ManagedMerge{
|
|
|
144
162
|
LegacyCodexHooksMerge,
|
|
145
163
|
}
|
|
146
164
|
|
|
147
|
-
func RequiredPayload(withCodex, withOmp, withPi bool) []string {
|
|
165
|
+
func RequiredPayload(withCodex, withOmp, withPi, withDevin bool) []string {
|
|
148
166
|
required := []string{
|
|
149
167
|
"claude/skills",
|
|
150
168
|
"claude/agents",
|
|
@@ -174,11 +192,18 @@ func RequiredPayload(withCodex, withOmp, withPi bool) []string {
|
|
|
174
192
|
"pi/AGENTS.md",
|
|
175
193
|
)
|
|
176
194
|
}
|
|
195
|
+
if withDevin {
|
|
196
|
+
required = append(required,
|
|
197
|
+
"devin/skills",
|
|
198
|
+
"devin/agents",
|
|
199
|
+
"devin/AGENTS.md",
|
|
200
|
+
)
|
|
201
|
+
}
|
|
177
202
|
return required
|
|
178
203
|
}
|
|
179
204
|
|
|
180
|
-
func ValidatePayload(payload fs.FS, withCodex, withOmp, withPi bool) error {
|
|
181
|
-
for _, rel := range RequiredPayload(withCodex, withOmp, withPi) {
|
|
205
|
+
func ValidatePayload(payload fs.FS, withCodex, withOmp, withPi, withDevin bool) error {
|
|
206
|
+
for _, rel := range RequiredPayload(withCodex, withOmp, withPi, withDevin) {
|
|
182
207
|
if _, err := fs.Stat(payload, rel); err != nil {
|
|
183
208
|
return fmt.Errorf("missing %s", rel)
|
|
184
209
|
}
|
|
@@ -186,7 +211,7 @@ func ValidatePayload(payload fs.FS, withCodex, withOmp, withPi bool) error {
|
|
|
186
211
|
return nil
|
|
187
212
|
}
|
|
188
213
|
|
|
189
|
-
func InstallTrees(withSkills, withAgents, withCodex, withOmp, withPi bool) []Tree {
|
|
214
|
+
func InstallTrees(withSkills, withAgents, withCodex, withOmp, withPi, withDevin bool) []Tree {
|
|
190
215
|
var trees []Tree
|
|
191
216
|
if withSkills {
|
|
192
217
|
trees = append(trees, Tree{PayloadPrefix: "claude/skills", TargetPrefix: ClaudeSkillsTarget})
|
|
@@ -202,6 +227,9 @@ func InstallTrees(withSkills, withAgents, withCodex, withOmp, withPi bool) []Tre
|
|
|
202
227
|
Tree{PayloadPrefix: "pi/prompts", TargetPrefix: PiPromptsTarget},
|
|
203
228
|
)
|
|
204
229
|
}
|
|
230
|
+
if withDevin {
|
|
231
|
+
trees = append(trees, Tree{PayloadPrefix: "devin/skills", TargetPrefix: DevinSkillsTarget})
|
|
232
|
+
}
|
|
205
233
|
}
|
|
206
234
|
if withAgents {
|
|
207
235
|
trees = append(trees, Tree{PayloadPrefix: "claude/agents", TargetPrefix: ClaudeAgentsTarget})
|
|
@@ -214,6 +242,9 @@ func InstallTrees(withSkills, withAgents, withCodex, withOmp, withPi bool) []Tre
|
|
|
214
242
|
if withPi {
|
|
215
243
|
trees = append(trees, Tree{PayloadPrefix: "pi/agents", TargetPrefix: PiAgentsTarget})
|
|
216
244
|
}
|
|
245
|
+
if withDevin {
|
|
246
|
+
trees = append(trees, Tree{PayloadPrefix: "devin/agents", TargetPrefix: DevinAgentsTarget})
|
|
247
|
+
}
|
|
217
248
|
}
|
|
218
249
|
if withSkills && withAgents {
|
|
219
250
|
trees = append(trees, Tree{PayloadPrefix: "claude/workflows", TargetPrefix: ClaudeWorkflowsTarget})
|
|
@@ -221,7 +252,7 @@ func InstallTrees(withSkills, withAgents, withCodex, withOmp, withPi bool) []Tre
|
|
|
221
252
|
return trees
|
|
222
253
|
}
|
|
223
254
|
|
|
224
|
-
func AliasTargets(alias Alias, withCodex, withOmp, withPi bool) []string {
|
|
255
|
+
func AliasTargets(alias Alias, withCodex, withOmp, withPi, withDevin bool) []string {
|
|
225
256
|
targets := []string{filepath.ToSlash(filepath.Join(ClaudeSkillsTarget, alias.Name, "SKILL.md"))}
|
|
226
257
|
if withCodex {
|
|
227
258
|
targets = append(targets, filepath.ToSlash(filepath.Join(CodexSkillsTarget, alias.Name, "SKILL.md")))
|
|
@@ -232,6 +263,9 @@ func AliasTargets(alias Alias, withCodex, withOmp, withPi bool) []string {
|
|
|
232
263
|
if withPi {
|
|
233
264
|
targets = append(targets, filepath.ToSlash(filepath.Join(PiSkillsTarget, alias.Name, "SKILL.md")))
|
|
234
265
|
}
|
|
266
|
+
if withDevin {
|
|
267
|
+
targets = append(targets, filepath.ToSlash(filepath.Join(DevinSkillsTarget, alias.Name, "SKILL.md")))
|
|
268
|
+
}
|
|
235
269
|
return targets
|
|
236
270
|
}
|
|
237
271
|
|
|
@@ -25,81 +25,95 @@ func TestValidatePayloadRequiresClaudeAndCodexFiles(t *testing.T) {
|
|
|
25
25
|
"pi/agents/devrites-code-reviewer.md": {},
|
|
26
26
|
"pi/prompts/rite.md": {},
|
|
27
27
|
"pi/AGENTS.md": {},
|
|
28
|
+
"devin/skills/rite/SKILL.md": {},
|
|
29
|
+
"devin/agents/devrites-code-reviewer.md": {},
|
|
30
|
+
"devin/AGENTS.md": {},
|
|
28
31
|
}
|
|
29
|
-
if err := ValidatePayload(payload, true, true, true); err != nil {
|
|
32
|
+
if err := ValidatePayload(payload, true, true, true, true); err != nil {
|
|
30
33
|
t.Fatal(err)
|
|
31
34
|
}
|
|
32
35
|
delete(payload, "codex/config.toml")
|
|
33
|
-
err := ValidatePayload(payload, true, true, true)
|
|
36
|
+
err := ValidatePayload(payload, true, true, true, true)
|
|
34
37
|
if err == nil || !strings.Contains(err.Error(), "missing codex/config.toml") {
|
|
35
38
|
t.Fatalf("ValidatePayload error = %v, want missing codex/config.toml", err)
|
|
36
39
|
}
|
|
37
|
-
if err := ValidatePayload(payload, false, true, true); err != nil {
|
|
40
|
+
if err := ValidatePayload(payload, false, true, true, true); err != nil {
|
|
38
41
|
t.Fatalf("claude-only payload should not require codex files: %v", err)
|
|
39
42
|
}
|
|
40
43
|
delete(payload, "omp/.omp-plugin/plugin.json")
|
|
41
|
-
err = ValidatePayload(payload, false, true, true)
|
|
44
|
+
err = ValidatePayload(payload, false, true, true, true)
|
|
42
45
|
if err == nil || !strings.Contains(err.Error(), "missing omp/.omp-plugin/plugin.json") {
|
|
43
46
|
t.Fatalf("ValidatePayload error = %v, want missing omp/.omp-plugin/plugin.json", err)
|
|
44
47
|
}
|
|
45
48
|
delete(payload, "pi/prompts/rite.md")
|
|
46
|
-
err = ValidatePayload(payload, false, false, true)
|
|
49
|
+
err = ValidatePayload(payload, false, false, true, true)
|
|
47
50
|
if err == nil || !strings.Contains(err.Error(), "missing pi/prompts") {
|
|
48
51
|
t.Fatalf("ValidatePayload error = %v, want missing pi/prompts", err)
|
|
49
52
|
}
|
|
50
|
-
|
|
51
|
-
|
|
53
|
+
delete(payload, "devin/AGENTS.md")
|
|
54
|
+
err = ValidatePayload(payload, false, false, false, true)
|
|
55
|
+
if err == nil || !strings.Contains(err.Error(), "missing devin/AGENTS.md") {
|
|
56
|
+
t.Fatalf("ValidatePayload error = %v, want missing devin/AGENTS.md", err)
|
|
57
|
+
}
|
|
58
|
+
if err := ValidatePayload(payload, false, false, false, false); err != nil {
|
|
59
|
+
t.Fatalf("claude-only payload should not require omp, pi, or devin files: %v", err)
|
|
52
60
|
}
|
|
53
61
|
}
|
|
54
62
|
|
|
55
63
|
func TestInstallTreesMapPayloadsToTargets(t *testing.T) {
|
|
56
|
-
got := InstallTrees(true, true, true, true, true)
|
|
64
|
+
got := InstallTrees(true, true, true, true, true, true)
|
|
57
65
|
want := []Tree{
|
|
58
66
|
{PayloadPrefix: "claude/skills", TargetPrefix: ".claude/skills"},
|
|
59
67
|
{PayloadPrefix: "codex/skills", TargetPrefix: ".agents/skills"},
|
|
60
68
|
{PayloadPrefix: "omp/skills", TargetPrefix: ".omp/skills"},
|
|
61
69
|
{PayloadPrefix: "pi/skills", TargetPrefix: ".pi/skills"},
|
|
62
70
|
{PayloadPrefix: "pi/prompts", TargetPrefix: ".pi/prompts"},
|
|
71
|
+
{PayloadPrefix: "devin/skills", TargetPrefix: ".devin/skills"},
|
|
63
72
|
{PayloadPrefix: "claude/agents", TargetPrefix: ".claude/agents"},
|
|
64
73
|
{PayloadPrefix: "codex/agents", TargetPrefix: ".codex/agents"},
|
|
65
74
|
{PayloadPrefix: "omp/agents", TargetPrefix: ".omp/agents"},
|
|
66
75
|
{PayloadPrefix: "pi/agents", TargetPrefix: ".pi/agents"},
|
|
76
|
+
{PayloadPrefix: "devin/agents", TargetPrefix: ".devin/agents"},
|
|
67
77
|
{PayloadPrefix: "claude/workflows", TargetPrefix: ".claude/workflows"},
|
|
68
78
|
}
|
|
69
79
|
if !reflect.DeepEqual(got, want) {
|
|
70
80
|
t.Fatalf("InstallTrees() = %#v, want %#v", got, want)
|
|
71
81
|
}
|
|
72
|
-
for _, trees := range [][]Tree{InstallTrees(true, false, true, true, true), InstallTrees(false, true, true, true, true)} {
|
|
82
|
+
for _, trees := range [][]Tree{InstallTrees(true, false, true, true, true, true), InstallTrees(false, true, true, true, true, true)} {
|
|
73
83
|
for _, tree := range trees {
|
|
74
84
|
if tree.PayloadPrefix == "claude/workflows" {
|
|
75
85
|
t.Fatal("Claude workflow installed without both skills and agents")
|
|
76
86
|
}
|
|
77
87
|
}
|
|
78
88
|
}
|
|
79
|
-
for _, tree := range InstallTrees(true, true, true, false, false) {
|
|
89
|
+
for _, tree := range InstallTrees(true, true, true, false, false, false) {
|
|
80
90
|
if strings.HasPrefix(tree.TargetPrefix, ".omp/") {
|
|
81
91
|
t.Fatalf("omp tree installed with withOmp=false: %#v", tree)
|
|
82
92
|
}
|
|
83
93
|
if strings.HasPrefix(tree.TargetPrefix, ".pi/") {
|
|
84
94
|
t.Fatalf("pi tree installed with withPi=false: %#v", tree)
|
|
85
95
|
}
|
|
96
|
+
if strings.HasPrefix(tree.TargetPrefix, ".devin/") {
|
|
97
|
+
t.Fatalf("devin tree installed with withDevin=false: %#v", tree)
|
|
98
|
+
}
|
|
86
99
|
}
|
|
87
100
|
}
|
|
88
101
|
|
|
89
102
|
func TestAliasTargetsIncludeOmpWhenEnabled(t *testing.T) {
|
|
90
|
-
got := AliasTargets(Alias{Name: "define"}, true, true, true)
|
|
103
|
+
got := AliasTargets(Alias{Name: "define"}, true, true, true, true)
|
|
91
104
|
want := []string{
|
|
92
105
|
".claude/skills/define/SKILL.md",
|
|
93
106
|
".agents/skills/define/SKILL.md",
|
|
94
107
|
".omp/skills/define/SKILL.md",
|
|
95
108
|
".pi/skills/define/SKILL.md",
|
|
109
|
+
".devin/skills/define/SKILL.md",
|
|
96
110
|
}
|
|
97
111
|
if !reflect.DeepEqual(got, want) {
|
|
98
112
|
t.Fatalf("AliasTargets() = %#v, want %#v", got, want)
|
|
99
113
|
}
|
|
100
|
-
got = AliasTargets(Alias{Name: "define"}, true, false, false)
|
|
114
|
+
got = AliasTargets(Alias{Name: "define"}, true, false, false, false)
|
|
101
115
|
for _, rel := range got {
|
|
102
|
-
if strings.HasPrefix(rel, ".omp/") || strings.HasPrefix(rel, ".pi/") {
|
|
116
|
+
if strings.HasPrefix(rel, ".omp/") || strings.HasPrefix(rel, ".pi/") || strings.HasPrefix(rel, ".devin/") {
|
|
103
117
|
t.Fatalf("disabled-host alias installed: %s", rel)
|
|
104
118
|
}
|
|
105
119
|
}
|
|
@@ -25,6 +25,7 @@ func (r *runner) install() error {
|
|
|
25
25
|
fmt.Fprintf(r.opts.Stdout, " codex : %s\n", yesno(r.opts.WithCodex))
|
|
26
26
|
fmt.Fprintf(r.opts.Stdout, " omp : %s\n", yesno(r.opts.WithOmp))
|
|
27
27
|
fmt.Fprintf(r.opts.Stdout, " pi : %s\n", yesno(r.opts.WithPi))
|
|
28
|
+
fmt.Fprintf(r.opts.Stdout, " devin : %s\n", yesno(r.opts.WithDevin))
|
|
28
29
|
fmt.Fprintf(r.opts.Stdout, " aliases: %s\n", r.opts.AliasMode)
|
|
29
30
|
if r.opts.DryRun {
|
|
30
31
|
fmt.Fprintln(r.opts.Stdout, " (dry run - no changes will be made)")
|
|
@@ -39,7 +40,7 @@ func (r *runner) install() error {
|
|
|
39
40
|
return err
|
|
40
41
|
}
|
|
41
42
|
|
|
42
|
-
for _, tree := range hostpack.InstallTrees(r.opts.WithSkills, r.opts.WithAgents, r.opts.WithCodex, r.opts.WithOmp, r.opts.WithPi) {
|
|
43
|
+
for _, tree := range hostpack.InstallTrees(r.opts.WithSkills, r.opts.WithAgents, r.opts.WithCodex, r.opts.WithOmp, r.opts.WithPi, r.opts.WithDevin) {
|
|
43
44
|
if err := r.installTree(tree.PayloadPrefix, tree.TargetPrefix); err != nil {
|
|
44
45
|
return fmt.Errorf("install tree %s: %w", tree.TargetPrefix, err)
|
|
45
46
|
}
|
|
@@ -50,7 +51,7 @@ func (r *runner) install() error {
|
|
|
50
51
|
if err != nil {
|
|
51
52
|
return fmt.Errorf("render alias skill %s: %w", alias.Name, err)
|
|
52
53
|
}
|
|
53
|
-
for _, rel := range hostpack.AliasTargets(alias, r.opts.WithCodex, r.opts.WithOmp, r.opts.WithPi) {
|
|
54
|
+
for _, rel := range hostpack.AliasTargets(alias, r.opts.WithCodex, r.opts.WithOmp, r.opts.WithPi, r.opts.WithDevin) {
|
|
54
55
|
if err := r.installData(data, rel); err != nil {
|
|
55
56
|
return fmt.Errorf("install alias: %w", err)
|
|
56
57
|
}
|
|
@@ -70,6 +71,11 @@ func (r *runner) install() error {
|
|
|
70
71
|
return fmt.Errorf("merge %s: %w", hostpack.PiAgentsMerge.TargetRel, err)
|
|
71
72
|
}
|
|
72
73
|
}
|
|
74
|
+
if r.opts.WithSkills && r.opts.WithDevin {
|
|
75
|
+
if err := r.mergeMarkerFile(hostpack.DevinAgentsMerge); err != nil {
|
|
76
|
+
return fmt.Errorf("merge %s: %w", hostpack.DevinAgentsMerge.TargetRel, err)
|
|
77
|
+
}
|
|
78
|
+
}
|
|
73
79
|
if r.opts.WithSkills {
|
|
74
80
|
if err := r.seedClaudeSettings(); err != nil {
|
|
75
81
|
return fmt.Errorf("seed claude settings: %w", err)
|
|
@@ -98,11 +104,15 @@ func (r *runner) install() error {
|
|
|
98
104
|
}
|
|
99
105
|
fmt.Fprintf(r.opts.Stdout, " installed: %d overwritten: %d skipped(conflict): %d pruned: %d\n", r.stats.installed, r.stats.overwrote, r.stats.skipped, r.stats.pruned)
|
|
100
106
|
if !r.opts.DryRun && r.opts.WithSkills {
|
|
107
|
+
claudeHosts := "Claude"
|
|
108
|
+
if r.opts.WithDevin {
|
|
109
|
+
claudeHosts = "Claude/Devin"
|
|
110
|
+
}
|
|
101
111
|
switch {
|
|
102
112
|
case r.opts.WithCodex && (r.opts.WithOmp || r.opts.WithPi):
|
|
103
|
-
fmt.
|
|
113
|
+
fmt.Fprintf(r.opts.Stdout, "Next: reopen the project, then run /rite (%s) or $rite (Codex) or /skill:rite (omp/pi).\n", claudeHosts)
|
|
104
114
|
case r.opts.WithCodex:
|
|
105
|
-
fmt.
|
|
115
|
+
fmt.Fprintf(r.opts.Stdout, "Next: reopen the project, then run /rite (%s) or $rite (Codex).\n", claudeHosts)
|
|
106
116
|
case r.opts.WithOmp || r.opts.WithPi:
|
|
107
117
|
fmt.Fprintln(r.opts.Stdout, "Next: reopen the project, then run /rite or /skill:rite.")
|
|
108
118
|
default:
|
|
@@ -320,6 +330,9 @@ func (r *runner) flagsString() string {
|
|
|
320
330
|
if !r.opts.WithPi {
|
|
321
331
|
flags = append(flags, "--no-pi")
|
|
322
332
|
}
|
|
333
|
+
if !r.opts.WithDevin {
|
|
334
|
+
flags = append(flags, "--no-devin")
|
|
335
|
+
}
|
|
323
336
|
if !r.opts.WithBinary {
|
|
324
337
|
flags = append(flags, "--no-binary")
|
|
325
338
|
}
|
|
@@ -36,6 +36,7 @@ type Options struct {
|
|
|
36
36
|
WithCodex bool
|
|
37
37
|
WithOmp bool
|
|
38
38
|
WithPi bool
|
|
39
|
+
WithDevin bool
|
|
39
40
|
WithBinary bool
|
|
40
41
|
KeepBinary bool
|
|
41
42
|
AliasMode string
|
|
@@ -86,6 +87,7 @@ func DefaultOptions(mode Mode) Options {
|
|
|
86
87
|
WithCodex: true,
|
|
87
88
|
WithOmp: true,
|
|
88
89
|
WithPi: true,
|
|
90
|
+
WithDevin: true,
|
|
89
91
|
WithBinary: true,
|
|
90
92
|
AliasMode: "safe",
|
|
91
93
|
Stdout: io.Discard,
|
|
@@ -138,6 +140,7 @@ func parseArgs(args []string, opts *Options) error {
|
|
|
138
140
|
noCodex := flags.Bool("no-codex", !opts.WithCodex, "")
|
|
139
141
|
noOmp := flags.Bool("no-omp", !opts.WithOmp, "")
|
|
140
142
|
noPi := flags.Bool("no-pi", !opts.WithPi, "")
|
|
143
|
+
noDevin := flags.Bool("no-devin", !opts.WithDevin, "")
|
|
141
144
|
noAgents := flags.Bool("no-agents", !opts.WithAgents, "")
|
|
142
145
|
noSkills := flags.Bool("no-skills", !opts.WithSkills, "")
|
|
143
146
|
noBinary := flags.Bool("no-binary", !opts.WithBinary, "")
|
|
@@ -166,6 +169,7 @@ func parseArgs(args []string, opts *Options) error {
|
|
|
166
169
|
opts.WithCodex = !*noCodex
|
|
167
170
|
opts.WithOmp = !*noOmp
|
|
168
171
|
opts.WithPi = !*noPi
|
|
172
|
+
opts.WithDevin = !*noDevin
|
|
169
173
|
opts.WithAgents = !*noAgents
|
|
170
174
|
opts.WithSkills = !*noSkills
|
|
171
175
|
opts.WithBinary = !*noBinary
|
|
@@ -212,7 +216,7 @@ func usage(mode Mode) string {
|
|
|
212
216
|
case ModeUpdate:
|
|
213
217
|
return "usage: devrites-engine update [--target DIR] [--dry-run] [--force] [--check] [install flags] [--source-dir DIR --payload-dir DIR]\n"
|
|
214
218
|
default:
|
|
215
|
-
return "usage: devrites-engine install [--target DIR] [--dry-run] [--force] [--no-codex] [--no-omp] [--no-pi] [--no-agents] [--no-skills] [--no-binary] [--short-aliases=all]\n"
|
|
219
|
+
return "usage: devrites-engine install [--target DIR] [--dry-run] [--force] [--no-codex] [--no-omp] [--no-pi] [--no-devin] [--no-agents] [--no-skills] [--no-binary] [--short-aliases=all]\n"
|
|
216
220
|
}
|
|
217
221
|
}
|
|
218
222
|
|
|
@@ -337,7 +341,7 @@ func (r *runner) validatePayload() error {
|
|
|
337
341
|
if r.payload == "" {
|
|
338
342
|
return fmt.Errorf("generated install payload not found; pass --payload-dir or run scripts/build-host-artifacts.sh")
|
|
339
343
|
}
|
|
340
|
-
if err := hostpack.ValidatePayload(r.payloadFS, r.opts.WithCodex, r.opts.WithOmp, r.opts.WithPi); err != nil {
|
|
344
|
+
if err := hostpack.ValidatePayload(r.payloadFS, r.opts.WithCodex, r.opts.WithOmp, r.opts.WithPi, r.opts.WithDevin); err != nil {
|
|
341
345
|
return fmt.Errorf("generated install payload under %s: %w", r.payload, err)
|
|
342
346
|
}
|
|
343
347
|
return nil
|
|
@@ -355,6 +359,9 @@ func isGlobalTarget(target string) bool {
|
|
|
355
359
|
filepath.Join(home, ".omp", "agent"),
|
|
356
360
|
filepath.Join(home, ".pi"),
|
|
357
361
|
filepath.Join(home, ".pi", "agent"),
|
|
362
|
+
filepath.Join(home, ".devin"),
|
|
363
|
+
filepath.Join(home, ".config", "devin"),
|
|
364
|
+
filepath.Join(home, ".agents"),
|
|
358
365
|
} {
|
|
359
366
|
if target == global || strings.HasPrefix(target, global+string(os.PathSeparator)) {
|
|
360
367
|
return true
|
|
@@ -54,12 +54,15 @@ func TestInstallPrintsFirstMoveForInstalledHosts(t *testing.T) {
|
|
|
54
54
|
withCodex bool
|
|
55
55
|
withOmp bool
|
|
56
56
|
withPi bool
|
|
57
|
+
withDevin bool
|
|
57
58
|
want string
|
|
58
59
|
}{
|
|
59
60
|
{name: "Claude, Codex, and OMP", withCodex: true, withOmp: true, want: "Next: reopen the project, then run /rite (Claude) or $rite (Codex) or /skill:rite (omp/pi)."},
|
|
60
61
|
{name: "Claude and Codex", withCodex: true, withOmp: false, withPi: false, want: "Next: reopen the project, then run /rite (Claude) or $rite (Codex)."},
|
|
62
|
+
{name: "Claude, Codex, and Devin", withCodex: true, withDevin: true, want: "Next: reopen the project, then run /rite (Claude/Devin) or $rite (Codex)."},
|
|
61
63
|
{name: "Claude and OMP", withCodex: false, withOmp: true, withPi: false, want: "Next: reopen the project, then run /rite or /skill:rite."},
|
|
62
64
|
{name: "Claude and pi", withCodex: false, withOmp: false, withPi: true, want: "Next: reopen the project, then run /rite or /skill:rite."},
|
|
65
|
+
{name: "Claude and Devin", withCodex: false, withDevin: true, want: "Next: reopen the project, then run /rite."},
|
|
63
66
|
{name: "Claude only", withCodex: false, withOmp: false, withPi: false, want: "Next: reopen the project, then run /rite."},
|
|
64
67
|
} {
|
|
65
68
|
t.Run(tc.name, func(t *testing.T) {
|
|
@@ -70,6 +73,7 @@ func TestInstallPrintsFirstMoveForInstalledHosts(t *testing.T) {
|
|
|
70
73
|
opts.WithCodex = tc.withCodex
|
|
71
74
|
opts.WithOmp = tc.withOmp
|
|
72
75
|
opts.WithPi = tc.withPi
|
|
76
|
+
opts.WithDevin = tc.withDevin
|
|
73
77
|
opts.Stdout = &out
|
|
74
78
|
opts.Stderr = &bytes.Buffer{}
|
|
75
79
|
|
|
@@ -125,6 +129,9 @@ func TestMarkerMergeAndUninstallPreserveUserContent(t *testing.T) {
|
|
|
125
129
|
if strings.Count(agents, "<!-- BEGIN DEVRITES CODEX -->") != 1 {
|
|
126
130
|
t.Fatalf("AGENTS marker duplicated:\n%s", agents)
|
|
127
131
|
}
|
|
132
|
+
if strings.Count(agents, "<!-- BEGIN DEVRITES DEVIN -->") != 1 {
|
|
133
|
+
t.Fatalf("AGENTS Devin marker missing or duplicated:\n%s", agents)
|
|
134
|
+
}
|
|
128
135
|
if !strings.Contains(agents, "user guidance") {
|
|
129
136
|
t.Fatal("AGENTS user content lost")
|
|
130
137
|
}
|
|
@@ -139,9 +146,12 @@ func TestMarkerMergeAndUninstallPreserveUserContent(t *testing.T) {
|
|
|
139
146
|
}
|
|
140
147
|
|
|
141
148
|
runUninstall(t, target)
|
|
142
|
-
if got := testutil.ReadFile(t, filepath.Join(target, "AGENTS.md")); !strings.Contains(got, "user guidance") || strings.Contains(got, "DEVRITES CODEX") {
|
|
149
|
+
if got := testutil.ReadFile(t, filepath.Join(target, "AGENTS.md")); !strings.Contains(got, "user guidance") || strings.Contains(got, "DEVRITES CODEX") || strings.Contains(got, "DEVRITES DEVIN") {
|
|
143
150
|
t.Fatalf("AGENTS uninstall preservation wrong:\n%s", got)
|
|
144
151
|
}
|
|
152
|
+
if exists(filepath.Join(target, ".devin")) {
|
|
153
|
+
t.Fatal("uninstall left .devin behind")
|
|
154
|
+
}
|
|
145
155
|
if got := testutil.ReadFile(t, filepath.Join(target, ".codex", "config.toml")); !strings.Contains(got, `model = "x"`) || strings.Contains(got, "DEVRITES CODEX") {
|
|
146
156
|
t.Fatalf("config uninstall preservation wrong:\n%s", got)
|
|
147
157
|
}
|
|
@@ -761,7 +771,7 @@ func TestLegacyCodexHooksMergeIsCleanupOnly(t *testing.T) {
|
|
|
761
771
|
if !ok || merge != legacy {
|
|
762
772
|
t.Fatalf("legacy marker lookup = %#v, %t", merge, ok)
|
|
763
773
|
}
|
|
764
|
-
if slices.Contains(hostpack.RequiredPayload(true, true, true), "codex/hooks.json") {
|
|
774
|
+
if slices.Contains(hostpack.RequiredPayload(true, true, true, true), "codex/hooks.json") {
|
|
765
775
|
t.Fatal("legacy Codex hooks entered the required payload")
|
|
766
776
|
}
|
|
767
777
|
r := runner{opts: DefaultOptions(ModeInstall), payloadFS: os.DirFS(testPayload(t))}
|
|
@@ -1254,6 +1264,9 @@ extends = ":workspace"
|
|
|
1254
1264
|
testutil.WriteFile(t, filepath.Join(root, "pi", "agents", "devrites-code-reviewer.md"), "pi agent\n")
|
|
1255
1265
|
testutil.WriteFile(t, filepath.Join(root, "pi", "prompts", "rite.md"), "pi prompt\n")
|
|
1256
1266
|
testutil.WriteFile(t, filepath.Join(root, "pi", "AGENTS.md"), "<!-- BEGIN DEVRITES PI -->\nDevRites\n<!-- END DEVRITES PI -->\n")
|
|
1267
|
+
testutil.WriteFile(t, filepath.Join(root, "devin", "skills", "rite", "SKILL.md"), "devin rite\n")
|
|
1268
|
+
testutil.WriteFile(t, filepath.Join(root, "devin", "agents", "devrites-code-reviewer.md"), "devin agent\n")
|
|
1269
|
+
testutil.WriteFile(t, filepath.Join(root, "devin", "AGENTS.md"), "<!-- BEGIN DEVRITES DEVIN -->\nDevRites\n<!-- END DEVRITES DEVIN -->\n")
|
|
1257
1270
|
}
|
|
1258
1271
|
|
|
1259
1272
|
func testSource(t *testing.T, version string) string {
|
|
@@ -93,7 +93,7 @@ func (r *runner) preflightUninstall(entries []string) error {
|
|
|
93
93
|
|
|
94
94
|
func (r *runner) desiredInstallPaths() (map[string]bool, error) {
|
|
95
95
|
out := map[string]bool{".devrites/README.md": true}
|
|
96
|
-
for _, tree := range hostpack.InstallTrees(r.opts.WithSkills, r.opts.WithAgents, r.opts.WithCodex, r.opts.WithOmp, r.opts.WithPi) {
|
|
96
|
+
for _, tree := range hostpack.InstallTrees(r.opts.WithSkills, r.opts.WithAgents, r.opts.WithCodex, r.opts.WithOmp, r.opts.WithPi, r.opts.WithDevin) {
|
|
97
97
|
err := fs.WalkDir(r.payloadFS, tree.PayloadPrefix, func(path string, d fs.DirEntry, err error) error {
|
|
98
98
|
if err != nil {
|
|
99
99
|
return err
|
|
@@ -114,7 +114,7 @@ func (r *runner) desiredInstallPaths() (map[string]bool, error) {
|
|
|
114
114
|
}
|
|
115
115
|
if r.opts.WithSkills && r.opts.AliasMode == "all" {
|
|
116
116
|
for _, alias := range hostpack.Aliases {
|
|
117
|
-
for _, rel := range hostpack.AliasTargets(alias, r.opts.WithCodex, r.opts.WithOmp, r.opts.WithPi) {
|
|
117
|
+
for _, rel := range hostpack.AliasTargets(alias, r.opts.WithCodex, r.opts.WithOmp, r.opts.WithPi, r.opts.WithDevin) {
|
|
118
118
|
out[rel] = true
|
|
119
119
|
}
|
|
120
120
|
}
|
|
@@ -126,6 +126,9 @@ func (r *runner) desiredInstallPaths() (map[string]bool, error) {
|
|
|
126
126
|
if r.opts.WithSkills && r.opts.WithPi {
|
|
127
127
|
out[hostpack.PiAgentsMerge.MarkerRel] = true
|
|
128
128
|
}
|
|
129
|
+
if r.opts.WithSkills && r.opts.WithDevin {
|
|
130
|
+
out[hostpack.DevinAgentsMerge.MarkerRel] = true
|
|
131
|
+
}
|
|
129
132
|
if r.opts.WithSkills {
|
|
130
133
|
out[hostpack.ClaudeSettingsMerge.MarkerRel] = true
|
|
131
134
|
}
|
|
@@ -142,6 +145,9 @@ func (r *runner) installMergeTargets() []string {
|
|
|
142
145
|
if r.opts.WithPi {
|
|
143
146
|
out = append(out, hostpack.PiAgentsMerge.TargetRel)
|
|
144
147
|
}
|
|
148
|
+
if r.opts.WithDevin {
|
|
149
|
+
out = append(out, hostpack.DevinAgentsMerge.TargetRel)
|
|
150
|
+
}
|
|
145
151
|
}
|
|
146
152
|
return out
|
|
147
153
|
}
|
|
@@ -65,7 +65,7 @@ func runUpdate(opts Options) error {
|
|
|
65
65
|
if err != nil {
|
|
66
66
|
return fmt.Errorf("resolve payload %s: %w", opts.PayloadDir, err)
|
|
67
67
|
}
|
|
68
|
-
if err := hostpack.ValidatePayload(os.DirFS(payload), true, true, true); err != nil {
|
|
68
|
+
if err := hostpack.ValidatePayload(os.DirFS(payload), true, true, true, true); err != nil {
|
|
69
69
|
return fmt.Errorf("local update payload under %s is invalid: %w", payload, err)
|
|
70
70
|
}
|
|
71
71
|
installFlags := manifestHeader(mf, "devrites-flags")
|