ralphy-spec 0.1.1 → 0.3.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 (257) hide show
  1. package/CHANGELOG.md +32 -0
  2. package/README.ja.md +94 -127
  3. package/README.ko.md +94 -127
  4. package/README.md +94 -129
  5. package/README.zh.md +94 -127
  6. package/bin/ralphy-spec.js +0 -0
  7. package/dist/cli/budget.d.ts +3 -0
  8. package/dist/cli/budget.d.ts.map +1 -0
  9. package/dist/cli/budget.js +77 -0
  10. package/dist/cli/budget.js.map +1 -0
  11. package/dist/cli/checkpoint.d.ts +3 -0
  12. package/dist/cli/checkpoint.d.ts.map +1 -0
  13. package/dist/cli/checkpoint.js +23 -0
  14. package/dist/cli/checkpoint.js.map +1 -0
  15. package/dist/cli/init.d.ts +3 -0
  16. package/dist/cli/init.d.ts.map +1 -0
  17. package/dist/cli/init.js +72 -0
  18. package/dist/cli/init.js.map +1 -0
  19. package/dist/cli/report.d.ts +3 -0
  20. package/dist/cli/report.d.ts.map +1 -0
  21. package/dist/cli/report.js +53 -0
  22. package/dist/cli/report.js.map +1 -0
  23. package/dist/cli/run.d.ts +3 -0
  24. package/dist/cli/run.d.ts.map +1 -0
  25. package/dist/cli/run.js +112 -0
  26. package/dist/cli/run.js.map +1 -0
  27. package/dist/cli/status.d.ts +3 -0
  28. package/dist/cli/status.d.ts.map +1 -0
  29. package/dist/cli/status.js +76 -0
  30. package/dist/cli/status.js.map +1 -0
  31. package/dist/cli/tail.d.ts +3 -0
  32. package/dist/cli/tail.d.ts.map +1 -0
  33. package/dist/cli/tail.js +46 -0
  34. package/dist/cli/tail.js.map +1 -0
  35. package/dist/cli/update.d.ts +3 -0
  36. package/dist/cli/update.d.ts.map +1 -0
  37. package/dist/cli/update.js +62 -0
  38. package/dist/cli/update.js.map +1 -0
  39. package/dist/cli/validate.d.ts +3 -0
  40. package/dist/cli/validate.d.ts.map +1 -0
  41. package/dist/cli/validate.js +83 -0
  42. package/dist/cli/validate.js.map +1 -0
  43. package/dist/core/artifacts/budget-writer.d.ts +11 -0
  44. package/dist/core/artifacts/budget-writer.d.ts.map +1 -0
  45. package/dist/core/artifacts/budget-writer.js +28 -0
  46. package/dist/core/artifacts/budget-writer.js.map +1 -0
  47. package/dist/core/artifacts/run-log-writer.d.ts +20 -0
  48. package/dist/core/artifacts/run-log-writer.d.ts.map +1 -0
  49. package/dist/core/artifacts/run-log-writer.js +40 -0
  50. package/dist/core/artifacts/run-log-writer.js.map +1 -0
  51. package/dist/core/artifacts/run-log-writer.test.d.ts +2 -0
  52. package/dist/core/artifacts/run-log-writer.test.d.ts.map +1 -0
  53. package/dist/core/artifacts/run-log-writer.test.js +37 -0
  54. package/dist/core/artifacts/run-log-writer.test.js.map +1 -0
  55. package/dist/core/artifacts/status-writer.d.ts +16 -0
  56. package/dist/core/artifacts/status-writer.d.ts.map +1 -0
  57. package/dist/core/artifacts/status-writer.js +52 -0
  58. package/dist/core/artifacts/status-writer.js.map +1 -0
  59. package/dist/core/artifacts/status-writer.test.d.ts +2 -0
  60. package/dist/core/artifacts/status-writer.test.d.ts.map +1 -0
  61. package/dist/core/artifacts/status-writer.test.js +47 -0
  62. package/dist/core/artifacts/status-writer.test.js.map +1 -0
  63. package/dist/core/artifacts/task-artifacts.d.ts +19 -0
  64. package/dist/core/artifacts/task-artifacts.d.ts.map +1 -0
  65. package/dist/core/artifacts/task-artifacts.js +35 -0
  66. package/dist/core/artifacts/task-artifacts.js.map +1 -0
  67. package/dist/core/artifacts/tasks-writer.d.ts +19 -0
  68. package/dist/core/artifacts/tasks-writer.d.ts.map +1 -0
  69. package/dist/core/artifacts/tasks-writer.js +67 -0
  70. package/dist/core/artifacts/tasks-writer.js.map +1 -0
  71. package/dist/core/artifacts/tasks-writer.test.d.ts +2 -0
  72. package/dist/core/artifacts/tasks-writer.test.d.ts.map +1 -0
  73. package/dist/core/artifacts/tasks-writer.test.js +28 -0
  74. package/dist/core/artifacts/tasks-writer.test.js.map +1 -0
  75. package/dist/core/backends/claude-code.d.ts +17 -0
  76. package/dist/core/backends/claude-code.d.ts.map +1 -0
  77. package/dist/core/backends/claude-code.js +75 -0
  78. package/dist/core/backends/claude-code.js.map +1 -0
  79. package/dist/core/backends/cursor.d.ts +17 -0
  80. package/dist/core/backends/cursor.d.ts.map +1 -0
  81. package/dist/core/backends/cursor.js +75 -0
  82. package/dist/core/backends/cursor.js.map +1 -0
  83. package/dist/core/backends/noop.d.ts +10 -0
  84. package/dist/core/backends/noop.d.ts.map +1 -0
  85. package/dist/core/backends/noop.js +17 -0
  86. package/dist/core/backends/noop.js.map +1 -0
  87. package/dist/core/backends/opencode.d.ts +16 -0
  88. package/dist/core/backends/opencode.d.ts.map +1 -0
  89. package/dist/core/backends/opencode.js +73 -0
  90. package/dist/core/backends/opencode.js.map +1 -0
  91. package/dist/core/backends/types.d.ts +21 -0
  92. package/dist/core/backends/types.d.ts.map +1 -0
  93. package/dist/core/backends/types.js +3 -0
  94. package/dist/core/backends/types.js.map +1 -0
  95. package/dist/core/budgets/errors.d.ts +5 -0
  96. package/dist/core/budgets/errors.d.ts.map +1 -0
  97. package/dist/core/budgets/errors.js +11 -0
  98. package/dist/core/budgets/errors.js.map +1 -0
  99. package/dist/core/budgets/manager.d.ts +21 -0
  100. package/dist/core/budgets/manager.d.ts.map +1 -0
  101. package/dist/core/budgets/manager.js +48 -0
  102. package/dist/core/budgets/manager.js.map +1 -0
  103. package/dist/core/budgets/state.d.ts +25 -0
  104. package/dist/core/budgets/state.d.ts.map +1 -0
  105. package/dist/core/budgets/state.js +33 -0
  106. package/dist/core/budgets/state.js.map +1 -0
  107. package/dist/core/budgets/tiers.d.ts +32 -0
  108. package/dist/core/budgets/tiers.d.ts.map +1 -0
  109. package/dist/core/budgets/tiers.js +67 -0
  110. package/dist/core/budgets/tiers.js.map +1 -0
  111. package/dist/core/engine/constraints.d.ts +16 -0
  112. package/dist/core/engine/constraints.d.ts.map +1 -0
  113. package/dist/core/engine/constraints.js +21 -0
  114. package/dist/core/engine/constraints.js.map +1 -0
  115. package/dist/core/engine/constraints.policy.test.d.ts +2 -0
  116. package/dist/core/engine/constraints.policy.test.d.ts.map +1 -0
  117. package/dist/core/engine/constraints.policy.test.js +85 -0
  118. package/dist/core/engine/constraints.policy.test.js.map +1 -0
  119. package/dist/core/engine/context-pack.d.ts +12 -0
  120. package/dist/core/engine/context-pack.d.ts.map +1 -0
  121. package/dist/core/engine/context-pack.js +45 -0
  122. package/dist/core/engine/context-pack.js.map +1 -0
  123. package/dist/core/engine/loop.d.ts +28 -0
  124. package/dist/core/engine/loop.d.ts.map +1 -0
  125. package/dist/core/engine/loop.hardcap.test.d.ts +2 -0
  126. package/dist/core/engine/loop.hardcap.test.d.ts.map +1 -0
  127. package/dist/core/engine/loop.hardcap.test.js +77 -0
  128. package/dist/core/engine/loop.hardcap.test.js.map +1 -0
  129. package/dist/core/engine/loop.js +864 -0
  130. package/dist/core/engine/loop.js.map +1 -0
  131. package/dist/core/engine/phases.d.ts +2 -0
  132. package/dist/core/engine/phases.d.ts.map +1 -0
  133. package/dist/core/engine/phases.js +3 -0
  134. package/dist/core/engine/phases.js.map +1 -0
  135. package/dist/core/engine/repair.d.ts +6 -0
  136. package/dist/core/engine/repair.d.ts.map +1 -0
  137. package/dist/core/engine/repair.js +23 -0
  138. package/dist/core/engine/repair.js.map +1 -0
  139. package/dist/core/folders.d.ts +26 -0
  140. package/dist/core/folders.d.ts.map +1 -0
  141. package/dist/core/folders.js +58 -0
  142. package/dist/core/folders.js.map +1 -0
  143. package/dist/core/memory/ledger.d.ts +13 -0
  144. package/dist/core/memory/ledger.d.ts.map +1 -0
  145. package/dist/core/memory/ledger.js +24 -0
  146. package/dist/core/memory/ledger.js.map +1 -0
  147. package/dist/core/memory/persistence.d.ts +54 -0
  148. package/dist/core/memory/persistence.d.ts.map +1 -0
  149. package/dist/core/memory/persistence.js +180 -0
  150. package/dist/core/memory/persistence.js.map +1 -0
  151. package/dist/core/reporting/failure-summary.d.ts +23 -0
  152. package/dist/core/reporting/failure-summary.d.ts.map +1 -0
  153. package/dist/core/reporting/failure-summary.js +63 -0
  154. package/dist/core/reporting/failure-summary.js.map +1 -0
  155. package/dist/core/reporting/failure-summary.test.d.ts +2 -0
  156. package/dist/core/reporting/failure-summary.test.d.ts.map +1 -0
  157. package/dist/core/reporting/failure-summary.test.js +22 -0
  158. package/dist/core/reporting/failure-summary.test.js.map +1 -0
  159. package/dist/core/reporting/spend.d.ts +40 -0
  160. package/dist/core/reporting/spend.d.ts.map +1 -0
  161. package/dist/core/reporting/spend.js +157 -0
  162. package/dist/core/reporting/spend.js.map +1 -0
  163. package/dist/core/spec/dag.d.ts +7 -0
  164. package/dist/core/spec/dag.d.ts.map +1 -0
  165. package/dist/core/spec/dag.js +65 -0
  166. package/dist/core/spec/dag.js.map +1 -0
  167. package/dist/core/spec/file-contract.d.ts +13 -0
  168. package/dist/core/spec/file-contract.d.ts.map +1 -0
  169. package/dist/core/spec/file-contract.js +29 -0
  170. package/dist/core/spec/file-contract.js.map +1 -0
  171. package/dist/core/spec/loader.d.ts +8 -0
  172. package/dist/core/spec/loader.d.ts.map +1 -0
  173. package/dist/core/spec/loader.js +62 -0
  174. package/dist/core/spec/loader.js.map +1 -0
  175. package/dist/core/spec/schemas.d.ts +1135 -0
  176. package/dist/core/spec/schemas.d.ts.map +1 -0
  177. package/dist/core/spec/schemas.js +235 -0
  178. package/dist/core/spec/schemas.js.map +1 -0
  179. package/dist/core/spec/sprint-defaults.d.ts +16 -0
  180. package/dist/core/spec/sprint-defaults.d.ts.map +1 -0
  181. package/dist/core/spec/sprint-defaults.js +55 -0
  182. package/dist/core/spec/sprint-defaults.js.map +1 -0
  183. package/dist/core/spec/sprint-defaults.test.d.ts +2 -0
  184. package/dist/core/spec/sprint-defaults.test.d.ts.map +1 -0
  185. package/dist/core/spec/sprint-defaults.test.js +51 -0
  186. package/dist/core/spec/sprint-defaults.test.js.map +1 -0
  187. package/dist/core/spec/types.d.ts +82 -0
  188. package/dist/core/spec/types.d.ts.map +1 -0
  189. package/dist/core/spec/types.js +3 -0
  190. package/dist/core/spec/types.js.map +1 -0
  191. package/dist/core/validators/parsers/eslint.d.ts +3 -0
  192. package/dist/core/validators/parsers/eslint.d.ts.map +1 -0
  193. package/dist/core/validators/parsers/eslint.js +35 -0
  194. package/dist/core/validators/parsers/eslint.js.map +1 -0
  195. package/dist/core/validators/parsers/jest.d.ts +3 -0
  196. package/dist/core/validators/parsers/jest.d.ts.map +1 -0
  197. package/dist/core/validators/parsers/jest.js +16 -0
  198. package/dist/core/validators/parsers/jest.js.map +1 -0
  199. package/dist/core/validators/parsers/tsc.d.ts +3 -0
  200. package/dist/core/validators/parsers/tsc.d.ts.map +1 -0
  201. package/dist/core/validators/parsers/tsc.js +32 -0
  202. package/dist/core/validators/parsers/tsc.js.map +1 -0
  203. package/dist/core/validators/runner.d.ts +8 -0
  204. package/dist/core/validators/runner.d.ts.map +1 -0
  205. package/dist/core/validators/runner.js +85 -0
  206. package/dist/core/validators/runner.js.map +1 -0
  207. package/dist/core/validators/signatures.d.ts +3 -0
  208. package/dist/core/validators/signatures.d.ts.map +1 -0
  209. package/dist/core/validators/signatures.js +10 -0
  210. package/dist/core/validators/signatures.js.map +1 -0
  211. package/dist/core/validators/types.d.ts +27 -0
  212. package/dist/core/validators/types.d.ts.map +1 -0
  213. package/dist/core/validators/types.js +3 -0
  214. package/dist/core/validators/types.js.map +1 -0
  215. package/dist/core/workspace/contract-enforcer.d.ts +54 -0
  216. package/dist/core/workspace/contract-enforcer.d.ts.map +1 -0
  217. package/dist/core/workspace/contract-enforcer.js +128 -0
  218. package/dist/core/workspace/contract-enforcer.js.map +1 -0
  219. package/dist/core/workspace/manager.d.ts +28 -0
  220. package/dist/core/workspace/manager.d.ts.map +1 -0
  221. package/dist/core/workspace/manager.js +3 -0
  222. package/dist/core/workspace/manager.js.map +1 -0
  223. package/dist/core/workspace/merge.d.ts +38 -0
  224. package/dist/core/workspace/merge.d.ts.map +1 -0
  225. package/dist/core/workspace/merge.js +92 -0
  226. package/dist/core/workspace/merge.js.map +1 -0
  227. package/dist/core/workspace/patch-mode.d.ts +22 -0
  228. package/dist/core/workspace/patch-mode.d.ts.map +1 -0
  229. package/dist/core/workspace/patch-mode.js +91 -0
  230. package/dist/core/workspace/patch-mode.js.map +1 -0
  231. package/dist/core/workspace/scope-detector.d.ts +13 -0
  232. package/dist/core/workspace/scope-detector.d.ts.map +1 -0
  233. package/dist/core/workspace/scope-detector.js +34 -0
  234. package/dist/core/workspace/scope-detector.js.map +1 -0
  235. package/dist/core/workspace/worktree-mode.d.ts +28 -0
  236. package/dist/core/workspace/worktree-mode.d.ts.map +1 -0
  237. package/dist/core/workspace/worktree-mode.js +157 -0
  238. package/dist/core/workspace/worktree-mode.js.map +1 -0
  239. package/dist/index.js +16 -4
  240. package/dist/index.js.map +1 -1
  241. package/dist/templates/claude-code/ralphy-archive.md +1 -1
  242. package/dist/templates/claude-code/ralphy-implement.md +1 -1
  243. package/dist/templates/claude-code/ralphy-plan.md +1 -1
  244. package/dist/templates/claude-code/ralphy-validate.md +1 -1
  245. package/dist/templates/cursor/ralphy-archive.md +1 -1
  246. package/dist/templates/cursor/ralphy-implement.md +1 -1
  247. package/dist/templates/cursor/ralphy-plan.md +1 -1
  248. package/dist/templates/cursor/ralphy-validate.md +1 -1
  249. package/dist/templates/shared/openspec-tasks-template.md +23 -3
  250. package/dist/templates/shared/project-template.yml +232 -0
  251. package/dist/utils/installer.d.ts.map +1 -1
  252. package/dist/utils/installer.js +31 -1
  253. package/dist/utils/installer.js.map +1 -1
  254. package/dist/utils/validator.d.ts.map +1 -1
  255. package/dist/utils/validator.js +10 -0
  256. package/dist/utils/validator.js.map +1 -1
  257. package/package.json +15 -5
