rafcode 1.0.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 (370) hide show
  1. package/.claude/settings.local.json +32 -0
  2. package/CLAUDE.md +187 -0
  3. package/LICENSE +21 -0
  4. package/RAF/001-raf-task-improvements/input.md +9 -0
  5. package/RAF/001-raf-task-improvements/outcomes/001-add-decisions-folder.md +21 -0
  6. package/RAF/001-raf-task-improvements/outcomes/002-fix-write-error-on-shutdown.md +22 -0
  7. package/RAF/001-raf-task-improvements/outcomes/003-stash-changes-on-failure.md +34 -0
  8. package/RAF/001-raf-task-improvements/outcomes/004-add-project-name-to-commits.md +28 -0
  9. package/RAF/001-raf-task-improvements/outcomes/005-add-running-time-display.md +36 -0
  10. package/RAF/001-raf-task-improvements/outcomes/006-add-task-name-to-logs.md +22 -0
  11. package/RAF/001-raf-task-improvements/outcomes/007-show-model-at-task-start.md +52 -0
  12. package/RAF/001-raf-task-improvements/outcomes/009-remove-editor-placeholder-text.md +20 -0
  13. package/RAF/001-raf-task-improvements/outcomes/SUMMARY.md +83 -0
  14. package/RAF/001-raf-task-improvements/plans/001-add-decisions-folder.md +38 -0
  15. package/RAF/001-raf-task-improvements/plans/002-fix-write-error-on-shutdown.md +33 -0
  16. package/RAF/001-raf-task-improvements/plans/003-stash-changes-on-failure.md +37 -0
  17. package/RAF/001-raf-task-improvements/plans/004-add-project-name-to-commits.md +34 -0
  18. package/RAF/001-raf-task-improvements/plans/005-add-running-time-display.md +39 -0
  19. package/RAF/001-raf-task-improvements/plans/006-add-task-name-to-logs.md +37 -0
  20. package/RAF/001-raf-task-improvements/plans/009-remove-editor-placeholder-text.md +34 -0
  21. package/RAF/002-raf-task-improvements-execution/decisions/DECISIONS.md +13 -0
  22. package/RAF/002-raf-task-improvements-execution/input.md +3 -0
  23. package/RAF/002-raf-task-improvements-execution/outcomes/001-commit-show-model-at-task-start.md +17 -0
  24. package/RAF/002-raf-task-improvements-execution/outcomes/002-delete-skipped-plan.md +23 -0
  25. package/RAF/002-raf-task-improvements-execution/outcomes/SUMMARY.md +32 -0
  26. package/RAF/002-raf-task-improvements-execution/plans/001-commit-show-model-at-task-start.md +37 -0
  27. package/RAF/002-raf-task-improvements-execution/plans/002-delete-skipped-plan.md +23 -0
  28. package/RAF/003-multi-project-execution/decisions/DECISIONS.md +68 -0
  29. package/RAF/003-multi-project-execution/input.md +6 -0
  30. package/RAF/003-multi-project-execution/outcomes/001-remove-state-json.md +52 -0
  31. package/RAF/003-multi-project-execution/outcomes/002-update-raf-status.md +50 -0
  32. package/RAF/003-multi-project-execution/outcomes/003-simplify-git-logic.md +35 -0
  33. package/RAF/003-multi-project-execution/outcomes/004-auto-commit-planning.md +43 -0
  34. package/RAF/003-multi-project-execution/outcomes/005-rerun-failed-tasks.md +43 -0
  35. package/RAF/003-multi-project-execution/outcomes/006-multi-project-execution.md +42 -0
  36. package/RAF/003-multi-project-execution/outcomes/007-verify-timeout.md +54 -0
  37. package/RAF/003-multi-project-execution/outcomes/008-move-decisions-file.md +38 -0
  38. package/RAF/003-multi-project-execution/outcomes/SUMMARY.md +79 -0
  39. package/RAF/003-multi-project-execution/plans/001-remove-state-json.md +71 -0
  40. package/RAF/003-multi-project-execution/plans/002-update-raf-status.md +65 -0
  41. package/RAF/003-multi-project-execution/plans/003-simplify-git-logic.md +74 -0
  42. package/RAF/003-multi-project-execution/plans/004-auto-commit-planning.md +57 -0
  43. package/RAF/003-multi-project-execution/plans/005-rerun-failed-tasks.md +69 -0
  44. package/RAF/003-multi-project-execution/plans/006-multi-project-execution.md +81 -0
  45. package/RAF/003-multi-project-execution/plans/007-verify-timeout.md +63 -0
  46. package/RAF/003-multi-project-execution/plans/008-move-decisions-file.md +78 -0
  47. package/RAF/004-task-naming-optimization/decisions.md +22 -0
  48. package/RAF/004-task-naming-optimization/input.md +6 -0
  49. package/RAF/004-task-naming-optimization/outcomes/001-remove-summary-file.md +17 -0
  50. package/RAF/004-task-naming-optimization/outcomes/002-base36-project-numbering.md +32 -0
  51. package/RAF/004-task-naming-optimization/outcomes/003-improve-haiku-prompt.md +20 -0
  52. package/RAF/004-task-naming-optimization/outcomes/SUMMARY.md +28 -0
  53. package/RAF/004-task-naming-optimization/plans/001-remove-summary-file.md +34 -0
  54. package/RAF/004-task-naming-optimization/plans/002-base36-project-numbering.md +56 -0
  55. package/RAF/004-task-naming-optimization/plans/003-improve-haiku-prompt.md +50 -0
  56. package/RAF/005-task-naming-improvements/decisions.md +60 -0
  57. package/RAF/005-task-naming-improvements/input.md +2 -0
  58. package/RAF/005-task-naming-improvements/outcomes/001-enhance-identifier-resolution.md +42 -0
  59. package/RAF/005-task-naming-improvements/outcomes/002-add-identifier-support-to-status.md +38 -0
  60. package/RAF/005-task-naming-improvements/outcomes/003-update-do-for-full-folder-names.md +44 -0
  61. package/RAF/005-task-naming-improvements/outcomes/004-implement-amend-flag-for-plan.md +55 -0
  62. package/RAF/005-task-naming-improvements/outcomes/005-commit-outcomes-on-complete.md +47 -0
  63. package/RAF/005-task-naming-improvements/outcomes/006-update-execution-prompt-commit-schema.md +40 -0
  64. package/RAF/005-task-naming-improvements/outcomes/007-allow-pending-task-amendments.md +38 -0
  65. package/RAF/005-task-naming-improvements/outcomes/008-fix-timeout-label.md +24 -0
  66. package/RAF/005-task-naming-improvements/plans/001-enhance-identifier-resolution.md +46 -0
  67. package/RAF/005-task-naming-improvements/plans/002-add-identifier-support-to-status.md +36 -0
  68. package/RAF/005-task-naming-improvements/plans/003-update-do-for-full-folder-names.md +38 -0
  69. package/RAF/005-task-naming-improvements/plans/004-implement-amend-flag-for-plan.md +67 -0
  70. package/RAF/005-task-naming-improvements/plans/005-commit-outcomes-on-complete.md +86 -0
  71. package/RAF/005-task-naming-improvements/plans/006-update-execution-prompt-commit-schema.md +60 -0
  72. package/RAF/005-task-naming-improvements/plans/007-allow-pending-task-amendments.md +60 -0
  73. package/RAF/005-task-naming-improvements/plans/008-fix-timeout-label.md +31 -0
  74. package/RAF/006-fix-double-summary-headers/decisions.md +28 -0
  75. package/RAF/006-fix-double-summary-headers/input.md +3 -0
  76. package/RAF/006-fix-double-summary-headers/outcomes/001-fix-double-summary-headers.md +29 -0
  77. package/RAF/006-fix-double-summary-headers/outcomes/002-update-readme-for-npm.md +31 -0
  78. package/RAF/006-fix-double-summary-headers/outcomes/003-npm-publish-instructions.md +30 -0
  79. package/RAF/006-fix-double-summary-headers/outcomes/004-flexible-project-lookup.md +47 -0
  80. package/RAF/006-fix-double-summary-headers/plans/001-fix-double-summary-headers.md +42 -0
  81. package/RAF/006-fix-double-summary-headers/plans/002-update-readme-for-npm.md +44 -0
  82. package/RAF/006-fix-double-summary-headers/plans/003-npm-publish-instructions.md +45 -0
  83. package/RAF/006-fix-double-summary-headers/plans/004-flexible-project-lookup.md +40 -0
  84. package/RAF/007-improve-outcome-format/decisions.md +28 -0
  85. package/RAF/007-improve-outcome-format/input.md +2 -0
  86. package/RAF/007-improve-outcome-format/outcomes/001-update-execution-prompt.md +10 -0
  87. package/RAF/007-improve-outcome-format/outcomes/002-update-state-derivation.md +17 -0
  88. package/RAF/007-improve-outcome-format/outcomes/003-update-do-command-outcome-handling.md +16 -0
  89. package/RAF/007-improve-outcome-format/outcomes/004-implement-failure-analysis.md +16 -0
  90. package/RAF/007-improve-outcome-format/outcomes/005-update-documentation.md +15 -0
  91. package/RAF/007-improve-outcome-format/plans/001-update-execution-prompt.md +36 -0
  92. package/RAF/007-improve-outcome-format/plans/002-update-state-derivation.md +35 -0
  93. package/RAF/007-improve-outcome-format/plans/003-update-do-command-outcome-handling.md +37 -0
  94. package/RAF/007-improve-outcome-format/plans/004-implement-failure-analysis.md +44 -0
  95. package/RAF/007-improve-outcome-format/plans/005-update-documentation.md +33 -0
  96. package/RAF/008-beautiful-do/decisions.md +31 -0
  97. package/RAF/008-beautiful-do/input.md +1 -0
  98. package/RAF/008-beautiful-do/outcomes/001-terminal-symbols.md +55 -0
  99. package/RAF/008-beautiful-do/outcomes/002-refactor-do-output.md +95 -0
  100. package/RAF/008-beautiful-do/outcomes/003-refactor-status-output.md +71 -0
  101. package/RAF/008-beautiful-do/outcomes/004-simplify-logger.md +53 -0
  102. package/RAF/008-beautiful-do/outcomes/005-add-tests.md +41 -0
  103. package/RAF/008-beautiful-do/plans/001-terminal-symbols.md +41 -0
  104. package/RAF/008-beautiful-do/plans/002-refactor-do-output.md +44 -0
  105. package/RAF/008-beautiful-do/plans/003-refactor-status-output.md +37 -0
  106. package/RAF/008-beautiful-do/plans/004-simplify-logger.md +32 -0
  107. package/RAF/008-beautiful-do/plans/005-add-tests.md +40 -0
  108. package/RAF/009-system-promt-ammend/decisions.md +13 -0
  109. package/RAF/009-system-promt-ammend/input.md +9 -0
  110. package/RAF/009-system-promt-ammend/outcomes/001-model-override.md +79 -0
  111. package/RAF/009-system-promt-ammend/outcomes/002-system-prompt-append.md +51 -0
  112. package/RAF/009-system-promt-ammend/outcomes/003-retry-context.md +60 -0
  113. package/RAF/009-system-promt-ammend/plans/001-model-override.md +61 -0
  114. package/RAF/009-system-promt-ammend/plans/002-system-prompt-append.md +56 -0
  115. package/RAF/009-system-promt-ammend/plans/003-retry-context.md +76 -0
  116. package/RAF/010-outcome-marker-fallback/decisions.md +19 -0
  117. package/RAF/010-outcome-marker-fallback/input.md +1 -0
  118. package/RAF/010-outcome-marker-fallback/outcomes/001-outcome-file-marker-fallback.md +35 -0
  119. package/RAF/010-outcome-marker-fallback/outcomes/002-creative-project-naming.md +47 -0
  120. package/RAF/010-outcome-marker-fallback/plans/001-outcome-file-marker-fallback.md +58 -0
  121. package/RAF/010-outcome-marker-fallback/plans/002-creative-project-naming.md +68 -0
  122. package/RAF/011-do-task-in-commit/decisions.md +22 -0
  123. package/RAF/011-do-task-in-commit/input.md +1 -0
  124. package/RAF/011-do-task-in-commit/outcomes/001-update-execution-prompt.md +54 -0
  125. package/RAF/011-do-task-in-commit/outcomes/002-update-tests.md +61 -0
  126. package/RAF/011-do-task-in-commit/outcomes/003-update-documentation.md +51 -0
  127. package/RAF/011-do-task-in-commit/plans/001-update-execution-prompt.md +46 -0
  128. package/RAF/011-do-task-in-commit/plans/002-update-tests.md +51 -0
  129. package/RAF/011-do-task-in-commit/plans/003-update-documentation.md +45 -0
  130. package/RAF/012-name-picker-buffet/decisions.md +40 -0
  131. package/RAF/012-name-picker-buffet/input.md +6 -0
  132. package/RAF/012-name-picker-buffet/outcomes/001-name-picker-for-raf-plan.md +49 -0
  133. package/RAF/012-name-picker-buffet/outcomes/002-interactive-project-picker-for-raf-do.md +49 -0
  134. package/RAF/012-name-picker-buffet/outcomes/003-raf-status-truncation.md +55 -0
  135. package/RAF/012-name-picker-buffet/outcomes/004-failure-reason-details.md +65 -0
  136. package/RAF/012-name-picker-buffet/outcomes/005-remove-raf-commits.md +57 -0
  137. package/RAF/012-name-picker-buffet/outcomes/006-update-execution-prompt-for-commits.md +47 -0
  138. package/RAF/012-name-picker-buffet/outcomes/007-fix-plan-mode-user-prompt.md +83 -0
  139. package/RAF/012-name-picker-buffet/outcomes/008-add-auto-flag-for-plan-mode.md +77 -0
  140. package/RAF/012-name-picker-buffet/plans/001-name-picker-for-raf-plan.md +47 -0
  141. package/RAF/012-name-picker-buffet/plans/002-interactive-project-picker-for-raf-do.md +43 -0
  142. package/RAF/012-name-picker-buffet/plans/003-raf-status-truncation.md +36 -0
  143. package/RAF/012-name-picker-buffet/plans/004-failure-reason-details.md +46 -0
  144. package/RAF/012-name-picker-buffet/plans/005-remove-raf-commits.md +42 -0
  145. package/RAF/012-name-picker-buffet/plans/006-update-execution-prompt-for-commits.md +47 -0
  146. package/RAF/012-name-picker-buffet/plans/007-fix-plan-mode-user-prompt.md +55 -0
  147. package/RAF/012-name-picker-buffet/plans/008-add-auto-flag-for-plan-mode.md +49 -0
  148. package/RAF/013-dependencies-watchdog/decisions.md +37 -0
  149. package/RAF/013-dependencies-watchdog/input.md +1 -0
  150. package/RAF/013-dependencies-watchdog/outcomes/001-define-dependency-syntax.md +56 -0
  151. package/RAF/013-dependencies-watchdog/outcomes/002-update-planning-prompts.md +60 -0
  152. package/RAF/013-dependencies-watchdog/outcomes/003-parse-dependencies-update-state.md +81 -0
  153. package/RAF/013-dependencies-watchdog/outcomes/004-implement-dependency-checking-in-do.md +116 -0
  154. package/RAF/013-dependencies-watchdog/outcomes/005-update-execution-prompts.md +75 -0
  155. package/RAF/013-dependencies-watchdog/outcomes/006-add-tests.md +100 -0
  156. package/RAF/013-dependencies-watchdog/outcomes/007-add-act-alias.md +46 -0
  157. package/RAF/013-dependencies-watchdog/outcomes/008-add-exit-message.md +52 -0
  158. package/RAF/013-dependencies-watchdog/plans/001-define-dependency-syntax.md +32 -0
  159. package/RAF/013-dependencies-watchdog/plans/002-update-planning-prompts.md +38 -0
  160. package/RAF/013-dependencies-watchdog/plans/003-parse-dependencies-update-state.md +46 -0
  161. package/RAF/013-dependencies-watchdog/plans/004-implement-dependency-checking-in-do.md +48 -0
  162. package/RAF/013-dependencies-watchdog/plans/005-update-execution-prompts.md +44 -0
  163. package/RAF/013-dependencies-watchdog/plans/006-add-tests.md +54 -0
  164. package/RAF/013-dependencies-watchdog/plans/007-add-act-alias.md +26 -0
  165. package/RAF/013-dependencies-watchdog/plans/008-add-exit-message.md +31 -0
  166. package/RAF/014-watchdog/decisions.md +16 -0
  167. package/RAF/014-watchdog/input.md +2 -0
  168. package/RAF/014-watchdog/outcomes/001-amend-flag-position.md +50 -0
  169. package/RAF/014-watchdog/outcomes/002-details-only-on-failure.md +58 -0
  170. package/RAF/014-watchdog/plans/001-amend-flag-position.md +34 -0
  171. package/RAF/014-watchdog/plans/002-details-only-on-failure.md +46 -0
  172. package/RAF/015-name-lottery/decisions.md +14 -0
  173. package/RAF/015-name-lottery/input.md +3 -0
  174. package/RAF/015-name-lottery/outcomes/001-auto-pick-project-name.md +31 -0
  175. package/RAF/015-name-lottery/outcomes/002-mention-plan-files-in-commit.md +23 -0
  176. package/RAF/015-name-lottery/outcomes/003-fix-input-md-in-amend-flow.md +44 -0
  177. package/RAF/015-name-lottery/plans/001-auto-pick-project-name.md +38 -0
  178. package/RAF/015-name-lottery/plans/002-mention-plan-files-in-commit.md +32 -0
  179. package/RAF/015-name-lottery/plans/003-fix-input-md-in-amend-flow.md +44 -0
  180. package/README.md +116 -0
  181. package/dist/commands/do.d.ts +12 -0
  182. package/dist/commands/do.d.ts.map +1 -0
  183. package/dist/commands/do.js +684 -0
  184. package/dist/commands/do.js.map +1 -0
  185. package/dist/commands/plan.d.ts +3 -0
  186. package/dist/commands/plan.d.ts.map +1 -0
  187. package/dist/commands/plan.js +345 -0
  188. package/dist/commands/plan.js.map +1 -0
  189. package/dist/commands/status.d.ts +3 -0
  190. package/dist/commands/status.d.ts.map +1 -0
  191. package/dist/commands/status.js +117 -0
  192. package/dist/commands/status.js.map +1 -0
  193. package/dist/core/claude-runner.d.ts +78 -0
  194. package/dist/core/claude-runner.d.ts.map +1 -0
  195. package/dist/core/claude-runner.js +297 -0
  196. package/dist/core/claude-runner.js.map +1 -0
  197. package/dist/core/editor.d.ts +10 -0
  198. package/dist/core/editor.d.ts.map +1 -0
  199. package/dist/core/editor.js +77 -0
  200. package/dist/core/editor.js.map +1 -0
  201. package/dist/core/failure-analyzer.d.ts +28 -0
  202. package/dist/core/failure-analyzer.d.ts.map +1 -0
  203. package/dist/core/failure-analyzer.js +305 -0
  204. package/dist/core/failure-analyzer.js.map +1 -0
  205. package/dist/core/git.d.ts +42 -0
  206. package/dist/core/git.d.ts.map +1 -0
  207. package/dist/core/git.js +148 -0
  208. package/dist/core/git.js.map +1 -0
  209. package/dist/core/project-manager.d.ts +72 -0
  210. package/dist/core/project-manager.d.ts.map +1 -0
  211. package/dist/core/project-manager.js +193 -0
  212. package/dist/core/project-manager.js.map +1 -0
  213. package/dist/core/retry-handler.d.ts +19 -0
  214. package/dist/core/retry-handler.d.ts.map +1 -0
  215. package/dist/core/retry-handler.js +51 -0
  216. package/dist/core/retry-handler.js.map +1 -0
  217. package/dist/core/shutdown-handler.d.ts +30 -0
  218. package/dist/core/shutdown-handler.d.ts.map +1 -0
  219. package/dist/core/shutdown-handler.js +79 -0
  220. package/dist/core/shutdown-handler.js.map +1 -0
  221. package/dist/core/state-derivation.d.ts +82 -0
  222. package/dist/core/state-derivation.d.ts.map +1 -0
  223. package/dist/core/state-derivation.js +271 -0
  224. package/dist/core/state-derivation.js.map +1 -0
  225. package/dist/core/state-manager.d.ts +54 -0
  226. package/dist/core/state-manager.d.ts.map +1 -0
  227. package/dist/core/state-manager.js +198 -0
  228. package/dist/core/state-manager.js.map +1 -0
  229. package/dist/index.d.ts +3 -0
  230. package/dist/index.d.ts.map +1 -0
  231. package/dist/index.js +16 -0
  232. package/dist/index.js.map +1 -0
  233. package/dist/parsers/output-parser.d.ts +19 -0
  234. package/dist/parsers/output-parser.d.ts.map +1 -0
  235. package/dist/parsers/output-parser.js +137 -0
  236. package/dist/parsers/output-parser.js.map +1 -0
  237. package/dist/prompts/amend.d.ts +20 -0
  238. package/dist/prompts/amend.d.ts.map +1 -0
  239. package/dist/prompts/amend.js +166 -0
  240. package/dist/prompts/amend.js.map +1 -0
  241. package/dist/prompts/execution.d.ts +30 -0
  242. package/dist/prompts/execution.d.ts.map +1 -0
  243. package/dist/prompts/execution.js +179 -0
  244. package/dist/prompts/execution.js.map +1 -0
  245. package/dist/prompts/planning.d.ts +15 -0
  246. package/dist/prompts/planning.d.ts.map +1 -0
  247. package/dist/prompts/planning.js +163 -0
  248. package/dist/prompts/planning.js.map +1 -0
  249. package/dist/types/config.d.ts +26 -0
  250. package/dist/types/config.d.ts.map +1 -0
  251. package/dist/types/config.js +7 -0
  252. package/dist/types/config.js.map +1 -0
  253. package/dist/types/state.d.ts +33 -0
  254. package/dist/types/state.d.ts.map +1 -0
  255. package/dist/types/state.js +28 -0
  256. package/dist/types/state.js.map +1 -0
  257. package/dist/ui/name-picker-subprocess.d.ts +11 -0
  258. package/dist/ui/name-picker-subprocess.d.ts.map +1 -0
  259. package/dist/ui/name-picker-subprocess.js +83 -0
  260. package/dist/ui/name-picker-subprocess.js.map +1 -0
  261. package/dist/ui/name-picker.d.ts +19 -0
  262. package/dist/ui/name-picker.d.ts.map +1 -0
  263. package/dist/ui/name-picker.js +173 -0
  264. package/dist/ui/name-picker.js.map +1 -0
  265. package/dist/ui/project-picker.d.ts +27 -0
  266. package/dist/ui/project-picker.d.ts.map +1 -0
  267. package/dist/ui/project-picker.js +58 -0
  268. package/dist/ui/project-picker.js.map +1 -0
  269. package/dist/utils/config.d.ts +24 -0
  270. package/dist/utils/config.d.ts.map +1 -0
  271. package/dist/utils/config.js +63 -0
  272. package/dist/utils/config.js.map +1 -0
  273. package/dist/utils/logger.d.ts +32 -0
  274. package/dist/utils/logger.d.ts.map +1 -0
  275. package/dist/utils/logger.js +60 -0
  276. package/dist/utils/logger.js.map +1 -0
  277. package/dist/utils/name-generator.d.ts +20 -0
  278. package/dist/utils/name-generator.d.ts.map +1 -0
  279. package/dist/utils/name-generator.js +183 -0
  280. package/dist/utils/name-generator.js.map +1 -0
  281. package/dist/utils/paths.d.ts +132 -0
  282. package/dist/utils/paths.d.ts.map +1 -0
  283. package/dist/utils/paths.js +412 -0
  284. package/dist/utils/paths.js.map +1 -0
  285. package/dist/utils/status-line.d.ts +14 -0
  286. package/dist/utils/status-line.d.ts.map +1 -0
  287. package/dist/utils/status-line.js +36 -0
  288. package/dist/utils/status-line.js.map +1 -0
  289. package/dist/utils/terminal-symbols.d.ts +50 -0
  290. package/dist/utils/terminal-symbols.d.ts.map +1 -0
  291. package/dist/utils/terminal-symbols.js +97 -0
  292. package/dist/utils/terminal-symbols.js.map +1 -0
  293. package/dist/utils/timer.d.ts +17 -0
  294. package/dist/utils/timer.d.ts.map +1 -0
  295. package/dist/utils/timer.js +56 -0
  296. package/dist/utils/timer.js.map +1 -0
  297. package/dist/utils/validation.d.ts +17 -0
  298. package/dist/utils/validation.d.ts.map +1 -0
  299. package/dist/utils/validation.js +106 -0
  300. package/dist/utils/validation.js.map +1 -0
  301. package/dist/utils/version.d.ts +2 -0
  302. package/dist/utils/version.d.ts.map +1 -0
  303. package/dist/utils/version.js +12 -0
  304. package/dist/utils/version.js.map +1 -0
  305. package/jest.config.ts +30 -0
  306. package/package.json +55 -0
  307. package/src/commands/do.ts +829 -0
  308. package/src/commands/plan.ts +422 -0
  309. package/src/commands/status.ts +146 -0
  310. package/src/core/claude-runner.ts +374 -0
  311. package/src/core/editor.ts +85 -0
  312. package/src/core/failure-analyzer.ts +372 -0
  313. package/src/core/git.ts +166 -0
  314. package/src/core/project-manager.ts +243 -0
  315. package/src/core/retry-handler.ts +72 -0
  316. package/src/core/shutdown-handler.ts +93 -0
  317. package/src/core/state-derivation.ts +343 -0
  318. package/src/index.ts +20 -0
  319. package/src/parsers/output-parser.ts +164 -0
  320. package/src/prompts/amend.ts +194 -0
  321. package/src/prompts/execution.ts +223 -0
  322. package/src/prompts/planning.ts +175 -0
  323. package/src/types/config.ts +35 -0
  324. package/src/ui/name-picker-subprocess.ts +96 -0
  325. package/src/ui/name-picker.ts +198 -0
  326. package/src/ui/project-picker.ts +80 -0
  327. package/src/utils/config.ts +69 -0
  328. package/src/utils/logger.ts +81 -0
  329. package/src/utils/name-generator.ts +211 -0
  330. package/src/utils/paths.ts +497 -0
  331. package/src/utils/status-line.ts +45 -0
  332. package/src/utils/terminal-symbols.ts +124 -0
  333. package/src/utils/timer.ts +64 -0
  334. package/src/utils/validation.ts +132 -0
  335. package/src/utils/version.ts +12 -0
  336. package/tests/unit/claude-runner-interactive.test.ts +343 -0
  337. package/tests/unit/claude-runner.test.ts +629 -0
  338. package/tests/unit/command-output.test.ts +295 -0
  339. package/tests/unit/config.test.ts +72 -0
  340. package/tests/unit/dependency-integration.test.ts +559 -0
  341. package/tests/unit/do-blocked-tasks.test.ts +323 -0
  342. package/tests/unit/do-command.test.ts +198 -0
  343. package/tests/unit/do-multiproject.test.ts +270 -0
  344. package/tests/unit/do-rerun.test.ts +270 -0
  345. package/tests/unit/execution-prompt.test.ts +406 -0
  346. package/tests/unit/failure-analyzer.test.ts +276 -0
  347. package/tests/unit/failure-history.test.ts +143 -0
  348. package/tests/unit/git-stash.test.ts +138 -0
  349. package/tests/unit/git.test.ts +80 -0
  350. package/tests/unit/logger.test.ts +132 -0
  351. package/tests/unit/name-generator.test.ts +283 -0
  352. package/tests/unit/name-picker.test.ts +179 -0
  353. package/tests/unit/outcome-content.test.ts +166 -0
  354. package/tests/unit/output-parser.test.ts +178 -0
  355. package/tests/unit/paths.test.ts +741 -0
  356. package/tests/unit/plan-command-amend-flag.test.ts +115 -0
  357. package/tests/unit/plan-command-amend-input.test.ts +156 -0
  358. package/tests/unit/plan-command-auto-flag.test.ts +112 -0
  359. package/tests/unit/plan-command.test.ts +580 -0
  360. package/tests/unit/planning-prompt.test.ts +137 -0
  361. package/tests/unit/project-manager.test.ts +265 -0
  362. package/tests/unit/project-picker.test.ts +338 -0
  363. package/tests/unit/retry-handler.test.ts +89 -0
  364. package/tests/unit/state-derivation.test.ts +714 -0
  365. package/tests/unit/status-command.test.ts +271 -0
  366. package/tests/unit/status-line.test.ts +92 -0
  367. package/tests/unit/terminal-symbols.test.ts +214 -0
  368. package/tests/unit/timer.test.ts +102 -0
  369. package/tests/unit/validation.test.ts +118 -0
  370. package/tsconfig.json +26 -0
