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,96 @@
1
+ #!/usr/bin/env node
2
+ /**
3
+ * Subprocess script for running the name picker.
4
+ * This isolates @inquirer/prompts from the main process to prevent
5
+ * stdin corruption that affects subsequent node-pty usage.
6
+ *
7
+ * Usage: node name-picker-subprocess.js <json-encoded-names-array> <output-file>
8
+ * Output: Selected name written to output file
9
+ */
10
+
11
+ import { select, input } from '@inquirer/prompts';
12
+ import * as fs from 'node:fs';
13
+
14
+ const OTHER_OPTION_VALUE = '__OTHER__';
15
+
16
+ async function main(): Promise<void> {
17
+ // Get names from command line argument
18
+ const namesJson = process.argv[2];
19
+ const outputFile = process.argv[3];
20
+
21
+ if (!namesJson || !outputFile) {
22
+ console.error('Usage: name-picker-subprocess <json-encoded-names-array> <output-file>');
23
+ process.exit(1);
24
+ }
25
+
26
+ let names: string[];
27
+ try {
28
+ names = JSON.parse(namesJson);
29
+ } catch {
30
+ console.error('Invalid JSON input');
31
+ process.exit(1);
32
+ }
33
+
34
+ const result = await pickProjectName(names);
35
+
36
+ // Write result to output file
37
+ fs.writeFileSync(outputFile, result, 'utf-8');
38
+ }
39
+
40
+ async function pickProjectName(names: string[]): Promise<string> {
41
+ if (names.length === 0) {
42
+ return promptForCustomName();
43
+ }
44
+
45
+ const choices = [
46
+ ...names.map((name) => ({
47
+ name: name,
48
+ value: name,
49
+ })),
50
+ {
51
+ name: 'Other (enter custom name)',
52
+ value: OTHER_OPTION_VALUE,
53
+ },
54
+ ];
55
+
56
+ const selected = await select({
57
+ message: 'Select a project name:',
58
+ choices,
59
+ });
60
+
61
+ if (selected === OTHER_OPTION_VALUE) {
62
+ return promptForCustomName();
63
+ }
64
+
65
+ return selected;
66
+ }
67
+
68
+ async function promptForCustomName(): Promise<string> {
69
+ const customName = await input({
70
+ message: 'Enter project name:',
71
+ validate: (value) => {
72
+ const trimmed = value.trim();
73
+ if (!trimmed) {
74
+ return 'Project name cannot be empty';
75
+ }
76
+ if (trimmed.length > 50) {
77
+ return 'Project name must be 50 characters or less';
78
+ }
79
+ if (!/^[a-zA-Z0-9][a-zA-Z0-9_-]*$/.test(trimmed)) {
80
+ return 'Project name can only contain letters, numbers, hyphens, and underscores';
81
+ }
82
+ return true;
83
+ },
84
+ });
85
+
86
+ return customName.trim().toLowerCase();
87
+ }
88
+
89
+ main().catch((error) => {
90
+ // Check if user cancelled with Ctrl+C
91
+ if (error.message?.includes('User force closed') || error.name === 'ExitPromptError') {
92
+ process.exit(130); // Standard SIGINT exit code
93
+ }
94
+ console.error('Error:', error.message);
95
+ process.exit(1);
96
+ });
@@ -0,0 +1,198 @@
1
+ import { fileURLToPath } from 'node:url';
2
+ import * as path from 'node:path';
3
+ import * as fs from 'node:fs';
4
+ import * as os from 'node:os';
5
+ import * as pty from 'node-pty';
6
+
7
+ // For testing: allow direct import of @inquirer/prompts functions
8
+ let directSelect: typeof import('@inquirer/prompts').select | null = null;
9
+ let directInput: typeof import('@inquirer/prompts').input | null = null;
10
+
11
+ const OTHER_OPTION_VALUE = '__OTHER__';
12
+
13
+ /**
14
+ * Enable direct mode for testing (bypasses subprocess).
15
+ * This should only be called in test setup.
16
+ */
17
+ export async function enableDirectMode(): Promise<void> {
18
+ const inquirer = await import('@inquirer/prompts');
19
+ directSelect = inquirer.select;
20
+ directInput = inquirer.input;
21
+ }
22
+
23
+ /**
24
+ * Disable direct mode (use subprocess).
25
+ */
26
+ export function disableDirectMode(): void {
27
+ directSelect = null;
28
+ directInput = null;
29
+ }
30
+
31
+ /**
32
+ * Display an interactive name picker with arrow-key navigation.
33
+ * Runs in a PTY subprocess to completely isolate @inquirer/prompts
34
+ * stdin manipulation from the main process.
35
+ *
36
+ * @param names - Array of generated name suggestions (3-5 names)
37
+ * @returns The selected or custom project name
38
+ */
39
+ export async function pickProjectName(names: string[]): Promise<string> {
40
+ // Use direct mode if enabled (for testing)
41
+ if (directSelect) {
42
+ return pickProjectNameDirect(names);
43
+ }
44
+
45
+ // Get path to the subprocess script
46
+ const currentFile = fileURLToPath(import.meta.url);
47
+ const currentDir = path.dirname(currentFile);
48
+
49
+ // Use the compiled js file
50
+ const subprocessScript = path.join(currentDir, 'name-picker-subprocess.js');
51
+
52
+ // Create temp file for result
53
+ const tempFile = path.join(os.tmpdir(), `raf-name-picker-${process.pid}.txt`);
54
+
55
+ return new Promise((resolve, reject) => {
56
+ // Spawn subprocess in its own PTY (completely isolates stdin)
57
+ const ptyProcess = pty.spawn('node', [subprocessScript, JSON.stringify(names), tempFile], {
58
+ name: 'xterm-256color',
59
+ cols: process.stdout.columns ?? 80,
60
+ rows: process.stdout.rows ?? 24,
61
+ cwd: process.cwd(),
62
+ env: process.env as Record<string, string>,
63
+ });
64
+
65
+ // Set raw mode on our stdin to pass through keypresses
66
+ if (process.stdin.isTTY) {
67
+ process.stdin.setRawMode(true);
68
+ }
69
+ process.stdin.resume();
70
+
71
+ // Forward input from our stdin to the PTY
72
+ const onData = (data: Buffer): void => {
73
+ ptyProcess.write(data.toString());
74
+ };
75
+ process.stdin.on('data', onData);
76
+
77
+ // Forward output from PTY to our stdout
78
+ ptyProcess.onData((data) => {
79
+ process.stdout.write(data);
80
+ });
81
+
82
+ ptyProcess.onExit(({ exitCode }) => {
83
+ // Cleanup stdin
84
+ process.stdin.off('data', onData);
85
+ if (process.stdin.isTTY) {
86
+ process.stdin.setRawMode(false);
87
+ }
88
+ process.stdin.pause();
89
+
90
+ if (exitCode === 130) {
91
+ // SIGINT - user cancelled
92
+ process.exit(130);
93
+ }
94
+
95
+ if (exitCode !== 0) {
96
+ // Clean up temp file
97
+ try {
98
+ if (fs.existsSync(tempFile)) {
99
+ fs.unlinkSync(tempFile);
100
+ }
101
+ } catch {
102
+ // Ignore
103
+ }
104
+ reject(new Error(`Name picker subprocess failed with code ${exitCode}`));
105
+ return;
106
+ }
107
+
108
+ // Read the result from temp file
109
+ try {
110
+ if (!fs.existsSync(tempFile)) {
111
+ reject(new Error('Name picker did not write a selection'));
112
+ return;
113
+ }
114
+
115
+ const selectedName = fs.readFileSync(tempFile, 'utf-8').trim();
116
+
117
+ // Clean up temp file
118
+ try {
119
+ fs.unlinkSync(tempFile);
120
+ } catch {
121
+ // Ignore
122
+ }
123
+
124
+ if (!selectedName) {
125
+ reject(new Error('Name picker returned empty selection'));
126
+ return;
127
+ }
128
+
129
+ resolve(selectedName);
130
+ } catch (error) {
131
+ reject(error);
132
+ }
133
+ });
134
+ });
135
+ }
136
+
137
+ /**
138
+ * Direct implementation for testing (uses @inquirer/prompts in-process).
139
+ */
140
+ async function pickProjectNameDirect(names: string[]): Promise<string> {
141
+ if (!directSelect || !directInput) {
142
+ throw new Error('Direct mode not enabled');
143
+ }
144
+
145
+ if (names.length === 0) {
146
+ return promptForCustomNameDirect();
147
+ }
148
+
149
+ const choices = [
150
+ ...names.map((name) => ({
151
+ name: name,
152
+ value: name,
153
+ })),
154
+ {
155
+ name: 'Other (enter custom name)',
156
+ value: OTHER_OPTION_VALUE,
157
+ },
158
+ ];
159
+
160
+ const selected = await directSelect({
161
+ message: 'Select a project name:',
162
+ choices,
163
+ });
164
+
165
+ if (selected === OTHER_OPTION_VALUE) {
166
+ return promptForCustomNameDirect();
167
+ }
168
+
169
+ return selected;
170
+ }
171
+
172
+ /**
173
+ * Prompt user to enter a custom project name (direct mode).
174
+ */
175
+ async function promptForCustomNameDirect(): Promise<string> {
176
+ if (!directInput) {
177
+ throw new Error('Direct mode not enabled');
178
+ }
179
+
180
+ const customName = await directInput({
181
+ message: 'Enter project name:',
182
+ validate: (value) => {
183
+ const trimmed = value.trim();
184
+ if (!trimmed) {
185
+ return 'Project name cannot be empty';
186
+ }
187
+ if (trimmed.length > 50) {
188
+ return 'Project name must be 50 characters or less';
189
+ }
190
+ if (!/^[a-zA-Z0-9][a-zA-Z0-9_-]*$/.test(trimmed)) {
191
+ return 'Project name can only contain letters, numbers, hyphens, and underscores';
192
+ }
193
+ return true;
194
+ },
195
+ });
196
+
197
+ return customName.trim().toLowerCase();
198
+ }
@@ -0,0 +1,80 @@
1
+ import { select } from '@inquirer/prompts';
2
+ import { discoverProjects, deriveProjectState, getDerivedStats } from '../core/state-derivation.js';
3
+ import { extractProjectNumber, formatProjectNumber } from '../utils/paths.js';
4
+
5
+ /**
6
+ * Information about a pending project for display in the picker.
7
+ */
8
+ export interface PendingProjectInfo {
9
+ folder: string;
10
+ number: number;
11
+ name: string;
12
+ path: string;
13
+ completedTasks: number;
14
+ totalTasks: number;
15
+ }
16
+
17
+ /**
18
+ * Get all projects that have pending tasks (not fully completed).
19
+ * Returns projects sorted by number (oldest first).
20
+ */
21
+ export function getPendingProjects(rafDir: string): PendingProjectInfo[] {
22
+ const allProjects = discoverProjects(rafDir);
23
+ const pendingProjects: PendingProjectInfo[] = [];
24
+
25
+ for (const project of allProjects) {
26
+ const state = deriveProjectState(project.path);
27
+ const stats = getDerivedStats(state);
28
+
29
+ // Include projects that are not fully completed (have pending or failed tasks)
30
+ if (stats.pending > 0 || stats.failed > 0) {
31
+ const projectNumber = extractProjectNumber(project.path);
32
+ const formattedNumber = projectNumber ?? formatProjectNumber(project.number);
33
+
34
+ pendingProjects.push({
35
+ folder: `${formattedNumber}-${project.name}`,
36
+ number: project.number,
37
+ name: project.name,
38
+ path: project.path,
39
+ completedTasks: stats.completed,
40
+ totalTasks: stats.total,
41
+ });
42
+ }
43
+ }
44
+
45
+ // Sort by number (already sorted by discoverProjects, but ensure it)
46
+ return pendingProjects.sort((a, b) => a.number - b.number);
47
+ }
48
+
49
+ /**
50
+ * Format a project for display in the picker.
51
+ * Example: "001 fix-auth-bug (2/5 tasks)"
52
+ */
53
+ export function formatProjectChoice(project: PendingProjectInfo): string {
54
+ const projectNumber = extractProjectNumber(project.path) ?? formatProjectNumber(project.number);
55
+ return `${projectNumber} ${project.name} (${project.completedTasks}/${project.totalTasks} tasks)`;
56
+ }
57
+
58
+ /**
59
+ * Display an interactive project picker for pending projects.
60
+ * Returns the selected project folder name or null if no projects or cancelled.
61
+ */
62
+ export async function pickPendingProject(rafDir: string): Promise<string | null> {
63
+ const pendingProjects = getPendingProjects(rafDir);
64
+
65
+ if (pendingProjects.length === 0) {
66
+ return null;
67
+ }
68
+
69
+ const choices = pendingProjects.map((project) => ({
70
+ name: formatProjectChoice(project),
71
+ value: project.folder,
72
+ }));
73
+
74
+ const selected = await select({
75
+ message: 'Select a project to execute:',
76
+ choices,
77
+ });
78
+
79
+ return selected;
80
+ }
@@ -0,0 +1,69 @@
1
+ import * as fs from 'node:fs';
2
+ import * as path from 'node:path';
3
+ import * as os from 'node:os';
4
+ import { RafConfig, DEFAULT_RAF_CONFIG } from '../types/config.js';
5
+
6
+ const CONFIG_FILENAME = 'raf.config.json';
7
+
8
+ /**
9
+ * Get the path to Claude CLI settings file.
10
+ */
11
+ export function getClaudeSettingsPath(): string {
12
+ return path.join(os.homedir(), '.claude', 'settings.json');
13
+ }
14
+
15
+ export function loadConfig(rafDir: string): RafConfig {
16
+ const configPath = path.join(rafDir, CONFIG_FILENAME);
17
+
18
+ if (!fs.existsSync(configPath)) {
19
+ return { ...DEFAULT_RAF_CONFIG };
20
+ }
21
+
22
+ try {
23
+ const content = fs.readFileSync(configPath, 'utf-8');
24
+ const userConfig = JSON.parse(content) as Partial<RafConfig>;
25
+ return { ...DEFAULT_RAF_CONFIG, ...userConfig };
26
+ } catch {
27
+ return { ...DEFAULT_RAF_CONFIG };
28
+ }
29
+ }
30
+
31
+ export function saveConfig(rafDir: string, config: RafConfig): void {
32
+ const configPath = path.join(rafDir, CONFIG_FILENAME);
33
+ fs.writeFileSync(configPath, JSON.stringify(config, null, 2));
34
+ }
35
+
36
+ export function getEditor(): string {
37
+ return process.env['EDITOR'] ?? process.env['VISUAL'] ?? 'vi';
38
+ }
39
+
40
+ /**
41
+ * Get the Claude model name from Claude CLI settings.
42
+ * Returns the model name or null if not found.
43
+ * @param settingsPath Optional path to settings file (for testing)
44
+ */
45
+ export function getClaudeModel(settingsPath?: string): string | null {
46
+ const filePath = settingsPath ?? getClaudeSettingsPath();
47
+ try {
48
+ if (!fs.existsSync(filePath)) {
49
+ return null;
50
+ }
51
+ const content = fs.readFileSync(filePath, 'utf-8');
52
+ const settings = JSON.parse(content) as { model?: string };
53
+ return settings.model ?? null;
54
+ } catch {
55
+ return null;
56
+ }
57
+ }
58
+
59
+ /**
60
+ * Get runtime configuration for task execution.
61
+ * Returns default values which can be overridden by command line options.
62
+ */
63
+ export function getConfig(): { timeout: number; maxRetries: number; autoCommit: boolean } {
64
+ return {
65
+ timeout: DEFAULT_RAF_CONFIG.defaultTimeout,
66
+ maxRetries: DEFAULT_RAF_CONFIG.defaultMaxRetries,
67
+ autoCommit: DEFAULT_RAF_CONFIG.autoCommit,
68
+ };
69
+ }
@@ -0,0 +1,81 @@
1
+ export type LogLevel = 'debug' | 'info' | 'warn' | 'error';
2
+
3
+ interface LoggerOptions {
4
+ verbose?: boolean;
5
+ debug?: boolean;
6
+ }
7
+
8
+ class Logger {
9
+ private verbose = false;
10
+ private debugMode = false;
11
+
12
+ configure(options: LoggerOptions): void {
13
+ this.verbose = options.verbose ?? false;
14
+ this.debugMode = options.debug ?? false;
15
+ }
16
+
17
+ /**
18
+ * @deprecated No longer used - kept for backwards compatibility
19
+ */
20
+ setContext(_prefix: string): void {
21
+ // No-op: context prefix feature removed in favor of minimal output style
22
+ }
23
+
24
+ /**
25
+ * @deprecated No longer used - kept for backwards compatibility
26
+ */
27
+ clearContext(): void {
28
+ // No-op: context prefix feature removed in favor of minimal output style
29
+ }
30
+
31
+ private formatMessage(message: string): string {
32
+ return message;
33
+ }
34
+
35
+ debug(message: string, ...args: unknown[]): void {
36
+ if (this.debugMode) {
37
+ console.log(`[DEBUG] ${message}`, ...args);
38
+ }
39
+ }
40
+
41
+ info(message: string, ...args: unknown[]): void {
42
+ console.log(this.formatMessage(message), ...args);
43
+ }
44
+
45
+ verbose_log(message: string, ...args: unknown[]): void {
46
+ if (this.verbose || this.debugMode) {
47
+ console.log(this.formatMessage(message), ...args);
48
+ }
49
+ }
50
+
51
+ warn(message: string, ...args: unknown[]): void {
52
+ console.warn(`⚠️ ${this.formatMessage(message)}`, ...args);
53
+ }
54
+
55
+ error(message: string, ...args: unknown[]): void {
56
+ console.error(`✗ ${this.formatMessage(message)}`, ...args);
57
+ }
58
+
59
+ print(message: string, ...args: unknown[]): void {
60
+ console.log(message, ...args);
61
+ }
62
+
63
+ success(message: string, ...args: unknown[]): void {
64
+ console.log(`✓ ${this.formatMessage(message)}`, ...args);
65
+ }
66
+
67
+ task(status: string, name: string): void {
68
+ console.log(`${status} ${name}`);
69
+ }
70
+
71
+ newline(): void {
72
+ console.log();
73
+ }
74
+
75
+ dim(message: string, ...args: unknown[]): void {
76
+ // ANSI escape code for dim text
77
+ console.log(`\x1b[2m${this.formatMessage(message)}\x1b[0m`, ...args);
78
+ }
79
+ }
80
+
81
+ export const logger = new Logger();