@@ -0,0 +1 @@
1
+ {"version":3,"file":"patch-mode.js","sourceRoot":"","sources":["../../../src/core/workspace/patch-mode.ts"],"names":[],"mappings":";;;;;;AAkGA,sDAEC;AApGD,iCAA8B;AAC9B,0DAA6B;AAE7B,yDAA6D;AAY7D,MAAa,kBAAkB;IAIA;IAH7B,IAAI,GAAY,OAAO,CAAC;IACP,WAAW,GAAG,IAAI,GAAG,EAA0B,CAAC;IAEjE,YAA6B,QAAgB;QAAhB,aAAQ,GAAR,QAAQ,CAAQ;IAAG,CAAC;IAEjD,KAAK,CAAC,OAAO,CAAC,MAAc;QAC1B,MAAM,cAAc,GAAG,MAAM,IAAI,CAAC,GAAG,CAAC,CAAC,WAAW,EAAE,MAAM,CAAC,CAAC,CAAC;QAC7D,IAAI,CAAC,WAAW,CAAC,GAAG,CAAC,MAAM,EAAE,EAAE,cAAc,EAAE,CAAC,CAAC;QACjD,OAAO,EAAE,MAAM,EAAE,UAAU,EAAE,IAAI,CAAC,QAAQ,EAAE,CAAC;IAC/C,CAAC;IAED,aAAa,CAAC,OAAe;QAC3B,OAAO,IAAI,CAAC,QAAQ,CAAC;IACvB,CAAC;IAED,KAAK,CAAC,eAAe,CAAC,OAAe;QACnC,2CAA2C;QAC3C,MAAM,GAAG,GAAG,MAAM,IAAI,CAAC,GAAG,CAAC,CAAC,MAAM,EAAE,eAAe,CAAC,CAAC,CAAC;QACtD,MAAM,KAAK,GAAG,GAAG;aACd,KAAK,CAAC,IAAI,CAAC;aACX,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC;aACpB,MAAM,CAAC,OAAO,CAAC,CAAC;QAEnB,MAAM,OAAO,GAA4C,EAAE,CAAC;QAC5D,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;YACzB,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC;YAChC,MAAM,MAAM,GAAG,KAAK,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC;YAC9B,MAAM,IAAI,GAAG,KAAK,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC;YAC5B,IAAI,CAAC,IAAI;gBAAE,SAAS;YACpB,OAAO,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,KAAK,EAAE,MAAM,CAAC,UAAU,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;QACxD,CAAC;QACD,OAAO,OAAO,CAAC;IACjB,CAAC;IAED,KAAK,CAAC,eAAe,CAAC,MAAc,EAAE,QAAsB;QAC1D,MAAM,YAAY,GAAG,MAAM,IAAI,CAAC,eAAe,CAAC,MAAM,CAAC,CAAC;QACxD,MAAM,UAAU,GAAG,IAAA,oCAAoB,EAAC,EAAE,YAAY,EAAE,QAAQ,EAAE,CAAC,CAAC;QACpE,IAAI,UAAU,CAAC,MAAM,EAAE,CAAC;YACtB,MAAM,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC;QAC5B,CAAC;QACD,OAAO,UAAU,CAAC;IACpB,CAAC;IAED,KAAK,CAAC,UAAU,CAAC,MAAc,EAAE,OAAe;QAC9C,sEAAsE;QACtE,MAAM,IAAI,CAAC,GAAG,CAAC,CAAC,KAAK,EAAE,IAAI,CAAC,CAAC,CAAC;QAC9B,MAAM,SAAS,GAAG,iBAAiB,MAAM,KAAK,OAAO,EAAE,CAAC;QACxD,IAAI,CAAC;YACH,MAAM,IAAI,CAAC,GAAG,CAAC,CAAC,QAAQ,EAAE,IAAI,EAAE,SAAS,CAAC,CAAC,CAAC;QAC9C,CAAC;QAAC,MAAM,CAAC;YACP,6BAA6B;QAC/B,CAAC;QACD,MAAM,GAAG,GAAG,MAAM,IAAI,CAAC,GAAG,CAAC,CAAC,WAAW,EAAE,MAAM,CAAC,CAAC,CAAC;QAClD,OAAO,EAAE,GAAG,EAAE,CAAC;IACjB,CAAC;IAED,KAAK,CAAC,KAAK,CAAC,OAAe;QACzB,+CAA+C;IACjD,CAAC;IAED,KAAK,CAAC,MAAM,CAAC,MAAc;QACzB,MAAM,KAAK,GAAG,IAAI,CAAC,WAAW,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC;QAC3C,IAAI,CAAC,KAAK;YAAE,OAAO;QAEnB,wDAAwD;QACxD,MAAM,IAAI,CAAC,GAAG,CAAC,CAAC,OAAO,EAAE,QAAQ,EAAE,KAAK,CAAC,cAAc,CAAC,CAAC,CAAC;QAC1D,MAAM,IAAI,CAAC,GAAG,CAAC,CAAC,OAAO,EAAE,KAAK,CAAC,CAAC,CAAC;IACnC,CAAC;IAED,KAAK,CAAC,OAAO,CAAC,OAAe;QAC3B,wBAAwB;IAC1B,CAAC;IAEO,KAAK,CAAC,GAAG,CAAC,IAAc;QAC9B,MAAM,GAAG,GAAG,MAAM,IAAA,aAAK,EAAC,KAAK,EAAE,IAAI,EAAE;YACnC,GAAG,EAAE,IAAI,CAAC,QAAQ;YAClB,KAAK,EAAE,MAAM;SACd,CAAC,CAAC;QACH,OAAO,GAAG,CAAC,MAAM,CAAC,IAAI,EAAE,CAAC;IAC3B,CAAC;CACF;AAjFD,gDAiFC;AAED,SAAgB,qBAAqB,CAAC,QAAgB;IACpD,OAAO,mBAAI,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC;AAChC,CAAC"}
@@ -0,0 +1,13 @@
1
+ import type { TaskSpec } from "../spec/types";
2
+ export type ScopeViolation = {
3
+ file?: string;
4
+ message: string;
5
+ };
6
+ export declare function detectScopeViolations(args: {
7
+ task: TaskSpec;
8
+ changedFiles: Array<{
9
+ file: string;
10
+ isNew: boolean;
11
+ }>;
12
+ }): ScopeViolation[];
13
+ //# sourceMappingURL=scope-detector.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"scope-detector.d.ts","sourceRoot":"","sources":["../../../src/core/workspace/scope-detector.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAC;AAE9C,MAAM,MAAM,cAAc,GAAG;IAC3B,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,OAAO,EAAE,MAAM,CAAC;CACjB,CAAC;AAMF,wBAAgB,qBAAqB,CAAC,IAAI,EAAE;IAC1C,IAAI,EAAE,QAAQ,CAAC;IACf,YAAY,EAAE,KAAK,CAAC;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,OAAO,CAAA;KAAE,CAAC,CAAC;CACvD,GAAG,cAAc,EAAE,CA8BnB"}
@@ -0,0 +1,34 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.detectScopeViolations = detectScopeViolations;
4
+ const minimatch_1 = require("minimatch");
5
+ function matchesAny(file, globs) {
6
+ return globs.some((g) => (0, minimatch_1.minimatch)(file, g, { dot: true }));
7
+ }
8
+ function detectScopeViolations(args) {
9
+ const intent = args.task.sprint?.intent;
10
+ if (!intent)
11
+ return [];
12
+ // If a file contract exists, use it as the primary scope boundary.
13
+ const allowed = args.task.filesContract?.allowed ?? [];
14
+ // Very small "fix" tasks should stay tight.
15
+ const maxFiles = intent === "fix" ? 5 : intent === "feature" ? 20 : intent === "infra" ? 50 : Infinity;
16
+ const violations = [];
17
+ if (args.changedFiles.length > maxFiles) {
18
+ violations.push({
19
+ message: `Scope violation: "${intent}" intent changed ${args.changedFiles.length} files (max ${maxFiles}).`,
20
+ });
21
+ }
22
+ if (intent === "fix" && allowed.length) {
23
+ for (const cf of args.changedFiles) {
24
+ if (!matchesAny(cf.file, allowed)) {
25
+ violations.push({
26
+ file: cf.file,
27
+ message: `Scope violation: "${intent}" intent changed file outside allowed scope: ${cf.file}`,
28
+ });
29
+ }
30
+ }
31
+ }
32
+ return violations;
33
+ }
34
+ //# sourceMappingURL=scope-detector.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"scope-detector.js","sourceRoot":"","sources":["../../../src/core/workspace/scope-detector.ts"],"names":[],"mappings":";;AAYA,sDAiCC;AA7CD,yCAAsC;AAQtC,SAAS,UAAU,CAAC,IAAY,EAAE,KAAe;IAC/C,OAAO,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,IAAA,qBAAS,EAAC,IAAI,EAAE,CAAC,EAAE,EAAE,GAAG,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC;AAC9D,CAAC;AAED,SAAgB,qBAAqB,CAAC,IAGrC;IACC,MAAM,MAAM,GAAG,IAAI,CAAC,IAAI,CAAC,MAAM,EAAE,MAAM,CAAC;IACxC,IAAI,CAAC,MAAM;QAAE,OAAO,EAAE,CAAC;IAEvB,mEAAmE;IACnE,MAAM,OAAO,GAAG,IAAI,CAAC,IAAI,CAAC,aAAa,EAAE,OAAO,IAAI,EAAE,CAAC;IAEvD,4CAA4C;IAC5C,MAAM,QAAQ,GACZ,MAAM,KAAK,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,MAAM,KAAK,OAAO,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,QAAQ,CAAC;IAExF,MAAM,UAAU,GAAqB,EAAE,CAAC;IACxC,IAAI,IAAI,CAAC,YAAY,CAAC,MAAM,GAAG,QAAQ,EAAE,CAAC;QACxC,UAAU,CAAC,IAAI,CAAC;YACd,OAAO,EAAE,qBAAqB,MAAM,oBAAoB,IAAI,CAAC,YAAY,CAAC,MAAM,eAAe,QAAQ,IAAI;SAC5G,CAAC,CAAC;IACL,CAAC;IAED,IAAI,MAAM,KAAK,KAAK,IAAI,OAAO,CAAC,MAAM,EAAE,CAAC;QACvC,KAAK,MAAM,EAAE,IAAI,IAAI,CAAC,YAAY,EAAE,CAAC;YACnC,IAAI,CAAC,UAAU,CAAC,EAAE,CAAC,IAAI,EAAE,OAAO,CAAC,EAAE,CAAC;gBAClC,UAAU,CAAC,IAAI,CAAC;oBACd,IAAI,EAAE,EAAE,CAAC,IAAI;oBACb,OAAO,EAAE,qBAAqB,MAAM,gDAAgD,EAAE,CAAC,IAAI,EAAE;iBAC9F,CAAC,CAAC;YACL,CAAC;QACH,CAAC;IACH,CAAC;IAED,OAAO,UAAU,CAAC;AACpB,CAAC"}
@@ -0,0 +1,28 @@
1
+ import type { FileContract } from "../spec/types";
2
+ import type { CheckpointRef, ContractViolation, WorkspaceContext, WorkspaceManager } from "./manager";
3
+ /**
4
+ * WorktreeModeWorkspace uses git worktrees for task isolation.
5
+ *
6
+ * Each task runs in its own worktree branch, providing complete isolation
7
+ * from the main working directory. Changes are merged back on success.
8
+ */
9
+ export declare class WorktreeModeWorkspace implements WorkspaceManager {
10
+ private readonly repoRoot;
11
+ mode: "worktree";
12
+ private readonly stateByTask;
13
+ private readonly worktreeBase;
14
+ constructor(repoRoot: string);
15
+ prepare(taskId: string): Promise<WorkspaceContext>;
16
+ getWorkingDir(taskId: string): string;
17
+ getChangedFiles(taskId: string): Promise<Array<{
18
+ file: string;
19
+ isNew: boolean;
20
+ }>>;
21
+ enforceContract(taskId: string, contract: FileContract): Promise<ContractViolation[]>;
22
+ checkpoint(taskId: string, message: string): Promise<CheckpointRef>;
23
+ merge(taskId: string): Promise<void>;
24
+ revert(taskId: string): Promise<void>;
25
+ cleanup(taskId: string): Promise<void>;
26
+ private git;
27
+ }
28
+ //# sourceMappingURL=worktree-mode.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"worktree-mode.d.ts","sourceRoot":"","sources":["../../../src/core/workspace/worktree-mode.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,eAAe,CAAC;AAGlD,OAAO,KAAK,EACV,aAAa,EACb,iBAAiB,EACjB,gBAAgB,EAChB,gBAAgB,EACjB,MAAM,WAAW,CAAC;AAQnB;;;;;GAKG;AACH,qBAAa,qBAAsB,YAAW,gBAAgB;IAKhD,OAAO,CAAC,QAAQ,CAAC,QAAQ;IAJrC,IAAI,EAAE,UAAU,CAAc;IAC9B,OAAO,CAAC,QAAQ,CAAC,WAAW,CAAoC;IAChE,OAAO,CAAC,QAAQ,CAAC,YAAY,CAAS;gBAET,QAAQ,EAAE,MAAM;IAIvC,OAAO,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,gBAAgB,CAAC;IAoCxD,aAAa,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM;IAK/B,eAAe,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,KAAK,CAAC;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,OAAO,CAAA;KAAE,CAAC,CAAC;IA2BjF,eAAe,CAAC,MAAM,EAAE,MAAM,EAAE,QAAQ,EAAE,YAAY,GAAG,OAAO,CAAC,iBAAiB,EAAE,CAAC;IAYrF,UAAU,CAAC,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,aAAa,CAAC;IAoBnE,KAAK,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAyBpC,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IASrC,OAAO,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;YAiB9B,GAAG;CAalB"}
@@ -0,0 +1,157 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.WorktreeModeWorkspace = void 0;
7
+ const execa_1 = require("execa");
8
+ const node_path_1 = __importDefault(require("node:path"));
9
+ const promises_1 = __importDefault(require("node:fs/promises"));
10
+ const folders_1 = require("../folders");
11
+ const file_contract_1 = require("../spec/file-contract");
12
+ /**
13
+ * WorktreeModeWorkspace uses git worktrees for task isolation.
14
+ *
15
+ * Each task runs in its own worktree branch, providing complete isolation
16
+ * from the main working directory. Changes are merged back on success.
17
+ */
18
+ class WorktreeModeWorkspace {
19
+ repoRoot;
20
+ mode = "worktree";
21
+ stateByTask = new Map();
22
+ worktreeBase;
23
+ constructor(repoRoot) {
24
+ this.repoRoot = repoRoot;
25
+ this.worktreeBase = node_path_1.default.join((0, folders_1.getRalphyRoot)(repoRoot), folders_1.FOLDERS.worktrees);
26
+ }
27
+ async prepare(taskId) {
28
+ // Ensure worktree base directory exists
29
+ await promises_1.default.mkdir(this.worktreeBase, { recursive: true });
30
+ // Get current HEAD as base
31
+ const baseCommit = await this.git(["rev-parse", "HEAD"], this.repoRoot);
32
+ // Create a unique branch name for this task
33
+ const branchName = `ralphy/${taskId}/${Date.now()}`;
34
+ const worktreePath = node_path_1.default.join(this.worktreeBase, taskId.replace(/[^a-zA-Z0-9-_]/g, "_"));
35
+ // Clean up existing worktree if present
36
+ try {
37
+ await promises_1.default.rm(worktreePath, { recursive: true, force: true });
38
+ }
39
+ catch {
40
+ // Ignore if doesn't exist
41
+ }
42
+ // Remove stale worktree entry if any
43
+ try {
44
+ await this.git(["worktree", "remove", "--force", worktreePath], this.repoRoot);
45
+ }
46
+ catch {
47
+ // Ignore if doesn't exist
48
+ }
49
+ // Create new worktree with a new branch
50
+ await this.git(["worktree", "add", "-b", branchName, worktreePath, baseCommit], this.repoRoot);
51
+ this.stateByTask.set(taskId, { worktreePath, branchName, baseCommit });
52
+ return { taskId, workingDir: worktreePath };
53
+ }
54
+ getWorkingDir(taskId) {
55
+ const state = this.stateByTask.get(taskId);
56
+ return state?.worktreePath ?? this.repoRoot;
57
+ }
58
+ async getChangedFiles(taskId) {
59
+ const state = this.stateByTask.get(taskId);
60
+ if (!state)
61
+ return [];
62
+ // Get changes compared to base commit
63
+ const out = await this.git(["diff", "--name-status", state.baseCommit], state.worktreePath);
64
+ const lines = out
65
+ .split("\n")
66
+ .map((l) => l.trim())
67
+ .filter(Boolean);
68
+ const changed = [];
69
+ for (const line of lines) {
70
+ const parts = line.split(/\s+/);
71
+ const status = parts[0] ?? "";
72
+ const file = parts[1] ?? "";
73
+ if (!file)
74
+ continue;
75
+ changed.push({ file, isNew: status.startsWith("A") });
76
+ }
77
+ return changed;
78
+ }
79
+ async enforceContract(taskId, contract) {
80
+ const changedFiles = await this.getChangedFiles(taskId);
81
+ const violations = (0, file_contract_1.evaluateFileContract)({ changedFiles, contract });
82
+ if (violations.length) {
83
+ // Revert the worktree to base state
84
+ await this.revert(taskId);
85
+ }
86
+ return violations;
87
+ }
88
+ async checkpoint(taskId, message) {
89
+ const state = this.stateByTask.get(taskId);
90
+ if (!state) {
91
+ throw new Error(`No worktree state for task ${taskId}`);
92
+ }
93
+ // Stage and commit all changes in worktree
94
+ await this.git(["add", "-A"], state.worktreePath);
95
+ const commitMsg = `[ralphy-spec] ${taskId}: ${message}`;
96
+ try {
97
+ await this.git(["commit", "-m", commitMsg], state.worktreePath);
98
+ }
99
+ catch {
100
+ // Likely nothing to commit
101
+ }
102
+ const ref = await this.git(["rev-parse", "HEAD"], state.worktreePath);
103
+ return { ref };
104
+ }
105
+ async merge(taskId) {
106
+ const state = this.stateByTask.get(taskId);
107
+ if (!state)
108
+ return;
109
+ // Get the current branch in main repo
110
+ const currentBranch = await this.git(["rev-parse", "--abbrev-ref", "HEAD"], this.repoRoot);
111
+ // Merge the task branch back using --squash for clean history
112
+ try {
113
+ await this.git(["merge", "--squash", state.branchName], this.repoRoot);
114
+ await this.git(["commit", "-m", `[ralphy-spec] Merge task ${taskId}`], this.repoRoot);
115
+ }
116
+ catch (err) {
117
+ // If merge fails, user may need to resolve manually
118
+ throw new Error(`Failed to merge task ${taskId}: ${err?.message ?? String(err)}. Manual resolution may be required.`);
119
+ }
120
+ }
121
+ async revert(taskId) {
122
+ const state = this.stateByTask.get(taskId);
123
+ if (!state)
124
+ return;
125
+ // Hard reset worktree to base commit
126
+ await this.git(["reset", "--hard", state.baseCommit], state.worktreePath);
127
+ await this.git(["clean", "-fd"], state.worktreePath);
128
+ }
129
+ async cleanup(taskId) {
130
+ const state = this.stateByTask.get(taskId);
131
+ if (!state)
132
+ return;
133
+ try {
134
+ // Remove the worktree
135
+ await this.git(["worktree", "remove", "--force", state.worktreePath], this.repoRoot);
136
+ // Delete the branch
137
+ await this.git(["branch", "-D", state.branchName], this.repoRoot);
138
+ }
139
+ catch {
140
+ // Best effort cleanup
141
+ }
142
+ this.stateByTask.delete(taskId);
143
+ }
144
+ async git(args, cwd) {
145
+ const res = await (0, execa_1.execa)("git", args, {
146
+ cwd,
147
+ stdio: "pipe",
148
+ reject: false,
149
+ });
150
+ if (res.exitCode !== 0 && res.stderr) {
151
+ throw new Error(`git ${args.join(" ")} failed: ${res.stderr}`);
152
+ }
153
+ return res.stdout.trim();
154
+ }
155
+ }
156
+ exports.WorktreeModeWorkspace = WorktreeModeWorkspace;
157
+ //# sourceMappingURL=worktree-mode.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"worktree-mode.js","sourceRoot":"","sources":["../../../src/core/workspace/worktree-mode.ts"],"names":[],"mappings":"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"}
package/dist/index.js CHANGED
@@ -1,18 +1,30 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  const commander_1 = require("commander");
4
- const init_1 = require("./commands/init");
5
- const validate_1 = require("./commands/validate");
6
- const update_1 = require("./commands/update");
4
+ const init_1 = require("./cli/init");
5
+ const validate_1 = require("./cli/validate");
6
+ const update_1 = require("./cli/update");
7
+ const run_1 = require("./cli/run");
8
+ const status_1 = require("./cli/status");
9
+ const report_1 = require("./cli/report");
10
+ const tail_1 = require("./cli/tail");
11
+ const checkpoint_1 = require("./cli/checkpoint");
12
+ const budget_1 = require("./cli/budget");
7
13
  function buildProgram() {
8
14
  const program = new commander_1.Command();
9
15
  program
10
16
  .name("ralphy-spec")
11
17
  .description("One-command setup for Ralph loop + OpenSpec workflows across Cursor, OpenCode, and Claude Code.")
12
- .version("0.1.1");
18
+ .version("0.3.0");
13
19
  (0, init_1.registerInitCommand)(program);
14
20
  (0, validate_1.registerValidateCommand)(program);
15
21
  (0, update_1.registerUpdateCommand)(program);
22
+ (0, run_1.registerRunCommand)(program);
23
+ (0, status_1.registerStatusCommand)(program);
24
+ (0, budget_1.registerBudgetCommand)(program);
25
+ (0, report_1.registerReportCommand)(program);
26
+ (0, tail_1.registerTailCommand)(program);
27
+ (0, checkpoint_1.registerCheckpointCommand)(program);
16
28
  return program;
17
29
  }