@@ -0,0 +1,343 @@
1
+ import * as fs from 'node:fs';
2
+ import * as path from 'node:path';
3
+ import { getPlansDir, getOutcomesDir, getInputPath } from '../utils/paths.js';
4
+
5
+ export type DerivedTaskStatus = 'pending' | 'completed' | 'failed' | 'blocked';
6
+
7
+ export type DerivedProjectStatus =
8
+ | 'planning'
9
+ | 'ready'
10
+ | 'executing'
11
+ | 'completed'
12
+ | 'failed';
13
+
14
+ export interface DerivedTask {
15
+ id: string;
16
+ planFile: string;
17
+ status: DerivedTaskStatus;
18
+ dependencies: string[];
19
+ }
20
+
21
+ export interface DerivedProjectState {
22
+ tasks: DerivedTask[];
23
+ status: DerivedProjectStatus;
24
+ }
25
+
26
+ export interface DiscoveredProject {
27
+ number: number;
28
+ name: string;
29
+ path: string;
30
+ }
31
+
32
+ export interface DerivedStats {
33
+ pending: number;
34
+ completed: number;
35
+ failed: number;
36
+ blocked: number;
37
+ total: number;
38
+ }
39
+
40
+ /**
41
+ * Discover all projects in the RAF directory.
42
+ * Projects are directories matching the pattern NNN-project-name.
43
+ */
44
+ export function discoverProjects(rafDir: string): DiscoveredProject[] {
45
+ if (!fs.existsSync(rafDir)) {
46
+ return [];
47
+ }
48
+
49
+ const entries = fs.readdirSync(rafDir, { withFileTypes: true });
50
+ const projects: DiscoveredProject[] = [];
51
+
52
+ for (const entry of entries) {
53
+ if (entry.isDirectory()) {
54
+ const match = entry.name.match(/^(\d{2,3})-(.+)$/);
55
+ if (match && match[1] && match[2]) {
56
+ projects.push({
57
+ number: parseInt(match[1], 10),
58
+ name: match[2],
59
+ path: path.join(rafDir, entry.name),
60
+ });
61
+ }
62
+ }
63
+ }
64
+
65
+ return projects.sort((a, b) => a.number - b.number);
66
+ }
67
+
68
+ /**
69
+ * Parse the Dependencies section from plan file content.
70
+ * Format: `## Dependencies\n001, 002` → ["001", "002"]
71
+ * Returns empty array if no Dependencies section exists.
72
+ */
73
+ export function parseDependencies(content: string): string[] {
74
+ const dependenciesMatch = content.match(/^## Dependencies\s*\n([^\n#]+)/m);
75
+ if (!dependenciesMatch || !dependenciesMatch[1]) {
76
+ return [];
77
+ }
78
+
79
+ const dependenciesLine = dependenciesMatch[1].trim();
80
+ if (!dependenciesLine) {
81
+ return [];
82
+ }
83
+
84
+ // Parse comma-separated task IDs
85
+ return dependenciesLine
86
+ .split(',')
87
+ .map((id) => id.trim())
88
+ .filter((id) => /^\d{2,3}$/.test(id));
89
+ }
90
+
91
+ /**
92
+ * Parse an outcome file to extract its status.
93
+ * Status is determined by the presence of promise markers:
94
+ * - `<promise>COMPLETE</promise>` → completed
95
+ * - `<promise>FAILED</promise>` → failed
96
+ * - `<promise>BLOCKED</promise>` → blocked
97
+ * Uses the last occurrence if multiple markers exist.
98
+ */
99
+ export function parseOutcomeStatus(content: string): DerivedTaskStatus | null {
100
+ const markerRegex = /<promise>(COMPLETE|FAILED|BLOCKED)<\/promise>/g;
101
+ let lastMatch: RegExpExecArray | null = null;
102
+ let match: RegExpExecArray | null;
103
+
104
+ while ((match = markerRegex.exec(content)) !== null) {
105
+ lastMatch = match;
106
+ }
107
+
108
+ if (lastMatch && lastMatch[1]) {
109
+ switch (lastMatch[1]) {
110
+ case 'COMPLETE':
111
+ return 'completed';
112
+ case 'FAILED':
113
+ return 'failed';
114
+ case 'BLOCKED':
115
+ return 'blocked';
116
+ }
117
+ }
118
+ return null;
119
+ }
120
+
121
+ /**
122
+ * Derive project status from tasks.
123
+ * - planning: has input.md but no plans folder or empty plans
124
+ * - ready: has plan files but no outcome files
125
+ * - executing: has some outcome files but not all (or has failed outcomes without SUCCESS)
126
+ * - completed: all plan files have corresponding SUCCESS outcomes
127
+ * - failed: has FAILED outcome files
128
+ */
129
+ export function deriveProjectStatus(
130
+ projectPath: string,
131
+ tasks: DerivedTask[]
132
+ ): DerivedProjectStatus {
133
+ const plansDir = getPlansDir(projectPath);
134
+ const inputPath = getInputPath(projectPath);
135
+
136
+ const hasInput = fs.existsSync(inputPath);
137
+ const hasPlansDir = fs.existsSync(plansDir);
138
+
139
+ // If no plans directory or empty plans
140
+ if (!hasPlansDir || tasks.length === 0) {
141
+ return hasInput ? 'planning' : 'planning';
142
+ }
143
+
144
+ const stats = {
145
+ pending: 0,
146
+ completed: 0,
147
+ failed: 0,
148
+ };
149
+
150
+ for (const task of tasks) {
151
+ if (task.status === 'pending') stats.pending++;
152
+ else if (task.status === 'completed') stats.completed++;
153
+ else if (task.status === 'failed') stats.failed++;
154
+ }
155
+
156
+ // If any task failed, project is failed
157
+ if (stats.failed > 0) {
158
+ return 'failed';
159
+ }
160
+
161
+ // If all tasks completed, project is completed
162
+ if (stats.completed === tasks.length && tasks.length > 0) {
163
+ return 'completed';
164
+ }
165
+
166
+ // If no tasks have been started (all pending), project is ready
167
+ if (stats.pending === tasks.length) {
168
+ return 'ready';
169
+ }
170
+
171
+ // Otherwise, project is executing
172
+ return 'executing';
173
+ }
174
+
175
+ /**
176
+ * Derive project state from the folder structure.
177
+ * Scans plans/ for plan files and outcomes/ for outcome files.
178
+ * Matches them by task ID (NNN prefix) and determines status.
179
+ * Also parses dependencies and derives blocked status.
180
+ */
181
+ export function deriveProjectState(projectPath: string): DerivedProjectState {
182
+ const plansDir = getPlansDir(projectPath);
183
+ const outcomesDir = getOutcomesDir(projectPath);
184
+
185
+ const tasks: DerivedTask[] = [];
186
+
187
+ // Scan plans directory for plan files
188
+ if (!fs.existsSync(plansDir)) {
189
+ const status = deriveProjectStatus(projectPath, tasks);
190
+ return { tasks, status };
191
+ }
192
+
193
+ const planFiles = fs.readdirSync(plansDir)
194
+ .filter((f) => f.endsWith('.md'))
195
+ .sort();
196
+
197
+ // Build a map of outcome statuses
198
+ const outcomeStatuses = new Map<string, DerivedTaskStatus>();
199
+ if (fs.existsSync(outcomesDir)) {
200
+ const outcomeFiles = fs.readdirSync(outcomesDir)
201
+ .filter((f) => f.endsWith('.md'))
202
+ .sort();
203
+
204
+ for (const outcomeFile of outcomeFiles) {
205
+ const match = outcomeFile.match(/^(\d{2,3})-/);
206
+ if (match && match[1]) {
207
+ const taskId = match[1];
208
+ const content = fs.readFileSync(path.join(outcomesDir, outcomeFile), 'utf-8');
209
+ const status = parseOutcomeStatus(content);
210
+ if (status) {
211
+ outcomeStatuses.set(taskId, status);
212
+ }
213
+ }
214
+ }
215
+ }
216
+
217
+ // First pass: Match plan files to outcomes and parse dependencies
218
+ for (const planFile of planFiles) {
219
+ const match = planFile.match(/^(\d{2,3})-(.+)\.md$/);
220
+ if (match && match[1]) {
221
+ const taskId = match[1];
222
+ const status = outcomeStatuses.get(taskId) ?? 'pending';
223
+
224
+ // Read plan file to extract dependencies
225
+ const planContent = fs.readFileSync(path.join(plansDir, planFile), 'utf-8');
226
+ const dependencies = parseDependencies(planContent);
227
+
228
+ tasks.push({
229
+ id: taskId,
230
+ planFile: path.join('plans', planFile),
231
+ status,
232
+ dependencies,
233
+ });
234
+ }
235
+ }
236
+
237
+ // Second pass: Derive blocked status for pending tasks
238
+ // A task is blocked if any of its dependencies are failed or blocked
239
+ const taskStatusMap = new Map<string, DerivedTaskStatus>();
240
+ for (const task of tasks) {
241
+ taskStatusMap.set(task.id, task.status);
242
+ }
243
+
244
+ // Process blocked status (may need multiple passes for transitive blocking)
245
+ let changed = true;
246
+ while (changed) {
247
+ changed = false;
248
+ for (const task of tasks) {
249
+ if (task.status === 'pending' && task.dependencies.length > 0) {
250
+ const isBlocked = task.dependencies.some((depId) => {
251
+ const depStatus = taskStatusMap.get(depId);
252
+ return depStatus === 'failed' || depStatus === 'blocked';
253
+ });
254
+ if (isBlocked) {
255
+ task.status = 'blocked';
256
+ taskStatusMap.set(task.id, 'blocked');
257
+ changed = true;
258
+ }
259
+ }
260
+ }
261
+ }
262
+
263
+ const projectStatus = deriveProjectStatus(projectPath, tasks);
264
+ return { tasks, status: projectStatus };
265
+ }
266
+
267
+ /**
268
+ * Get the next pending task from derived state.
269
+ */
270
+ export function getNextPendingTask(state: DerivedProjectState): DerivedTask | null {
271
+ for (const task of state.tasks) {
272
+ if (task.status === 'pending') {
273
+ return task;
274
+ }
275
+ }
276
+ return null;
277
+ }
278
+
279
+ /**
280
+ * Get the next task that should be executed (pending or failed).
281
+ * Skips blocked tasks - they cannot be executed until their dependencies pass.
282
+ */
283
+ export function getNextExecutableTask(state: DerivedProjectState): DerivedTask | null {
284
+ // First try pending tasks (blocked tasks have status 'blocked', not 'pending')
285
+ for (const task of state.tasks) {
286
+ if (task.status === 'pending') {
287
+ return task;
288
+ }
289
+ }
290
+ // Then try failed tasks (for retry)
291
+ for (const task of state.tasks) {
292
+ if (task.status === 'failed') {
293
+ return task;
294
+ }
295
+ }
296
+ return null;
297
+ }
298
+
299
+ /**
300
+ * Calculate statistics from derived state.
301
+ */
302
+ export function getDerivedStats(state: DerivedProjectState): DerivedStats {
303
+ const stats: DerivedStats = {
304
+ pending: 0,
305
+ completed: 0,
306
+ failed: 0,
307
+ blocked: 0,
308
+ total: state.tasks.length,
309
+ };
310
+
311
+ for (const task of state.tasks) {
312
+ switch (task.status) {
313
+ case 'pending':
314
+ stats.pending++;
315
+ break;
316
+ case 'completed':
317
+ stats.completed++;
318
+ break;
319
+ case 'failed':
320
+ stats.failed++;
321
+ break;
322
+ case 'blocked':
323
+ stats.blocked++;
324
+ break;
325
+ }
326
+ }
327
+
328
+ return stats;
329
+ }
330
+
331
+ /**
332
+ * Check if all tasks are completed.
333
+ */
334
+ export function isProjectComplete(state: DerivedProjectState): boolean {
335
+ return state.tasks.every((t) => t.status === 'completed');
336
+ }
337
+
338
+ /**
339
+ * Check if any task has failed.
340
+ */
341
+ export function hasProjectFailed(state: DerivedProjectState): boolean {
342
+ return state.tasks.some((t) => t.status === 'failed');
343
+ }
package/src/index.ts ADDED
@@ -0,0 +1,20 @@
1
+ #!/usr/bin/env node
2
+
3
+ import { Command } from 'commander';
4
+ import { createPlanCommand } from './commands/plan.js';
5
+ import { createDoCommand } from './commands/do.js';
6
+ import { createStatusCommand } from './commands/status.js';
7
+ import { getVersion } from './utils/version.js';
8
+
9
+ const program = new Command();
10
+
11
+ program
12
+ .name('raf')
13
+ .description('RAF - Automated Task Planning & Execution with Claude Code')
14
+ .version(getVersion());
15
+
16
+ program.addCommand(createPlanCommand());
17
+ program.addCommand(createDoCommand());
18
+ program.addCommand(createStatusCommand());
19
+
20
+ program.parse();
@@ -0,0 +1,164 @@
1
+ export type TaskResult = 'complete' | 'failed' | 'unknown';
2
+
3
+ export interface ParsedOutput {
4
+ result: TaskResult;
5
+ failureReason?: string;
6
+ contextOverflow: boolean;
7
+ }
8
+
9
+ const COMPLETE_PATTERN = /<promise>COMPLETE<\/promise>/i;
10
+ const FAILED_PATTERN = /<promise>FAILED<\/promise>/i;
11
+ const FAILURE_REASON_PATTERN = /Reason:\s*(.+?)(?:\n|$)/i;
12
+
13
+ const CONTEXT_OVERFLOW_PATTERNS = [
14
+ /context length exceeded/i,
15
+ /token limit/i,
16
+ /maximum context/i,
17
+ /context window/i,
18
+ /too many tokens/i,
19
+ ];
20
+
21
+ /**
22
+ * Parse Claude's output to determine task result.
23
+ */
24
+ export function parseOutput(output: string): ParsedOutput {
25
+ const result: ParsedOutput = {
26
+ result: 'unknown',
27
+ contextOverflow: false,
28
+ };
29
+
30
+ // Check for context overflow
31
+ for (const pattern of CONTEXT_OVERFLOW_PATTERNS) {
32
+ if (pattern.test(output)) {
33
+ result.contextOverflow = true;
34
+ break;
35
+ }
36
+ }
37
+
38
+ // Check for completion markers (search from the end for the last occurrence)
39
+ const completeMatch = output.match(COMPLETE_PATTERN);
40
+ const failedMatch = output.match(FAILED_PATTERN);
41
+
42
+ if (completeMatch && failedMatch) {
43
+ // Both present - use whichever appears last
44
+ const completeIndex = output.lastIndexOf(completeMatch[0]);
45
+ const failedIndex = output.lastIndexOf(failedMatch[0]);
46
+
47
+ if (failedIndex > completeIndex) {
48
+ result.result = 'failed';
49
+ extractFailureReason(output, result);
50
+ } else {
51
+ result.result = 'complete';
52
+ }
53
+ } else if (completeMatch) {
54
+ result.result = 'complete';
55
+ } else if (failedMatch) {
56
+ result.result = 'failed';
57
+ extractFailureReason(output, result);
58
+ }
59
+
60
+ return result;
61
+ }
62
+
63
+ function extractFailureReason(output: string, result: ParsedOutput): void {
64
+ const reasonMatch = output.match(FAILURE_REASON_PATTERN);
65
+ if (reasonMatch) {
66
+ result.failureReason = reasonMatch[1]?.trim();
67
+ } else {
68
+ // Try to find any text after the FAILED marker
69
+ const failedIndex = output.lastIndexOf('<promise>FAILED</promise>');
70
+ if (failedIndex !== -1) {
71
+ const afterFailed = output.substring(failedIndex + '<promise>FAILED</promise>'.length).trim();
72
+ if (afterFailed) {
73
+ // Take first few lines as reason
74
+ const lines = afterFailed.split('\n').slice(0, 3);
75
+ result.failureReason = lines.join(' ').trim().substring(0, 500);
76
+ }
77
+ }
78
+ }
79
+
80
+ if (!result.failureReason) {
81
+ result.failureReason = 'Unknown failure (no reason provided)';
82
+ }
83
+ }
84
+
85
+ /**
86
+ * Check if output indicates a retryable failure.
87
+ */
88
+ export function isRetryableFailure(parsed: ParsedOutput): boolean {
89
+ // Context overflow is not retryable
90
+ if (parsed.contextOverflow) {
91
+ return false;
92
+ }
93
+
94
+ // Unknown result might be retryable
95
+ if (parsed.result === 'unknown') {
96
+ return true;
97
+ }
98
+
99
+ // Check failure reason for non-retryable patterns
100
+ if (parsed.result === 'failed' && parsed.failureReason) {
101
+ const nonRetryable = [
102
+ /cannot be done/i,
103
+ /impossible/i,
104
+ /not supported/i,
105
+ /permission denied/i,
106
+ /access denied/i,
107
+ ];
108
+
109
+ for (const pattern of nonRetryable) {
110
+ if (pattern.test(parsed.failureReason)) {
111
+ return false;
112
+ }
113
+ }
114
+
115
+ // Most failures are retryable
116
+ return true;
117
+ }
118
+
119
+ return false;
120
+ }
121
+
122
+ /**
123
+ * Extract a summary from Claude's output for the outcome file.
124
+ */
125
+ export function extractSummary(output: string): string {
126
+ // Remove ANSI codes
127
+ const cleanOutput = output.replace(/\x1b\[[0-9;]*m/g, '');
128
+
129
+ // Try to find meaningful summary sections
130
+ const lines = cleanOutput.split('\n');
131
+ const summaryLines: string[] = [];
132
+ let inCodeBlock = false;
133
+
134
+ for (const line of lines) {
135
+ // Skip code blocks
136
+ if (line.trim().startsWith('```')) {
137
+ inCodeBlock = !inCodeBlock;
138
+ continue;
139
+ }
140
+
141
+ if (inCodeBlock) {
142
+ continue;
143
+ }
144
+
145
+ // Skip empty lines and very short lines
146
+ if (line.trim().length < 5) {
147
+ continue;
148
+ }
149
+
150
+ // Skip lines that look like file paths or commands
151
+ if (line.trim().startsWith('/') || line.trim().startsWith('$')) {
152
+ continue;
153
+ }
154
+
155
+ summaryLines.push(line);
156
+
157
+ // Limit summary length
158
+ if (summaryLines.length >= 50) {
159
+ break;
160
+ }
161
+ }
162
+
163
+ return summaryLines.join('\n').trim() || 'No summary available.';
164
+ }