rafcode 1.3.2 → 2.1.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 (417) hide show
  1. package/.claude/settings.local.json +3 -1
  2. package/CLAUDE.md +118 -22
  3. package/RAF/aaaacu-worktree-weaver/decisions.md +88 -0
  4. package/RAF/aaaacu-worktree-weaver/input.md +27 -0
  5. package/RAF/aaaacu-worktree-weaver/outcomes/01-git-worktree-utilities.md +41 -0
  6. package/RAF/aaaacu-worktree-weaver/outcomes/02-worktree-plan-command.md +44 -0
  7. package/RAF/aaaacu-worktree-weaver/outcomes/03-worktree-do-command.md +58 -0
  8. package/RAF/aaaacu-worktree-weaver/outcomes/04-auto-merge-and-cleanup.md +40 -0
  9. package/RAF/aaaacu-worktree-weaver/outcomes/05-worktree-tests.md +43 -0
  10. package/RAF/aaaacu-worktree-weaver/outcomes/06-update-documentation.md +33 -0
  11. package/RAF/aaaacu-worktree-weaver/plans/01-git-worktree-utilities.md +51 -0
  12. package/RAF/aaaacu-worktree-weaver/plans/02-worktree-plan-command.md +93 -0
  13. package/RAF/aaaacu-worktree-weaver/plans/03-worktree-do-command.md +81 -0
  14. package/RAF/aaaacu-worktree-weaver/plans/04-auto-merge-and-cleanup.md +51 -0
  15. package/RAF/aaaacu-worktree-weaver/plans/05-worktree-tests.md +52 -0
  16. package/RAF/aaaacu-worktree-weaver/plans/06-update-documentation.md +55 -0
  17. package/RAF/aaaacv-trim-the-fat/decisions.md +34 -0
  18. package/RAF/aaaacv-trim-the-fat/input.md +5 -0
  19. package/RAF/aaaacv-trim-the-fat/outcomes/01-add-worktree-support-to-status.md +43 -0
  20. package/RAF/aaaacv-trim-the-fat/outcomes/02-remove-multi-project-from-do.md +50 -0
  21. package/RAF/aaaacv-trim-the-fat/outcomes/03-commit-artifacts-on-amend.md +35 -0
  22. package/RAF/aaaacv-trim-the-fat/outcomes/04-worktree-aware-exit-messages.md +36 -0
  23. package/RAF/aaaacv-trim-the-fat/plans/01-add-worktree-support-to-status.md +43 -0
  24. package/RAF/aaaacv-trim-the-fat/plans/02-remove-multi-project-from-do.md +44 -0
  25. package/RAF/aaaacv-trim-the-fat/plans/03-commit-artifacts-on-amend.md +38 -0
  26. package/RAF/aaaacv-trim-the-fat/plans/04-worktree-aware-exit-messages.md +38 -0
  27. package/RAF/aaaacw-prune-cycle/decisions.md +25 -0
  28. package/RAF/aaaacw-prune-cycle/input.md +5 -0
  29. package/RAF/aaaacw-prune-cycle/outcomes/01-create-worktree-from-branch.md +32 -0
  30. package/RAF/aaaacw-prune-cycle/outcomes/02-cleanup-worktree-on-success.md +33 -0
  31. package/RAF/aaaacw-prune-cycle/outcomes/03-amend-recreate-worktree.md +40 -0
  32. package/RAF/aaaacw-prune-cycle/plans/01-create-worktree-from-branch.md +31 -0
  33. package/RAF/aaaacw-prune-cycle/plans/02-cleanup-worktree-on-success.md +38 -0
  34. package/RAF/aaaacw-prune-cycle/plans/03-amend-recreate-worktree.md +50 -0
  35. package/RAF/aaaacx-epoch-shift/decisions.md +25 -0
  36. package/RAF/aaaacx-epoch-shift/input.md +1 -0
  37. package/RAF/aaaacx-epoch-shift/outcomes/01-epoch-id-generation.md +34 -0
  38. package/RAF/aaaacx-epoch-shift/outcomes/02-update-pattern-matching.md +32 -0
  39. package/RAF/aaaacx-epoch-shift/outcomes/03-update-tests.md +59 -0
  40. package/RAF/aaaacx-epoch-shift/outcomes/04-update-documentation.md +30 -0
  41. package/RAF/aaaacx-epoch-shift/plans/01-epoch-id-generation.md +40 -0
  42. package/RAF/aaaacx-epoch-shift/plans/02-update-pattern-matching.md +60 -0
  43. package/RAF/aaaacx-epoch-shift/plans/03-update-tests.md +48 -0
  44. package/RAF/aaaacx-epoch-shift/plans/04-update-documentation.md +44 -0
  45. package/RAF/ahmpro-merge-guardian/decisions.md +25 -0
  46. package/RAF/ahmpro-merge-guardian/input.md +4 -0
  47. package/RAF/ahmpro-merge-guardian/outcomes/001-fix-amend-worktree-commit.md +45 -0
  48. package/RAF/ahmpro-merge-guardian/outcomes/002-base36-task-ids.md +55 -0
  49. package/RAF/ahmpro-merge-guardian/outcomes/003-worktree-pr-creation.md +41 -0
  50. package/RAF/ahmpro-merge-guardian/outcomes/004-post-execution-picker.md +53 -0
  51. package/RAF/ahmpro-merge-guardian/plans/001-fix-amend-worktree-commit.md +39 -0
  52. package/RAF/ahmpro-merge-guardian/plans/002-base36-task-ids.md +43 -0
  53. package/RAF/ahmpro-merge-guardian/plans/003-worktree-pr-creation.md +43 -0
  54. package/RAF/ahmpro-merge-guardian/plans/004-post-execution-picker.md +51 -0
  55. package/RAF/ahnbcu-letterjam/decisions.md +13 -0
  56. package/RAF/ahnbcu-letterjam/input.md +3 -0
  57. package/RAF/ahnbcu-letterjam/outcomes/01-base26-encoding.md +42 -0
  58. package/RAF/ahnbcu-letterjam/outcomes/02-update-tests.md +38 -0
  59. package/RAF/ahnbcu-letterjam/outcomes/03-migrate-command.md +51 -0
  60. package/RAF/ahnbcu-letterjam/outcomes/04-update-documentation.md +29 -0
  61. package/RAF/ahnbcu-letterjam/plans/01-base26-encoding.md +36 -0
  62. package/RAF/ahnbcu-letterjam/plans/02-update-tests.md +37 -0
  63. package/RAF/ahnbcu-letterjam/plans/03-migrate-command.md +49 -0
  64. package/RAF/ahnbcu-letterjam/plans/04-update-documentation.md +39 -0
  65. package/RAF/ahnwrk-worktree-weaver/decisions.md +19 -0
  66. package/RAF/ahnwrk-worktree-weaver/input.md +4 -0
  67. package/RAF/ahnwrk-worktree-weaver/outcomes/01-remove-co-authored-by.md +20 -0
  68. package/RAF/ahnwrk-worktree-weaver/outcomes/02-update-task-status-format.md +21 -0
  69. package/RAF/ahnwrk-worktree-weaver/outcomes/03-worktree-auto-discovery.md +34 -0
  70. package/RAF/ahnwrk-worktree-weaver/outcomes/04-fix-pr-description.md +30 -0
  71. package/RAF/ahnwrk-worktree-weaver/plans/01-remove-co-authored-by.md +26 -0
  72. package/RAF/ahnwrk-worktree-weaver/plans/02-update-task-status-format.md +27 -0
  73. package/RAF/ahnwrk-worktree-weaver/plans/03-worktree-auto-discovery.md +37 -0
  74. package/RAF/ahnwrk-worktree-weaver/plans/04-fix-pr-description.md +50 -0
  75. package/RAF/ahrren-turbo-finder/decisions.md +19 -0
  76. package/RAF/ahrren-turbo-finder/input.md +2 -0
  77. package/RAF/ahrren-turbo-finder/outcomes/01-worktree-auto-detect.md +40 -0
  78. package/RAF/ahrren-turbo-finder/outcomes/02-medium-effort-do.md +34 -0
  79. package/RAF/ahrren-turbo-finder/plans/01-worktree-auto-detect.md +44 -0
  80. package/RAF/ahrren-turbo-finder/plans/02-medium-effort-do.md +39 -0
  81. package/RAF/ahrtxf-session-sentinel/decisions.md +19 -0
  82. package/RAF/ahrtxf-session-sentinel/input.md +1 -0
  83. package/RAF/ahrtxf-session-sentinel/outcomes/01-capture-session-id.md +37 -0
  84. package/RAF/ahrtxf-session-sentinel/outcomes/02-resume-flag.md +45 -0
  85. package/RAF/ahrtxf-session-sentinel/plans/01-capture-session-id.md +41 -0
  86. package/RAF/ahrtxf-session-sentinel/plans/02-resume-flag.md +51 -0
  87. package/README.md +56 -10
  88. package/dist/commands/do.d.ts +15 -0
  89. package/dist/commands/do.d.ts.map +1 -1
  90. package/dist/commands/do.js +431 -129
  91. package/dist/commands/do.js.map +1 -1
  92. package/dist/commands/migrate.d.ts +14 -0
  93. package/dist/commands/migrate.d.ts.map +1 -0
  94. package/dist/commands/migrate.js +228 -0
  95. package/dist/commands/migrate.js.map +1 -0
  96. package/dist/commands/plan.d.ts.map +1 -1
  97. package/dist/commands/plan.js +237 -40
  98. package/dist/commands/plan.js.map +1 -1
  99. package/dist/commands/status.d.ts.map +1 -1
  100. package/dist/commands/status.js +221 -47
  101. package/dist/commands/status.js.map +1 -1
  102. package/dist/core/claude-runner.d.ts +21 -2
  103. package/dist/core/claude-runner.d.ts.map +1 -1
  104. package/dist/core/claude-runner.js +199 -29
  105. package/dist/core/claude-runner.js.map +1 -1
  106. package/dist/core/git.d.ts +15 -6
  107. package/dist/core/git.d.ts.map +1 -1
  108. package/dist/core/git.js +53 -20
  109. package/dist/core/git.js.map +1 -1
  110. package/dist/core/project-manager.d.ts.map +1 -1
  111. package/dist/core/project-manager.js +2 -2
  112. package/dist/core/project-manager.js.map +1 -1
  113. package/dist/core/pull-request.d.ts +84 -0
  114. package/dist/core/pull-request.d.ts.map +1 -0
  115. package/dist/core/pull-request.js +414 -0
  116. package/dist/core/pull-request.js.map +1 -0
  117. package/dist/core/shutdown-handler.d.ts.map +1 -1
  118. package/dist/core/shutdown-handler.js +4 -0
  119. package/dist/core/shutdown-handler.js.map +1 -1
  120. package/dist/core/state-derivation.d.ts +3 -3
  121. package/dist/core/state-derivation.d.ts.map +1 -1
  122. package/dist/core/state-derivation.js +18 -14
  123. package/dist/core/state-derivation.js.map +1 -1
  124. package/dist/core/worktree.d.ts +138 -0
  125. package/dist/core/worktree.d.ts.map +1 -0
  126. package/dist/core/worktree.js +383 -0
  127. package/dist/core/worktree.js.map +1 -0
  128. package/dist/index.js +2 -0
  129. package/dist/index.js.map +1 -1
  130. package/dist/parsers/stream-renderer.d.ts +3 -0
  131. package/dist/parsers/stream-renderer.d.ts.map +1 -1
  132. package/dist/parsers/stream-renderer.js +1 -1
  133. package/dist/parsers/stream-renderer.js.map +1 -1
  134. package/dist/prompts/amend.d.ts +1 -0
  135. package/dist/prompts/amend.d.ts.map +1 -1
  136. package/dist/prompts/amend.js +14 -10
  137. package/dist/prompts/amend.js.map +1 -1
  138. package/dist/prompts/execution.d.ts.map +1 -1
  139. package/dist/prompts/execution.js +4 -2
  140. package/dist/prompts/execution.js.map +1 -1
  141. package/dist/prompts/planning.d.ts +1 -0
  142. package/dist/prompts/planning.d.ts.map +1 -1
  143. package/dist/prompts/planning.js +9 -8
  144. package/dist/prompts/planning.js.map +1 -1
  145. package/dist/types/config.d.ts +6 -0
  146. package/dist/types/config.d.ts.map +1 -1
  147. package/dist/ui/project-picker.d.ts +34 -3
  148. package/dist/ui/project-picker.d.ts.map +1 -1
  149. package/dist/ui/project-picker.js +78 -10
  150. package/dist/ui/project-picker.js.map +1 -1
  151. package/dist/utils/paths.d.ts +38 -43
  152. package/dist/utils/paths.d.ts.map +1 -1
  153. package/dist/utils/paths.js +123 -193
  154. package/dist/utils/paths.js.map +1 -1
  155. package/dist/utils/terminal-symbols.d.ts +2 -2
  156. package/dist/utils/terminal-symbols.js +3 -3
  157. package/dist/utils/terminal-symbols.js.map +1 -1
  158. package/dist/utils/validation.d.ts.map +1 -1
  159. package/dist/utils/validation.js +2 -8
  160. package/dist/utils/validation.js.map +1 -1
  161. package/package.json +1 -1
  162. package/src/commands/do.ts +505 -139
  163. package/src/commands/migrate.ts +269 -0
  164. package/src/commands/plan.ts +264 -40
  165. package/src/commands/status.ts +252 -45
  166. package/src/core/claude-runner.ts +246 -33
  167. package/src/core/git.ts +57 -21
  168. package/src/core/project-manager.ts +2 -1
  169. package/src/core/pull-request.ts +480 -0
  170. package/src/core/shutdown-handler.ts +5 -0
  171. package/src/core/state-derivation.ts +18 -14
  172. package/src/core/worktree.ts +434 -0
  173. package/src/index.ts +2 -0
  174. package/src/parsers/stream-renderer.ts +4 -1
  175. package/src/prompts/amend.ts +15 -9
  176. package/src/prompts/execution.ts +4 -2
  177. package/src/prompts/planning.ts +10 -8
  178. package/src/types/config.ts +7 -0
  179. package/src/ui/project-picker.ts +110 -10
  180. package/src/utils/paths.ts +129 -214
  181. package/src/utils/terminal-symbols.ts +3 -3
  182. package/src/utils/validation.ts +2 -9
  183. package/tests/unit/amend-prompt.test.ts +85 -0
  184. package/tests/unit/claude-runner-interactive.test.ts +24 -0
  185. package/tests/unit/claude-runner.test.ts +518 -64
  186. package/tests/unit/commit-planning-artifacts-worktree.test.ts +327 -0
  187. package/tests/unit/commit-planning-artifacts.test.ts +303 -35
  188. package/tests/unit/dependency-integration.test.ts +95 -95
  189. package/tests/unit/do-blocked-tasks.test.ts +53 -53
  190. package/tests/unit/do-command.test.ts +39 -132
  191. package/tests/unit/do-rerun.test.ts +65 -65
  192. package/tests/unit/do-worktree-cleanup.test.ts +151 -0
  193. package/tests/unit/execution-prompt.test.ts +71 -60
  194. package/tests/unit/failure-history.test.ts +19 -19
  195. package/tests/unit/git-commit-helpers.test.ts +5 -5
  196. package/tests/unit/git-stash.test.ts +4 -4
  197. package/tests/unit/migrate-command.test.ts +197 -0
  198. package/tests/unit/outcome-content.test.ts +20 -20
  199. package/tests/unit/paths.test.ts +269 -467
  200. package/tests/unit/plan-amend-worktree-recreate.test.ts +246 -0
  201. package/tests/unit/plan-command.test.ts +103 -103
  202. package/tests/unit/planning-prompt.test.ts +41 -4
  203. package/tests/unit/post-execution-picker.test.ts +252 -0
  204. package/tests/unit/project-manager.test.ts +20 -8
  205. package/tests/unit/project-picker.test.ts +425 -42
  206. package/tests/unit/pull-request.test.ts +852 -0
  207. package/tests/unit/state-derivation.test.ts +138 -137
  208. package/tests/unit/status-command.test.ts +344 -76
  209. package/tests/unit/stream-renderer.test.ts +30 -0
  210. package/tests/unit/terminal-symbols.test.ts +4 -4
  211. package/tests/unit/worktree-integration.test.ts +405 -0
  212. package/tests/unit/worktree.test.ts +625 -0
  213. package/tests/unit/do-multiproject.test.ts +0 -270
  214. /package/RAF/{001-raf-task-improvements → aaaaab-raf-task-improvements}/input.md +0 -0
  215. /package/RAF/{001-raf-task-improvements/outcomes/001-add-decisions-folder.md → aaaaab-raf-task-improvements/outcomes/01-add-decisions-folder.md} +0 -0
  216. /package/RAF/{001-raf-task-improvements/outcomes/002-fix-write-error-on-shutdown.md → aaaaab-raf-task-improvements/outcomes/02-fix-write-error-on-shutdown.md} +0 -0
  217. /package/RAF/{001-raf-task-improvements/outcomes/003-stash-changes-on-failure.md → aaaaab-raf-task-improvements/outcomes/03-stash-changes-on-failure.md} +0 -0
  218. /package/RAF/{001-raf-task-improvements/outcomes/004-add-project-name-to-commits.md → aaaaab-raf-task-improvements/outcomes/04-add-project-name-to-commits.md} +0 -0
  219. /package/RAF/{001-raf-task-improvements/outcomes/005-add-running-time-display.md → aaaaab-raf-task-improvements/outcomes/05-add-running-time-display.md} +0 -0
  220. /package/RAF/{001-raf-task-improvements/outcomes/006-add-task-name-to-logs.md → aaaaab-raf-task-improvements/outcomes/06-add-task-name-to-logs.md} +0 -0
  221. /package/RAF/{001-raf-task-improvements/outcomes/007-show-model-at-task-start.md → aaaaab-raf-task-improvements/outcomes/07-show-model-at-task-start.md} +0 -0
  222. /package/RAF/{001-raf-task-improvements/outcomes/009-remove-editor-placeholder-text.md → aaaaab-raf-task-improvements/outcomes/09-remove-editor-placeholder-text.md} +0 -0
  223. /package/RAF/{001-raf-task-improvements → aaaaab-raf-task-improvements}/outcomes/SUMMARY.md +0 -0
  224. /package/RAF/{001-raf-task-improvements/plans/001-add-decisions-folder.md → aaaaab-raf-task-improvements/plans/01-add-decisions-folder.md} +0 -0
  225. /package/RAF/{001-raf-task-improvements/plans/002-fix-write-error-on-shutdown.md → aaaaab-raf-task-improvements/plans/02-fix-write-error-on-shutdown.md} +0 -0
  226. /package/RAF/{001-raf-task-improvements/plans/003-stash-changes-on-failure.md → aaaaab-raf-task-improvements/plans/03-stash-changes-on-failure.md} +0 -0
  227. /package/RAF/{001-raf-task-improvements/plans/004-add-project-name-to-commits.md → aaaaab-raf-task-improvements/plans/04-add-project-name-to-commits.md} +0 -0
  228. /package/RAF/{001-raf-task-improvements/plans/005-add-running-time-display.md → aaaaab-raf-task-improvements/plans/05-add-running-time-display.md} +0 -0
  229. /package/RAF/{001-raf-task-improvements/plans/006-add-task-name-to-logs.md → aaaaab-raf-task-improvements/plans/06-add-task-name-to-logs.md} +0 -0
  230. /package/RAF/{001-raf-task-improvements/plans/009-remove-editor-placeholder-text.md → aaaaab-raf-task-improvements/plans/09-remove-editor-placeholder-text.md} +0 -0
  231. /package/RAF/{002-raf-task-improvements-execution → aaaaac-raf-task-improvements-execution}/decisions/DECISIONS.md +0 -0
  232. /package/RAF/{002-raf-task-improvements-execution → aaaaac-raf-task-improvements-execution}/input.md +0 -0
  233. /package/RAF/{002-raf-task-improvements-execution/outcomes/001-commit-show-model-at-task-start.md → aaaaac-raf-task-improvements-execution/outcomes/01-commit-show-model-at-task-start.md} +0 -0
  234. /package/RAF/{002-raf-task-improvements-execution/outcomes/002-delete-skipped-plan.md → aaaaac-raf-task-improvements-execution/outcomes/02-delete-skipped-plan.md} +0 -0
  235. /package/RAF/{002-raf-task-improvements-execution → aaaaac-raf-task-improvements-execution}/outcomes/SUMMARY.md +0 -0
  236. /package/RAF/{002-raf-task-improvements-execution/plans/001-commit-show-model-at-task-start.md → aaaaac-raf-task-improvements-execution/plans/01-commit-show-model-at-task-start.md} +0 -0
  237. /package/RAF/{002-raf-task-improvements-execution/plans/002-delete-skipped-plan.md → aaaaac-raf-task-improvements-execution/plans/02-delete-skipped-plan.md} +0 -0
  238. /package/RAF/{003-multi-project-execution → aaaaad-multi-project-execution}/decisions/DECISIONS.md +0 -0
  239. /package/RAF/{003-multi-project-execution → aaaaad-multi-project-execution}/input.md +0 -0
  240. /package/RAF/{003-multi-project-execution/outcomes/001-remove-state-json.md → aaaaad-multi-project-execution/outcomes/01-remove-state-json.md} +0 -0
  241. /package/RAF/{003-multi-project-execution/outcomes/002-update-raf-status.md → aaaaad-multi-project-execution/outcomes/02-update-raf-status.md} +0 -0
  242. /package/RAF/{003-multi-project-execution/outcomes/003-simplify-git-logic.md → aaaaad-multi-project-execution/outcomes/03-simplify-git-logic.md} +0 -0
  243. /package/RAF/{003-multi-project-execution/outcomes/004-auto-commit-planning.md → aaaaad-multi-project-execution/outcomes/04-auto-commit-planning.md} +0 -0
  244. /package/RAF/{003-multi-project-execution/outcomes/005-rerun-failed-tasks.md → aaaaad-multi-project-execution/outcomes/05-rerun-failed-tasks.md} +0 -0
  245. /package/RAF/{003-multi-project-execution/outcomes/006-multi-project-execution.md → aaaaad-multi-project-execution/outcomes/06-multi-project-execution.md} +0 -0
  246. /package/RAF/{003-multi-project-execution/outcomes/007-verify-timeout.md → aaaaad-multi-project-execution/outcomes/07-verify-timeout.md} +0 -0
  247. /package/RAF/{003-multi-project-execution/outcomes/008-move-decisions-file.md → aaaaad-multi-project-execution/outcomes/08-move-decisions-file.md} +0 -0
  248. /package/RAF/{003-multi-project-execution → aaaaad-multi-project-execution}/outcomes/SUMMARY.md +0 -0
  249. /package/RAF/{003-multi-project-execution/plans/001-remove-state-json.md → aaaaad-multi-project-execution/plans/01-remove-state-json.md} +0 -0
  250. /package/RAF/{003-multi-project-execution/plans/002-update-raf-status.md → aaaaad-multi-project-execution/plans/02-update-raf-status.md} +0 -0
  251. /package/RAF/{003-multi-project-execution/plans/003-simplify-git-logic.md → aaaaad-multi-project-execution/plans/03-simplify-git-logic.md} +0 -0
  252. /package/RAF/{003-multi-project-execution/plans/004-auto-commit-planning.md → aaaaad-multi-project-execution/plans/04-auto-commit-planning.md} +0 -0
  253. /package/RAF/{003-multi-project-execution/plans/005-rerun-failed-tasks.md → aaaaad-multi-project-execution/plans/05-rerun-failed-tasks.md} +0 -0
  254. /package/RAF/{003-multi-project-execution/plans/006-multi-project-execution.md → aaaaad-multi-project-execution/plans/06-multi-project-execution.md} +0 -0
  255. /package/RAF/{003-multi-project-execution/plans/007-verify-timeout.md → aaaaad-multi-project-execution/plans/07-verify-timeout.md} +0 -0
  256. /package/RAF/{003-multi-project-execution/plans/008-move-decisions-file.md → aaaaad-multi-project-execution/plans/08-move-decisions-file.md} +0 -0
  257. /package/RAF/{004-task-naming-optimization → aaaaae-task-naming-optimization}/decisions.md +0 -0
  258. /package/RAF/{004-task-naming-optimization → aaaaae-task-naming-optimization}/input.md +0 -0
  259. /package/RAF/{004-task-naming-optimization/outcomes/001-remove-summary-file.md → aaaaae-task-naming-optimization/outcomes/01-remove-summary-file.md} +0 -0
  260. /package/RAF/{004-task-naming-optimization/outcomes/002-base36-project-numbering.md → aaaaae-task-naming-optimization/outcomes/02-base36-project-numbering.md} +0 -0
  261. /package/RAF/{004-task-naming-optimization/outcomes/003-improve-haiku-prompt.md → aaaaae-task-naming-optimization/outcomes/03-improve-haiku-prompt.md} +0 -0
  262. /package/RAF/{004-task-naming-optimization → aaaaae-task-naming-optimization}/outcomes/SUMMARY.md +0 -0
  263. /package/RAF/{004-task-naming-optimization/plans/001-remove-summary-file.md → aaaaae-task-naming-optimization/plans/01-remove-summary-file.md} +0 -0
  264. /package/RAF/{004-task-naming-optimization/plans/002-base36-project-numbering.md → aaaaae-task-naming-optimization/plans/02-base36-project-numbering.md} +0 -0
  265. /package/RAF/{004-task-naming-optimization/plans/003-improve-haiku-prompt.md → aaaaae-task-naming-optimization/plans/03-improve-haiku-prompt.md} +0 -0
  266. /package/RAF/{005-task-naming-improvements → aaaaaf-task-naming-improvements}/decisions.md +0 -0
  267. /package/RAF/{005-task-naming-improvements → aaaaaf-task-naming-improvements}/input.md +0 -0
  268. /package/RAF/{005-task-naming-improvements/outcomes/001-enhance-identifier-resolution.md → aaaaaf-task-naming-improvements/outcomes/01-enhance-identifier-resolution.md} +0 -0
  269. /package/RAF/{005-task-naming-improvements/outcomes/002-add-identifier-support-to-status.md → aaaaaf-task-naming-improvements/outcomes/02-add-identifier-support-to-status.md} +0 -0
  270. /package/RAF/{005-task-naming-improvements/outcomes/003-update-do-for-full-folder-names.md → aaaaaf-task-naming-improvements/outcomes/03-update-do-for-full-folder-names.md} +0 -0
  271. /package/RAF/{005-task-naming-improvements/outcomes/004-implement-amend-flag-for-plan.md → aaaaaf-task-naming-improvements/outcomes/04-implement-amend-flag-for-plan.md} +0 -0
  272. /package/RAF/{005-task-naming-improvements/outcomes/005-commit-outcomes-on-complete.md → aaaaaf-task-naming-improvements/outcomes/05-commit-outcomes-on-complete.md} +0 -0
  273. /package/RAF/{005-task-naming-improvements/outcomes/006-update-execution-prompt-commit-schema.md → aaaaaf-task-naming-improvements/outcomes/06-update-execution-prompt-commit-schema.md} +0 -0
  274. /package/RAF/{005-task-naming-improvements/outcomes/007-allow-pending-task-amendments.md → aaaaaf-task-naming-improvements/outcomes/07-allow-pending-task-amendments.md} +0 -0
  275. /package/RAF/{005-task-naming-improvements/outcomes/008-fix-timeout-label.md → aaaaaf-task-naming-improvements/outcomes/08-fix-timeout-label.md} +0 -0
  276. /package/RAF/{005-task-naming-improvements/plans/001-enhance-identifier-resolution.md → aaaaaf-task-naming-improvements/plans/01-enhance-identifier-resolution.md} +0 -0
  277. /package/RAF/{005-task-naming-improvements/plans/002-add-identifier-support-to-status.md → aaaaaf-task-naming-improvements/plans/02-add-identifier-support-to-status.md} +0 -0
  278. /package/RAF/{005-task-naming-improvements/plans/003-update-do-for-full-folder-names.md → aaaaaf-task-naming-improvements/plans/03-update-do-for-full-folder-names.md} +0 -0
  279. /package/RAF/{005-task-naming-improvements/plans/004-implement-amend-flag-for-plan.md → aaaaaf-task-naming-improvements/plans/04-implement-amend-flag-for-plan.md} +0 -0
  280. /package/RAF/{005-task-naming-improvements/plans/005-commit-outcomes-on-complete.md → aaaaaf-task-naming-improvements/plans/05-commit-outcomes-on-complete.md} +0 -0
  281. /package/RAF/{005-task-naming-improvements/plans/006-update-execution-prompt-commit-schema.md → aaaaaf-task-naming-improvements/plans/06-update-execution-prompt-commit-schema.md} +0 -0
  282. /package/RAF/{005-task-naming-improvements/plans/007-allow-pending-task-amendments.md → aaaaaf-task-naming-improvements/plans/07-allow-pending-task-amendments.md} +0 -0
  283. /package/RAF/{005-task-naming-improvements/plans/008-fix-timeout-label.md → aaaaaf-task-naming-improvements/plans/08-fix-timeout-label.md} +0 -0
  284. /package/RAF/{006-fix-double-summary-headers → aaaaag-fix-double-summary-headers}/decisions.md +0 -0
  285. /package/RAF/{006-fix-double-summary-headers → aaaaag-fix-double-summary-headers}/input.md +0 -0
  286. /package/RAF/{006-fix-double-summary-headers/outcomes/001-fix-double-summary-headers.md → aaaaag-fix-double-summary-headers/outcomes/01-fix-double-summary-headers.md} +0 -0
  287. /package/RAF/{006-fix-double-summary-headers/outcomes/002-update-readme-for-npm.md → aaaaag-fix-double-summary-headers/outcomes/02-update-readme-for-npm.md} +0 -0
  288. /package/RAF/{006-fix-double-summary-headers/outcomes/003-npm-publish-instructions.md → aaaaag-fix-double-summary-headers/outcomes/03-npm-publish-instructions.md} +0 -0
  289. /package/RAF/{006-fix-double-summary-headers/outcomes/004-flexible-project-lookup.md → aaaaag-fix-double-summary-headers/outcomes/04-flexible-project-lookup.md} +0 -0
  290. /package/RAF/{006-fix-double-summary-headers/plans/001-fix-double-summary-headers.md → aaaaag-fix-double-summary-headers/plans/01-fix-double-summary-headers.md} +0 -0
  291. /package/RAF/{006-fix-double-summary-headers/plans/002-update-readme-for-npm.md → aaaaag-fix-double-summary-headers/plans/02-update-readme-for-npm.md} +0 -0
  292. /package/RAF/{006-fix-double-summary-headers/plans/003-npm-publish-instructions.md → aaaaag-fix-double-summary-headers/plans/03-npm-publish-instructions.md} +0 -0
  293. /package/RAF/{006-fix-double-summary-headers/plans/004-flexible-project-lookup.md → aaaaag-fix-double-summary-headers/plans/04-flexible-project-lookup.md} +0 -0
  294. /package/RAF/{007-improve-outcome-format → aaaaah-improve-outcome-format}/decisions.md +0 -0
  295. /package/RAF/{007-improve-outcome-format → aaaaah-improve-outcome-format}/input.md +0 -0
  296. /package/RAF/{007-improve-outcome-format/outcomes/001-update-execution-prompt.md → aaaaah-improve-outcome-format/outcomes/01-update-execution-prompt.md} +0 -0
  297. /package/RAF/{007-improve-outcome-format/outcomes/002-update-state-derivation.md → aaaaah-improve-outcome-format/outcomes/02-update-state-derivation.md} +0 -0
  298. /package/RAF/{007-improve-outcome-format/outcomes/003-update-do-command-outcome-handling.md → aaaaah-improve-outcome-format/outcomes/03-update-do-command-outcome-handling.md} +0 -0
  299. /package/RAF/{007-improve-outcome-format/outcomes/004-implement-failure-analysis.md → aaaaah-improve-outcome-format/outcomes/04-implement-failure-analysis.md} +0 -0
  300. /package/RAF/{007-improve-outcome-format/outcomes/005-update-documentation.md → aaaaah-improve-outcome-format/outcomes/05-update-documentation.md} +0 -0
  301. /package/RAF/{007-improve-outcome-format/plans/001-update-execution-prompt.md → aaaaah-improve-outcome-format/plans/01-update-execution-prompt.md} +0 -0
  302. /package/RAF/{007-improve-outcome-format/plans/002-update-state-derivation.md → aaaaah-improve-outcome-format/plans/02-update-state-derivation.md} +0 -0
  303. /package/RAF/{007-improve-outcome-format/plans/003-update-do-command-outcome-handling.md → aaaaah-improve-outcome-format/plans/03-update-do-command-outcome-handling.md} +0 -0
  304. /package/RAF/{007-improve-outcome-format/plans/004-implement-failure-analysis.md → aaaaah-improve-outcome-format/plans/04-implement-failure-analysis.md} +0 -0
  305. /package/RAF/{007-improve-outcome-format/plans/005-update-documentation.md → aaaaah-improve-outcome-format/plans/05-update-documentation.md} +0 -0
  306. /package/RAF/{008-beautiful-do → aaaaai-beautiful-do}/decisions.md +0 -0
  307. /package/RAF/{008-beautiful-do → aaaaai-beautiful-do}/input.md +0 -0
  308. /package/RAF/{008-beautiful-do/outcomes/001-terminal-symbols.md → aaaaai-beautiful-do/outcomes/01-terminal-symbols.md} +0 -0
  309. /package/RAF/{008-beautiful-do/outcomes/002-refactor-do-output.md → aaaaai-beautiful-do/outcomes/02-refactor-do-output.md} +0 -0
  310. /package/RAF/{008-beautiful-do/outcomes/003-refactor-status-output.md → aaaaai-beautiful-do/outcomes/03-refactor-status-output.md} +0 -0
  311. /package/RAF/{008-beautiful-do/outcomes/004-simplify-logger.md → aaaaai-beautiful-do/outcomes/04-simplify-logger.md} +0 -0
  312. /package/RAF/{008-beautiful-do/outcomes/005-add-tests.md → aaaaai-beautiful-do/outcomes/05-add-tests.md} +0 -0
  313. /package/RAF/{008-beautiful-do/plans/001-terminal-symbols.md → aaaaai-beautiful-do/plans/01-terminal-symbols.md} +0 -0
  314. /package/RAF/{008-beautiful-do/plans/002-refactor-do-output.md → aaaaai-beautiful-do/plans/02-refactor-do-output.md} +0 -0
  315. /package/RAF/{008-beautiful-do/plans/003-refactor-status-output.md → aaaaai-beautiful-do/plans/03-refactor-status-output.md} +0 -0
  316. /package/RAF/{008-beautiful-do/plans/004-simplify-logger.md → aaaaai-beautiful-do/plans/04-simplify-logger.md} +0 -0
  317. /package/RAF/{008-beautiful-do/plans/005-add-tests.md → aaaaai-beautiful-do/plans/05-add-tests.md} +0 -0
  318. /package/RAF/{009-system-promt-ammend → aaaaaj-system-promt-ammend}/decisions.md +0 -0
  319. /package/RAF/{009-system-promt-ammend → aaaaaj-system-promt-ammend}/input.md +0 -0
  320. /package/RAF/{009-system-promt-ammend/outcomes/001-model-override.md → aaaaaj-system-promt-ammend/outcomes/01-model-override.md} +0 -0
  321. /package/RAF/{009-system-promt-ammend/outcomes/002-system-prompt-append.md → aaaaaj-system-promt-ammend/outcomes/02-system-prompt-append.md} +0 -0
  322. /package/RAF/{009-system-promt-ammend/outcomes/003-retry-context.md → aaaaaj-system-promt-ammend/outcomes/03-retry-context.md} +0 -0
  323. /package/RAF/{009-system-promt-ammend/plans/001-model-override.md → aaaaaj-system-promt-ammend/plans/01-model-override.md} +0 -0
  324. /package/RAF/{009-system-promt-ammend/plans/002-system-prompt-append.md → aaaaaj-system-promt-ammend/plans/02-system-prompt-append.md} +0 -0
  325. /package/RAF/{009-system-promt-ammend/plans/003-retry-context.md → aaaaaj-system-promt-ammend/plans/03-retry-context.md} +0 -0
  326. /package/RAF/{010-outcome-marker-fallback → aaaabk-outcome-marker-fallback}/decisions.md +0 -0
  327. /package/RAF/{010-outcome-marker-fallback → aaaabk-outcome-marker-fallback}/input.md +0 -0
  328. /package/RAF/{010-outcome-marker-fallback/outcomes/001-outcome-file-marker-fallback.md → aaaabk-outcome-marker-fallback/outcomes/01-outcome-file-marker-fallback.md} +0 -0
  329. /package/RAF/{010-outcome-marker-fallback/outcomes/002-creative-project-naming.md → aaaabk-outcome-marker-fallback/outcomes/02-creative-project-naming.md} +0 -0
  330. /package/RAF/{010-outcome-marker-fallback/plans/001-outcome-file-marker-fallback.md → aaaabk-outcome-marker-fallback/plans/01-outcome-file-marker-fallback.md} +0 -0
  331. /package/RAF/{010-outcome-marker-fallback/plans/002-creative-project-naming.md → aaaabk-outcome-marker-fallback/plans/02-creative-project-naming.md} +0 -0
  332. /package/RAF/{011-do-task-in-commit → aaaabl-do-task-in-commit}/decisions.md +0 -0
  333. /package/RAF/{011-do-task-in-commit → aaaabl-do-task-in-commit}/input.md +0 -0
  334. /package/RAF/{011-do-task-in-commit/outcomes/001-update-execution-prompt.md → aaaabl-do-task-in-commit/outcomes/01-update-execution-prompt.md} +0 -0
  335. /package/RAF/{011-do-task-in-commit/outcomes/002-update-tests.md → aaaabl-do-task-in-commit/outcomes/02-update-tests.md} +0 -0
  336. /package/RAF/{011-do-task-in-commit/outcomes/003-update-documentation.md → aaaabl-do-task-in-commit/outcomes/03-update-documentation.md} +0 -0
  337. /package/RAF/{011-do-task-in-commit/plans/001-update-execution-prompt.md → aaaabl-do-task-in-commit/plans/01-update-execution-prompt.md} +0 -0
  338. /package/RAF/{011-do-task-in-commit/plans/002-update-tests.md → aaaabl-do-task-in-commit/plans/02-update-tests.md} +0 -0
  339. /package/RAF/{011-do-task-in-commit/plans/003-update-documentation.md → aaaabl-do-task-in-commit/plans/03-update-documentation.md} +0 -0
  340. /package/RAF/{012-name-picker-buffet → aaaabm-name-picker-buffet}/decisions.md +0 -0
  341. /package/RAF/{012-name-picker-buffet → aaaabm-name-picker-buffet}/input.md +0 -0
  342. /package/RAF/{012-name-picker-buffet/outcomes/001-name-picker-for-raf-plan.md → aaaabm-name-picker-buffet/outcomes/01-name-picker-for-raf-plan.md} +0 -0
  343. /package/RAF/{012-name-picker-buffet/outcomes/002-interactive-project-picker-for-raf-do.md → aaaabm-name-picker-buffet/outcomes/02-interactive-project-picker-for-raf-do.md} +0 -0
  344. /package/RAF/{012-name-picker-buffet/outcomes/003-raf-status-truncation.md → aaaabm-name-picker-buffet/outcomes/03-raf-status-truncation.md} +0 -0
  345. /package/RAF/{012-name-picker-buffet/outcomes/004-failure-reason-details.md → aaaabm-name-picker-buffet/outcomes/04-failure-reason-details.md} +0 -0
  346. /package/RAF/{012-name-picker-buffet/outcomes/005-remove-raf-commits.md → aaaabm-name-picker-buffet/outcomes/05-remove-raf-commits.md} +0 -0
  347. /package/RAF/{012-name-picker-buffet/outcomes/006-update-execution-prompt-for-commits.md → aaaabm-name-picker-buffet/outcomes/06-update-execution-prompt-for-commits.md} +0 -0
  348. /package/RAF/{012-name-picker-buffet/outcomes/007-fix-plan-mode-user-prompt.md → aaaabm-name-picker-buffet/outcomes/07-fix-plan-mode-user-prompt.md} +0 -0
  349. /package/RAF/{012-name-picker-buffet/outcomes/008-add-auto-flag-for-plan-mode.md → aaaabm-name-picker-buffet/outcomes/08-add-auto-flag-for-plan-mode.md} +0 -0
  350. /package/RAF/{012-name-picker-buffet/plans/001-name-picker-for-raf-plan.md → aaaabm-name-picker-buffet/plans/01-name-picker-for-raf-plan.md} +0 -0
  351. /package/RAF/{012-name-picker-buffet/plans/002-interactive-project-picker-for-raf-do.md → aaaabm-name-picker-buffet/plans/02-interactive-project-picker-for-raf-do.md} +0 -0
  352. /package/RAF/{012-name-picker-buffet/plans/003-raf-status-truncation.md → aaaabm-name-picker-buffet/plans/03-raf-status-truncation.md} +0 -0
  353. /package/RAF/{012-name-picker-buffet/plans/004-failure-reason-details.md → aaaabm-name-picker-buffet/plans/04-failure-reason-details.md} +0 -0
  354. /package/RAF/{012-name-picker-buffet/plans/005-remove-raf-commits.md → aaaabm-name-picker-buffet/plans/05-remove-raf-commits.md} +0 -0
  355. /package/RAF/{012-name-picker-buffet/plans/006-update-execution-prompt-for-commits.md → aaaabm-name-picker-buffet/plans/06-update-execution-prompt-for-commits.md} +0 -0
  356. /package/RAF/{012-name-picker-buffet/plans/007-fix-plan-mode-user-prompt.md → aaaabm-name-picker-buffet/plans/07-fix-plan-mode-user-prompt.md} +0 -0
  357. /package/RAF/{012-name-picker-buffet/plans/008-add-auto-flag-for-plan-mode.md → aaaabm-name-picker-buffet/plans/08-add-auto-flag-for-plan-mode.md} +0 -0
  358. /package/RAF/{013-dependencies-watchdog → aaaabn-dependencies-watchdog}/decisions.md +0 -0
  359. /package/RAF/{013-dependencies-watchdog → aaaabn-dependencies-watchdog}/input.md +0 -0
  360. /package/RAF/{013-dependencies-watchdog/outcomes/001-define-dependency-syntax.md → aaaabn-dependencies-watchdog/outcomes/01-define-dependency-syntax.md} +0 -0
  361. /package/RAF/{013-dependencies-watchdog/outcomes/002-update-planning-prompts.md → aaaabn-dependencies-watchdog/outcomes/02-update-planning-prompts.md} +0 -0
  362. /package/RAF/{013-dependencies-watchdog/outcomes/003-parse-dependencies-update-state.md → aaaabn-dependencies-watchdog/outcomes/03-parse-dependencies-update-state.md} +0 -0
  363. /package/RAF/{013-dependencies-watchdog/outcomes/004-implement-dependency-checking-in-do.md → aaaabn-dependencies-watchdog/outcomes/04-implement-dependency-checking-in-do.md} +0 -0
  364. /package/RAF/{013-dependencies-watchdog/outcomes/005-update-execution-prompts.md → aaaabn-dependencies-watchdog/outcomes/05-update-execution-prompts.md} +0 -0
  365. /package/RAF/{013-dependencies-watchdog/outcomes/006-add-tests.md → aaaabn-dependencies-watchdog/outcomes/06-add-tests.md} +0 -0
  366. /package/RAF/{013-dependencies-watchdog/outcomes/007-add-act-alias.md → aaaabn-dependencies-watchdog/outcomes/07-add-act-alias.md} +0 -0
  367. /package/RAF/{013-dependencies-watchdog/outcomes/008-add-exit-message.md → aaaabn-dependencies-watchdog/outcomes/08-add-exit-message.md} +0 -0
  368. /package/RAF/{013-dependencies-watchdog/plans/001-define-dependency-syntax.md → aaaabn-dependencies-watchdog/plans/01-define-dependency-syntax.md} +0 -0
  369. /package/RAF/{013-dependencies-watchdog/plans/002-update-planning-prompts.md → aaaabn-dependencies-watchdog/plans/02-update-planning-prompts.md} +0 -0
  370. /package/RAF/{013-dependencies-watchdog/plans/003-parse-dependencies-update-state.md → aaaabn-dependencies-watchdog/plans/03-parse-dependencies-update-state.md} +0 -0
  371. /package/RAF/{013-dependencies-watchdog/plans/004-implement-dependency-checking-in-do.md → aaaabn-dependencies-watchdog/plans/04-implement-dependency-checking-in-do.md} +0 -0
  372. /package/RAF/{013-dependencies-watchdog/plans/005-update-execution-prompts.md → aaaabn-dependencies-watchdog/plans/05-update-execution-prompts.md} +0 -0
  373. /package/RAF/{013-dependencies-watchdog/plans/006-add-tests.md → aaaabn-dependencies-watchdog/plans/06-add-tests.md} +0 -0
  374. /package/RAF/{013-dependencies-watchdog/plans/007-add-act-alias.md → aaaabn-dependencies-watchdog/plans/07-add-act-alias.md} +0 -0
  375. /package/RAF/{013-dependencies-watchdog/plans/008-add-exit-message.md → aaaabn-dependencies-watchdog/plans/08-add-exit-message.md} +0 -0
  376. /package/RAF/{014-watchdog → aaaabo-watchdog}/decisions.md +0 -0
  377. /package/RAF/{014-watchdog → aaaabo-watchdog}/input.md +0 -0
  378. /package/RAF/{014-watchdog/outcomes/001-amend-flag-position.md → aaaabo-watchdog/outcomes/01-amend-flag-position.md} +0 -0
  379. /package/RAF/{014-watchdog/outcomes/002-details-only-on-failure.md → aaaabo-watchdog/outcomes/02-details-only-on-failure.md} +0 -0
  380. /package/RAF/{014-watchdog/plans/001-amend-flag-position.md → aaaabo-watchdog/plans/01-amend-flag-position.md} +0 -0
  381. /package/RAF/{014-watchdog/plans/002-details-only-on-failure.md → aaaabo-watchdog/plans/02-details-only-on-failure.md} +0 -0
  382. /package/RAF/{015-name-lottery → aaaabp-name-lottery}/decisions.md +0 -0
  383. /package/RAF/{015-name-lottery → aaaabp-name-lottery}/input.md +0 -0
  384. /package/RAF/{015-name-lottery/outcomes/001-auto-pick-project-name.md → aaaabp-name-lottery/outcomes/01-auto-pick-project-name.md} +0 -0
  385. /package/RAF/{015-name-lottery/outcomes/002-mention-plan-files-in-commit.md → aaaabp-name-lottery/outcomes/02-mention-plan-files-in-commit.md} +0 -0
  386. /package/RAF/{015-name-lottery/outcomes/003-fix-input-md-in-amend-flow.md → aaaabp-name-lottery/outcomes/03-fix-input-md-in-amend-flow.md} +0 -0
  387. /package/RAF/{015-name-lottery/plans/001-auto-pick-project-name.md → aaaabp-name-lottery/plans/01-auto-pick-project-name.md} +0 -0
  388. /package/RAF/{015-name-lottery/plans/002-mention-plan-files-in-commit.md → aaaabp-name-lottery/plans/02-mention-plan-files-in-commit.md} +0 -0
  389. /package/RAF/{015-name-lottery/plans/003-fix-input-md-in-amend-flow.md → aaaabp-name-lottery/plans/03-fix-input-md-in-amend-flow.md} +0 -0
  390. /package/RAF/{016-planning-scalpel → aaaabq-planning-scalpel}/decisions.md +0 -0
  391. /package/RAF/{016-planning-scalpel → aaaabq-planning-scalpel}/input.md +0 -0
  392. /package/RAF/{016-planning-scalpel/outcomes/001-update-git-commit-instructions.md → aaaabq-planning-scalpel/outcomes/01-update-git-commit-instructions.md} +0 -0
  393. /package/RAF/{016-planning-scalpel/plans/001-update-git-commit-instructions.md → aaaabq-planning-scalpel/plans/01-update-git-commit-instructions.md} +0 -0
  394. /package/RAF/{017-decision-vault → aaaabr-decision-vault}/decisions.md +0 -0
  395. /package/RAF/{017-decision-vault → aaaabr-decision-vault}/input.md +0 -0
  396. /package/RAF/{017-decision-vault/outcomes/001-create-git-commit-utility.md → aaaabr-decision-vault/outcomes/01-create-git-commit-utility.md} +0 -0
  397. /package/RAF/{017-decision-vault/outcomes/002-integrate-commit-into-plan.md → aaaabr-decision-vault/outcomes/02-integrate-commit-into-plan.md} +0 -0
  398. /package/RAF/{017-decision-vault/outcomes/003-add-tests-for-planning-commit.md → aaaabr-decision-vault/outcomes/03-add-tests-for-planning-commit.md} +0 -0
  399. /package/RAF/{017-decision-vault/plans/001-create-git-commit-utility.md → aaaabr-decision-vault/plans/01-create-git-commit-utility.md} +0 -0
  400. /package/RAF/{017-decision-vault/plans/002-integrate-commit-into-plan.md → aaaabr-decision-vault/plans/02-integrate-commit-into-plan.md} +0 -0
  401. /package/RAF/{017-decision-vault/plans/003-add-tests-for-planning-commit.md → aaaabr-decision-vault/plans/03-add-tests-for-planning-commit.md} +0 -0
  402. /package/RAF/{018-workflow-forge → aaaabs-workflow-forge}/decisions.md +0 -0
  403. /package/RAF/{018-workflow-forge → aaaabs-workflow-forge}/input.md +0 -0
  404. /package/RAF/{018-workflow-forge/outcomes/001-add-task-number-progress.md → aaaabs-workflow-forge/outcomes/01-add-task-number-progress.md} +0 -0
  405. /package/RAF/{018-workflow-forge/outcomes/002-update-plan-do-prompts.md → aaaabs-workflow-forge/outcomes/02-update-plan-do-prompts.md} +0 -0
  406. /package/RAF/{018-workflow-forge/plans/001-add-task-number-progress.md → aaaabs-workflow-forge/plans/01-add-task-number-progress.md} +0 -0
  407. /package/RAF/{018-workflow-forge/plans/002-update-plan-do-prompts.md → aaaabs-workflow-forge/plans/02-update-plan-do-prompts.md} +0 -0
  408. /package/RAF/{019-verbose-chronicle → aaaabt-verbose-chronicle}/decisions.md +0 -0
  409. /package/RAF/{019-verbose-chronicle → aaaabt-verbose-chronicle}/input.md +0 -0
  410. /package/RAF/{019-verbose-chronicle/outcomes/001-amend-iteration-references.md → aaaabt-verbose-chronicle/outcomes/01-amend-iteration-references.md} +0 -0
  411. /package/RAF/{019-verbose-chronicle/outcomes/002-verbose-task-name-display.md → aaaabt-verbose-chronicle/outcomes/02-verbose-task-name-display.md} +0 -0
  412. /package/RAF/{019-verbose-chronicle/outcomes/003-verbose-streaming-fix.md → aaaabt-verbose-chronicle/outcomes/03-verbose-streaming-fix.md} +0 -0
  413. /package/RAF/{019-verbose-chronicle/outcomes/004-commit-verification-before-halt.md → aaaabt-verbose-chronicle/outcomes/04-commit-verification-before-halt.md} +0 -0
  414. /package/RAF/{019-verbose-chronicle/plans/001-amend-iteration-references.md → aaaabt-verbose-chronicle/plans/01-amend-iteration-references.md} +0 -0
  415. /package/RAF/{019-verbose-chronicle/plans/002-verbose-task-name-display.md → aaaabt-verbose-chronicle/plans/02-verbose-task-name-display.md} +0 -0
  416. /package/RAF/{019-verbose-chronicle/plans/003-verbose-streaming-fix.md → aaaabt-verbose-chronicle/plans/03-verbose-streaming-fix.md} +0 -0
  417. /package/RAF/{019-verbose-chronicle/plans/004-commit-verification-before-halt.md → aaaabt-verbose-chronicle/plans/04-commit-verification-before-halt.md} +0 -0