18
30
  async function main() {
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";;AAAA,yCAAoC;AACpC,0CAAsD;AACtD,kDAA8D;AAC9D,8CAA0D;AAE1D,SAAS,YAAY;IACnB,MAAM,OAAO,GAAG,IAAI,mBAAO,EAAE,CAAC;IAE9B,OAAO;SACJ,IAAI,CAAC,aAAa,CAAC;SACnB,WAAW,CACV,iGAAiG,CAClG;SACA,OAAO,CAAC,OAAO,CAAC,CAAC;IAEpB,IAAA,0BAAmB,EAAC,OAAO,CAAC,CAAC;IAC7B,IAAA,kCAAuB,EAAC,OAAO,CAAC,CAAC;IACjC,IAAA,8BAAqB,EAAC,OAAO,CAAC,CAAC;IAE/B,OAAO,OAAO,CAAC;AACjB,CAAC;AAED,KAAK,UAAU,IAAI;IACjB,MAAM,OAAO,GAAG,YAAY,EAAE,CAAC;IAC/B,MAAM,OAAO,CAAC,UAAU,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC;AACzC,CAAC;AAED,mEAAmE;AACnE,IAAI,EAAE,CAAC"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";;AAAA,yCAAoC;AACpC,qCAAiD;AACjD,6CAAyD;AACzD,yCAAqD;AACrD,mCAA+C;AAC/C,yCAAqD;AACrD,yCAAqD;AACrD,qCAAiD;AACjD,iDAA6D;AAC7D,yCAAqD;AAErD,SAAS,YAAY;IACnB,MAAM,OAAO,GAAG,IAAI,mBAAO,EAAE,CAAC;IAE9B,OAAO;SACJ,IAAI,CAAC,aAAa,CAAC;SACnB,WAAW,CACV,iGAAiG,CAClG;SACA,OAAO,CAAC,OAAO,CAAC,CAAC;IAEpB,IAAA,0BAAmB,EAAC,OAAO,CAAC,CAAC;IAC7B,IAAA,kCAAuB,EAAC,OAAO,CAAC,CAAC;IACjC,IAAA,8BAAqB,EAAC,OAAO,CAAC,CAAC;IAC/B,IAAA,wBAAkB,EAAC,OAAO,CAAC,CAAC;IAC5B,IAAA,8BAAqB,EAAC,OAAO,CAAC,CAAC;IAC/B,IAAA,8BAAqB,EAAC,OAAO,CAAC,CAAC;IAC/B,IAAA,8BAAqB,EAAC,OAAO,CAAC,CAAC;IAC/B,IAAA,0BAAmB,EAAC,OAAO,CAAC,CAAC;IAC7B,IAAA,sCAAyB,EAAC,OAAO,CAAC,CAAC;IAEnC,OAAO,OAAO,CAAC;AACjB,CAAC;AAED,KAAK,UAAU,IAAI;IACjB,MAAM,OAAO,GAAG,YAAY,EAAE,CAAC;IAC/B,MAAM,OAAO,CAAC,UAAU,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC;AACzC,CAAC;AAED,mEAAmE;AACnE,IAAI,EAAE,CAAC"}
@@ -1,4 +1,4 @@
1
- # /ralphy:archive (Archive completed change)
1
+ # /ralphy-archive (Archive completed change)
2
2
 
