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.
Files changed (309) hide show
  1. package/CHANGELOG.md +12 -0
  2. package/README.md +8 -6
  3. package/engine/internal/devritespaths/paths.go +3 -0
  4. package/engine/internal/hostpack/hostpack.go +45 -6
  5. package/engine/internal/hostpack/hostpack_test.go +29 -13
  6. package/engine/internal/install/apply.go +14 -5
  7. package/engine/internal/install/install.go +8 -2
  8. package/engine/internal/install/install_test.go +12 -5
  9. package/engine/internal/install/merge.go +5 -0
  10. package/engine/internal/install/preflight.go +20 -2
  11. package/engine/internal/install/uninstall.go +5 -0
  12. package/engine/internal/install/update.go +1 -1
  13. package/install.sh +107 -38
  14. package/pack/.claude/skills/rite-define/SKILL.md +1 -1
  15. package/pack/.claude/skills/rite-handoff/SKILL.md +1 -1
  16. package/pack/.claude/skills/rite-plan/SKILL.md +1 -1
  17. package/pack/.claude/skills/rite-pressure-test/SKILL.md +1 -1
  18. package/pack/.claude/skills/rite-quick/SKILL.md +1 -1
  19. package/pack/.claude/skills/rite-status/SKILL.md +1 -1
  20. package/pack/.claude/skills/rite-zoom-out/SKILL.md +1 -1
  21. package/pack/generated/README.md +5 -1
  22. package/pack/generated/claude/skills/rite-define/SKILL.md +1 -1
  23. package/pack/generated/claude/skills/rite-handoff/SKILL.md +1 -1
  24. package/pack/generated/claude/skills/rite-plan/SKILL.md +1 -1
  25. package/pack/generated/claude/skills/rite-pressure-test/SKILL.md +1 -1
  26. package/pack/generated/claude/skills/rite-quick/SKILL.md +1 -1
  27. package/pack/generated/claude/skills/rite-status/SKILL.md +1 -1
  28. package/pack/generated/claude/skills/rite-zoom-out/SKILL.md +1 -1
  29. package/pack/generated/codex/skills/rite-define/SKILL.md +1 -1
  30. package/pack/generated/codex/skills/rite-handoff/SKILL.md +1 -1
  31. package/pack/generated/codex/skills/rite-plan/SKILL.md +1 -1
  32. package/pack/generated/codex/skills/rite-pressure-test/SKILL.md +1 -1
  33. package/pack/generated/codex/skills/rite-quick/SKILL.md +1 -1
  34. package/pack/generated/codex/skills/rite-status/SKILL.md +1 -1
  35. package/pack/generated/codex/skills/rite-zoom-out/SKILL.md +1 -1
  36. package/pack/generated/omp/skills/rite-define/SKILL.md +1 -1
  37. package/pack/generated/omp/skills/rite-handoff/SKILL.md +1 -1
  38. package/pack/generated/omp/skills/rite-plan/SKILL.md +1 -1
  39. package/pack/generated/omp/skills/rite-pressure-test/SKILL.md +1 -1
  40. package/pack/generated/omp/skills/rite-quick/SKILL.md +1 -1
  41. package/pack/generated/omp/skills/rite-status/SKILL.md +1 -1
  42. package/pack/generated/omp/skills/rite-zoom-out/SKILL.md +1 -1
  43. package/pack/generated/pi/AGENTS.md +22 -0
  44. package/pack/generated/pi/agents/devrites-code-reviewer.md +142 -0
  45. package/pack/generated/pi/agents/devrites-devex-reviewer.md +124 -0
  46. package/pack/generated/pi/agents/devrites-doubt-reviewer.md +88 -0
  47. package/pack/generated/pi/agents/devrites-evidence-scout.md +72 -0
  48. package/pack/generated/pi/agents/devrites-frontend-reviewer.md +116 -0
  49. package/pack/generated/pi/agents/devrites-performance-reviewer.md +115 -0
  50. package/pack/generated/pi/agents/devrites-plan-drafter.md +99 -0
  51. package/pack/generated/pi/agents/devrites-plan-reviewer.md +142 -0
  52. package/pack/generated/pi/agents/devrites-proof-runner.md +74 -0
  53. package/pack/generated/pi/agents/devrites-retrospector.md +61 -0
  54. package/pack/generated/pi/agents/devrites-security-auditor.md +109 -0
  55. package/pack/generated/pi/agents/devrites-simplifier-reviewer.md +94 -0
  56. package/pack/generated/pi/agents/devrites-slice-wright.md +204 -0
  57. package/pack/generated/pi/agents/devrites-spec-reviewer.md +96 -0
  58. package/pack/generated/pi/agents/devrites-strategy-reviewer.md +100 -0
  59. package/pack/generated/pi/agents/devrites-test-analyst.md +94 -0
  60. package/pack/generated/pi/agents/devrites-upgrade-planner.md +89 -0
  61. package/pack/generated/pi/prompts/rite-adopt.md +5 -0
  62. package/pack/generated/pi/prompts/rite-autocomplete.md +5 -0
  63. package/pack/generated/pi/prompts/rite-build.md +5 -0
  64. package/pack/generated/pi/prompts/rite-clarify.md +5 -0
  65. package/pack/generated/pi/prompts/rite-converge.md +5 -0
  66. package/pack/generated/pi/prompts/rite-customize.md +5 -0
  67. package/pack/generated/pi/prompts/rite-define.md +5 -0
  68. package/pack/generated/pi/prompts/rite-doctor.md +5 -0
  69. package/pack/generated/pi/prompts/rite-dogfood.md +5 -0
  70. package/pack/generated/pi/prompts/rite-explain.md +5 -0
  71. package/pack/generated/pi/prompts/rite-frame.md +5 -0
  72. package/pack/generated/pi/prompts/rite-handoff.md +5 -0
  73. package/pack/generated/pi/prompts/rite-learn.md +5 -0
  74. package/pack/generated/pi/prompts/rite-plan.md +5 -0
  75. package/pack/generated/pi/prompts/rite-polish.md +5 -0
  76. package/pack/generated/pi/prompts/rite-pov.md +5 -0
  77. package/pack/generated/pi/prompts/rite-pr-feedback.md +5 -0
  78. package/pack/generated/pi/prompts/rite-pressure-test.md +5 -0
  79. package/pack/generated/pi/prompts/rite-prototype.md +5 -0
  80. package/pack/generated/pi/prompts/rite-prove.md +5 -0
  81. package/pack/generated/pi/prompts/rite-quick.md +5 -0
  82. package/pack/generated/pi/prompts/rite-resolve.md +5 -0
  83. package/pack/generated/pi/prompts/rite-review.md +5 -0
  84. package/pack/generated/pi/prompts/rite-seal.md +5 -0
  85. package/pack/generated/pi/prompts/rite-ship.md +5 -0
  86. package/pack/generated/pi/prompts/rite-spec.md +5 -0
  87. package/pack/generated/pi/prompts/rite-status.md +5 -0
  88. package/pack/generated/pi/prompts/rite-temper.md +5 -0
  89. package/pack/generated/pi/prompts/rite-upgrade.md +5 -0
  90. package/pack/generated/pi/prompts/rite-vet.md +5 -0
  91. package/pack/generated/pi/prompts/rite-watch-pr.md +5 -0
  92. package/pack/generated/pi/prompts/rite-zoom-out.md +5 -0
  93. package/pack/generated/pi/prompts/rite.md +5 -0
  94. package/pack/generated/pi/skills/devrites-api-interface/SKILL.md +63 -0
  95. package/pack/generated/pi/skills/devrites-audit/SKILL.md +50 -0
  96. package/pack/generated/pi/skills/devrites-browser-proof/SKILL.md +76 -0
  97. package/pack/generated/pi/skills/devrites-browser-proof/reference/browser-performance.md +15 -0
  98. package/pack/generated/pi/skills/devrites-browser-proof/reference/visual-verdict.md +34 -0
  99. package/pack/generated/pi/skills/devrites-debug-recovery/SKILL.md +96 -0
  100. package/pack/generated/pi/skills/devrites-debug-recovery/reference/build-the-loop.md +58 -0
  101. package/pack/generated/pi/skills/devrites-debug-recovery/reference/cleanup-and-classify.md +34 -0
  102. package/pack/generated/pi/skills/devrites-debug-recovery/reference/hypotheses.md +17 -0
  103. package/pack/generated/pi/skills/devrites-debug-recovery/reference/instrumentation.md +21 -0
  104. package/pack/generated/pi/skills/devrites-debug-recovery/reference/regression-test.md +30 -0
  105. package/pack/generated/pi/skills/devrites-debug-recovery/reference/trace.md +25 -0
  106. package/pack/generated/pi/skills/devrites-doubt/SKILL.md +79 -0
  107. package/pack/generated/pi/skills/devrites-frontend-craft/SKILL.md +86 -0
  108. package/pack/generated/pi/skills/devrites-frontend-craft/reference/craft.md +63 -0
  109. package/pack/generated/pi/skills/devrites-frontend-craft/reference/design-references.md +116 -0
  110. package/pack/generated/pi/skills/devrites-frontend-craft/reference/fullstack.md +46 -0
  111. package/pack/generated/pi/skills/devrites-frontend-craft/reference/quality-standards.md +294 -0
  112. package/pack/generated/pi/skills/devrites-frontend-craft/reference/reuse-first.md +53 -0
  113. package/pack/generated/pi/skills/devrites-frontend-craft/reference/shape.md +56 -0
  114. package/pack/generated/pi/skills/devrites-interview/SKILL.md +102 -0
  115. package/pack/generated/pi/skills/devrites-lib/SKILL.md +58 -0
  116. package/pack/generated/pi/skills/devrites-lib/reference/candidate-integrity.md +42 -0
  117. package/pack/generated/pi/skills/devrites-lib/reference/intent-map.md +64 -0
  118. package/pack/generated/pi/skills/devrites-lib/reference/orchestration-profiles.md +27 -0
  119. package/pack/generated/pi/skills/devrites-lib/reference/parallel-dispatch.md +73 -0
  120. package/pack/generated/pi/skills/devrites-lib/reference/reply-contract.md +88 -0
  121. package/pack/generated/pi/skills/devrites-lib/reference/standards/README.md +60 -0
  122. package/pack/generated/pi/skills/devrites-lib/reference/standards/acceptance-preserving-reslice.md +30 -0
  123. package/pack/generated/pi/skills/devrites-lib/reference/standards/afk-hitl.md +398 -0
  124. package/pack/generated/pi/skills/devrites-lib/reference/standards/agents.md +99 -0
  125. package/pack/generated/pi/skills/devrites-lib/reference/standards/anti-patterns.md +48 -0
  126. package/pack/generated/pi/skills/devrites-lib/reference/standards/browser-proof-checklist.md +24 -0
  127. package/pack/generated/pi/skills/devrites-lib/reference/standards/ci-cd.md +50 -0
  128. package/pack/generated/pi/skills/devrites-lib/reference/standards/code-navigation.md +43 -0
  129. package/pack/generated/pi/skills/devrites-lib/reference/standards/code-review.md +108 -0
  130. package/pack/generated/pi/skills/devrites-lib/reference/standards/coding-style.md +48 -0
  131. package/pack/generated/pi/skills/devrites-lib/reference/standards/context-hygiene.md +109 -0
  132. package/pack/generated/pi/skills/devrites-lib/reference/standards/core.md +167 -0
  133. package/pack/generated/pi/skills/devrites-lib/reference/standards/data-integrity.md +118 -0
  134. package/pack/generated/pi/skills/devrites-lib/reference/standards/debug-recovery.md +28 -0
  135. package/pack/generated/pi/skills/devrites-lib/reference/standards/definition-of-done.md +19 -0
  136. package/pack/generated/pi/skills/devrites-lib/reference/standards/deprecation.md +31 -0
  137. package/pack/generated/pi/skills/devrites-lib/reference/standards/developer-experience.md +119 -0
  138. package/pack/generated/pi/skills/devrites-lib/reference/standards/development-workflow.md +29 -0
  139. package/pack/generated/pi/skills/devrites-lib/reference/standards/documentation.md +43 -0
  140. package/pack/generated/pi/skills/devrites-lib/reference/standards/edge-case-trace.md +92 -0
  141. package/pack/generated/pi/skills/devrites-lib/reference/standards/elicitation.md +85 -0
  142. package/pack/generated/pi/skills/devrites-lib/reference/standards/error-handling.md +47 -0
  143. package/pack/generated/pi/skills/devrites-lib/reference/standards/git-workflow.md +49 -0
  144. package/pack/generated/pi/skills/devrites-lib/reference/standards/hooks.md +25 -0
  145. package/pack/generated/pi/skills/devrites-lib/reference/standards/integration-reliability.md +102 -0
  146. package/pack/generated/pi/skills/devrites-lib/reference/standards/loop-operations.md +85 -0
  147. package/pack/generated/pi/skills/devrites-lib/reference/standards/observability.md +88 -0
  148. package/pack/generated/pi/skills/devrites-lib/reference/standards/one-shot-actions.md +97 -0
  149. package/pack/generated/pi/skills/devrites-lib/reference/standards/patterns.md +68 -0
  150. package/pack/generated/pi/skills/devrites-lib/reference/standards/performance.md +51 -0
  151. package/pack/generated/pi/skills/devrites-lib/reference/standards/principles.md +42 -0
  152. package/pack/generated/pi/skills/devrites-lib/reference/standards/prose-style.md +123 -0
  153. package/pack/generated/pi/skills/devrites-lib/reference/standards/release/ship-checklist.md +8 -0
  154. package/pack/generated/pi/skills/devrites-lib/reference/standards/repository-topology.md +80 -0
  155. package/pack/generated/pi/skills/devrites-lib/reference/standards/review-checklist.md +12 -0
  156. package/pack/generated/pi/skills/devrites-lib/reference/standards/security-checklist.md +25 -0
  157. package/pack/generated/pi/skills/devrites-lib/reference/standards/security.md +202 -0
  158. package/pack/generated/pi/skills/devrites-lib/reference/standards/skill-authoring.md +209 -0
  159. package/pack/generated/pi/skills/devrites-lib/reference/standards/spec-grammar.md +197 -0
  160. package/pack/generated/pi/skills/devrites-lib/reference/standards/test-proof-checklist.md +13 -0
  161. package/pack/generated/pi/skills/devrites-lib/reference/standards/testing.md +212 -0
  162. package/pack/generated/pi/skills/devrites-lib/reference/standards/tooling.md +92 -0
  163. package/pack/generated/pi/skills/devrites-lib/reference/standards/workflow-artifacts.md +427 -0
  164. package/pack/generated/pi/skills/devrites-lib/reference/visual-playbooks/code.md +44 -0
  165. package/pack/generated/pi/skills/devrites-lib/reference/visual-playbooks/comparison.md +42 -0
  166. package/pack/generated/pi/skills/devrites-lib/reference/visual-playbooks/diagram.md +51 -0
  167. package/pack/generated/pi/skills/devrites-lib/reference/visual-playbooks/index.md +66 -0
  168. package/pack/generated/pi/skills/devrites-lib/reference/visual-playbooks/input.md +46 -0
  169. package/pack/generated/pi/skills/devrites-lib/reference/visual-playbooks/outline-template.md +106 -0
  170. package/pack/generated/pi/skills/devrites-lib/reference/visual-playbooks/plan.md +48 -0
  171. package/pack/generated/pi/skills/devrites-lib/reference/visual-playbooks/slides.md +40 -0
  172. package/pack/generated/pi/skills/devrites-lib/reference/visual-playbooks/table.md +42 -0
  173. package/pack/generated/pi/skills/devrites-lib/reference/workspace-artifact-schema.md +267 -0
  174. package/pack/generated/pi/skills/devrites-prose-craft/SKILL.md +73 -0
  175. package/pack/generated/pi/skills/devrites-prose-craft/reference/banned-phrases.md +132 -0
  176. package/pack/generated/pi/skills/devrites-prose-craft/reference/examples.md +131 -0
  177. package/pack/generated/pi/skills/devrites-prose-craft/reference/structures.md +196 -0
  178. package/pack/generated/pi/skills/devrites-source-driven/SKILL.md +52 -0
  179. package/pack/generated/pi/skills/devrites-ux-shape/SKILL.md +134 -0
  180. package/pack/generated/pi/skills/devrites-ux-shape/reference/brief-template.md +108 -0
  181. package/pack/generated/pi/skills/devrites-ux-shape/reference/visual-direction-probe.md +48 -0
  182. package/pack/generated/pi/skills/rite/SKILL.md +148 -0
  183. package/pack/generated/pi/skills/rite/reference/menu.md +48 -0
  184. package/pack/generated/pi/skills/rite-adopt/SKILL.md +52 -0
  185. package/pack/generated/pi/skills/rite-adopt/reference/adoption.md +19 -0
  186. package/pack/generated/pi/skills/rite-adopt/reference/anti-patterns.md +19 -0
  187. package/pack/generated/pi/skills/rite-autocomplete/SKILL.md +132 -0
  188. package/pack/generated/pi/skills/rite-autocomplete/reference/decision-policy.md +41 -0
  189. package/pack/generated/pi/skills/rite-autocomplete/reference/loop.md +148 -0
  190. package/pack/generated/pi/skills/rite-autocomplete/reference/stop-conditions.md +92 -0
  191. package/pack/generated/pi/skills/rite-build/SKILL.md +96 -0
  192. package/pack/generated/pi/skills/rite-build/reference/afk-discipline.md +145 -0
  193. package/pack/generated/pi/skills/rite-build/reference/anti-patterns.md +23 -0
  194. package/pack/generated/pi/skills/rite-build/reference/checkpoint-protocol.md +120 -0
  195. package/pack/generated/pi/skills/rite-build/reference/checkpoint.md +44 -0
  196. package/pack/generated/pi/skills/rite-build/reference/frontend-trigger.md +39 -0
  197. package/pack/generated/pi/skills/rite-build/reference/one-slice-cycle.md +50 -0
  198. package/pack/generated/pi/skills/rite-build/reference/output.md +33 -0
  199. package/pack/generated/pi/skills/rite-build/reference/parallel-batch.md +205 -0
  200. package/pack/generated/pi/skills/rite-build/reference/phase-contract.md +87 -0
  201. package/pack/generated/pi/skills/rite-build/reference/spec-drift-guard.md +84 -0
  202. package/pack/generated/pi/skills/rite-build/reference/tdd.md +27 -0
  203. package/pack/generated/pi/skills/rite-build/reference/wright-dispatch.md +89 -0
  204. package/pack/generated/pi/skills/rite-clarify/SKILL.md +99 -0
  205. package/pack/generated/pi/skills/rite-clarify/reference/anti-patterns.md +24 -0
  206. package/pack/generated/pi/skills/rite-clarify/reference/decision-coverage.md +55 -0
  207. package/pack/generated/pi/skills/rite-converge/SKILL.md +145 -0
  208. package/pack/generated/pi/skills/rite-converge/reference/anti-patterns.md +35 -0
  209. package/pack/generated/pi/skills/rite-converge/reference/convergence-assessment.md +65 -0
  210. package/pack/generated/pi/skills/rite-customize/SKILL.md +60 -0
  211. package/pack/generated/pi/skills/rite-define/SKILL.md +169 -0
  212. package/pack/generated/pi/skills/rite-define/reference/anti-patterns.md +26 -0
  213. package/pack/generated/pi/skills/rite-define/reference/gates.md +154 -0
  214. package/pack/generated/pi/skills/rite-define/reference/plan-template.md +149 -0
  215. package/pack/generated/pi/skills/rite-doctor/SKILL.md +69 -0
  216. package/pack/generated/pi/skills/rite-dogfood/SKILL.md +55 -0
  217. package/pack/generated/pi/skills/rite-explain/SKILL.md +152 -0
  218. package/pack/generated/pi/skills/rite-explain/reference/intake.md +89 -0
  219. package/pack/generated/pi/skills/rite-frame/SKILL.md +115 -0
  220. package/pack/generated/pi/skills/rite-frame/reference/failure-modes.md +66 -0
  221. package/pack/generated/pi/skills/rite-handoff/SKILL.md +97 -0
  222. package/pack/generated/pi/skills/rite-handoff/reference/handoff-template.md +44 -0
  223. package/pack/generated/pi/skills/rite-learn/SKILL.md +72 -0
  224. package/pack/generated/pi/skills/rite-plan/SKILL.md +186 -0
  225. package/pack/generated/pi/skills/rite-plan/reference/anti-patterns.md +34 -0
  226. package/pack/generated/pi/skills/rite-plan/reference/dependency-graph.md +48 -0
  227. package/pack/generated/pi/skills/rite-plan/reference/replan-and-repair.md +105 -0
  228. package/pack/generated/pi/skills/rite-plan/reference/slicing.md +167 -0
  229. package/pack/generated/pi/skills/rite-plan/reference/task-breakdown.md +42 -0
  230. package/pack/generated/pi/skills/rite-polish/SKILL.md +104 -0
  231. package/pack/generated/pi/skills/rite-polish/reference/adr-promotion.md +11 -0
  232. package/pack/generated/pi/skills/rite-polish/reference/anti-ai-slop.md +187 -0
  233. package/pack/generated/pi/skills/rite-polish/reference/anti-patterns.md +30 -0
  234. package/pack/generated/pi/skills/rite-polish/reference/backend-polish.md +80 -0
  235. package/pack/generated/pi/skills/rite-polish/reference/browser-polish-evidence.md +33 -0
  236. package/pack/generated/pi/skills/rite-polish/reference/code.md +82 -0
  237. package/pack/generated/pi/skills/rite-polish/reference/design-memory.md +117 -0
  238. package/pack/generated/pi/skills/rite-polish/reference/design-system-discovery.md +8 -0
  239. package/pack/generated/pi/skills/rite-polish/reference/harden-checklist.md +109 -0
  240. package/pack/generated/pi/skills/rite-polish/reference/ledger.md +65 -0
  241. package/pack/generated/pi/skills/rite-polish/reference/ui.md +137 -0
  242. package/pack/generated/pi/skills/rite-pov/SKILL.md +58 -0
  243. package/pack/generated/pi/skills/rite-pr-feedback/SKILL.md +54 -0
  244. package/pack/generated/pi/skills/rite-pressure-test/SKILL.md +67 -0
  245. package/pack/generated/pi/skills/rite-prototype/SKILL.md +104 -0
  246. package/pack/generated/pi/skills/rite-prove/SKILL.md +120 -0
  247. package/pack/generated/pi/skills/rite-prove/reference/acceptance-proof.md +88 -0
  248. package/pack/generated/pi/skills/rite-prove/reference/anti-patterns.md +25 -0
  249. package/pack/generated/pi/skills/rite-prove/reference/browser-proof.md +51 -0
  250. package/pack/generated/pi/skills/rite-prove/reference/failure-triage.md +43 -0
  251. package/pack/generated/pi/skills/rite-prove/reference/proof-ladder.md +28 -0
  252. package/pack/generated/pi/skills/rite-prove/reference/test-command-discovery.md +30 -0
  253. package/pack/generated/pi/skills/rite-quick/SKILL.md +82 -0
  254. package/pack/generated/pi/skills/rite-resolve/SKILL.md +95 -0
  255. package/pack/generated/pi/skills/rite-resolve/reference/answer-protocol.md +118 -0
  256. package/pack/generated/pi/skills/rite-review/SKILL.md +170 -0
  257. package/pack/generated/pi/skills/rite-review/reference/anti-patterns.md +32 -0
  258. package/pack/generated/pi/skills/rite-review/reference/cognitive-load.md +90 -0
  259. package/pack/generated/pi/skills/rite-review/reference/feature-scoped-review.md +26 -0
  260. package/pack/generated/pi/skills/rite-review/reference/five-axis-review.md +66 -0
  261. package/pack/generated/pi/skills/rite-review/reference/nielsen-heuristics.md +126 -0
  262. package/pack/generated/pi/skills/rite-review/reference/performance-checklist.md +80 -0
  263. package/pack/generated/pi/skills/rite-review/reference/performance-review.md +14 -0
  264. package/pack/generated/pi/skills/rite-review/reference/security-review.md +42 -0
  265. package/pack/generated/pi/skills/rite-seal/SKILL.md +75 -0
  266. package/pack/generated/pi/skills/rite-seal/reference/anti-patterns.md +29 -0
  267. package/pack/generated/pi/skills/rite-seal/reference/final-evidence.md +41 -0
  268. package/pack/generated/pi/skills/rite-seal/reference/go-no-go.md +29 -0
  269. package/pack/generated/pi/skills/rite-seal/reference/output.md +5 -0
  270. package/pack/generated/pi/skills/rite-seal/reference/phase-contract.md +47 -0
  271. package/pack/generated/pi/skills/rite-seal/reference/risk-and-rollback.md +56 -0
  272. package/pack/generated/pi/skills/rite-seal/reference/seal-template.md +27 -0
  273. package/pack/generated/pi/skills/rite-ship/SKILL.md +88 -0
  274. package/pack/generated/pi/skills/rite-ship/reference/anti-patterns.md +28 -0
  275. package/pack/generated/pi/skills/rite-ship/reference/close-out.md +68 -0
  276. package/pack/generated/pi/skills/rite-ship/reference/git-ship.md +120 -0
  277. package/pack/generated/pi/skills/rite-ship/reference/rollout.md +62 -0
  278. package/pack/generated/pi/skills/rite-ship/reference/ship-template.md +39 -0
  279. package/pack/generated/pi/skills/rite-spec/SKILL.md +150 -0
  280. package/pack/generated/pi/skills/rite-spec/reference/acceptance-criteria.md +31 -0
  281. package/pack/generated/pi/skills/rite-spec/reference/ai-spec-template.md +40 -0
  282. package/pack/generated/pi/skills/rite-spec/reference/anti-patterns.md +27 -0
  283. package/pack/generated/pi/skills/rite-spec/reference/interview-patterns.md +56 -0
  284. package/pack/generated/pi/skills/rite-spec/reference/investigation.md +83 -0
  285. package/pack/generated/pi/skills/rite-spec/reference/question-protocol.md +36 -0
  286. package/pack/generated/pi/skills/rite-spec/reference/references-intake.md +62 -0
  287. package/pack/generated/pi/skills/rite-spec/reference/spec-checklists.md +89 -0
  288. package/pack/generated/pi/skills/rite-spec/reference/spec-template.md +154 -0
  289. package/pack/generated/pi/skills/rite-spec/reference/state-workspace.md +227 -0
  290. package/pack/generated/pi/skills/rite-status/SKILL.md +57 -0
  291. package/pack/generated/pi/skills/rite-temper/SKILL.md +130 -0
  292. package/pack/generated/pi/skills/rite-temper/reference/anti-patterns.md +30 -0
  293. package/pack/generated/pi/skills/rite-temper/reference/review-dimensions.md +66 -0
  294. package/pack/generated/pi/skills/rite-temper/reference/scope-modes.md +53 -0
  295. package/pack/generated/pi/skills/rite-temper/reference/significance.md +46 -0
  296. package/pack/generated/pi/skills/rite-temper/reference/strategy-template.md +90 -0
  297. package/pack/generated/pi/skills/rite-upgrade/SKILL.md +121 -0
  298. package/pack/generated/pi/skills/rite-vet/SKILL.md +193 -0
  299. package/pack/generated/pi/skills/rite-vet/reference/anti-patterns.md +43 -0
  300. package/pack/generated/pi/skills/rite-vet/reference/artifacts.md +202 -0
  301. package/pack/generated/pi/skills/rite-vet/reference/cross-model.md +19 -0
  302. package/pack/generated/pi/skills/rite-vet/reference/depth.md +59 -0
  303. package/pack/generated/pi/skills/rite-vet/reference/eng-lenses.md +48 -0
  304. package/pack/generated/pi/skills/rite-vet/reference/review-axes.md +201 -0
  305. package/pack/generated/pi/skills/rite-watch-pr/SKILL.md +85 -0
  306. package/pack/generated/pi/skills/rite-zoom-out/SKILL.md +69 -0
  307. package/package.json +3 -2
  308. package/scripts/build-host-artifacts.sh +100 -37
  309. 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.5.0`](https://github.com/ViktorsBaikers/DevRites/releases/tag/v5.5.0): see [`CHANGELOG.md`](CHANGELOG.md) for release notes.
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 and Codex. It does not
51
- write skills, agents, or hooks to `~/.claude` or `~/.codex`.
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>`. The menu and direct forms run
82
- the same skill.
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` integration. |
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
- if err := ValidatePayload(payload, false, false); err != nil {
42
- t.Fatalf("claude-only payload should not require omp files: %v", err)
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("omp alias installed with withOmp=false: %s", rel)
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 only", withCodex: false, withOmp: false, want: "Next: reopen the project, then run /rite."},
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")