@@ -140,7 +140,8 @@ describe('ClaudeRunner', () => {
140
140
  const runPromise = runner.run('test prompt', { timeout: 5 });
141
141
 
142
142
  // Emit some output and close the process normally
143
- mockProc.stdout.emit('data', Buffer.from('<promise>COMPLETE</promise>'));
143
+ const event = JSON.stringify({ type: 'assistant', message: { content: [{ type: 'text', text: '<promise>COMPLETE</promise>' }] } });
144
+ mockProc.stdout.emit('data', Buffer.from(event + '\n'));
144
145
  mockProc.emit('close', 0);
145
146
 
146
147
  const result = await runPromise;
@@ -162,8 +163,9 @@ describe('ClaudeRunner', () => {
162
163
 
163
164
  const runPromise1 = runner.run('first prompt', { timeout: 2 });
164
165
 
165
- // Complete first call quickly
166
- mockProc1.stdout.emit('data', Buffer.from('output'));
166
+ // Complete first call quickly (NDJSON event)
167
+ const event = JSON.stringify({ type: 'assistant', message: { content: [{ type: 'text', text: 'output' }] } });
168
+ mockProc1.stdout.emit('data', Buffer.from(event + '\n'));
167
169
  mockProc1.emit('close', 0);
168
170
  await runPromise1;
169
171
 
@@ -211,8 +213,9 @@ describe('ClaudeRunner', () => {
211
213
  // Advance a bit but not to timeout
212
214
  jest.advanceTimersByTime(30000);
213
215
 
214
- // Complete process
215
- mockProc.stdout.emit('data', Buffer.from('output'));
216
+ // Complete process (NDJSON event)
217
+ const event = JSON.stringify({ type: 'assistant', message: { content: [{ type: 'text', text: 'output' }] } });
218
+ mockProc.stdout.emit('data', Buffer.from(event + '\n'));
216
219
  mockProc.emit('close', 0);
217
220
 
218
221
  const result = await runPromise;
@@ -232,8 +235,9 @@ describe('ClaudeRunner', () => {
232
235
  jest.advanceTimersByTime(1000);
233
236
  expect(mockProc.kill).not.toHaveBeenCalled();
234
237
 
235
- // Complete the process normally before reaching the 60 minute timeout
236
- mockProc.stdout.emit('data', Buffer.from('output'));
238
+ // Complete the process normally before reaching the 60 minute timeout (NDJSON event)
239
+ const event = JSON.stringify({ type: 'assistant', message: { content: [{ type: 'text', text: 'output' }] } });
240
+ mockProc.stdout.emit('data', Buffer.from(event + '\n'));
237
241
  mockProc.emit('close', 0);
238
242
 
239
243
  const result = await runPromise;
@@ -305,8 +309,9 @@ describe('ClaudeRunner', () => {
305
309
  const runner = new ClaudeRunner();
306
310
  const runPromise = runner.run('test prompt', { timeout: 60 });
307
311
 
308
- // Emit context overflow message
309
- mockProc.stdout.emit('data', Buffer.from('Error: context length exceeded'));
312
+ // Emit context overflow message as NDJSON assistant event (run() now uses stream-json)
313
+ const event = JSON.stringify({ type: 'assistant', message: { content: [{ type: 'text', text: 'Error: context length exceeded' }] } });
314
+ mockProc.stdout.emit('data', Buffer.from(event + '\n'));
310
315
 
311
316
  const result = await runPromise;
312
317
  expect(result.contextOverflow).toBe(true);
@@ -333,7 +338,9 @@ describe('ClaudeRunner', () => {
333
338
  const runner = new ClaudeRunner();
334
339
  const runPromise = runner.run('test prompt', { timeout: 60 });
335
340
 
336
- mockProc.stdout.emit('data', Buffer.from(`Error: ${pattern}`));
341
+ // Emit as NDJSON assistant event (run() now uses stream-json)
342
+ const event = JSON.stringify({ type: 'assistant', message: { content: [{ type: 'text', text: `Error: ${pattern}` }] } });
343
+ mockProc.stdout.emit('data', Buffer.from(event + '\n'));
337
344
 
338
345
  const result = await runPromise;
339
346
  expect(result.contextOverflow).toBe(true);
@@ -355,17 +362,18 @@ describe('ClaudeRunner', () => {
355
362
  return proc;
356
363
  }
357
364
 
358
- it('should collect all stdout output', async () => {
365
+ it('should collect all stdout output from NDJSON events', async () => {
359
366
  const mockProc = createMockProcess();
360
367
  mockSpawn.mockReturnValue(mockProc);
361
368
 
362
369
  const runner = new ClaudeRunner();
363
370
  const runPromise = runner.run('test prompt', { timeout: 60 });
364
371
 
365
- // Emit multiple chunks
366
- mockProc.stdout.emit('data', Buffer.from('chunk1'));
367
- mockProc.stdout.emit('data', Buffer.from('chunk2'));
368
- mockProc.stdout.emit('data', Buffer.from('chunk3'));
372
+ // Emit NDJSON assistant events (run() now uses stream-json)
373
+ const event1 = JSON.stringify({ type: 'assistant', message: { content: [{ type: 'text', text: 'chunk1' }] } });
374
+ const event2 = JSON.stringify({ type: 'assistant', message: { content: [{ type: 'text', text: 'chunk2' }] } });
375
+ const event3 = JSON.stringify({ type: 'assistant', message: { content: [{ type: 'text', text: 'chunk3' }] } });
376
+ mockProc.stdout.emit('data', Buffer.from(event1 + '\n' + event2 + '\n' + event3 + '\n'));
369
377
  mockProc.emit('close', 0);
370
378
 
371
379
  const result = await runPromise;
@@ -472,6 +480,109 @@ describe('ClaudeRunner', () => {
472
480
  });
473
481
  });
474
482
 
483
+ describe('effort level', () => {
484
+ function createMockProcess() {
485
+ const stdout = new EventEmitter();
486
+ const stderr = new EventEmitter();
487
+ const proc = new EventEmitter() as any;
488
+ proc.stdout = stdout;
489
+ proc.stderr = stderr;
490
+ proc.kill = jest.fn();
491
+ return proc;
492
+ }
493
+
494
+ it('should set CLAUDE_CODE_EFFORT_LEVEL env var in run() when effortLevel is provided', async () => {
495
+ const mockProc = createMockProcess();
496
+ mockSpawn.mockReturnValue(mockProc);
497
+
498
+ const runner = new ClaudeRunner();
499
+ const runPromise = runner.run('test prompt', { timeout: 60, effortLevel: 'medium' });
500
+
501
+ mockProc.emit('close', 0);
502
+ await runPromise;
503
+
504
+ const spawnOptions = mockSpawn.mock.calls[0][2];
505
+ expect(spawnOptions.env.CLAUDE_CODE_EFFORT_LEVEL).toBe('medium');
506
+ });
507
+
508
+ it('should set CLAUDE_CODE_EFFORT_LEVEL env var in runVerbose() when effortLevel is provided', async () => {
509
+ const mockProc = createMockProcess();
510
+ mockSpawn.mockReturnValue(mockProc);
511
+
512
+ const runner = new ClaudeRunner();
513
+ const runPromise = runner.runVerbose('test prompt', { timeout: 60, effortLevel: 'medium' });
514
+
515
+ mockProc.emit('close', 0);
516
+ await runPromise;
517
+
518
+ const spawnOptions = mockSpawn.mock.calls[0][2];
519
+ expect(spawnOptions.env.CLAUDE_CODE_EFFORT_LEVEL).toBe('medium');
520
+ });
521
+
522
+ it('should NOT set CLAUDE_CODE_EFFORT_LEVEL when effortLevel is not provided in run()', async () => {
523
+ const mockProc = createMockProcess();
524
+ mockSpawn.mockReturnValue(mockProc);
525
+
526
+ const runner = new ClaudeRunner();
527
+ const runPromise = runner.run('test prompt', { timeout: 60 });
528
+
529
+ mockProc.emit('close', 0);
530
+ await runPromise;
531
+
532
+ const spawnOptions = mockSpawn.mock.calls[0][2];
533
+ // env should be process.env directly (no CLAUDE_CODE_EFFORT_LEVEL override)
534
+ expect(spawnOptions.env).toBe(process.env);
535
+ });
536
+
537
+ it('should NOT set CLAUDE_CODE_EFFORT_LEVEL when effortLevel is not provided in runVerbose()', async () => {
538
+ const mockProc = createMockProcess();
539
+ mockSpawn.mockReturnValue(mockProc);
540
+
541
+ const runner = new ClaudeRunner();
542
+ const runPromise = runner.runVerbose('test prompt', { timeout: 60 });
543
+
544
+ mockProc.emit('close', 0);
545
+ await runPromise;
546
+
547
+ const spawnOptions = mockSpawn.mock.calls[0][2];
548
+ // env should be process.env directly (no CLAUDE_CODE_EFFORT_LEVEL override)
549
+ expect(spawnOptions.env).toBe(process.env);
550
+ });
551
+
552
+ it('should support different effort levels', async () => {
553
+ for (const level of ['low', 'medium', 'high'] as const) {
554
+ const mockProc = createMockProcess();
555
+ mockSpawn.mockReturnValue(mockProc);
556
+
557
+ const runner = new ClaudeRunner();
558
+ const runPromise = runner.run('test prompt', { timeout: 60, effortLevel: level });
559
+
560
+ mockProc.emit('close', 0);
561
+ await runPromise;
562
+
563
+ const spawnOptions = mockSpawn.mock.calls[mockSpawn.mock.calls.length - 1][2];
564
+ expect(spawnOptions.env.CLAUDE_CODE_EFFORT_LEVEL).toBe(level);
565
+ }
566
+ });
567
+
568
+ it('should preserve other env vars when effortLevel is set', async () => {
569
+ const mockProc = createMockProcess();
570
+ mockSpawn.mockReturnValue(mockProc);
571
+
572
+ const runner = new ClaudeRunner();
573
+ const runPromise = runner.run('test prompt', { timeout: 60, effortLevel: 'medium' });
574
+
575
+ mockProc.emit('close', 0);
576
+ await runPromise;
577
+
578
+ const spawnOptions = mockSpawn.mock.calls[0][2];
579
+ // Should have PATH from process.env
580
+ expect(spawnOptions.env.PATH).toBe(process.env.PATH);
581
+ // And the injected effort level
582
+ expect(spawnOptions.env.CLAUDE_CODE_EFFORT_LEVEL).toBe('medium');
583
+ });
584
+ });
585
+
475
586
  describe('system prompt append flag', () => {
476
587
  function createMockProcess() {
477
588
  const stdout = new EventEmitter();
@@ -593,7 +704,7 @@ describe('ClaudeRunner', () => {
593
704
  expect(spawnArgs).toContain('--verbose');
594
705
  });
595
706
 
596
- it('should NOT include --output-format or --verbose flags in run()', async () => {
707
+ it('should include --output-format stream-json and --verbose flags in run()', async () => {
597
708
  const mockProc = createMockProcess();
598
709
  mockSpawn.mockReturnValue(mockProc);
599
710
 
@@ -604,9 +715,9 @@ describe('ClaudeRunner', () => {
604
715
  await runPromise;
605
716
 
606
717
  const spawnArgs = mockSpawn.mock.calls[0][1] as string[];
607
- expect(spawnArgs).not.toContain('--output-format');
608
- expect(spawnArgs).not.toContain('stream-json');
609
- expect(spawnArgs).not.toContain('--verbose');
718
+ expect(spawnArgs).toContain('--output-format');
719
+ expect(spawnArgs).toContain('stream-json');
720
+ expect(spawnArgs).toContain('--verbose');
610
721
  });
611
722
 
612
723
  it('should extract text from NDJSON assistant events', async () => {
@@ -693,8 +804,9 @@ describe('ClaudeRunner', () => {
693
804
  jest.advanceTimersByTime(60000);
694
805
  expect(mockProc2.kill).not.toHaveBeenCalled();
695
806
 
696
- // Complete successfully
697
- mockProc2.stdout.emit('data', Buffer.from('success'));
807
+ // Complete successfully (NDJSON event)
808
+ const successEvent = JSON.stringify({ type: 'assistant', message: { content: [{ type: 'text', text: 'success' }] } });
809
+ mockProc2.stdout.emit('data', Buffer.from(successEvent + '\n'));
698
810
  mockProc2.emit('close', 0);
699
811
 
700
812
  const result2 = await runPromise2;
@@ -715,8 +827,9 @@ describe('ClaudeRunner', () => {
715
827
  // Run for 4 minutes (240000ms)
716
828
  jest.advanceTimersByTime(240000);
717
829
 
718
- // Fail without timeout
719
- mockProc1.stdout.emit('data', Buffer.from('<promise>FAILED</promise>'));
830
+ // Fail without timeout (NDJSON event)
831
+ const failEvent = JSON.stringify({ type: 'assistant', message: { content: [{ type: 'text', text: '<promise>FAILED</promise>' }] } });
832
+ mockProc1.stdout.emit('data', Buffer.from(failEvent + '\n'));
720
833
  mockProc1.emit('close', 1);
721
834
 
722
835
  const result1 = await runPromise1;
@@ -766,8 +879,9 @@ describe('ClaudeRunner', () => {
766
879
  const runner = new ClaudeRunner();
767
880
  const runPromise = runner.run('test prompt', { timeout: 60 });
768
881
 
769
- // Emit output with completion marker
770
- mockProc.stdout.emit('data', Buffer.from('Writing outcome...\n<promise>COMPLETE</promise>\n'));
882
+ // Emit output with completion marker (NDJSON event)
883
+ const event = JSON.stringify({ type: 'assistant', message: { content: [{ type: 'text', text: 'Writing outcome...\n<promise>COMPLETE</promise>' }] } });
884
+ mockProc.stdout.emit('data', Buffer.from(event + '\n'));
771
885
 
772
886
  // Process should not be killed immediately
773
887
  expect(mockProc.kill).not.toHaveBeenCalled();
@@ -792,8 +906,9 @@ describe('ClaudeRunner', () => {
792
906
  const runner = new ClaudeRunner();
793
907
  const runPromise = runner.run('test prompt', { timeout: 60 });
794
908
 
795
- // Emit output with failed marker
796
- mockProc.stdout.emit('data', Buffer.from('<promise>FAILED</promise>\nReason: test error'));
909
+ // Emit output with failed marker (NDJSON event)
910
+ const event = JSON.stringify({ type: 'assistant', message: { content: [{ type: 'text', text: '<promise>FAILED</promise>\nReason: test error' }] } });
911
+ mockProc.stdout.emit('data', Buffer.from(event + '\n'));
797
912
 
798
913
  // Advance past grace period
799
914
  jest.advanceTimersByTime(COMPLETION_GRACE_PERIOD_MS + 1);
@@ -810,13 +925,15 @@ describe('ClaudeRunner', () => {
810
925
  const runner = new ClaudeRunner();
811
926
  const runPromise = runner.run('test prompt', { timeout: 60 });
812
927
 
813
- // Emit partial output (no marker yet)
814
- mockProc.stdout.emit('data', Buffer.from('Working on task...\n'));
928
+ // Emit partial output (no marker yet) as NDJSON
929
+ const event1 = JSON.stringify({ type: 'assistant', message: { content: [{ type: 'text', text: 'Working on task...' }] } });
930
+ mockProc.stdout.emit('data', Buffer.from(event1 + '\n'));
815
931
  jest.advanceTimersByTime(10000);
816
932
  expect(mockProc.kill).not.toHaveBeenCalled();
817
933
 
818
- // Emit marker in second chunk
819
- mockProc.stdout.emit('data', Buffer.from('<promise>COMPLETE</promise>\n'));
934
+ // Emit marker in second chunk as NDJSON
935
+ const event2 = JSON.stringify({ type: 'assistant', message: { content: [{ type: 'text', text: '<promise>COMPLETE</promise>' }] } });
936
+ mockProc.stdout.emit('data', Buffer.from(event2 + '\n'));
820
937
 
821
938
  // Grace period starts now - advance past it
822
939
  jest.advanceTimersByTime(COMPLETION_GRACE_PERIOD_MS + 1);
@@ -834,8 +951,9 @@ describe('ClaudeRunner', () => {
834
951
  const runner = new ClaudeRunner();
835
952
  const runPromise = runner.run('test prompt', { timeout: 60 });
836
953
 
837
- // Emit completion marker
838
- mockProc.stdout.emit('data', Buffer.from('<promise>COMPLETE</promise>\n'));
954
+ // Emit completion marker as NDJSON
955
+ const event = JSON.stringify({ type: 'assistant', message: { content: [{ type: 'text', text: '<promise>COMPLETE</promise>' }] } });
956
+ mockProc.stdout.emit('data', Buffer.from(event + '\n'));
839
957
 
840
958
  // Process exits naturally before grace period
841
959
  jest.advanceTimersByTime(5000);
@@ -854,7 +972,7 @@ describe('ClaudeRunner', () => {
854
972
  const mockProc = createMockProcess();
855
973
  mockSpawn.mockReturnValue(mockProc);
856
974
 
857
- const outcomePath = '/test/project/outcomes/001-task.md';
975
+ const outcomePath = '/test/project/outcomes/01-task.md';
858
976
 
859
977
  // Outcome file doesn't exist initially
860
978
  mockExistsSync.mockReturnValue(false);
@@ -865,8 +983,9 @@ describe('ClaudeRunner', () => {
865
983
  outcomeFilePath: outcomePath,
866
984
  });
867
985
 
868
- // No output marker in stdout - just regular output
869
- mockProc.stdout.emit('data', Buffer.from('Working on task...'));
986
+ // No output marker in stdout - just regular output (NDJSON event)
987
+ const event = JSON.stringify({ type: 'assistant', message: { content: [{ type: 'text', text: 'Working on task...' }] } });
988
+ mockProc.stdout.emit('data', Buffer.from(event + '\n'));
870
989
 
871
990
  // After some time, outcome file appears with marker
872
991
  jest.advanceTimersByTime(OUTCOME_POLL_INTERVAL_MS - 1);
@@ -893,7 +1012,7 @@ describe('ClaudeRunner', () => {
893
1012
  mockProc.kill = jest.fn();
894
1013
  mockSpawn.mockReturnValue(mockProc);
895
1014
 
896
- const outcomePath = '/test/project/outcomes/001-task.md';
1015
+ const outcomePath = '/test/project/outcomes/01-task.md';
897
1016
 
898
1017
  // Outcome file already exists from previous failed run
899
1018
  mockExistsSync.mockReturnValue(true);
@@ -910,8 +1029,9 @@ describe('ClaudeRunner', () => {
910
1029
  jest.advanceTimersByTime(OUTCOME_POLL_INTERVAL_MS * 5);
911
1030
  expect(mockProc.kill).not.toHaveBeenCalled();
912
1031
 
913
- // Complete normally
914
- mockProc.stdout.emit('data', Buffer.from('done'));
1032
+ // Complete normally (NDJSON event)
1033
+ const doneEvent = JSON.stringify({ type: 'assistant', message: { content: [{ type: 'text', text: 'done' }] } });
1034
+ mockProc.stdout.emit('data', Buffer.from(doneEvent + '\n'));
915
1035
  mockProc.emit('close', 0);
916
1036
 
917
1037
  await runPromise;
@@ -944,14 +1064,16 @@ describe('ClaudeRunner', () => {
944
1064
  const runner = new ClaudeRunner();
945
1065
  const runPromise = runner.run('test prompt', { timeout: 60 });
946
1066
 
947
- // Emit first marker
948
- mockProc.stdout.emit('data', Buffer.from('<promise>COMPLETE</promise>\n'));
1067
+ // Emit first marker as NDJSON
1068
+ const event1 = JSON.stringify({ type: 'assistant', message: { content: [{ type: 'text', text: '<promise>COMPLETE</promise>' }] } });
1069
+ mockProc.stdout.emit('data', Buffer.from(event1 + '\n'));
949
1070
 
950
1071
  // Advance halfway through grace period
951
1072
  jest.advanceTimersByTime(COMPLETION_GRACE_PERIOD_MS / 2);
952
1073
 
953
- // Emit second marker (e.g., Claude reading back what it wrote)
954
- mockProc.stdout.emit('data', Buffer.from('Verified: <promise>COMPLETE</promise>\n'));
1074
+ // Emit second marker (e.g., Claude reading back what it wrote) as NDJSON
1075
+ const event2 = JSON.stringify({ type: 'assistant', message: { content: [{ type: 'text', text: 'Verified: <promise>COMPLETE</promise>' }] } });
1076
+ mockProc.stdout.emit('data', Buffer.from(event2 + '\n'));
955
1077
 
956
1078
  // Advance remaining grace period from FIRST detection
957
1079
  jest.advanceTimersByTime(COMPLETION_GRACE_PERIOD_MS / 2 + 1);
@@ -981,8 +1103,8 @@ describe('ClaudeRunner', () => {
981
1103
 
982
1104
  const commitContext = {
983
1105
  preExecutionHead: 'aaa111',
984
- expectedPrefix: 'RAF[005:001]',
985
- outcomeFilePath: '/project/outcomes/001-task.md',
1106
+ expectedPrefix: 'RAF[005:01]',
1107
+ outcomeFilePath: '/project/outcomes/01-task.md',
986
1108
  };
987
1109
 
988
1110
  beforeEach(() => {
@@ -998,7 +1120,7 @@ describe('ClaudeRunner', () => {
998
1120
 
999
1121
  // Commit lands during grace period
1000
1122
  mockGetHeadCommitHash.mockReturnValue('bbb222');
1001
- mockGetHeadCommitMessage.mockReturnValue('RAF[005:001] Add feature');
1123
+ mockGetHeadCommitMessage.mockReturnValue('RAF[005:01] Add feature');
1002
1124
  mockIsFileCommittedInHead.mockReturnValue(true);
1003
1125
 
1004
1126
  const runner = new ClaudeRunner();
@@ -1007,8 +1129,9 @@ describe('ClaudeRunner', () => {
1007
1129
  commitContext,
1008
1130
  });
1009
1131
 
1010
- // Emit COMPLETE marker
1011
- mockProc.stdout.emit('data', Buffer.from('<promise>COMPLETE</promise>\n'));
1132
+ // Emit COMPLETE marker as NDJSON
1133
+ const event = JSON.stringify({ type: 'assistant', message: { content: [{ type: 'text', text: '<promise>COMPLETE</promise>' }] } });
1134
+ mockProc.stdout.emit('data', Buffer.from(event + '\n'));
1012
1135
 
1013
1136
  // Advance to grace period expiry - commit already verified
1014
1137
  jest.advanceTimersByTime(COMPLETION_GRACE_PERIOD_MS + 1);
@@ -1032,8 +1155,9 @@ describe('ClaudeRunner', () => {
1032
1155
  commitContext,
1033
1156
  });
1034
1157
 
1035
- // Emit COMPLETE marker
1036
- mockProc.stdout.emit('data', Buffer.from('<promise>COMPLETE</promise>\n'));
1158
+ // Emit COMPLETE marker as NDJSON
1159
+ const event = JSON.stringify({ type: 'assistant', message: { content: [{ type: 'text', text: '<promise>COMPLETE</promise>' }] } });
1160
+ mockProc.stdout.emit('data', Buffer.from(event + '\n'));
1037
1161
 
1038
1162
  // Advance past initial grace period - commit not found, should extend
1039
1163
  jest.advanceTimersByTime(COMPLETION_GRACE_PERIOD_MS + 1);
@@ -1042,7 +1166,7 @@ describe('ClaudeRunner', () => {
1042
1166
 
1043
1167
  // Now simulate commit landing during extended polling
1044
1168
  mockGetHeadCommitHash.mockReturnValue('bbb222');
1045
- mockGetHeadCommitMessage.mockReturnValue('RAF[005:001] Add feature');
1169
+ mockGetHeadCommitMessage.mockReturnValue('RAF[005:01] Add feature');
1046
1170
  mockIsFileCommittedInHead.mockReturnValue(true);
1047
1171
 
1048
1172
  // Advance to next commit poll interval
@@ -1067,8 +1191,9 @@ describe('ClaudeRunner', () => {
1067
1191
  commitContext,
1068
1192
  });
1069
1193
 
1070
- // Emit COMPLETE marker
1071
- mockProc.stdout.emit('data', Buffer.from('<promise>COMPLETE</promise>\n'));
1194
+ // Emit COMPLETE marker as NDJSON
1195
+ const event = JSON.stringify({ type: 'assistant', message: { content: [{ type: 'text', text: '<promise>COMPLETE</promise>' }] } });
1196
+ mockProc.stdout.emit('data', Buffer.from(event + '\n'));
1072
1197
 
1073
1198
  // Advance past initial grace period
1074
1199
  jest.advanceTimersByTime(COMPLETION_GRACE_PERIOD_MS + 1);
@@ -1094,8 +1219,9 @@ describe('ClaudeRunner', () => {
1094
1219
  commitContext,
1095
1220
  });
1096
1221
 
1097
- // Emit FAILED marker (not COMPLETE)
1098
- mockProc.stdout.emit('data', Buffer.from('<promise>FAILED</promise>\n'));
1222
+ // Emit FAILED marker (not COMPLETE) as NDJSON
1223
+ const event = JSON.stringify({ type: 'assistant', message: { content: [{ type: 'text', text: '<promise>FAILED</promise>' }] } });
1224
+ mockProc.stdout.emit('data', Buffer.from(event + '\n'));
1099
1225
 
1100
1226
  // Grace period should expire normally without extension
1101
1227
  jest.advanceTimersByTime(COMPLETION_GRACE_PERIOD_MS + 1);
@@ -1114,8 +1240,9 @@ describe('ClaudeRunner', () => {
1114
1240
  // No commitContext provided
1115
1241
  });
1116
1242
 
1117
- // Emit COMPLETE marker
1118
- mockProc.stdout.emit('data', Buffer.from('<promise>COMPLETE</promise>\n'));
1243
+ // Emit COMPLETE marker as NDJSON
1244
+ const event = JSON.stringify({ type: 'assistant', message: { content: [{ type: 'text', text: '<promise>COMPLETE</promise>' }] } });
1245
+ mockProc.stdout.emit('data', Buffer.from(event + '\n'));
1119
1246
 
1120
1247
  // Grace period should expire normally (no commit check)
1121
1248
  jest.advanceTimersByTime(COMPLETION_GRACE_PERIOD_MS + 1);
@@ -1131,7 +1258,7 @@ describe('ClaudeRunner', () => {
1131
1258
 
1132
1259
  // HEAD changed but message doesn't match expected prefix
1133
1260
  mockGetHeadCommitHash.mockReturnValue('bbb222');
1134
- mockGetHeadCommitMessage.mockReturnValue('RAF[005:002] Wrong task');
1261
+ mockGetHeadCommitMessage.mockReturnValue('RAF[005:02] Wrong task');
1135
1262
  mockIsFileCommittedInHead.mockReturnValue(true);
1136
1263
 
1137
1264
  const runner = new ClaudeRunner();
@@ -1140,15 +1267,16 @@ describe('ClaudeRunner', () => {
1140
1267
  commitContext,
1141
1268
  });
1142
1269
 
1143
- // Emit COMPLETE marker
1144
- mockProc.stdout.emit('data', Buffer.from('<promise>COMPLETE</promise>\n'));
1270
+ // Emit COMPLETE marker as NDJSON
1271
+ const event = JSON.stringify({ type: 'assistant', message: { content: [{ type: 'text', text: '<promise>COMPLETE</promise>' }] } });
1272
+ mockProc.stdout.emit('data', Buffer.from(event + '\n'));
1145
1273
 
1146
1274
  // Grace period expires - commit message doesn't match, should extend
1147
1275
  jest.advanceTimersByTime(COMPLETION_GRACE_PERIOD_MS + 1);
1148
1276
  expect(mockProc.kill).not.toHaveBeenCalled();
1149
1277
 
1150
1278
  // Fix commit message
1151
- mockGetHeadCommitMessage.mockReturnValue('RAF[005:001] Correct task');
1279
+ mockGetHeadCommitMessage.mockReturnValue('RAF[005:01] Correct task');
1152
1280
 
1153
1281
  // Next poll finds it
1154
1282
  jest.advanceTimersByTime(COMMIT_POLL_INTERVAL_MS);
@@ -1165,7 +1293,7 @@ describe('ClaudeRunner', () => {
1165
1293
 
1166
1294
  // HEAD changed and message matches, but file not committed
1167
1295
  mockGetHeadCommitHash.mockReturnValue('bbb222');
1168
- mockGetHeadCommitMessage.mockReturnValue('RAF[005:001] Add feature');
1296
+ mockGetHeadCommitMessage.mockReturnValue('RAF[005:01] Add feature');
1169
1297
  mockIsFileCommittedInHead.mockReturnValue(false);
1170
1298
 
1171
1299
  const runner = new ClaudeRunner();
@@ -1174,8 +1302,9 @@ describe('ClaudeRunner', () => {
1174
1302
  commitContext,
1175
1303
  });
1176
1304
 
1177
- // Emit COMPLETE marker
1178
- mockProc.stdout.emit('data', Buffer.from('<promise>COMPLETE</promise>\n'));
1305
+ // Emit COMPLETE marker as NDJSON
1306
+ const event = JSON.stringify({ type: 'assistant', message: { content: [{ type: 'text', text: '<promise>COMPLETE</promise>' }] } });
1307
+ mockProc.stdout.emit('data', Buffer.from(event + '\n'));
1179
1308
 
1180
1309
  // Grace period expires - file not committed, should extend
1181
1310
  jest.advanceTimersByTime(COMPLETION_GRACE_PERIOD_MS + 1);
@@ -1192,4 +1321,329 @@ describe('ClaudeRunner', () => {
1192
1321
  await runPromise;
1193
1322
  });
1194
1323
  });
1324
+
1325
+ describe('session ID extraction', () => {
1326
+ function createMockProcess() {
1327
+ const stdout = new EventEmitter();
1328
+ const stderr = new EventEmitter();
1329
+ const proc = new EventEmitter() as any;
1330
+ proc.stdout = stdout;
1331
+ proc.stderr = stderr;
1332
+ proc.kill = jest.fn();
1333
+ return proc;
1334
+ }
1335
+
1336
+ it('should extract sessionId from system init event in run()', async () => {
1337
+ const mockProc = createMockProcess();
1338
+ mockSpawn.mockReturnValue(mockProc);
1339
+
1340
+ const runner = new ClaudeRunner();
1341
+ const runPromise = runner.run('test prompt', { timeout: 60 });
1342
+
1343
+ // Emit system init event with session_id
1344
+ const initEvent = JSON.stringify({
1345
+ type: 'system',
1346
+ subtype: 'init',
1347
+ session_id: 'test-session-123',
1348
+ tools: ['Read', 'Write'],
1349
+ model: 'claude-opus-4-6',
1350
+ });
1351
+ const textEvent = JSON.stringify({
1352
+ type: 'assistant',
1353
+ message: { content: [{ type: 'text', text: 'done' }] },
1354
+ });
1355
+ mockProc.stdout.emit('data', Buffer.from(initEvent + '\n' + textEvent + '\n'));
1356
+ mockProc.emit('close', 0);
1357
+
1358
+ const result = await runPromise;
1359
+ expect(result.sessionId).toBe('test-session-123');
1360
+ });
1361
+
1362
+ it('should extract sessionId from system init event in runVerbose()', async () => {
1363
+ const mockProc = createMockProcess();
1364
+ mockSpawn.mockReturnValue(mockProc);
1365
+
1366
+ const runner = new ClaudeRunner();
1367
+ const runPromise = runner.runVerbose('test prompt', { timeout: 60 });
1368
+
1369
+ // Emit system init event with session_id
1370
+ const initEvent = JSON.stringify({
1371
+ type: 'system',
1372
+ subtype: 'init',
1373
+ session_id: 'verbose-session-456',
1374
+ tools: ['Read', 'Write'],
1375
+ model: 'claude-opus-4-6',
1376
+ });
1377
+ mockProc.stdout.emit('data', Buffer.from(initEvent + '\n'));
1378
+ mockProc.emit('close', 0);
1379
+
1380
+ const result = await runPromise;
1381
+ expect(result.sessionId).toBe('verbose-session-456');
1382
+ });
1383
+
1384
+ it('should return undefined sessionId when no system init event', async () => {
1385
+ const mockProc = createMockProcess();
1386
+ mockSpawn.mockReturnValue(mockProc);
1387
+
1388
+ const runner = new ClaudeRunner();
1389
+ const runPromise = runner.run('test prompt', { timeout: 60 });
1390
+
1391
+ // Only emit assistant event, no system init
1392
+ const textEvent = JSON.stringify({
1393
+ type: 'assistant',
1394
+ message: { content: [{ type: 'text', text: 'output' }] },
1395
+ });
1396
+ mockProc.stdout.emit('data', Buffer.from(textEvent + '\n'));
1397
+ mockProc.emit('close', 0);
1398
+
1399
+ const result = await runPromise;
1400
+ expect(result.sessionId).toBeUndefined();
1401
+ });
1402
+
1403
+ it('should expose sessionId via getter on ClaudeRunner', async () => {
1404
+ const mockProc = createMockProcess();
1405
+ mockSpawn.mockReturnValue(mockProc);
1406
+
1407
+ const runner = new ClaudeRunner();
1408
+ expect(runner.sessionId).toBeUndefined();
1409
+
1410
+ const runPromise = runner.run('test prompt', { timeout: 60 });
1411
+
1412
+ const initEvent = JSON.stringify({
1413
+ type: 'system',
1414
+ subtype: 'init',
1415
+ session_id: 'getter-session-789',
1416
+ tools: [],
1417
+ model: 'claude-opus-4-6',
1418
+ });
1419
+ mockProc.stdout.emit('data', Buffer.from(initEvent + '\n'));
1420
+ mockProc.emit('close', 0);
1421
+
1422
+ await runPromise;
1423
+ expect(runner.sessionId).toBe('getter-session-789');
1424
+ });
1425
+
1426
+ it('should only capture the first sessionId (ignore duplicates)', async () => {
1427
+ const mockProc = createMockProcess();
1428
+ mockSpawn.mockReturnValue(mockProc);
1429
+
1430
+ const runner = new ClaudeRunner();
1431
+ const runPromise = runner.run('test prompt', { timeout: 60 });
1432
+
1433
+ // Emit two system init events (shouldn't happen but test robustness)
1434
+ const init1 = JSON.stringify({ type: 'system', subtype: 'init', session_id: 'first-session' });
1435
+ const init2 = JSON.stringify({ type: 'system', subtype: 'init', session_id: 'second-session' });
1436
+ mockProc.stdout.emit('data', Buffer.from(init1 + '\n' + init2 + '\n'));
1437
+ mockProc.emit('close', 0);
1438
+
1439
+ const result = await runPromise;
1440
+ expect(result.sessionId).toBe('first-session');
1441
+ });
1442
+ });
1443
+
1444
+ describe('runResume()', () => {
1445
+ function createMockProcess() {
1446
+ const stdout = new EventEmitter();
1447
+ const stderr = new EventEmitter();
1448
+ const proc = new EventEmitter() as any;
1449
+ proc.stdout = stdout;
1450
+ proc.stderr = stderr;
1451
+ proc.kill = jest.fn().mockImplementation(() => {
1452
+ setImmediate(() => proc.emit('close', 1));
1453
+ });
1454
+ return proc;
1455
+ }
1456
+
1457
+ it('should spawn Claude with --resume flag and session ID', async () => {
1458
+ const mockProc = createMockProcess();
1459
+ mockProc.kill = jest.fn();
1460
+ mockSpawn.mockReturnValue(mockProc);
1461
+
1462
+ const runner = new ClaudeRunner();
1463
+ const runPromise = runner.runResume('test-session-abc', { timeout: 60 });
1464
+
1465
+ const event = JSON.stringify({ type: 'assistant', message: { content: [{ type: 'text', text: 'resumed output' }] } });
1466
+ mockProc.stdout.emit('data', Buffer.from(event + '\n'));
1467
+ mockProc.emit('close', 0);
1468
+
1469
+ await runPromise;
1470
+
1471
+ const spawnArgs = mockSpawn.mock.calls[0][1] as string[];
1472
+ expect(spawnArgs).toContain('--resume');
1473
+ expect(spawnArgs).toContain('test-session-abc');
1474
+
1475
+ // Verify --resume comes before the session ID
1476
+ const resumeIndex = spawnArgs.indexOf('--resume');
1477
+ expect(spawnArgs[resumeIndex + 1]).toBe('test-session-abc');
1478
+ });
1479
+
1480
+ it('should NOT include --model, --append-system-prompt, or -p flags', async () => {
1481
+ const mockProc = createMockProcess();
1482
+ mockProc.kill = jest.fn();
1483
+ mockSpawn.mockReturnValue(mockProc);
1484
+
1485
+ const runner = new ClaudeRunner({ model: 'sonnet' });
1486
+ const runPromise = runner.runResume('session-123', { timeout: 60 });
1487
+
1488
+ mockProc.emit('close', 0);
1489
+ await runPromise;
1490
+
1491
+ const spawnArgs = mockSpawn.mock.calls[0][1] as string[];
1492
+ expect(spawnArgs).not.toContain('--model');
1493
+ expect(spawnArgs).not.toContain('--append-system-prompt');
1494
+ expect(spawnArgs).not.toContain('-p');
1495
+ });
1496
+
1497
+ it('should include --dangerously-skip-permissions flag', async () => {
1498
+ const mockProc = createMockProcess();
1499
+ mockProc.kill = jest.fn();
1500
+ mockSpawn.mockReturnValue(mockProc);
1501
+
1502
+ const runner = new ClaudeRunner();
1503
+ const runPromise = runner.runResume('session-123', { timeout: 60 });
1504
+
1505
+ mockProc.emit('close', 0);
1506
+ await runPromise;
1507
+
1508
+ const spawnArgs = mockSpawn.mock.calls[0][1] as string[];
1509
+ expect(spawnArgs).toContain('--dangerously-skip-permissions');
1510
+ });
1511
+
1512
+ it('should include --output-format stream-json and --verbose flags', async () => {
1513
+ const mockProc = createMockProcess();
1514
+ mockProc.kill = jest.fn();
1515
+ mockSpawn.mockReturnValue(mockProc);
1516
+
1517
+ const runner = new ClaudeRunner();
1518
+ const runPromise = runner.runResume('session-123', { timeout: 60 });
1519
+
1520
+ mockProc.emit('close', 0);
1521
+ await runPromise;
1522
+
1523
+ const spawnArgs = mockSpawn.mock.calls[0][1] as string[];
1524
+ expect(spawnArgs).toContain('--output-format');
1525
+ expect(spawnArgs).toContain('stream-json');
1526
+ expect(spawnArgs).toContain('--verbose');
1527
+ });
1528
+
1529
+ it('should collect output from NDJSON events', async () => {
1530
+ const mockProc = createMockProcess();
1531
+ mockProc.kill = jest.fn();
1532
+ mockSpawn.mockReturnValue(mockProc);
1533
+
1534
+ const runner = new ClaudeRunner();
1535
+ const runPromise = runner.runResume('session-123', { timeout: 60 });
1536
+
1537
+ const event1 = JSON.stringify({ type: 'assistant', message: { content: [{ type: 'text', text: 'chunk1' }] } });
1538
+ const event2 = JSON.stringify({ type: 'assistant', message: { content: [{ type: 'text', text: 'chunk2' }] } });
1539
+ mockProc.stdout.emit('data', Buffer.from(event1 + '\n' + event2 + '\n'));
1540
+ mockProc.emit('close', 0);
1541
+
1542
+ const result = await runPromise;
1543
+ expect(result.output).toBe('chunk1chunk2');
1544
+ });
1545
+
1546
+ it('should handle timeout correctly', async () => {
1547
+ const mockProc = createMockProcess();
1548
+ mockSpawn.mockReturnValue(mockProc);
1549
+
1550
+ const runner = new ClaudeRunner();
1551
+ const runPromise = runner.runResume('session-123', { timeout: 5 }); // 5 minutes
1552
+
1553
+ // Fast forward past timeout
1554
+ jest.advanceTimersByTime(300001);
1555
+ expect(mockProc.kill).toHaveBeenCalledWith('SIGTERM');
1556
+
1557
+ const result = await runPromise;
1558
+ expect(result.timedOut).toBe(true);
1559
+ });
1560
+
1561
+ it('should detect completion markers', async () => {
1562
+ const mockProc = createMockProcess();
1563
+ mockSpawn.mockReturnValue(mockProc);
1564
+
1565
+ const runner = new ClaudeRunner();
1566
+ const runPromise = runner.runResume('session-123', { timeout: 60 });
1567
+
1568
+ const event = JSON.stringify({ type: 'assistant', message: { content: [{ type: 'text', text: '<promise>COMPLETE</promise>' }] } });
1569
+ mockProc.stdout.emit('data', Buffer.from(event + '\n'));
1570
+
1571
+ // Grace period should start
1572
+ expect(mockProc.kill).not.toHaveBeenCalled();
1573
+ jest.advanceTimersByTime(COMPLETION_GRACE_PERIOD_MS + 1);
1574
+ expect(mockProc.kill).toHaveBeenCalledWith('SIGTERM');
1575
+
1576
+ await runPromise;
1577
+ });
1578
+
1579
+ it('should extract session ID from resumed session', async () => {
1580
+ const mockProc = createMockProcess();
1581
+ mockProc.kill = jest.fn();
1582
+ mockSpawn.mockReturnValue(mockProc);
1583
+
1584
+ const runner = new ClaudeRunner();
1585
+ const runPromise = runner.runResume('old-session-123', { timeout: 60 });
1586
+
1587
+ const initEvent = JSON.stringify({ type: 'system', subtype: 'init', session_id: 'new-session-456' });
1588
+ const textEvent = JSON.stringify({ type: 'assistant', message: { content: [{ type: 'text', text: 'done' }] } });
1589
+ mockProc.stdout.emit('data', Buffer.from(initEvent + '\n' + textEvent + '\n'));
1590
+ mockProc.emit('close', 0);
1591
+
1592
+ const result = await runPromise;
1593
+ expect(result.sessionId).toBe('new-session-456');
1594
+ expect(runner.sessionId).toBe('new-session-456');
1595
+ });
1596
+
1597
+ it('should pass cwd to spawn', async () => {
1598
+ const mockProc = createMockProcess();
1599
+ mockProc.kill = jest.fn();
1600
+ mockSpawn.mockReturnValue(mockProc);
1601
+
1602
+ const runner = new ClaudeRunner();
1603
+ const runPromise = runner.runResume('session-123', { timeout: 60, cwd: '/worktree/path' });
1604
+
1605
+ mockProc.emit('close', 0);
1606
+ await runPromise;
1607
+
1608
+ expect(mockSpawn).toHaveBeenCalledWith(
1609
+ expect.any(String),
1610
+ expect.any(Array),
1611
+ expect.objectContaining({ cwd: '/worktree/path' })
1612
+ );
1613
+ });
1614
+
1615
+ it('should detect context overflow', async () => {
1616
+ jest.useRealTimers();
1617
+
1618
+ const mockProc = createMockProcess();
1619
+ mockSpawn.mockReturnValue(mockProc);
1620
+
1621
+ const runner = new ClaudeRunner();
1622
+ const runPromise = runner.runResume('session-123', { timeout: 60 });
1623
+
1624
+ const event = JSON.stringify({ type: 'assistant', message: { content: [{ type: 'text', text: 'Error: context length exceeded' }] } });
1625
+ mockProc.stdout.emit('data', Buffer.from(event + '\n'));
1626
+
1627
+ const result = await runPromise;
1628
+ expect(result.contextOverflow).toBe(true);
1629
+ expect(mockProc.kill).toHaveBeenCalledWith('SIGTERM');
1630
+
1631
+ jest.useFakeTimers();
1632
+ });
1633
+
1634
+ it('should set CLAUDE_CODE_EFFORT_LEVEL env var when effortLevel is provided', async () => {
1635
+ const mockProc = createMockProcess();
1636
+ mockProc.kill = jest.fn();
1637
+ mockSpawn.mockReturnValue(mockProc);
1638
+
1639
+ const runner = new ClaudeRunner();
1640
+ const runPromise = runner.runResume('session-123', { timeout: 60, effortLevel: 'medium' });
1641
+
1642
+ mockProc.emit('close', 0);
1643
+ await runPromise;
1644
+
1645
+ const spawnOptions = mockSpawn.mock.calls[0][2];
1646
+ expect(spawnOptions.env.CLAUDE_CODE_EFFORT_LEVEL).toBe('medium');
1647
+ });
1648
+ });
1195
1649
  });