3
3
  You are archiving a completed OpenSpec change.
4
4
 
@@ -1,4 +1,4 @@
1
- # /ralphy:implement (Implement OpenSpec tasks)
1
+ # /ralphy-implement (Implement OpenSpec tasks)
2
2
 
3
3
  You are implementing an OpenSpec change located under `openspec/changes/<change-name>/`.
4
4
 
@@ -1,4 +1,4 @@
1
- # /ralphy:plan (PRD -> OpenSpec change)
1
+ # /ralphy-plan (PRD -> OpenSpec change)
2
2
 
3
3
  You are an AI coding assistant. Convert the user's PRD/requirements into an OpenSpec change proposal with clear, testable acceptance criteria.
4
4
 
@@ -1,4 +1,4 @@
1
- # /ralphy:validate (Validate against acceptance criteria)
1
+ # /ralphy-validate (Validate against acceptance criteria)
2
2
 
3
3
  You are validating an OpenSpec change.
4
4
 
@@ -1,4 +1,4 @@
1
- # /ralphy:archive (Archive completed change)
1
+ # /ralphy-archive (Archive completed change)
2
2
 
3
3
  You are an AI coding assistant archiving a completed OpenSpec change.
4
4
 
@@ -1,4 +1,4 @@
1
- # /ralphy:implement (Implement OpenSpec tasks)
1
+ # /ralphy-implement (Implement OpenSpec tasks)
2
2
 
