devrites 5.10.2 → 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 +6 -0
- package/README.md +24 -10
- package/bin/devrites.mjs +2 -0
- package/docs/command-map.md +5 -4
- package/docs/skills.md +10 -4
- 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/install.sh +4 -1
- package/pack/generated/README.md +4 -2
- 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/package.json +4 -2
- package/scripts/build-host-artifacts.sh +48 -5
- package/scripts/devin-generate.sh +222 -0
- package/update.sh +2 -1
package/CHANGELOG.md
CHANGED
|
@@ -2,6 +2,12 @@
|
|
|
2
2
|
|
|
3
3
|
All notable changes to DevRites are documented here. The format follows [Keep a Changelog](https://keepachangelog.com/en/1.1.0/) and DevRites adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). Releases are generated automatically by [semantic-release](https://semantic-release.gitbook.io/) from Conventional Commits on `main`.
|
|
4
4
|
|
|
5
|
+
## [5.11.0](https://github.com/ViktorsBaikers/DevRites/compare/v5.10.2...v5.11.0) (2026-09-16)
|
|
6
|
+
|
|
7
|
+
### Added
|
|
8
|
+
|
|
9
|
+
* **installer:** add Devin CLI host generation and install support ([#79](https://github.com/ViktorsBaikers/DevRites/issues/79)) ([a94056b](https://github.com/ViktorsBaikers/DevRites/commit/a94056bc20f520537395cf5c7c075e700d5a0b26))
|
|
10
|
+
|
|
5
11
|
## [5.10.2](https://github.com/ViktorsBaikers/DevRites/compare/v5.10.1...v5.10.2) (2026-09-15)
|
|
6
12
|
|
|
7
13
|
### Fixed
|
package/README.md
CHANGED
|
@@ -4,9 +4,10 @@
|
|
|
4
4
|
|
|
5
5
|
# DevRites
|
|
6
6
|
|
|
7
|
-
DevRites is a repository-local workflow for building software with Claude Code
|
|
8
|
-
or
|
|
9
|
-
recorded proof, a release decision, and an explicit ship
|
|
7
|
+
DevRites is a repository-local workflow for building software with Claude Code,
|
|
8
|
+
Codex, omp, pi, or Devin CLI. It turns a feature request into a spec, a sliced
|
|
9
|
+
plan, working code, recorded proof, a release decision, and an explicit ship
|
|
10
|
+
step.
|
|
10
11
|
|
|
11
12
|
The work lives under `.devrites/`, not in chat history. A later session or a
|
|
12
13
|
different agent can read the same plan, decisions, state, and evidence before it
|
|
@@ -33,7 +34,7 @@ project-conventional push, tag, or PR action, and archive the workspace.
|
|
|
33
34
|
Unattended runs may create local WIP checkpoint commits along the way, but they
|
|
34
35
|
remain local unless Ship's disclosed plan includes an approved remote action.
|
|
35
36
|
|
|
36
|
-
**Status:** [`v5.
|
|
37
|
+
**Status:** [`v5.11.0`](https://github.com/ViktorsBaikers/DevRites/releases/tag/v5.11.0): see [`CHANGELOG.md`](CHANGELOG.md) for release notes.
|
|
37
38
|
|
|
38
39
|
This is the latest published release; `main` may contain unreleased work.
|
|
39
40
|
|
|
@@ -47,8 +48,9 @@ Run this from the root of your project. Node.js 18 or later is required.
|
|
|
47
48
|
npx devrites@latest
|
|
48
49
|
```
|
|
49
50
|
|
|
50
|
-
The installer adds project-local support for Claude Code, Codex, omp, and
|
|
51
|
-
It does not write skills, agents, or hooks to `~/.claude`, `~/.codex`,
|
|
51
|
+
The installer adds project-local support for Claude Code, Codex, omp, pi, and
|
|
52
|
+
Devin CLI. It does not write skills, agents, or hooks to `~/.claude`, `~/.codex`,
|
|
53
|
+
`~/.pi`, or `~/.config/devin`.
|
|
52
54
|
|
|
53
55
|
### 2. Choose the smallest route
|
|
54
56
|
|
|
@@ -78,8 +80,8 @@ proof and next action.
|
|
|
78
80
|
## How the lifecycle works
|
|
79
81
|
|
|
80
82
|
Claude Code supports both `/rite <verb>` and `/rite-<verb>`. Codex uses the same
|
|
81
|
-
forms with `$`: `$rite <verb>` and `$rite-<verb>`. omp and
|
|
82
|
-
slash forms (on pi they run as prompt templates under `.pi/prompts`, with
|
|
83
|
+
forms with `$`: `$rite <verb>` and `$rite-<verb>`. omp, pi, and Devin CLI use the
|
|
84
|
+
Claude slash forms (on pi they run as prompt templates under `.pi/prompts`, with
|
|
83
85
|
`/skill:rite-<verb>` equivalent). The menu and direct forms run the same skill.
|
|
84
86
|
|
|
85
87
|
| # | Stage | Direct command | What happens |
|
|
@@ -299,7 +301,9 @@ Useful install flags:
|
|
|
299
301
|
| `--dry-run` | Show planned file operations without changing anything. |
|
|
300
302
|
| `--force` | Replace or remove foreign or customized managed files. The installer still rejects symlinks and path escapes. |
|
|
301
303
|
| `--no-codex` | Skip `.agents`, `.codex`, and the Codex `AGENTS.md` block. |
|
|
304
|
+
| `--no-omp` | Skip `.omp` skills and agents. |
|
|
302
305
|
| `--no-pi` | Skip `.pi` skills, agents, prompt commands, and the pi `AGENTS.md` block. |
|
|
306
|
+
| `--no-devin` | Skip `.devin` skills, agents, and the Devin `AGENTS.md` block. |
|
|
303
307
|
| `--no-agents` | Skip hook-free native specialist profiles. |
|
|
304
308
|
| `--no-skills` | Skip skills and their bundled standards. |
|
|
305
309
|
| `--no-binary` | Do not keep the shared `devrites-engine` binary in a user or system bin directory. |
|
|
@@ -391,7 +395,7 @@ paths pass bounded streaming preflight before extraction. There is no unchecked
|
|
|
391
395
|
raw, source-archive, tag, or default-branch fallback. See
|
|
392
396
|
[`SECURITY.md`](SECURITY.md) for the representative bounds.
|
|
393
397
|
|
|
394
|
-
##
|
|
398
|
+
## Host integration
|
|
395
399
|
|
|
396
400
|
Claude Code receives skills under `.claude/skills/`, agents under
|
|
397
401
|
`.claude/agents/`, and native root permissions merged into
|
|
@@ -405,6 +409,15 @@ only `devrites-slice-wright` is writable; every other specialist is read-only.
|
|
|
405
409
|
Existing user content remains in place. Codex users invoke skills with `$rite`,
|
|
406
410
|
`$rite-spec`, or `/skills`.
|
|
407
411
|
|
|
412
|
+
Devin CLI receives the same skills under `.devin/skills/`, custom subagent
|
|
413
|
+
profiles under `.devin/agents/`, and a marked guidance block in `AGENTS.md`.
|
|
414
|
+
Profiles use `allowed-tools` with Devin tool names: only
|
|
415
|
+
`devrites-slice-wright` keeps `edit`, `write`, and `exec`; every other
|
|
416
|
+
specialist is read-only. Dispatch goes through `run_subagent` with the exact
|
|
417
|
+
`devrites-<role>` profile; a missing profile stops for HITL instead of
|
|
418
|
+
substituting `subagent_general`. Profiles load when a session starts, so reopen
|
|
419
|
+
the project after installing.
|
|
420
|
+
|
|
408
421
|
DevRites is installed through npm or the Bash bootstrap. It is not distributed
|
|
409
422
|
through Claude Code or Codex plugin stores.
|
|
410
423
|
|
|
@@ -417,7 +430,8 @@ shared contracts and engineering standards.
|
|
|
417
430
|
|
|
418
431
|
Seventeen fresh-context agent profiles ship with the pack. Claude has sixteen
|
|
419
432
|
read-only roles plus the sole source/test writer role,
|
|
420
|
-
`devrites-slice-wright`; Codex
|
|
433
|
+
`devrites-slice-wright`; Codex, omp, pi, and Devin generate the same
|
|
434
|
+
one-writer/sixteen-reader split.
|
|
421
435
|
|
|
422
436
|
The authoritative [skills catalogue](docs/skills.md) lists every skill and
|
|
423
437
|
agent. The [flow diagrams](docs/flow.md) show routing, reviewer fan-out, and
|
package/bin/devrites.mjs
CHANGED
|
@@ -63,6 +63,8 @@ Common flags:
|
|
|
63
63
|
--force Overwrite existing non-DevRites files
|
|
64
64
|
--no-codex Skip Codex support files (.agents, .codex, AGENTS.md)
|
|
65
65
|
--no-omp Skip OMP support files (.omp/skills, .omp/agents)
|
|
66
|
+
--no-pi Skip pi support files (.pi/skills, .pi/agents, .pi/prompts)
|
|
67
|
+
--no-devin Skip Devin CLI support files (.devin/skills, .devin/agents)
|
|
66
68
|
--short-aliases=all Also install /define /build /prove /seal
|
|
67
69
|
--no-agents Skip hook-free native specialist profiles
|
|
68
70
|
--no-skills Skip skills and bundled engineering standards
|
package/docs/command-map.md
CHANGED
|
@@ -3,9 +3,9 @@
|
|
|
3
3
|
This page lists every shipped skill and agent, including its triggers, inputs,
|
|
4
4
|
outputs, and interactions.
|
|
5
5
|
|
|
6
|
-
DevRites ships through npm (`npx devrites ...`). Claude Code
|
|
7
|
-
comes from generated host artifacts copied by the npm
|
|
8
|
-
distributed as a Claude or Codex plugin.
|
|
6
|
+
DevRites ships through npm (`npx devrites ...`). Claude Code, Codex, omp, pi,
|
|
7
|
+
and Devin CLI support comes from generated host artifacts copied by the npm
|
|
8
|
+
installer; DevRites is not distributed as a Claude or Codex plugin.
|
|
9
9
|
|
|
10
10
|
- **Workflow diagram** (top-level flow) → [`flow.md`](flow.md).
|
|
11
11
|
- **Architecture rationale** → [`architecture.md`](architecture.md).
|
|
@@ -57,7 +57,8 @@ pass; usage/root errors exit `2` and candidate blocks exit `3`. There are no
|
|
|
57
57
|
semantic readiness commands, reviewer-prose parsers, capability-ledger engine,
|
|
58
58
|
or compatibility telemetry.
|
|
59
59
|
|
|
60
|
-
Claude Code and
|
|
60
|
+
Claude Code, Codex, omp, pi, and Devin own native dispatch. Installed skills
|
|
61
|
+
and exact agents
|
|
61
62
|
own semantic readiness, traceability, acceptance/evidence quality, doubt,
|
|
62
63
|
review reconciliation, test-quality assessment, capability interpretation,
|
|
63
64
|
workspace compatibility, and
|
package/docs/skills.md
CHANGED
|
@@ -12,11 +12,16 @@ regenerate missing payload components before installation; the engine validates
|
|
|
12
12
|
and copies them but never generates them. The installer copies Codex skill
|
|
13
13
|
mirrors to `.agents/skills`, mirrors the rules under
|
|
14
14
|
`.agents/skills/devrites-lib/reference/standards`, installs `.codex/agents`, and
|
|
15
|
-
merges native Codex configuration and guidance.
|
|
15
|
+
merges native Codex configuration and guidance. Devin CLI receives skills under
|
|
16
|
+
`.devin/skills`, custom subagent profiles under `.devin/agents`, and a marked
|
|
17
|
+
guidance block in `AGENTS.md`.
|
|
16
18
|
|
|
17
19
|
The root and reviewers never write source. Claude enforces the root boundary in
|
|
18
20
|
plan mode. Codex uses a workspace-capable root so its sole write-capable
|
|
19
|
-
slice-wright can execute, while all other specialists remain read-only.
|
|
21
|
+
slice-wright can execute, while all other specialists remain read-only. On
|
|
22
|
+
Devin, `allowed-tools` gives only `devrites-slice-wright` `edit`, `write`, and
|
|
23
|
+
`exec`; a missing required profile stops for HITL instead of substituting a
|
|
24
|
+
generic profile. The
|
|
20
25
|
installed `devrites-engine` owns strict candidate identity, deterministic checks,
|
|
21
26
|
exact proof/review/seal bindings,
|
|
22
27
|
atomic state, secret scanning, and installation diagnostics. Native/root policy
|
|
@@ -28,8 +33,9 @@ bootstraps or proxies the engine directly (see [`cli.md`](cli.md)).
|
|
|
28
33
|
|
|
29
34
|
Each phase skill names the specialist the host should run when one is needed.
|
|
30
35
|
Codex loads those project agents from `.codex/agents`, then waits for and
|
|
31
|
-
reconciles their normal results.
|
|
32
|
-
|
|
36
|
+
reconciles their normal results. Devin loads the same profiles from
|
|
37
|
+
`.devin/agents` as `run_subagent` profiles. The engine has no dispatch protocol;
|
|
38
|
+
native hosts follow the shared, host-neutral
|
|
33
39
|
[`parallel-dispatch.md`](../pack/.claude/skills/devrites-lib/reference/parallel-dispatch.md)
|
|
34
40
|
contract when a rite names parallel reviewers.
|
|
35
41
|
|
|
@@ -17,10 +17,12 @@ const (
|
|
|
17
17
|
CodexSkillsTarget = ".agents/skills"
|
|
18
18
|
OmpSkillsTarget = ".omp/skills"
|
|
19
19
|
PiSkillsTarget = ".pi/skills"
|
|
20
|
+
DevinSkillsTarget = ".devin/skills"
|
|
20
21
|
ClaudeAgentsTarget = ".claude/agents"
|
|
21
22
|
CodexAgentsTarget = ".codex/agents"
|
|
22
23
|
OmpAgentsTarget = ".omp/agents"
|
|
23
24
|
PiAgentsTarget = ".pi/agents"
|
|
25
|
+
DevinAgentsTarget = ".devin/agents"
|
|
24
26
|
PiPromptsTarget = ".pi/prompts"
|
|
25
27
|
ClaudeWorkflowsTarget = ".claude/workflows"
|
|
26
28
|
|
|
@@ -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")
|