devrites 5.5.0 → 5.7.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 +12 -0
- package/README.md +8 -6
- package/engine/internal/devritespaths/paths.go +3 -0
- package/engine/internal/hostpack/hostpack.go +45 -6
- package/engine/internal/hostpack/hostpack_test.go +29 -13
- package/engine/internal/install/apply.go +14 -5
- package/engine/internal/install/install.go +8 -2
- package/engine/internal/install/install_test.go +12 -5
- package/engine/internal/install/merge.go +5 -0
- package/engine/internal/install/preflight.go +20 -2
- package/engine/internal/install/uninstall.go +5 -0
- package/engine/internal/install/update.go +1 -1
- package/install.sh +107 -38
- package/pack/.claude/skills/rite-define/SKILL.md +1 -1
- package/pack/.claude/skills/rite-handoff/SKILL.md +1 -1
- package/pack/.claude/skills/rite-plan/SKILL.md +1 -1
- package/pack/.claude/skills/rite-pressure-test/SKILL.md +1 -1
- package/pack/.claude/skills/rite-quick/SKILL.md +1 -1
- package/pack/.claude/skills/rite-status/SKILL.md +1 -1
- package/pack/.claude/skills/rite-zoom-out/SKILL.md +1 -1
- package/pack/generated/README.md +5 -1
- package/pack/generated/claude/skills/rite-define/SKILL.md +1 -1
- package/pack/generated/claude/skills/rite-handoff/SKILL.md +1 -1
- package/pack/generated/claude/skills/rite-plan/SKILL.md +1 -1
- package/pack/generated/claude/skills/rite-pressure-test/SKILL.md +1 -1
- package/pack/generated/claude/skills/rite-quick/SKILL.md +1 -1
- package/pack/generated/claude/skills/rite-status/SKILL.md +1 -1
- package/pack/generated/claude/skills/rite-zoom-out/SKILL.md +1 -1
- package/pack/generated/codex/skills/rite-define/SKILL.md +1 -1
- package/pack/generated/codex/skills/rite-handoff/SKILL.md +1 -1
- package/pack/generated/codex/skills/rite-plan/SKILL.md +1 -1
- package/pack/generated/codex/skills/rite-pressure-test/SKILL.md +1 -1
- package/pack/generated/codex/skills/rite-quick/SKILL.md +1 -1
- package/pack/generated/codex/skills/rite-status/SKILL.md +1 -1
- package/pack/generated/codex/skills/rite-zoom-out/SKILL.md +1 -1
- package/pack/generated/omp/skills/rite-define/SKILL.md +1 -1
- package/pack/generated/omp/skills/rite-handoff/SKILL.md +1 -1
- package/pack/generated/omp/skills/rite-plan/SKILL.md +1 -1
- package/pack/generated/omp/skills/rite-pressure-test/SKILL.md +1 -1
- package/pack/generated/omp/skills/rite-quick/SKILL.md +1 -1
- package/pack/generated/omp/skills/rite-status/SKILL.md +1 -1
- package/pack/generated/omp/skills/rite-zoom-out/SKILL.md +1 -1
- package/pack/generated/pi/AGENTS.md +22 -0
- package/pack/generated/pi/agents/devrites-code-reviewer.md +142 -0
- package/pack/generated/pi/agents/devrites-devex-reviewer.md +124 -0
- package/pack/generated/pi/agents/devrites-doubt-reviewer.md +88 -0
- package/pack/generated/pi/agents/devrites-evidence-scout.md +72 -0
- package/pack/generated/pi/agents/devrites-frontend-reviewer.md +116 -0
- package/pack/generated/pi/agents/devrites-performance-reviewer.md +115 -0
- package/pack/generated/pi/agents/devrites-plan-drafter.md +99 -0
- package/pack/generated/pi/agents/devrites-plan-reviewer.md +142 -0
- package/pack/generated/pi/agents/devrites-proof-runner.md +74 -0
- package/pack/generated/pi/agents/devrites-retrospector.md +61 -0
- package/pack/generated/pi/agents/devrites-security-auditor.md +109 -0
- package/pack/generated/pi/agents/devrites-simplifier-reviewer.md +94 -0
- package/pack/generated/pi/agents/devrites-slice-wright.md +204 -0
- package/pack/generated/pi/agents/devrites-spec-reviewer.md +96 -0
- package/pack/generated/pi/agents/devrites-strategy-reviewer.md +100 -0
- package/pack/generated/pi/agents/devrites-test-analyst.md +94 -0
- package/pack/generated/pi/agents/devrites-upgrade-planner.md +89 -0
- package/pack/generated/pi/prompts/rite-adopt.md +5 -0
- package/pack/generated/pi/prompts/rite-autocomplete.md +5 -0
- package/pack/generated/pi/prompts/rite-build.md +5 -0
- package/pack/generated/pi/prompts/rite-clarify.md +5 -0
- package/pack/generated/pi/prompts/rite-converge.md +5 -0
- package/pack/generated/pi/prompts/rite-customize.md +5 -0
- package/pack/generated/pi/prompts/rite-define.md +5 -0
- package/pack/generated/pi/prompts/rite-doctor.md +5 -0
- package/pack/generated/pi/prompts/rite-dogfood.md +5 -0
- package/pack/generated/pi/prompts/rite-explain.md +5 -0
- package/pack/generated/pi/prompts/rite-frame.md +5 -0
- package/pack/generated/pi/prompts/rite-handoff.md +5 -0
- package/pack/generated/pi/prompts/rite-learn.md +5 -0
- package/pack/generated/pi/prompts/rite-plan.md +5 -0
- package/pack/generated/pi/prompts/rite-polish.md +5 -0
- package/pack/generated/pi/prompts/rite-pov.md +5 -0
- package/pack/generated/pi/prompts/rite-pr-feedback.md +5 -0
- package/pack/generated/pi/prompts/rite-pressure-test.md +5 -0
- package/pack/generated/pi/prompts/rite-prototype.md +5 -0
- package/pack/generated/pi/prompts/rite-prove.md +5 -0
- package/pack/generated/pi/prompts/rite-quick.md +5 -0
- package/pack/generated/pi/prompts/rite-resolve.md +5 -0
- package/pack/generated/pi/prompts/rite-review.md +5 -0
- package/pack/generated/pi/prompts/rite-seal.md +5 -0
- package/pack/generated/pi/prompts/rite-ship.md +5 -0
- package/pack/generated/pi/prompts/rite-spec.md +5 -0
- package/pack/generated/pi/prompts/rite-status.md +5 -0
- package/pack/generated/pi/prompts/rite-temper.md +5 -0
- package/pack/generated/pi/prompts/rite-upgrade.md +5 -0
- package/pack/generated/pi/prompts/rite-vet.md +5 -0
- package/pack/generated/pi/prompts/rite-watch-pr.md +5 -0
- package/pack/generated/pi/prompts/rite-zoom-out.md +5 -0
- package/pack/generated/pi/prompts/rite.md +5 -0
- package/pack/generated/pi/skills/devrites-api-interface/SKILL.md +63 -0
- package/pack/generated/pi/skills/devrites-audit/SKILL.md +50 -0
- package/pack/generated/pi/skills/devrites-browser-proof/SKILL.md +76 -0
- package/pack/generated/pi/skills/devrites-browser-proof/reference/browser-performance.md +15 -0
- package/pack/generated/pi/skills/devrites-browser-proof/reference/visual-verdict.md +34 -0
- package/pack/generated/pi/skills/devrites-debug-recovery/SKILL.md +96 -0
- package/pack/generated/pi/skills/devrites-debug-recovery/reference/build-the-loop.md +58 -0
- package/pack/generated/pi/skills/devrites-debug-recovery/reference/cleanup-and-classify.md +34 -0
- package/pack/generated/pi/skills/devrites-debug-recovery/reference/hypotheses.md +17 -0
- package/pack/generated/pi/skills/devrites-debug-recovery/reference/instrumentation.md +21 -0
- package/pack/generated/pi/skills/devrites-debug-recovery/reference/regression-test.md +30 -0
- package/pack/generated/pi/skills/devrites-debug-recovery/reference/trace.md +25 -0
- package/pack/generated/pi/skills/devrites-doubt/SKILL.md +79 -0
- package/pack/generated/pi/skills/devrites-frontend-craft/SKILL.md +86 -0
- package/pack/generated/pi/skills/devrites-frontend-craft/reference/craft.md +63 -0
- package/pack/generated/pi/skills/devrites-frontend-craft/reference/design-references.md +116 -0
- package/pack/generated/pi/skills/devrites-frontend-craft/reference/fullstack.md +46 -0
- package/pack/generated/pi/skills/devrites-frontend-craft/reference/quality-standards.md +294 -0
- package/pack/generated/pi/skills/devrites-frontend-craft/reference/reuse-first.md +53 -0
- package/pack/generated/pi/skills/devrites-frontend-craft/reference/shape.md +56 -0
- package/pack/generated/pi/skills/devrites-interview/SKILL.md +102 -0
- package/pack/generated/pi/skills/devrites-lib/SKILL.md +58 -0
- package/pack/generated/pi/skills/devrites-lib/reference/candidate-integrity.md +42 -0
- package/pack/generated/pi/skills/devrites-lib/reference/intent-map.md +64 -0
- package/pack/generated/pi/skills/devrites-lib/reference/orchestration-profiles.md +27 -0
- package/pack/generated/pi/skills/devrites-lib/reference/parallel-dispatch.md +73 -0
- package/pack/generated/pi/skills/devrites-lib/reference/reply-contract.md +88 -0
- package/pack/generated/pi/skills/devrites-lib/reference/standards/README.md +60 -0
- package/pack/generated/pi/skills/devrites-lib/reference/standards/acceptance-preserving-reslice.md +30 -0
- package/pack/generated/pi/skills/devrites-lib/reference/standards/afk-hitl.md +398 -0
- package/pack/generated/pi/skills/devrites-lib/reference/standards/agents.md +99 -0
- package/pack/generated/pi/skills/devrites-lib/reference/standards/anti-patterns.md +48 -0
- package/pack/generated/pi/skills/devrites-lib/reference/standards/browser-proof-checklist.md +24 -0
- package/pack/generated/pi/skills/devrites-lib/reference/standards/ci-cd.md +50 -0
- package/pack/generated/pi/skills/devrites-lib/reference/standards/code-navigation.md +43 -0
- package/pack/generated/pi/skills/devrites-lib/reference/standards/code-review.md +108 -0
- package/pack/generated/pi/skills/devrites-lib/reference/standards/coding-style.md +48 -0
- package/pack/generated/pi/skills/devrites-lib/reference/standards/context-hygiene.md +109 -0
- package/pack/generated/pi/skills/devrites-lib/reference/standards/core.md +167 -0
- package/pack/generated/pi/skills/devrites-lib/reference/standards/data-integrity.md +118 -0
- package/pack/generated/pi/skills/devrites-lib/reference/standards/debug-recovery.md +28 -0
- package/pack/generated/pi/skills/devrites-lib/reference/standards/definition-of-done.md +19 -0
- package/pack/generated/pi/skills/devrites-lib/reference/standards/deprecation.md +31 -0
- package/pack/generated/pi/skills/devrites-lib/reference/standards/developer-experience.md +119 -0
- package/pack/generated/pi/skills/devrites-lib/reference/standards/development-workflow.md +29 -0
- package/pack/generated/pi/skills/devrites-lib/reference/standards/documentation.md +43 -0
- package/pack/generated/pi/skills/devrites-lib/reference/standards/edge-case-trace.md +92 -0
- package/pack/generated/pi/skills/devrites-lib/reference/standards/elicitation.md +85 -0
- package/pack/generated/pi/skills/devrites-lib/reference/standards/error-handling.md +47 -0
- package/pack/generated/pi/skills/devrites-lib/reference/standards/git-workflow.md +49 -0
- package/pack/generated/pi/skills/devrites-lib/reference/standards/hooks.md +25 -0
- package/pack/generated/pi/skills/devrites-lib/reference/standards/integration-reliability.md +102 -0
- package/pack/generated/pi/skills/devrites-lib/reference/standards/loop-operations.md +85 -0
- package/pack/generated/pi/skills/devrites-lib/reference/standards/observability.md +88 -0
- package/pack/generated/pi/skills/devrites-lib/reference/standards/one-shot-actions.md +97 -0
- package/pack/generated/pi/skills/devrites-lib/reference/standards/patterns.md +68 -0
- package/pack/generated/pi/skills/devrites-lib/reference/standards/performance.md +51 -0
- package/pack/generated/pi/skills/devrites-lib/reference/standards/principles.md +42 -0
- package/pack/generated/pi/skills/devrites-lib/reference/standards/prose-style.md +123 -0
- package/pack/generated/pi/skills/devrites-lib/reference/standards/release/ship-checklist.md +8 -0
- package/pack/generated/pi/skills/devrites-lib/reference/standards/repository-topology.md +80 -0
- package/pack/generated/pi/skills/devrites-lib/reference/standards/review-checklist.md +12 -0
- package/pack/generated/pi/skills/devrites-lib/reference/standards/security-checklist.md +25 -0
- package/pack/generated/pi/skills/devrites-lib/reference/standards/security.md +202 -0
- package/pack/generated/pi/skills/devrites-lib/reference/standards/skill-authoring.md +209 -0
- package/pack/generated/pi/skills/devrites-lib/reference/standards/spec-grammar.md +197 -0
- package/pack/generated/pi/skills/devrites-lib/reference/standards/test-proof-checklist.md +13 -0
- package/pack/generated/pi/skills/devrites-lib/reference/standards/testing.md +212 -0
- package/pack/generated/pi/skills/devrites-lib/reference/standards/tooling.md +92 -0
- package/pack/generated/pi/skills/devrites-lib/reference/standards/workflow-artifacts.md +427 -0
- package/pack/generated/pi/skills/devrites-lib/reference/visual-playbooks/code.md +44 -0
- package/pack/generated/pi/skills/devrites-lib/reference/visual-playbooks/comparison.md +42 -0
- package/pack/generated/pi/skills/devrites-lib/reference/visual-playbooks/diagram.md +51 -0
- package/pack/generated/pi/skills/devrites-lib/reference/visual-playbooks/index.md +66 -0
- package/pack/generated/pi/skills/devrites-lib/reference/visual-playbooks/input.md +46 -0
- package/pack/generated/pi/skills/devrites-lib/reference/visual-playbooks/outline-template.md +106 -0
- package/pack/generated/pi/skills/devrites-lib/reference/visual-playbooks/plan.md +48 -0
- package/pack/generated/pi/skills/devrites-lib/reference/visual-playbooks/slides.md +40 -0
- package/pack/generated/pi/skills/devrites-lib/reference/visual-playbooks/table.md +42 -0
- package/pack/generated/pi/skills/devrites-lib/reference/workspace-artifact-schema.md +267 -0
- package/pack/generated/pi/skills/devrites-prose-craft/SKILL.md +73 -0
- package/pack/generated/pi/skills/devrites-prose-craft/reference/banned-phrases.md +132 -0
- package/pack/generated/pi/skills/devrites-prose-craft/reference/examples.md +131 -0
- package/pack/generated/pi/skills/devrites-prose-craft/reference/structures.md +196 -0
- package/pack/generated/pi/skills/devrites-source-driven/SKILL.md +52 -0
- package/pack/generated/pi/skills/devrites-ux-shape/SKILL.md +134 -0
- package/pack/generated/pi/skills/devrites-ux-shape/reference/brief-template.md +108 -0
- package/pack/generated/pi/skills/devrites-ux-shape/reference/visual-direction-probe.md +48 -0
- package/pack/generated/pi/skills/rite/SKILL.md +148 -0
- package/pack/generated/pi/skills/rite/reference/menu.md +48 -0
- package/pack/generated/pi/skills/rite-adopt/SKILL.md +52 -0
- package/pack/generated/pi/skills/rite-adopt/reference/adoption.md +19 -0
- package/pack/generated/pi/skills/rite-adopt/reference/anti-patterns.md +19 -0
- package/pack/generated/pi/skills/rite-autocomplete/SKILL.md +132 -0
- package/pack/generated/pi/skills/rite-autocomplete/reference/decision-policy.md +41 -0
- package/pack/generated/pi/skills/rite-autocomplete/reference/loop.md +148 -0
- package/pack/generated/pi/skills/rite-autocomplete/reference/stop-conditions.md +92 -0
- package/pack/generated/pi/skills/rite-build/SKILL.md +96 -0
- package/pack/generated/pi/skills/rite-build/reference/afk-discipline.md +145 -0
- package/pack/generated/pi/skills/rite-build/reference/anti-patterns.md +23 -0
- package/pack/generated/pi/skills/rite-build/reference/checkpoint-protocol.md +120 -0
- package/pack/generated/pi/skills/rite-build/reference/checkpoint.md +44 -0
- package/pack/generated/pi/skills/rite-build/reference/frontend-trigger.md +39 -0
- package/pack/generated/pi/skills/rite-build/reference/one-slice-cycle.md +50 -0
- package/pack/generated/pi/skills/rite-build/reference/output.md +33 -0
- package/pack/generated/pi/skills/rite-build/reference/parallel-batch.md +205 -0
- package/pack/generated/pi/skills/rite-build/reference/phase-contract.md +87 -0
- package/pack/generated/pi/skills/rite-build/reference/spec-drift-guard.md +84 -0
- package/pack/generated/pi/skills/rite-build/reference/tdd.md +27 -0
- package/pack/generated/pi/skills/rite-build/reference/wright-dispatch.md +89 -0
- package/pack/generated/pi/skills/rite-clarify/SKILL.md +99 -0
- package/pack/generated/pi/skills/rite-clarify/reference/anti-patterns.md +24 -0
- package/pack/generated/pi/skills/rite-clarify/reference/decision-coverage.md +55 -0
- package/pack/generated/pi/skills/rite-converge/SKILL.md +145 -0
- package/pack/generated/pi/skills/rite-converge/reference/anti-patterns.md +35 -0
- package/pack/generated/pi/skills/rite-converge/reference/convergence-assessment.md +65 -0
- package/pack/generated/pi/skills/rite-customize/SKILL.md +60 -0
- package/pack/generated/pi/skills/rite-define/SKILL.md +169 -0
- package/pack/generated/pi/skills/rite-define/reference/anti-patterns.md +26 -0
- package/pack/generated/pi/skills/rite-define/reference/gates.md +154 -0
- package/pack/generated/pi/skills/rite-define/reference/plan-template.md +149 -0
- package/pack/generated/pi/skills/rite-doctor/SKILL.md +69 -0
- package/pack/generated/pi/skills/rite-dogfood/SKILL.md +55 -0
- package/pack/generated/pi/skills/rite-explain/SKILL.md +152 -0
- package/pack/generated/pi/skills/rite-explain/reference/intake.md +89 -0
- package/pack/generated/pi/skills/rite-frame/SKILL.md +115 -0
- package/pack/generated/pi/skills/rite-frame/reference/failure-modes.md +66 -0
- package/pack/generated/pi/skills/rite-handoff/SKILL.md +97 -0
- package/pack/generated/pi/skills/rite-handoff/reference/handoff-template.md +44 -0
- package/pack/generated/pi/skills/rite-learn/SKILL.md +72 -0
- package/pack/generated/pi/skills/rite-plan/SKILL.md +186 -0
- package/pack/generated/pi/skills/rite-plan/reference/anti-patterns.md +34 -0
- package/pack/generated/pi/skills/rite-plan/reference/dependency-graph.md +48 -0
- package/pack/generated/pi/skills/rite-plan/reference/replan-and-repair.md +105 -0
- package/pack/generated/pi/skills/rite-plan/reference/slicing.md +167 -0
- package/pack/generated/pi/skills/rite-plan/reference/task-breakdown.md +42 -0
- package/pack/generated/pi/skills/rite-polish/SKILL.md +104 -0
- package/pack/generated/pi/skills/rite-polish/reference/adr-promotion.md +11 -0
- package/pack/generated/pi/skills/rite-polish/reference/anti-ai-slop.md +187 -0
- package/pack/generated/pi/skills/rite-polish/reference/anti-patterns.md +30 -0
- package/pack/generated/pi/skills/rite-polish/reference/backend-polish.md +80 -0
- package/pack/generated/pi/skills/rite-polish/reference/browser-polish-evidence.md +33 -0
- package/pack/generated/pi/skills/rite-polish/reference/code.md +82 -0
- package/pack/generated/pi/skills/rite-polish/reference/design-memory.md +117 -0
- package/pack/generated/pi/skills/rite-polish/reference/design-system-discovery.md +8 -0
- package/pack/generated/pi/skills/rite-polish/reference/harden-checklist.md +109 -0
- package/pack/generated/pi/skills/rite-polish/reference/ledger.md +65 -0
- package/pack/generated/pi/skills/rite-polish/reference/ui.md +137 -0
- package/pack/generated/pi/skills/rite-pov/SKILL.md +58 -0
- package/pack/generated/pi/skills/rite-pr-feedback/SKILL.md +54 -0
- package/pack/generated/pi/skills/rite-pressure-test/SKILL.md +67 -0
- package/pack/generated/pi/skills/rite-prototype/SKILL.md +104 -0
- package/pack/generated/pi/skills/rite-prove/SKILL.md +120 -0
- package/pack/generated/pi/skills/rite-prove/reference/acceptance-proof.md +88 -0
- package/pack/generated/pi/skills/rite-prove/reference/anti-patterns.md +25 -0
- package/pack/generated/pi/skills/rite-prove/reference/browser-proof.md +51 -0
- package/pack/generated/pi/skills/rite-prove/reference/failure-triage.md +43 -0
- package/pack/generated/pi/skills/rite-prove/reference/proof-ladder.md +28 -0
- package/pack/generated/pi/skills/rite-prove/reference/test-command-discovery.md +30 -0
- package/pack/generated/pi/skills/rite-quick/SKILL.md +82 -0
- package/pack/generated/pi/skills/rite-resolve/SKILL.md +95 -0
- package/pack/generated/pi/skills/rite-resolve/reference/answer-protocol.md +118 -0
- package/pack/generated/pi/skills/rite-review/SKILL.md +170 -0
- package/pack/generated/pi/skills/rite-review/reference/anti-patterns.md +32 -0
- package/pack/generated/pi/skills/rite-review/reference/cognitive-load.md +90 -0
- package/pack/generated/pi/skills/rite-review/reference/feature-scoped-review.md +26 -0
- package/pack/generated/pi/skills/rite-review/reference/five-axis-review.md +66 -0
- package/pack/generated/pi/skills/rite-review/reference/nielsen-heuristics.md +126 -0
- package/pack/generated/pi/skills/rite-review/reference/performance-checklist.md +80 -0
- package/pack/generated/pi/skills/rite-review/reference/performance-review.md +14 -0
- package/pack/generated/pi/skills/rite-review/reference/security-review.md +42 -0
- package/pack/generated/pi/skills/rite-seal/SKILL.md +75 -0
- package/pack/generated/pi/skills/rite-seal/reference/anti-patterns.md +29 -0
- package/pack/generated/pi/skills/rite-seal/reference/final-evidence.md +41 -0
- package/pack/generated/pi/skills/rite-seal/reference/go-no-go.md +29 -0
- package/pack/generated/pi/skills/rite-seal/reference/output.md +5 -0
- package/pack/generated/pi/skills/rite-seal/reference/phase-contract.md +47 -0
- package/pack/generated/pi/skills/rite-seal/reference/risk-and-rollback.md +56 -0
- package/pack/generated/pi/skills/rite-seal/reference/seal-template.md +27 -0
- package/pack/generated/pi/skills/rite-ship/SKILL.md +88 -0
- package/pack/generated/pi/skills/rite-ship/reference/anti-patterns.md +28 -0
- package/pack/generated/pi/skills/rite-ship/reference/close-out.md +68 -0
- package/pack/generated/pi/skills/rite-ship/reference/git-ship.md +120 -0
- package/pack/generated/pi/skills/rite-ship/reference/rollout.md +62 -0
- package/pack/generated/pi/skills/rite-ship/reference/ship-template.md +39 -0
- package/pack/generated/pi/skills/rite-spec/SKILL.md +150 -0
- package/pack/generated/pi/skills/rite-spec/reference/acceptance-criteria.md +31 -0
- package/pack/generated/pi/skills/rite-spec/reference/ai-spec-template.md +40 -0
- package/pack/generated/pi/skills/rite-spec/reference/anti-patterns.md +27 -0
- package/pack/generated/pi/skills/rite-spec/reference/interview-patterns.md +56 -0
- package/pack/generated/pi/skills/rite-spec/reference/investigation.md +83 -0
- package/pack/generated/pi/skills/rite-spec/reference/question-protocol.md +36 -0
- package/pack/generated/pi/skills/rite-spec/reference/references-intake.md +62 -0
- package/pack/generated/pi/skills/rite-spec/reference/spec-checklists.md +89 -0
- package/pack/generated/pi/skills/rite-spec/reference/spec-template.md +154 -0
- package/pack/generated/pi/skills/rite-spec/reference/state-workspace.md +227 -0
- package/pack/generated/pi/skills/rite-status/SKILL.md +57 -0
- package/pack/generated/pi/skills/rite-temper/SKILL.md +130 -0
- package/pack/generated/pi/skills/rite-temper/reference/anti-patterns.md +30 -0
- package/pack/generated/pi/skills/rite-temper/reference/review-dimensions.md +66 -0
- package/pack/generated/pi/skills/rite-temper/reference/scope-modes.md +53 -0
- package/pack/generated/pi/skills/rite-temper/reference/significance.md +46 -0
- package/pack/generated/pi/skills/rite-temper/reference/strategy-template.md +90 -0
- package/pack/generated/pi/skills/rite-upgrade/SKILL.md +121 -0
- package/pack/generated/pi/skills/rite-vet/SKILL.md +193 -0
- package/pack/generated/pi/skills/rite-vet/reference/anti-patterns.md +43 -0
- package/pack/generated/pi/skills/rite-vet/reference/artifacts.md +202 -0
- package/pack/generated/pi/skills/rite-vet/reference/cross-model.md +19 -0
- package/pack/generated/pi/skills/rite-vet/reference/depth.md +59 -0
- package/pack/generated/pi/skills/rite-vet/reference/eng-lenses.md +48 -0
- package/pack/generated/pi/skills/rite-vet/reference/review-axes.md +201 -0
- package/pack/generated/pi/skills/rite-watch-pr/SKILL.md +85 -0
- package/pack/generated/pi/skills/rite-zoom-out/SKILL.md +69 -0
- package/package.json +3 -2
- package/scripts/build-host-artifacts.sh +100 -37
- package/scripts/pi-generate.sh +198 -0
package/CHANGELOG.md
CHANGED
|
@@ -2,6 +2,18 @@
|
|
|
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.7.0](https://github.com/ViktorsBaikers/DevRites/compare/v5.6.0...v5.7.0) (2026-09-13)
|
|
6
|
+
|
|
7
|
+
### Added
|
|
8
|
+
|
|
9
|
+
* **installer:** pi as fourth host target + skill frontmatter YAML fix ([#70](https://github.com/ViktorsBaikers/DevRites/issues/70)) ([9275755](https://github.com/ViktorsBaikers/DevRites/commit/92757555f4c6cf74f8cdec5f8e8688ec28360508))
|
|
10
|
+
|
|
11
|
+
## [5.6.0](https://github.com/ViktorsBaikers/DevRites/compare/v5.5.0...v5.6.0) (2026-09-13)
|
|
12
|
+
|
|
13
|
+
### Added
|
|
14
|
+
|
|
15
|
+
* **rite:** add pi as fourth host target ([#69](https://github.com/ViktorsBaikers/DevRites/issues/69)) ([8249a6b](https://github.com/ViktorsBaikers/DevRites/commit/8249a6b9d5bef3dfd2411089fdcd34845f535b12))
|
|
16
|
+
|
|
5
17
|
## [5.5.0](https://github.com/ViktorsBaikers/DevRites/compare/v5.4.0...v5.5.0) (2026-09-13)
|
|
6
18
|
|
|
7
19
|
### Added
|
package/README.md
CHANGED
|
@@ -33,7 +33,7 @@ project-conventional push, tag, or PR action, and archive the workspace.
|
|
|
33
33
|
Unattended runs may create local WIP checkpoint commits along the way, but they
|
|
34
34
|
remain local unless Ship's disclosed plan includes an approved remote action.
|
|
35
35
|
|
|
36
|
-
**Status:** [`v5.
|
|
36
|
+
**Status:** [`v5.7.0`](https://github.com/ViktorsBaikers/DevRites/releases/tag/v5.7.0): see [`CHANGELOG.md`](CHANGELOG.md) for release notes.
|
|
37
37
|
|
|
38
38
|
This is the latest published release; `main` may contain unreleased work.
|
|
39
39
|
|
|
@@ -47,8 +47,8 @@ Run this from the root of your project. Node.js 18 or later is required.
|
|
|
47
47
|
npx devrites@latest
|
|
48
48
|
```
|
|
49
49
|
|
|
50
|
-
The installer adds project-local support for Claude Code
|
|
51
|
-
write skills, agents, or hooks to `~/.claude
|
|
50
|
+
The installer adds project-local support for Claude Code, Codex, omp, and pi.
|
|
51
|
+
It does not write skills, agents, or hooks to `~/.claude`, `~/.codex`, or `~/.pi`.
|
|
52
52
|
|
|
53
53
|
### 2. Choose the smallest route
|
|
54
54
|
|
|
@@ -78,8 +78,9 @@ proof and next action.
|
|
|
78
78
|
## How the lifecycle works
|
|
79
79
|
|
|
80
80
|
Claude Code supports both `/rite <verb>` and `/rite-<verb>`. Codex uses the same
|
|
81
|
-
forms with `$`: `$rite <verb>` and `$rite-<verb>`.
|
|
82
|
-
|
|
81
|
+
forms with `$`: `$rite <verb>` and `$rite-<verb>`. omp and pi use the Claude
|
|
82
|
+
slash forms (on pi they run as prompt templates under `.pi/prompts`, with
|
|
83
|
+
`/skill:rite-<verb>` equivalent). The menu and direct forms run the same skill.
|
|
83
84
|
|
|
84
85
|
| # | Stage | Direct command | What happens |
|
|
85
86
|
| ---: | --- | --- | --- |
|
|
@@ -294,7 +295,8 @@ Useful install flags:
|
|
|
294
295
|
| `--target DIR` | Use another project directory. |
|
|
295
296
|
| `--dry-run` | Show planned file operations without changing anything. |
|
|
296
297
|
| `--force` | Replace or remove foreign or customized managed files. The installer still rejects symlinks and path escapes. |
|
|
297
|
-
| `--no-codex` | Skip `.agents`, `.codex`, and `AGENTS.md`
|
|
298
|
+
| `--no-codex` | Skip `.agents`, `.codex`, and the Codex `AGENTS.md` block. |
|
|
299
|
+
| `--no-pi` | Skip `.pi` skills, agents, prompt commands, and the pi `AGENTS.md` block. |
|
|
298
300
|
| `--no-agents` | Skip hook-free native specialist profiles. |
|
|
299
301
|
| `--no-skills` | Skip skills and their bundled standards. |
|
|
300
302
|
| `--no-binary` | Do not keep the shared `devrites-engine` binary in a user or system bin directory. |
|
|
@@ -16,9 +16,12 @@ const (
|
|
|
16
16
|
ClaudeSkillsTarget = ".claude/skills"
|
|
17
17
|
CodexSkillsTarget = ".agents/skills"
|
|
18
18
|
OmpSkillsTarget = ".omp/skills"
|
|
19
|
+
PiSkillsTarget = ".pi/skills"
|
|
19
20
|
ClaudeAgentsTarget = ".claude/agents"
|
|
20
21
|
CodexAgentsTarget = ".codex/agents"
|
|
21
22
|
OmpAgentsTarget = ".omp/agents"
|
|
23
|
+
PiAgentsTarget = ".pi/agents"
|
|
24
|
+
PiPromptsTarget = ".pi/prompts"
|
|
22
25
|
ClaudeWorkflowsTarget = ".claude/workflows"
|
|
23
26
|
|
|
24
27
|
ManifestName = ".claude/devrites.manifest"
|
|
@@ -17,9 +17,12 @@ const (
|
|
|
17
17
|
ClaudeSkillsTarget = devritespaths.ClaudeSkillsTarget
|
|
18
18
|
CodexSkillsTarget = devritespaths.CodexSkillsTarget
|
|
19
19
|
OmpSkillsTarget = devritespaths.OmpSkillsTarget
|
|
20
|
+
PiSkillsTarget = devritespaths.PiSkillsTarget
|
|
20
21
|
ClaudeAgentsTarget = devritespaths.ClaudeAgentsTarget
|
|
21
22
|
CodexAgentsTarget = devritespaths.CodexAgentsTarget
|
|
22
23
|
OmpAgentsTarget = devritespaths.OmpAgentsTarget
|
|
24
|
+
PiAgentsTarget = devritespaths.PiAgentsTarget
|
|
25
|
+
PiPromptsTarget = devritespaths.PiPromptsTarget
|
|
23
26
|
ClaudeWorkflowsTarget = devritespaths.ClaudeWorkflowsTarget
|
|
24
27
|
)
|
|
25
28
|
|
|
@@ -87,6 +90,15 @@ var ClaudeSettingsMerge = JSONMerge{
|
|
|
87
90
|
DryRunText: ".claude/settings.json (DevRites permissions)",
|
|
88
91
|
}
|
|
89
92
|
|
|
93
|
+
var PiAgentsMerge = MarkerMerge{
|
|
94
|
+
TargetRel: "AGENTS.md",
|
|
95
|
+
PayloadRel: "pi/AGENTS.md",
|
|
96
|
+
Begin: "<!-- BEGIN DEVRITES PI -->",
|
|
97
|
+
End: "<!-- END DEVRITES PI -->",
|
|
98
|
+
MarkerRel: ".claude/devrites.pi-agents-merge",
|
|
99
|
+
MarkerText: "AGENTS.md contains a DevRites managed block between BEGIN/END DEVRITES PI markers.",
|
|
100
|
+
}
|
|
101
|
+
|
|
90
102
|
var CodexConfigMerge = MarkerMerge{
|
|
91
103
|
TargetRel: ".codex/config.toml",
|
|
92
104
|
PayloadRel: "codex/config.toml",
|
|
@@ -108,7 +120,14 @@ var managedMerges = []ManagedMerge{
|
|
|
108
120
|
TargetRel: CodexAgentsMerge.TargetRel,
|
|
109
121
|
Begin: CodexAgentsMerge.Begin,
|
|
110
122
|
End: CodexAgentsMerge.End,
|
|
111
|
-
DryRun: "AGENTS.md DevRites block",
|
|
123
|
+
DryRun: "AGENTS.md DevRites Codex block",
|
|
124
|
+
},
|
|
125
|
+
{
|
|
126
|
+
MarkerRel: PiAgentsMerge.MarkerRel,
|
|
127
|
+
TargetRel: PiAgentsMerge.TargetRel,
|
|
128
|
+
Begin: PiAgentsMerge.Begin,
|
|
129
|
+
End: PiAgentsMerge.End,
|
|
130
|
+
DryRun: "AGENTS.md DevRites pi block",
|
|
112
131
|
},
|
|
113
132
|
{
|
|
114
133
|
MarkerRel: CodexConfigMerge.MarkerRel,
|
|
@@ -125,7 +144,7 @@ var managedMerges = []ManagedMerge{
|
|
|
125
144
|
LegacyCodexHooksMerge,
|
|
126
145
|
}
|
|
127
146
|
|
|
128
|
-
func RequiredPayload(withCodex, withOmp bool) []string {
|
|
147
|
+
func RequiredPayload(withCodex, withOmp, withPi bool) []string {
|
|
129
148
|
required := []string{
|
|
130
149
|
"claude/skills",
|
|
131
150
|
"claude/agents",
|
|
@@ -147,11 +166,19 @@ func RequiredPayload(withCodex, withOmp bool) []string {
|
|
|
147
166
|
"omp/.omp-plugin/plugin.json",
|
|
148
167
|
)
|
|
149
168
|
}
|
|
169
|
+
if withPi {
|
|
170
|
+
required = append(required,
|
|
171
|
+
"pi/skills",
|
|
172
|
+
"pi/agents",
|
|
173
|
+
"pi/prompts",
|
|
174
|
+
"pi/AGENTS.md",
|
|
175
|
+
)
|
|
176
|
+
}
|
|
150
177
|
return required
|
|
151
178
|
}
|
|
152
179
|
|
|
153
|
-
func ValidatePayload(payload fs.FS, withCodex, withOmp bool) error {
|
|
154
|
-
for _, rel := range RequiredPayload(withCodex, withOmp) {
|
|
180
|
+
func ValidatePayload(payload fs.FS, withCodex, withOmp, withPi bool) error {
|
|
181
|
+
for _, rel := range RequiredPayload(withCodex, withOmp, withPi) {
|
|
155
182
|
if _, err := fs.Stat(payload, rel); err != nil {
|
|
156
183
|
return fmt.Errorf("missing %s", rel)
|
|
157
184
|
}
|
|
@@ -159,7 +186,7 @@ func ValidatePayload(payload fs.FS, withCodex, withOmp bool) error {
|
|
|
159
186
|
return nil
|
|
160
187
|
}
|
|
161
188
|
|
|
162
|
-
func InstallTrees(withSkills, withAgents, withCodex, withOmp bool) []Tree {
|
|
189
|
+
func InstallTrees(withSkills, withAgents, withCodex, withOmp, withPi bool) []Tree {
|
|
163
190
|
var trees []Tree
|
|
164
191
|
if withSkills {
|
|
165
192
|
trees = append(trees, Tree{PayloadPrefix: "claude/skills", TargetPrefix: ClaudeSkillsTarget})
|
|
@@ -169,6 +196,12 @@ func InstallTrees(withSkills, withAgents, withCodex, withOmp bool) []Tree {
|
|
|
169
196
|
if withOmp {
|
|
170
197
|
trees = append(trees, Tree{PayloadPrefix: "omp/skills", TargetPrefix: OmpSkillsTarget})
|
|
171
198
|
}
|
|
199
|
+
if withPi {
|
|
200
|
+
trees = append(trees,
|
|
201
|
+
Tree{PayloadPrefix: "pi/skills", TargetPrefix: PiSkillsTarget},
|
|
202
|
+
Tree{PayloadPrefix: "pi/prompts", TargetPrefix: PiPromptsTarget},
|
|
203
|
+
)
|
|
204
|
+
}
|
|
172
205
|
}
|
|
173
206
|
if withAgents {
|
|
174
207
|
trees = append(trees, Tree{PayloadPrefix: "claude/agents", TargetPrefix: ClaudeAgentsTarget})
|
|
@@ -178,6 +211,9 @@ func InstallTrees(withSkills, withAgents, withCodex, withOmp bool) []Tree {
|
|
|
178
211
|
if withOmp {
|
|
179
212
|
trees = append(trees, Tree{PayloadPrefix: "omp/agents", TargetPrefix: OmpAgentsTarget})
|
|
180
213
|
}
|
|
214
|
+
if withPi {
|
|
215
|
+
trees = append(trees, Tree{PayloadPrefix: "pi/agents", TargetPrefix: PiAgentsTarget})
|
|
216
|
+
}
|
|
181
217
|
}
|
|
182
218
|
if withSkills && withAgents {
|
|
183
219
|
trees = append(trees, Tree{PayloadPrefix: "claude/workflows", TargetPrefix: ClaudeWorkflowsTarget})
|
|
@@ -185,7 +221,7 @@ func InstallTrees(withSkills, withAgents, withCodex, withOmp bool) []Tree {
|
|
|
185
221
|
return trees
|
|
186
222
|
}
|
|
187
223
|
|
|
188
|
-
func AliasTargets(alias Alias, withCodex, withOmp bool) []string {
|
|
224
|
+
func AliasTargets(alias Alias, withCodex, withOmp, withPi bool) []string {
|
|
189
225
|
targets := []string{filepath.ToSlash(filepath.Join(ClaudeSkillsTarget, alias.Name, "SKILL.md"))}
|
|
190
226
|
if withCodex {
|
|
191
227
|
targets = append(targets, filepath.ToSlash(filepath.Join(CodexSkillsTarget, alias.Name, "SKILL.md")))
|
|
@@ -193,6 +229,9 @@ func AliasTargets(alias Alias, withCodex, withOmp bool) []string {
|
|
|
193
229
|
if withOmp {
|
|
194
230
|
targets = append(targets, filepath.ToSlash(filepath.Join(OmpSkillsTarget, alias.Name, "SKILL.md")))
|
|
195
231
|
}
|
|
232
|
+
if withPi {
|
|
233
|
+
targets = append(targets, filepath.ToSlash(filepath.Join(PiSkillsTarget, alias.Name, "SKILL.md")))
|
|
234
|
+
}
|
|
196
235
|
return targets
|
|
197
236
|
}
|
|
198
237
|
|
|
@@ -21,70 +21,86 @@ func TestValidatePayloadRequiresClaudeAndCodexFiles(t *testing.T) {
|
|
|
21
21
|
"omp/skills/rite/SKILL.md": {},
|
|
22
22
|
"omp/agents/devrites-code-reviewer.md": {},
|
|
23
23
|
"omp/.omp-plugin/plugin.json": {},
|
|
24
|
+
"pi/skills/rite/SKILL.md": {},
|
|
25
|
+
"pi/agents/devrites-code-reviewer.md": {},
|
|
26
|
+
"pi/prompts/rite.md": {},
|
|
27
|
+
"pi/AGENTS.md": {},
|
|
24
28
|
}
|
|
25
|
-
if err := ValidatePayload(payload, true, true); err != nil {
|
|
29
|
+
if err := ValidatePayload(payload, true, true, true); err != nil {
|
|
26
30
|
t.Fatal(err)
|
|
27
31
|
}
|
|
28
32
|
delete(payload, "codex/config.toml")
|
|
29
|
-
err := ValidatePayload(payload, true, true)
|
|
33
|
+
err := ValidatePayload(payload, true, true, true)
|
|
30
34
|
if err == nil || !strings.Contains(err.Error(), "missing codex/config.toml") {
|
|
31
35
|
t.Fatalf("ValidatePayload error = %v, want missing codex/config.toml", err)
|
|
32
36
|
}
|
|
33
|
-
if err := ValidatePayload(payload, false, true); err != nil {
|
|
37
|
+
if err := ValidatePayload(payload, false, true, true); err != nil {
|
|
34
38
|
t.Fatalf("claude-only payload should not require codex files: %v", err)
|
|
35
39
|
}
|
|
36
40
|
delete(payload, "omp/.omp-plugin/plugin.json")
|
|
37
|
-
err = ValidatePayload(payload, false, true)
|
|
41
|
+
err = ValidatePayload(payload, false, true, true)
|
|
38
42
|
if err == nil || !strings.Contains(err.Error(), "missing omp/.omp-plugin/plugin.json") {
|
|
39
43
|
t.Fatalf("ValidatePayload error = %v, want missing omp/.omp-plugin/plugin.json", err)
|
|
40
44
|
}
|
|
41
|
-
|
|
42
|
-
|
|
45
|
+
delete(payload, "pi/prompts/rite.md")
|
|
46
|
+
err = ValidatePayload(payload, false, false, true)
|
|
47
|
+
if err == nil || !strings.Contains(err.Error(), "missing pi/prompts") {
|
|
48
|
+
t.Fatalf("ValidatePayload error = %v, want missing pi/prompts", err)
|
|
49
|
+
}
|
|
50
|
+
if err := ValidatePayload(payload, false, false, false); err != nil {
|
|
51
|
+
t.Fatalf("claude-only payload should not require omp or pi files: %v", err)
|
|
43
52
|
}
|
|
44
53
|
}
|
|
45
54
|
|
|
46
55
|
func TestInstallTreesMapPayloadsToTargets(t *testing.T) {
|
|
47
|
-
got := InstallTrees(true, true, true, true)
|
|
56
|
+
got := InstallTrees(true, true, true, true, true)
|
|
48
57
|
want := []Tree{
|
|
49
58
|
{PayloadPrefix: "claude/skills", TargetPrefix: ".claude/skills"},
|
|
50
59
|
{PayloadPrefix: "codex/skills", TargetPrefix: ".agents/skills"},
|
|
51
60
|
{PayloadPrefix: "omp/skills", TargetPrefix: ".omp/skills"},
|
|
61
|
+
{PayloadPrefix: "pi/skills", TargetPrefix: ".pi/skills"},
|
|
62
|
+
{PayloadPrefix: "pi/prompts", TargetPrefix: ".pi/prompts"},
|
|
52
63
|
{PayloadPrefix: "claude/agents", TargetPrefix: ".claude/agents"},
|
|
53
64
|
{PayloadPrefix: "codex/agents", TargetPrefix: ".codex/agents"},
|
|
54
65
|
{PayloadPrefix: "omp/agents", TargetPrefix: ".omp/agents"},
|
|
66
|
+
{PayloadPrefix: "pi/agents", TargetPrefix: ".pi/agents"},
|
|
55
67
|
{PayloadPrefix: "claude/workflows", TargetPrefix: ".claude/workflows"},
|
|
56
68
|
}
|
|
57
69
|
if !reflect.DeepEqual(got, want) {
|
|
58
70
|
t.Fatalf("InstallTrees() = %#v, want %#v", got, want)
|
|
59
71
|
}
|
|
60
|
-
for _, trees := range [][]Tree{InstallTrees(true, false, true, true), InstallTrees(false, true, true, true)} {
|
|
72
|
+
for _, trees := range [][]Tree{InstallTrees(true, false, true, true, true), InstallTrees(false, true, true, true, true)} {
|
|
61
73
|
for _, tree := range trees {
|
|
62
74
|
if tree.PayloadPrefix == "claude/workflows" {
|
|
63
75
|
t.Fatal("Claude workflow installed without both skills and agents")
|
|
64
76
|
}
|
|
65
77
|
}
|
|
66
78
|
}
|
|
67
|
-
for _, tree := range InstallTrees(true, true, true, false) {
|
|
79
|
+
for _, tree := range InstallTrees(true, true, true, false, false) {
|
|
68
80
|
if strings.HasPrefix(tree.TargetPrefix, ".omp/") {
|
|
69
81
|
t.Fatalf("omp tree installed with withOmp=false: %#v", tree)
|
|
70
82
|
}
|
|
83
|
+
if strings.HasPrefix(tree.TargetPrefix, ".pi/") {
|
|
84
|
+
t.Fatalf("pi tree installed with withPi=false: %#v", tree)
|
|
85
|
+
}
|
|
71
86
|
}
|
|
72
87
|
}
|
|
73
88
|
|
|
74
89
|
func TestAliasTargetsIncludeOmpWhenEnabled(t *testing.T) {
|
|
75
|
-
got := AliasTargets(Alias{Name: "define"}, true, true)
|
|
90
|
+
got := AliasTargets(Alias{Name: "define"}, true, true, true)
|
|
76
91
|
want := []string{
|
|
77
92
|
".claude/skills/define/SKILL.md",
|
|
78
93
|
".agents/skills/define/SKILL.md",
|
|
79
94
|
".omp/skills/define/SKILL.md",
|
|
95
|
+
".pi/skills/define/SKILL.md",
|
|
80
96
|
}
|
|
81
97
|
if !reflect.DeepEqual(got, want) {
|
|
82
98
|
t.Fatalf("AliasTargets() = %#v, want %#v", got, want)
|
|
83
99
|
}
|
|
84
|
-
got = AliasTargets(Alias{Name: "define"}, true, false)
|
|
100
|
+
got = AliasTargets(Alias{Name: "define"}, true, false, false)
|
|
85
101
|
for _, rel := range got {
|
|
86
|
-
if strings.HasPrefix(rel, ".omp/") {
|
|
87
|
-
t.Fatalf("
|
|
102
|
+
if strings.HasPrefix(rel, ".omp/") || strings.HasPrefix(rel, ".pi/") {
|
|
103
|
+
t.Fatalf("disabled-host alias installed: %s", rel)
|
|
88
104
|
}
|
|
89
105
|
}
|
|
90
106
|
}
|
|
@@ -24,6 +24,7 @@ func (r *runner) install() error {
|
|
|
24
24
|
fmt.Fprintf(r.opts.Stdout, " agents : %s\n", yesno(r.opts.WithAgents))
|
|
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
|
+
fmt.Fprintf(r.opts.Stdout, " pi : %s\n", yesno(r.opts.WithPi))
|
|
27
28
|
fmt.Fprintf(r.opts.Stdout, " aliases: %s\n", r.opts.AliasMode)
|
|
28
29
|
if r.opts.DryRun {
|
|
29
30
|
fmt.Fprintln(r.opts.Stdout, " (dry run - no changes will be made)")
|
|
@@ -38,7 +39,7 @@ func (r *runner) install() error {
|
|
|
38
39
|
return err
|
|
39
40
|
}
|
|
40
41
|
|
|
41
|
-
for _, tree := range hostpack.InstallTrees(r.opts.WithSkills, r.opts.WithAgents, r.opts.WithCodex, r.opts.WithOmp) {
|
|
42
|
+
for _, tree := range hostpack.InstallTrees(r.opts.WithSkills, r.opts.WithAgents, r.opts.WithCodex, r.opts.WithOmp, r.opts.WithPi) {
|
|
42
43
|
if err := r.installTree(tree.PayloadPrefix, tree.TargetPrefix); err != nil {
|
|
43
44
|
return fmt.Errorf("install tree %s: %w", tree.TargetPrefix, err)
|
|
44
45
|
}
|
|
@@ -49,7 +50,7 @@ func (r *runner) install() error {
|
|
|
49
50
|
if err != nil {
|
|
50
51
|
return fmt.Errorf("render alias skill %s: %w", alias.Name, err)
|
|
51
52
|
}
|
|
52
|
-
for _, rel := range hostpack.AliasTargets(alias, r.opts.WithCodex, r.opts.WithOmp) {
|
|
53
|
+
for _, rel := range hostpack.AliasTargets(alias, r.opts.WithCodex, r.opts.WithOmp, r.opts.WithPi) {
|
|
53
54
|
if err := r.installData(data, rel); err != nil {
|
|
54
55
|
return fmt.Errorf("install alias: %w", err)
|
|
55
56
|
}
|
|
@@ -64,6 +65,11 @@ func (r *runner) install() error {
|
|
|
64
65
|
return fmt.Errorf("merge %s: %w", hostpack.CodexConfigMerge.TargetRel, err)
|
|
65
66
|
}
|
|
66
67
|
}
|
|
68
|
+
if r.opts.WithSkills && r.opts.WithPi {
|
|
69
|
+
if err := r.mergeMarkerFile(hostpack.PiAgentsMerge); err != nil {
|
|
70
|
+
return fmt.Errorf("merge %s: %w", hostpack.PiAgentsMerge.TargetRel, err)
|
|
71
|
+
}
|
|
72
|
+
}
|
|
67
73
|
if r.opts.WithSkills {
|
|
68
74
|
if err := r.seedClaudeSettings(); err != nil {
|
|
69
75
|
return fmt.Errorf("seed claude settings: %w", err)
|
|
@@ -93,11 +99,11 @@ func (r *runner) install() error {
|
|
|
93
99
|
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)
|
|
94
100
|
if !r.opts.DryRun && r.opts.WithSkills {
|
|
95
101
|
switch {
|
|
96
|
-
case r.opts.WithCodex && r.opts.WithOmp:
|
|
97
|
-
fmt.Fprintln(r.opts.Stdout, "Next: reopen the project, then run /rite (Claude) or $rite (Codex) or /skill:rite.")
|
|
102
|
+
case r.opts.WithCodex && (r.opts.WithOmp || r.opts.WithPi):
|
|
103
|
+
fmt.Fprintln(r.opts.Stdout, "Next: reopen the project, then run /rite (Claude) or $rite (Codex) or /skill:rite (omp/pi).")
|
|
98
104
|
case r.opts.WithCodex:
|
|
99
105
|
fmt.Fprintln(r.opts.Stdout, "Next: reopen the project, then run /rite (Claude) or $rite (Codex).")
|
|
100
|
-
case r.opts.WithOmp:
|
|
106
|
+
case r.opts.WithOmp || r.opts.WithPi:
|
|
101
107
|
fmt.Fprintln(r.opts.Stdout, "Next: reopen the project, then run /rite or /skill:rite.")
|
|
102
108
|
default:
|
|
103
109
|
fmt.Fprintln(r.opts.Stdout, "Next: reopen the project, then run /rite.")
|
|
@@ -311,6 +317,9 @@ func (r *runner) flagsString() string {
|
|
|
311
317
|
if !r.opts.WithOmp {
|
|
312
318
|
flags = append(flags, "--no-omp")
|
|
313
319
|
}
|
|
320
|
+
if !r.opts.WithPi {
|
|
321
|
+
flags = append(flags, "--no-pi")
|
|
322
|
+
}
|
|
314
323
|
if !r.opts.WithBinary {
|
|
315
324
|
flags = append(flags, "--no-binary")
|
|
316
325
|
}
|
|
@@ -35,6 +35,7 @@ type Options struct {
|
|
|
35
35
|
WithAgents bool
|
|
36
36
|
WithCodex bool
|
|
37
37
|
WithOmp bool
|
|
38
|
+
WithPi bool
|
|
38
39
|
WithBinary bool
|
|
39
40
|
KeepBinary bool
|
|
40
41
|
AliasMode string
|
|
@@ -84,6 +85,7 @@ func DefaultOptions(mode Mode) Options {
|
|
|
84
85
|
WithAgents: true,
|
|
85
86
|
WithCodex: true,
|
|
86
87
|
WithOmp: true,
|
|
88
|
+
WithPi: true,
|
|
87
89
|
WithBinary: true,
|
|
88
90
|
AliasMode: "safe",
|
|
89
91
|
Stdout: io.Discard,
|
|
@@ -135,6 +137,7 @@ func parseArgs(args []string, opts *Options) error {
|
|
|
135
137
|
force := flags.Bool("force", opts.Force, "")
|
|
136
138
|
noCodex := flags.Bool("no-codex", !opts.WithCodex, "")
|
|
137
139
|
noOmp := flags.Bool("no-omp", !opts.WithOmp, "")
|
|
140
|
+
noPi := flags.Bool("no-pi", !opts.WithPi, "")
|
|
138
141
|
noAgents := flags.Bool("no-agents", !opts.WithAgents, "")
|
|
139
142
|
noSkills := flags.Bool("no-skills", !opts.WithSkills, "")
|
|
140
143
|
noBinary := flags.Bool("no-binary", !opts.WithBinary, "")
|
|
@@ -162,6 +165,7 @@ func parseArgs(args []string, opts *Options) error {
|
|
|
162
165
|
opts.Force = *force
|
|
163
166
|
opts.WithCodex = !*noCodex
|
|
164
167
|
opts.WithOmp = !*noOmp
|
|
168
|
+
opts.WithPi = !*noPi
|
|
165
169
|
opts.WithAgents = !*noAgents
|
|
166
170
|
opts.WithSkills = !*noSkills
|
|
167
171
|
opts.WithBinary = !*noBinary
|
|
@@ -208,7 +212,7 @@ func usage(mode Mode) string {
|
|
|
208
212
|
case ModeUpdate:
|
|
209
213
|
return "usage: devrites-engine update [--target DIR] [--dry-run] [--force] [--check] [install flags] [--source-dir DIR --payload-dir DIR]\n"
|
|
210
214
|
default:
|
|
211
|
-
return "usage: devrites-engine install [--target DIR] [--dry-run] [--force] [--no-codex] [--no-omp] [--no-agents] [--no-skills] [--no-binary] [--short-aliases=all]\n"
|
|
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"
|
|
212
216
|
}
|
|
213
217
|
}
|
|
214
218
|
|
|
@@ -333,7 +337,7 @@ func (r *runner) validatePayload() error {
|
|
|
333
337
|
if r.payload == "" {
|
|
334
338
|
return fmt.Errorf("generated install payload not found; pass --payload-dir or run scripts/build-host-artifacts.sh")
|
|
335
339
|
}
|
|
336
|
-
if err := hostpack.ValidatePayload(r.payloadFS, r.opts.WithCodex, r.opts.WithOmp); err != nil {
|
|
340
|
+
if err := hostpack.ValidatePayload(r.payloadFS, r.opts.WithCodex, r.opts.WithOmp, r.opts.WithPi); err != nil {
|
|
337
341
|
return fmt.Errorf("generated install payload under %s: %w", r.payload, err)
|
|
338
342
|
}
|
|
339
343
|
return nil
|
|
@@ -349,6 +353,8 @@ func isGlobalTarget(target string) bool {
|
|
|
349
353
|
filepath.Join(home, ".codex"),
|
|
350
354
|
filepath.Join(home, ".omp"),
|
|
351
355
|
filepath.Join(home, ".omp", "agent"),
|
|
356
|
+
filepath.Join(home, ".pi"),
|
|
357
|
+
filepath.Join(home, ".pi", "agent"),
|
|
352
358
|
} {
|
|
353
359
|
if target == global || strings.HasPrefix(target, global+string(os.PathSeparator)) {
|
|
354
360
|
return true
|
|
@@ -53,12 +53,14 @@ func TestInstallPrintsFirstMoveForInstalledHosts(t *testing.T) {
|
|
|
53
53
|
name string
|
|
54
54
|
withCodex bool
|
|
55
55
|
withOmp bool
|
|
56
|
+
withPi bool
|
|
56
57
|
want string
|
|
57
58
|
}{
|
|
58
|
-
{name: "Claude, Codex, and OMP", withCodex: true, withOmp: true, want: "Next: reopen the project, then run /rite (Claude) or $rite (Codex) or /skill:rite."},
|
|
59
|
-
{name: "Claude and Codex", withCodex: true, withOmp: false, want: "Next: reopen the project, then run /rite (Claude) or $rite (Codex)."},
|
|
60
|
-
{name: "Claude and OMP", withCodex: false, withOmp: true, want: "Next: reopen the project, then run /rite or /skill:rite."},
|
|
61
|
-
{name: "Claude
|
|
59
|
+
{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
|
+
{name: "Claude and Codex", withCodex: true, withOmp: false, withPi: false, want: "Next: reopen the project, then run /rite (Claude) or $rite (Codex)."},
|
|
61
|
+
{name: "Claude and OMP", withCodex: false, withOmp: true, withPi: false, want: "Next: reopen the project, then run /rite or /skill:rite."},
|
|
62
|
+
{name: "Claude and pi", withCodex: false, withOmp: false, withPi: true, want: "Next: reopen the project, then run /rite or /skill:rite."},
|
|
63
|
+
{name: "Claude only", withCodex: false, withOmp: false, withPi: false, want: "Next: reopen the project, then run /rite."},
|
|
62
64
|
} {
|
|
63
65
|
t.Run(tc.name, func(t *testing.T) {
|
|
64
66
|
var out bytes.Buffer
|
|
@@ -67,6 +69,7 @@ func TestInstallPrintsFirstMoveForInstalledHosts(t *testing.T) {
|
|
|
67
69
|
opts.PayloadDir = testPayload(t)
|
|
68
70
|
opts.WithCodex = tc.withCodex
|
|
69
71
|
opts.WithOmp = tc.withOmp
|
|
72
|
+
opts.WithPi = tc.withPi
|
|
70
73
|
opts.Stdout = &out
|
|
71
74
|
opts.Stderr = &bytes.Buffer{}
|
|
72
75
|
|
|
@@ -758,7 +761,7 @@ func TestLegacyCodexHooksMergeIsCleanupOnly(t *testing.T) {
|
|
|
758
761
|
if !ok || merge != legacy {
|
|
759
762
|
t.Fatalf("legacy marker lookup = %#v, %t", merge, ok)
|
|
760
763
|
}
|
|
761
|
-
if slices.Contains(hostpack.RequiredPayload(true, true), "codex/hooks.json") {
|
|
764
|
+
if slices.Contains(hostpack.RequiredPayload(true, true, true), "codex/hooks.json") {
|
|
762
765
|
t.Fatal("legacy Codex hooks entered the required payload")
|
|
763
766
|
}
|
|
764
767
|
r := runner{opts: DefaultOptions(ModeInstall), payloadFS: os.DirFS(testPayload(t))}
|
|
@@ -1247,6 +1250,10 @@ extends = ":workspace"
|
|
|
1247
1250
|
testutil.WriteFile(t, filepath.Join(root, "omp", "skills", "rite", "SKILL.md"), "omp rite\n")
|
|
1248
1251
|
testutil.WriteFile(t, filepath.Join(root, "omp", "agents", "devrites-code-reviewer.md"), "omp agent\n")
|
|
1249
1252
|
testutil.WriteFile(t, filepath.Join(root, "omp", ".omp-plugin", "plugin.json"), "{}\n")
|
|
1253
|
+
testutil.WriteFile(t, filepath.Join(root, "pi", "skills", "rite", "SKILL.md"), "pi rite\n")
|
|
1254
|
+
testutil.WriteFile(t, filepath.Join(root, "pi", "agents", "devrites-code-reviewer.md"), "pi agent\n")
|
|
1255
|
+
testutil.WriteFile(t, filepath.Join(root, "pi", "prompts", "rite.md"), "pi prompt\n")
|
|
1256
|
+
testutil.WriteFile(t, filepath.Join(root, "pi", "AGENTS.md"), "<!-- BEGIN DEVRITES PI -->\nDevRites\n<!-- END DEVRITES PI -->\n")
|
|
1250
1257
|
}
|
|
1251
1258
|
|
|
1252
1259
|
func testSource(t *testing.T, version string) string {
|
|
@@ -63,6 +63,11 @@ func (r *runner) mergeMarkerFile(merge hostpack.MarkerMerge) error {
|
|
|
63
63
|
if err := fsutil.WriteFileAtomic(dest, next, 0o644); err != nil {
|
|
64
64
|
return fmt.Errorf("cannot write %s: %w", merge.TargetRel, err)
|
|
65
65
|
}
|
|
66
|
+
// Multiple marker blocks can share one target (AGENTS.md carries both
|
|
67
|
+
// the Codex and pi blocks).
|
|
68
|
+
if err := r.refreshPreflight(merge.TargetRel); err != nil {
|
|
69
|
+
return err
|
|
70
|
+
}
|
|
66
71
|
}
|
|
67
72
|
return r.installMarker(merge.MarkerRel, merge.MarkerText)
|
|
68
73
|
}
|
|
@@ -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) {
|
|
96
|
+
for _, tree := range hostpack.InstallTrees(r.opts.WithSkills, r.opts.WithAgents, r.opts.WithCodex, r.opts.WithOmp, r.opts.WithPi) {
|
|
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) {
|
|
117
|
+
for _, rel := range hostpack.AliasTargets(alias, r.opts.WithCodex, r.opts.WithOmp, r.opts.WithPi) {
|
|
118
118
|
out[rel] = true
|
|
119
119
|
}
|
|
120
120
|
}
|
|
@@ -123,6 +123,9 @@ func (r *runner) desiredInstallPaths() (map[string]bool, error) {
|
|
|
123
123
|
out[hostpack.CodexAgentsMerge.MarkerRel] = true
|
|
124
124
|
out[hostpack.CodexConfigMerge.MarkerRel] = true
|
|
125
125
|
}
|
|
126
|
+
if r.opts.WithSkills && r.opts.WithPi {
|
|
127
|
+
out[hostpack.PiAgentsMerge.MarkerRel] = true
|
|
128
|
+
}
|
|
126
129
|
if r.opts.WithSkills {
|
|
127
130
|
out[hostpack.ClaudeSettingsMerge.MarkerRel] = true
|
|
128
131
|
}
|
|
@@ -136,6 +139,9 @@ func (r *runner) installMergeTargets() []string {
|
|
|
136
139
|
if r.opts.WithCodex {
|
|
137
140
|
out = append(out, hostpack.CodexAgentsMerge.TargetRel, hostpack.CodexConfigMerge.TargetRel)
|
|
138
141
|
}
|
|
142
|
+
if r.opts.WithPi {
|
|
143
|
+
out = append(out, hostpack.PiAgentsMerge.TargetRel)
|
|
144
|
+
}
|
|
139
145
|
}
|
|
140
146
|
return out
|
|
141
147
|
}
|
|
@@ -153,6 +159,18 @@ func (r *runner) rememberPath(rel string) (pathSnapshot, error) {
|
|
|
153
159
|
return snapshot, nil
|
|
154
160
|
}
|
|
155
161
|
|
|
162
|
+
// refreshPreflight replaces a recorded snapshot after the runner's own
|
|
163
|
+
// verified write (marker merge, strip). Needed when several managed merges
|
|
164
|
+
// share one target such as AGENTS.md.
|
|
165
|
+
func (r *runner) refreshPreflight(rel string) error {
|
|
166
|
+
snap, err := inspectManagedPath(r.target, rel)
|
|
167
|
+
if err != nil {
|
|
168
|
+
return err
|
|
169
|
+
}
|
|
170
|
+
r.preflight[filepath.ToSlash(rel)] = snap
|
|
171
|
+
return nil
|
|
172
|
+
}
|
|
173
|
+
|
|
156
174
|
func (r *runner) recheckPath(rel string) error {
|
|
157
175
|
rel = filepath.ToSlash(rel)
|
|
158
176
|
before, ok := r.preflight[rel]
|
|
@@ -58,6 +58,11 @@ func (r *runner) uninstall() error {
|
|
|
58
58
|
if err := stripMarkerPath(filepath.Join(r.target, filepath.FromSlash(merge.TargetRel)), merge.Begin, merge.End); err != nil {
|
|
59
59
|
return fmt.Errorf("strip marker block from %s: %w", merge.TargetRel, err)
|
|
60
60
|
}
|
|
61
|
+
// The Codex and pi AGENTS.md blocks share one target; record the strip
|
|
62
|
+
// so the next merge's recheckPath sees our own write, not a race.
|
|
63
|
+
if err := r.refreshPreflight(merge.TargetRel); err != nil {
|
|
64
|
+
return err
|
|
65
|
+
}
|
|
61
66
|
}
|
|
62
67
|
|
|
63
68
|
var dirs []string
|
|
@@ -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); err != nil {
|
|
68
|
+
if err := hostpack.ValidatePayload(os.DirFS(payload), 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")
|