3
3
  You are an AI coding assistant implementing an existing OpenSpec change.
4
4
 
@@ -1,4 +1,4 @@
1
- # /ralphy:plan (PRD -> OpenSpec change)
1
+ # /ralphy-plan (PRD -> OpenSpec change)
2
2
 
3
3
  You are an AI coding assistant. Your job is to convert user requirements into an OpenSpec change proposal with clear acceptance criteria.
4
4
 
@@ -1,4 +1,4 @@
1
- # /ralphy:validate (Validate against acceptance criteria)
1
+ # /ralphy-validate (Validate against acceptance criteria)
2
2
 
3
3
  You are an AI coding assistant validating an OpenSpec change against its acceptance criteria.
4
4
 
@@ -3,11 +3,15 @@
3
3
  Use this structure for `openspec/changes/<change-name>/tasks.md`.
4
4
 
5
5
  ## 1. Planning / Scaffolding
6
- - [ ] 1.1 Confirm scope and affected modules
6
+ - [ ] 1.1 Confirm scope, non-goals, and impacted modules
7
+ - Acceptance criteria:
8
+ - GIVEN the current `openspec/specs/` baseline
9
+ - WHEN this change is implemented
10
+ - THEN only the intended domains are affected
7
11
  - Test plan: N/A
8
12
 
9
13
  ## 2. Implementation
10
- - [ ] 2.1 Implement feature behavior
14
+ - [ ] 2.1 Implement feature behavior (spec-driven)
11
15
  - Acceptance criteria:
12
16
  - GIVEN ...
13
17
  - WHEN ...
@@ -16,13 +20,29 @@ Use this structure for `openspec/changes/<change-name>/tasks.md`.
16
20
  - Run: `npm test`
17
21
  - Assert: ...
18
22
 
23
+ ## 3. Validators / Budgets (v2+)
24
+ - [ ] 3.1 Define or update validators used by this change
25
+ - Notes:
26
+ - Validators are the ground truth (deterministic pass/fail)
27
+ - Prefer: `npm run typecheck`, `npm test`, `npm run lint`
28
+ - Test plan:
29
+ - Run the validator commands locally/CI
30
+
31
+ - [ ] 3.2 If the change introduces budgeted execution (v2.1+), document expected behavior
32
+ - Notes:
33
+ - Optimal → Warning → Hard tier expectations
34
+ - WARNING tier should shrink context + enforce repair-only constraints
35
+ - HARD tier should stop safely (no silent retries)
36
+ - Test plan:
37
+ - Run a small demo task that crosses WARNING tier and confirm behaviors
38
+
19
39
  ## 3. Validation
20
40
  - [ ] 3.1 Add/adjust tests to cover all scenarios
21
41
  - Test plan:
22
42
  - Run: `npm test`
23
43
 
24
44
  ## 4. Documentation / Archive
25
- - [ ] 4.1 Update specs and archive change
45
+ - [ ] 4.1 Update OpenSpec docs/spec deltas (if needed) and archive change
26
46
  - Test plan:
27
47
  - Run: `npm test`
28
48
 
@@ -0,0 +1,232 @@
1
+ # ralphy-spec Project Configuration
2
+ # Generated by: ralphy-spec init
3
+ # Version: 2.1 (Budget Intelligence + Sprint Semantics)
4
+
5
+ version: "1.1"
6
+
7
+ project:
8
+ name: "my-project"
9
+ repoRoot: "."
10
+ language: "ts"
11
+ packageManager: "npm" # user-defined: npm | pnpm | yarn | bun
12
+
13
+ defaults:
14
+ backend: "cursor"
15
+ workspaceMode: "patch" # "worktree" | "patch"
16
+ checkpointMode: "commit" # "commit" | "patch"
17
+ validators:
18
+ - typecheck
19
+ - test
20
+ - lint
21
+
22
+ # Artifacts (IDE-friendly human interface)
23
+ # NOTE: These are defaults; users can override or disable.
24
+ artifacts:
25
+ enabled: true
26
+ rootDir: "ralphy-spec" # default; can be overridden via CLI: --artifact-dir
27
+ statusIcons: "emoji" # "emoji" | "ascii" | "none"
28
+
29
+ # Run-level budgets (hard limits for entire run)
30
+ budgets:
31
+ run:
32
+ money_usd: 20 # Max USD per run
33
+ tokens: 2000000 # Max tokens per run
34
+ wall_time_minutes: 90 # Max wall clock time
35
+ max_iterations_total: 80 # Max total iterations across all tasks
36
+
37
+ limits:
38
+ max_parallel_tasks: 1 # Concurrent tasks (v1: always 1)
39
+ max_parallel_validators: 2 # Concurrent validators
40
+ command_timeout_seconds: 900
41
+
42
+ # Sprint size defaults (applied when task has sprint.size but no explicit budget)
43
+ # Users can override per-task
44
+ sprint_defaults:
45
+ XS:
46
+ optimal: { usd: 0.20, tokens: 15000, time_minutes: 3 }
47
+ warning: { usd: 0.35, tokens: 25000, time_minutes: 5 }
48
+ hard: { usd: 0.50, tokens: 40000, time_minutes: 8, max_iterations: 3 }
49
+ S:
50
+ optimal: { usd: 0.50, tokens: 40000, time_minutes: 5 }
51
+ warning: { usd: 0.80, tokens: 65000, time_minutes: 8 }
52
+ hard: { usd: 1.20, tokens: 100000, time_minutes: 12, max_iterations: 5 }
53
+ M:
54
+ optimal: { usd: 1.20, tokens: 80000, time_minutes: 10 }
55
+ warning: { usd: 2.00, tokens: 150000, time_minutes: 15 }
56
+ hard: { usd: 3.00, tokens: 250000, time_minutes: 20, max_iterations: 8 }
57
+ L:
58
+ optimal: { usd: 2.50, tokens: 150000, time_minutes: 20 }
59
+ warning: { usd: 4.00, tokens: 280000, time_minutes: 35 }
60
+ hard: { usd: 6.00, tokens: 450000, time_minutes: 50, max_iterations: 12 }
61
+ XL:
62
+ optimal: { usd: 5.00, tokens: 300000, time_minutes: 40 }
63
+ warning: { usd: 8.00, tokens: 550000, time_minutes: 70 }
64
+ hard: { usd: 12.00, tokens: 900000, time_minutes: 100, max_iterations: 20 }
65
+
66
+ backends:
67
+ cursor:
68
+ command: "cursor"
69
+ modelTiers:
70
+ default: { hint: "balanced" }
71
+ cheap: { hint: "cheap" }
72
+ strong: { hint: "strong" }
73
+ opencode:
74
+ command: "opencode"
75
+ modelTiers:
76
+ default: {}
77
+ cheap: {}
78
+ claude_code:
79
+ command: "claude"
80
+ modelTiers:
81
+ default: {}
82
+
83
+ validators:
84
+ - id: "typecheck"
85
+ # Avoid hard-coding package manager. Choose commands that match your repo.
86
+ run: "npm run typecheck"
87
+ timeout_seconds: 600
88
+ parser: "tsc"
89
+ - id: "test"
90
+ run: "npm test"
91
+ timeout_seconds: 900
92
+ parser: "jest"
93
+ - id: "lint"
94
+ run: "npm run lint"
95
+ timeout_seconds: 600
96
+ parser: "eslint"
97
+
98
+ # Tasks - define your implementation tasks here
99
+ tasks: []
100
+
101
+ # ============================================================
102
+ # TASK EXAMPLES (uncomment and modify as needed)
103
+ # ============================================================
104
+
105
+ # Example 1: Simple fix (XS sprint, uses defaults)
106
+ # - id: "fix-typo-001"
107
+ # title: "Fix typo in error message"
108
+ # goal: "Correct spelling in validation error"
109
+ #
110
+ # sprint:
111
+ # size: XS # Uses XS defaults: $0.20 optimal, 3 max iter
112
+ # intent: "fix" # No refactoring allowed
113
+ #
114
+ # files_contract:
115
+ # allowed: ["src/utils/validation.ts"]
116
+ # forbidden: []
117
+ # allow_new_files: false
118
+ #
119
+ # acceptance:
120
+ # - id: "acc-1"
121
+ # text: "Error message spelled correctly"
122
+ # type: "behavior"
123
+
124
+ # Example 2: Feature (M sprint with custom budget)
125
+ # - id: "auth-001"
126
+ # title: "JWT middleware"
127
+ # goal: "Add JWT auth middleware for API routes"
128
+ #
129
+ # sprint:
130
+ # size: M
131
+ # intent: "feature" # Limited refactoring allowed
132
+ #
133
+ # budget: # Optional: override sprint defaults
134
+ # optimal:
135
+ # usd: 1.2
136
+ # tokens: 80000
137
+ # time_minutes: 10
138
+ # warning:
139
+ # usd: 2.0
140
+ # tokens: 150000
141
+ # time_minutes: 15
142
+ # hard:
143
+ # usd: 3.0
144
+ # tokens: 250000
145
+ # time_minutes: 20
146
+ # max_iterations: 8
147
+ #
148
+ # files_contract:
149
+ # allowed:
150
+ # - "src/middleware/**"
151
+ # - "src/api/**"
152
+ # forbidden:
153
+ # - "src/db/**"
154
+ # allow_new_files: true
155
+ #
156
+ # context:
157
+ # docs: ["README.md"]
158
+ # files: ["src/api/index.ts"]
159
+ #
160
+ # acceptance:
161
+ # - id: "acc-1"
162
+ # text: "Requests without token return 401"
163
+ # type: "behavior"
164
+ # - id: "acc-2"
165
+ # text: "Valid tokens allow access"
166
+ # type: "behavior"
167
+ # - id: "acc-3"
168
+ # text: "Unit tests added"
169
+ # type: "evidence"
170
+ # evidence:
171
+ # must_include_files: ["src/**/__tests__/**"]
172
+ #
173
+ # validators: ["typecheck", "test", "lint"]
174
+ # done_policy:
175
+ # require_all_validators_pass: true
176
+ # require_acceptance_evidence: true
177
+
178
+ # Example 3: Large refactor (L sprint)
179
+ # - id: "refactor-db-001"
180
+ # title: "Migrate to Prisma"
181
+ # goal: "Replace raw SQL with Prisma ORM"
182
+ # deps: ["auth-001"] # Depends on auth task
183
+ #
184
+ # sprint:
185
+ # size: L
186
+ # intent: "refactor" # Full refactoring allowed
187
+ #
188
+ # files_contract:
189
+ # allowed:
190
+ # - "src/db/**"
191
+ # - "prisma/**"
192
+ # forbidden:
193
+ # - "src/api/**" # Don't touch API layer
194
+ # allow_new_files: true
195
+ #
196
+ # acceptance:
197
+ # - id: "acc-1"
198
+ # text: "All database queries use Prisma"
199
+ # type: "behavior"
200
+ # - id: "acc-2"
201
+ # text: "Existing tests pass"
202
+ # type: "evidence"
203
+
204
+ # ============================================================
205
+ # BUDGET TIERS EXPLAINED
206
+ # ============================================================
207
+ #
208
+ # OPTIMAL: Expected cost for correct completion
209
+ # - Agent operates normally with full context
210
+ # - All features enabled (self-review, planning)
211
+ #
212
+ # WARNING: Still acceptable but attention needed
213
+ # - Context shrink: fewer files, only failing tests
214
+ # - Repair-only mode: "fix only, no refactor"
215
+ # - Optional calls disabled
216
+ # - STATUS.md shows pressure signals
217
+ #
218
+ # HARD: Must stop immediately
219
+ # - Task marked as BLOCKED
220
+ # - Workspace preserved for debugging
221
+ # - Failure summary written
222
+ # - No silent retries
223
+ #
224
+ # ============================================================
225
+ # SPRINT SIZES GUIDE
226
+ # ============================================================
227
+ #
228
+ # XS: Single file fix, typo, simple config change
229
+ # S: Small function, add a test, minor refactor
230
+ # M: Feature slice, new endpoint, component
231
+ # L: Multi-file feature, significant change
232
+ # XL: Infrastructure, major refactor, migration
@@ -1 +1 @@
1
- {"version":3,"file":"installer.d.ts","sourceRoot":"","sources":["../../src/utils/installer.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,UAAU,CAAC;AAgBvC,wBAAsB,sBAAsB,CAAC,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAyB9E;AAED,wBAAsB,oBAAoB,CACxC,UAAU,EAAE,MAAM,EAClB,KAAK,EAAE,MAAM,EAAE,EACf,IAAI,EAAE;IAAE,KAAK,EAAE,OAAO,CAAA;CAAE,GACvB,OAAO,CAAC,IAAI,CAAC,CA+Df"}
1
+ {"version":3,"file":"installer.d.ts","sourceRoot":"","sources":["../../src/utils/installer.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,UAAU,CAAC;AAiBvC,wBAAsB,sBAAsB,CAAC,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAsD9E;AAED,wBAAsB,oBAAoB,CACxC,UAAU,EAAE,MAAM,EAClB,KAAK,EAAE,MAAM,EAAE,EACf,IAAI,EAAE;IAAE,KAAK,EAAE,OAAO,CAAA;CAAE,GACvB,OAAO,CAAC,IAAI,CAAC,CA+Df"}