aiwcli 0.15.5 → 0.17.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 (435) hide show
  1. package/README.md +108 -1124
  2. package/bin/run.js +0 -4
  3. package/dist/capabilities/branch/adapters.d.ts +2 -0
  4. package/dist/capabilities/branch/adapters.js +21 -0
  5. package/dist/capabilities/branch/contracts.d.ts +57 -0
  6. package/dist/capabilities/branch/contracts.js +1 -0
  7. package/dist/capabilities/branch/control-plane.d.ts +2 -0
  8. package/dist/capabilities/branch/control-plane.js +343 -0
  9. package/dist/capabilities/branch/runtime-core.d.ts +5 -0
  10. package/dist/capabilities/branch/runtime-core.js +36 -0
  11. package/dist/capabilities/installation/control-plane/clean-command.d.ts +41 -0
  12. package/dist/capabilities/installation/control-plane/clean-command.js +196 -0
  13. package/dist/capabilities/installation/control-plane/clear-command.d.ts +162 -0
  14. package/dist/capabilities/installation/control-plane/clear-command.js +1249 -0
  15. package/dist/capabilities/installation/control-plane/init-command.d.ts +81 -0
  16. package/dist/capabilities/installation/control-plane/init-command.js +449 -0
  17. package/dist/capabilities/launch/contracts.d.ts +86 -0
  18. package/dist/capabilities/launch/contracts.js +1 -0
  19. package/dist/capabilities/launch/control-plane/execute-launch.d.ts +2 -0
  20. package/dist/capabilities/launch/control-plane/execute-launch.js +261 -0
  21. package/dist/capabilities/launch/runtime-core/launch-decisions.d.ts +82 -0
  22. package/dist/capabilities/launch/runtime-core/launch-decisions.js +202 -0
  23. package/dist/capabilities/launch/runtime-core/launch-options.d.ts +14 -0
  24. package/dist/capabilities/launch/runtime-core/launch-options.js +69 -0
  25. package/dist/cli/base-command.d.ts +18 -0
  26. package/dist/cli/base-command.js +55 -0
  27. package/dist/commands/branch.d.ts +1 -21
  28. package/dist/commands/branch.js +25 -417
  29. package/dist/commands/clean.d.ts +1 -41
  30. package/dist/commands/clean.js +1 -196
  31. package/dist/commands/clear.d.ts +1 -161
  32. package/dist/commands/clear.js +1 -1121
  33. package/dist/commands/init/index.d.ts +1 -98
  34. package/dist/commands/init/index.js +4 -478
  35. package/dist/commands/launch.d.ts +32 -12
  36. package/dist/commands/launch.js +107 -166
  37. package/dist/lib/claude-settings-types.d.ts +31 -19
  38. package/dist/lib/config.js +1 -2
  39. package/dist/lib/context/context-formatter.d.ts +74 -0
  40. package/dist/lib/context/context-formatter.js +493 -0
  41. package/dist/lib/context/context-selector.d.ts +42 -0
  42. package/dist/lib/context/context-selector.js +451 -0
  43. package/dist/lib/context/context-store.d.ts +100 -0
  44. package/dist/lib/context/context-store.js +644 -0
  45. package/dist/lib/context/plan-manager.d.ts +54 -0
  46. package/dist/lib/context/plan-manager.js +282 -0
  47. package/dist/lib/context/task-tracker.d.ts +44 -0
  48. package/dist/lib/context/task-tracker.js +146 -0
  49. package/dist/lib/core-ide-base.d.ts +4 -0
  50. package/dist/lib/core-ide-base.js +77 -0
  51. package/dist/lib/core-installer.d.ts +5 -0
  52. package/dist/lib/core-installer.js +33 -0
  53. package/dist/lib/debug.d.ts +0 -10
  54. package/dist/lib/debug.js +0 -10
  55. package/dist/lib/env-sanitizer.d.ts +25 -0
  56. package/dist/lib/env-sanitizer.js +46 -0
  57. package/dist/lib/errors.d.ts +0 -13
  58. package/dist/lib/errors.js +0 -15
  59. package/dist/lib/git-exclude-manager.d.ts +2 -2
  60. package/dist/lib/git-exclude-manager.js +3 -3
  61. package/dist/lib/hooks/context-monitor-logic.d.ts +6 -0
  62. package/dist/lib/hooks/context-monitor-logic.js +25 -0
  63. package/dist/lib/hooks/hook-utils.d.ts +143 -0
  64. package/dist/lib/hooks/hook-utils.js +620 -0
  65. package/dist/lib/hooks/prompt-binding-logic.d.ts +7 -0
  66. package/dist/lib/hooks/prompt-binding-logic.js +50 -0
  67. package/dist/lib/hooks/session-end-logic.d.ts +5 -0
  68. package/dist/lib/hooks/session-end-logic.js +51 -0
  69. package/dist/lib/hooks-merger.js +25 -19
  70. package/dist/lib/ide-path-resolver.d.ts +19 -7
  71. package/dist/lib/ide-path-resolver.js +25 -9
  72. package/dist/lib/install-state.d.ts +34 -0
  73. package/dist/lib/install-state.js +154 -0
  74. package/dist/lib/json-io.d.ts +12 -0
  75. package/dist/lib/json-io.js +30 -0
  76. package/dist/lib/lsp-patch.d.ts +12 -0
  77. package/dist/lib/lsp-patch.js +156 -0
  78. package/dist/lib/multiplexer.d.ts +65 -0
  79. package/dist/lib/multiplexer.js +38 -0
  80. package/dist/lib/multiplexers/psmux.d.ts +55 -0
  81. package/dist/lib/multiplexers/psmux.js +324 -0
  82. package/dist/lib/multiplexers/tmux.d.ts +36 -0
  83. package/dist/lib/multiplexers/tmux.js +221 -0
  84. package/dist/lib/multiplexers/wezterm.d.ts +38 -0
  85. package/dist/lib/multiplexers/wezterm.js +225 -0
  86. package/dist/lib/mux-utils.d.ts +6 -0
  87. package/dist/lib/mux-utils.js +36 -0
  88. package/dist/lib/paths.d.ts +2 -2
  89. package/dist/lib/paths.js +2 -2
  90. package/dist/lib/platform-commands.d.ts +27 -0
  91. package/dist/lib/platform-commands.js +49 -0
  92. package/dist/lib/prompt-file-manager.d.ts +23 -0
  93. package/dist/lib/prompt-file-manager.js +41 -0
  94. package/dist/lib/runtime/agent-launcher.d.ts +67 -0
  95. package/dist/lib/runtime/agent-launcher.js +262 -0
  96. package/dist/lib/runtime/aiw-cli.d.ts +39 -0
  97. package/dist/lib/runtime/aiw-cli.js +76 -0
  98. package/dist/lib/runtime/atomic-write.d.ts +19 -0
  99. package/dist/lib/runtime/atomic-write.js +121 -0
  100. package/dist/lib/runtime/cli-args.d.ts +58 -0
  101. package/dist/lib/runtime/cli-args.js +200 -0
  102. package/dist/lib/runtime/constants.d.ts +56 -0
  103. package/dist/lib/runtime/constants.js +230 -0
  104. package/dist/lib/runtime/executable-policy.d.ts +16 -0
  105. package/dist/lib/runtime/executable-policy.js +57 -0
  106. package/dist/lib/runtime/git-state.d.ts +9 -0
  107. package/dist/lib/runtime/git-state.js +59 -0
  108. package/dist/lib/runtime/inference.d.ts +37 -0
  109. package/dist/lib/runtime/inference.js +251 -0
  110. package/dist/lib/runtime/lint-dispatch.d.ts +40 -0
  111. package/dist/lib/runtime/lint-dispatch.js +285 -0
  112. package/dist/lib/runtime/logger.d.ts +66 -0
  113. package/dist/lib/runtime/logger.js +201 -0
  114. package/dist/lib/runtime/models.d.ts +20 -0
  115. package/dist/lib/runtime/models.js +20 -0
  116. package/dist/lib/runtime/platform-adapter.d.ts +7 -0
  117. package/dist/lib/runtime/platform-adapter.js +21 -0
  118. package/dist/lib/runtime/preflight.d.ts +24 -0
  119. package/dist/lib/runtime/preflight.js +65 -0
  120. package/dist/lib/runtime/sentinel-ipc.d.ts +14 -0
  121. package/dist/lib/runtime/sentinel-ipc.js +67 -0
  122. package/dist/lib/runtime/state-io.d.ts +31 -0
  123. package/dist/lib/runtime/state-io.js +179 -0
  124. package/dist/lib/runtime/stop-words.d.ts +20 -0
  125. package/dist/lib/runtime/stop-words.js +150 -0
  126. package/dist/lib/runtime/subprocess-utils.d.ts +29 -0
  127. package/dist/lib/runtime/subprocess-utils.js +96 -0
  128. package/dist/lib/runtime/tmux-preflight.d.ts +13 -0
  129. package/dist/lib/runtime/tmux-preflight.js +78 -0
  130. package/dist/lib/runtime/utils.d.ts +62 -0
  131. package/dist/lib/runtime/utils.js +192 -0
  132. package/dist/lib/schemas.d.ts +250 -0
  133. package/dist/lib/schemas.js +216 -0
  134. package/dist/lib/sentinel-manager.d.ts +32 -0
  135. package/dist/lib/sentinel-manager.js +62 -0
  136. package/dist/lib/sentinel-wrapper.d.ts +10 -0
  137. package/dist/lib/sentinel-wrapper.js +29 -0
  138. package/dist/lib/settings-hierarchy.js +3 -20
  139. package/dist/lib/shell-adapters/bash-adapter.d.ts +18 -0
  140. package/dist/lib/shell-adapters/bash-adapter.js +69 -0
  141. package/dist/lib/shell-adapters/index.d.ts +5 -0
  142. package/dist/lib/shell-adapters/index.js +7 -0
  143. package/dist/lib/shell-adapters/powershell-adapter.d.ts +18 -0
  144. package/dist/lib/shell-adapters/powershell-adapter.js +62 -0
  145. package/dist/lib/shell-adapters/shell-adapter.d.ts +45 -0
  146. package/dist/lib/shell-adapters/shell-adapter.js +5 -0
  147. package/dist/lib/shell-quoting.d.ts +5 -0
  148. package/dist/lib/shell-quoting.js +17 -0
  149. package/dist/lib/spawn-errors.d.ts +9 -0
  150. package/dist/lib/spawn-errors.js +29 -0
  151. package/dist/lib/spawn.js +5 -11
  152. package/dist/lib/spinner.d.ts +0 -5
  153. package/dist/lib/spinner.js +0 -16
  154. package/dist/lib/template-installer.d.ts +14 -5
  155. package/dist/lib/template-installer.js +40 -38
  156. package/dist/lib/template-resolver.d.ts +6 -7
  157. package/dist/lib/template-resolver.js +26 -21
  158. package/dist/lib/template-settings-reconstructor.d.ts +7 -2
  159. package/dist/lib/template-settings-reconstructor.js +76 -45
  160. package/dist/lib/terminal-strategy.d.ts +12 -0
  161. package/dist/lib/terminal-strategy.js +55 -0
  162. package/dist/lib/terminal.d.ts +34 -4
  163. package/dist/lib/terminal.js +192 -119
  164. package/dist/lib/tmux-pane-placement.d.ts +17 -0
  165. package/dist/lib/tmux-pane-placement.js +58 -0
  166. package/dist/lib/tmux-primitives.d.ts +3 -0
  167. package/dist/lib/tmux-primitives.js +11 -0
  168. package/dist/lib/tmux-session.d.ts +32 -0
  169. package/dist/lib/tmux-session.js +87 -0
  170. package/dist/lib/tty-detection.js +1 -1
  171. package/dist/lib/types.d.ts +168 -0
  172. package/dist/lib/types.js +6 -0
  173. package/dist/lib/version.d.ts +1 -1
  174. package/dist/lib/version.js +1 -1
  175. package/dist/lib/windsurf-hooks-hierarchy.js +6 -23
  176. package/dist/platform/launch.d.ts +11 -0
  177. package/dist/platform/launch.js +11 -0
  178. package/dist/templates/CLAUDE.md +30 -40
  179. package/dist/templates/cc-native/.claude/settings.json +26 -36
  180. package/dist/templates/cc-native/CC-NATIVE-README.md +1 -1
  181. package/dist/templates/cc-native/TEMPLATE-SCHEMA.md +20 -12
  182. package/dist/templates/cc-native/_cc-native/cc-native.config.json +2 -6
  183. package/dist/templates/cc-native/_cc-native/hooks/CLAUDE.md +39 -59
  184. package/dist/templates/cc-native/_cc-native/hooks/cc-native-plan-review.ts +9 -11
  185. package/dist/templates/cc-native/_cc-native/hooks/enhance_plan_post_subagent.ts +2 -2
  186. package/dist/templates/cc-native/_cc-native/hooks/enhance_plan_post_write.ts +4 -5
  187. package/dist/templates/cc-native/_cc-native/hooks/mark_questions_asked.ts +4 -4
  188. package/dist/templates/cc-native/_cc-native/hooks/plan_questions_early.ts +2 -27
  189. package/dist/templates/cc-native/_cc-native/hooks/validate_task_prompt.ts +7 -7
  190. package/dist/templates/cc-native/_cc-native/lib-ts/.mocharc.json +9 -0
  191. package/dist/templates/cc-native/_cc-native/lib-ts/__tests__/aggregate-agents.test.ts +118 -0
  192. package/dist/templates/cc-native/_cc-native/lib-ts/__tests__/artifacts.test.ts +234 -0
  193. package/dist/templates/cc-native/_cc-native/lib-ts/__tests__/cc-native-state.test.ts +170 -0
  194. package/dist/templates/cc-native/_cc-native/lib-ts/__tests__/cli-output-parser.test.ts +73 -0
  195. package/dist/templates/cc-native/_cc-native/lib-ts/__tests__/config.test.ts +64 -0
  196. package/dist/templates/cc-native/_cc-native/lib-ts/__tests__/constants.test.ts +40 -0
  197. package/dist/templates/cc-native/_cc-native/lib-ts/__tests__/debug.test.ts +42 -0
  198. package/dist/templates/cc-native/_cc-native/lib-ts/__tests__/exports.test.ts +58 -0
  199. package/dist/templates/cc-native/_cc-native/lib-ts/__tests__/helpers.ts +107 -0
  200. package/dist/templates/cc-native/_cc-native/lib-ts/__tests__/hooks/add-plan-context.hook.test.ts +97 -0
  201. package/dist/templates/cc-native/_cc-native/lib-ts/__tests__/hooks/plan-questions.hook.test.ts +81 -0
  202. package/dist/templates/cc-native/_cc-native/lib-ts/__tests__/hooks/plan-review.hook.test.ts +71 -0
  203. package/dist/templates/cc-native/_cc-native/lib-ts/__tests__/json-parser.test.ts +99 -0
  204. package/dist/templates/cc-native/_cc-native/lib-ts/__tests__/orchestrator-agent.test.ts +288 -0
  205. package/dist/templates/cc-native/_cc-native/lib-ts/__tests__/orchestrator.test.ts +48 -0
  206. package/dist/templates/cc-native/_cc-native/lib-ts/__tests__/reviewers.test.ts +32 -0
  207. package/dist/templates/cc-native/_cc-native/lib-ts/__tests__/state.test.ts +124 -0
  208. package/dist/templates/cc-native/_cc-native/lib-ts/__tests__/verdict.test.ts +93 -0
  209. package/dist/templates/cc-native/_cc-native/lib-ts/agent-selection.ts +163 -0
  210. package/dist/templates/cc-native/_cc-native/lib-ts/aggregate-agents.ts +6 -14
  211. package/dist/templates/cc-native/_cc-native/{artifacts/lib → lib-ts/artifacts}/format.ts +597 -599
  212. package/dist/templates/cc-native/_cc-native/{artifacts/lib → lib-ts/artifacts}/index.ts +26 -26
  213. package/dist/templates/cc-native/_cc-native/{artifacts/lib → lib-ts/artifacts}/tracker.ts +106 -107
  214. package/dist/templates/cc-native/_cc-native/{artifacts/lib → lib-ts/artifacts}/write.ts +118 -119
  215. package/dist/templates/cc-native/_cc-native/lib-ts/artifacts.ts +21 -0
  216. package/dist/templates/cc-native/_cc-native/lib-ts/cc-native-state.ts +17 -16
  217. package/dist/templates/cc-native/_cc-native/lib-ts/cli-output-parser.ts +132 -10
  218. package/dist/templates/cc-native/_cc-native/lib-ts/config.ts +1 -1
  219. package/dist/templates/cc-native/_cc-native/lib-ts/constants.ts +6 -6
  220. package/dist/templates/cc-native/_cc-native/lib-ts/corroboration.ts +119 -0
  221. package/dist/templates/cc-native/_cc-native/lib-ts/debug.ts +2 -3
  222. package/dist/templates/cc-native/_cc-native/{plan-review/lib → lib-ts}/graduation.ts +132 -132
  223. package/dist/templates/cc-native/_cc-native/lib-ts/index.ts +88 -86
  224. package/dist/templates/cc-native/_cc-native/lib-ts/json-parser.ts +5 -6
  225. package/dist/templates/cc-native/_cc-native/{plan-review/lib → lib-ts}/orchestrator.ts +70 -70
  226. package/dist/templates/cc-native/_cc-native/{plan-review/lib → lib-ts}/output-builder.ts +130 -121
  227. package/dist/templates/cc-native/_cc-native/lib-ts/package-lock.json +1679 -0
  228. package/dist/templates/cc-native/_cc-native/lib-ts/package.json +24 -0
  229. package/dist/templates/cc-native/_cc-native/lib-ts/plan-discovery.ts +5 -5
  230. package/dist/templates/cc-native/_cc-native/lib-ts/plan-enhancement.ts +1 -6
  231. package/dist/templates/cc-native/_cc-native/{plan-review/lib → lib-ts}/plan-questions.ts +101 -101
  232. package/dist/templates/cc-native/_cc-native/{plan-review/lib → lib-ts}/review-pipeline.ts +511 -543
  233. package/dist/templates/cc-native/_cc-native/lib-ts/reviewers/__tests__/agent-providers.test.ts +262 -0
  234. package/dist/templates/cc-native/_cc-native/{plan-review/lib → lib-ts}/reviewers/agent.ts +71 -85
  235. package/dist/templates/{_shared/lib-ts/agent-exec → cc-native/_cc-native/lib-ts/reviewers/base}/base-agent.ts +138 -150
  236. package/dist/templates/cc-native/_cc-native/{plan-review/lib → lib-ts}/reviewers/index.ts +12 -12
  237. package/dist/templates/cc-native/_cc-native/{plan-review/lib → lib-ts}/reviewers/providers/claude-agent.ts +66 -57
  238. package/dist/templates/cc-native/_cc-native/{plan-review/lib → lib-ts}/reviewers/providers/codex-agent.ts +185 -200
  239. package/dist/templates/cc-native/_cc-native/{plan-review/lib → lib-ts}/reviewers/providers/gemini-agent.ts +39 -40
  240. package/dist/templates/cc-native/_cc-native/{plan-review/lib → lib-ts}/reviewers/providers/orchestrator-claude-agent.ts +196 -225
  241. package/dist/templates/cc-native/_cc-native/{plan-review/lib → lib-ts}/reviewers/schemas.ts +201 -201
  242. package/dist/templates/cc-native/_cc-native/{plan-review/lib → lib-ts}/reviewers/types.ts +21 -23
  243. package/dist/templates/cc-native/_cc-native/lib-ts/rlm/__tests__/hyde.test.ts +365 -0
  244. package/dist/templates/cc-native/_cc-native/lib-ts/rlm/__tests__/ollama-client.test.ts +223 -0
  245. package/dist/templates/cc-native/_cc-native/lib-ts/rlm/embedding-indexer.ts +12 -16
  246. package/dist/templates/cc-native/_cc-native/lib-ts/rlm/hyde.ts +3 -2
  247. package/dist/templates/cc-native/_cc-native/lib-ts/rlm/index.ts +31 -31
  248. package/dist/templates/cc-native/_cc-native/lib-ts/rlm/logger.ts +7 -8
  249. package/dist/templates/cc-native/_cc-native/lib-ts/rlm/ollama-client.ts +7 -9
  250. package/dist/templates/cc-native/_cc-native/lib-ts/rlm/retrieval-pipeline.ts +16 -19
  251. package/dist/templates/cc-native/_cc-native/lib-ts/rlm/transcript-indexer.ts +37 -41
  252. package/dist/templates/cc-native/_cc-native/lib-ts/rlm/transcript-loader.ts +33 -43
  253. package/dist/templates/cc-native/_cc-native/lib-ts/rlm/transcript-searcher.ts +20 -20
  254. package/dist/templates/cc-native/_cc-native/lib-ts/rlm/types.ts +9 -10
  255. package/dist/templates/cc-native/_cc-native/lib-ts/rlm/vector-store.ts +3 -4
  256. package/dist/templates/cc-native/_cc-native/lib-ts/settings.ts +50 -126
  257. package/dist/templates/cc-native/_cc-native/lib-ts/state.ts +20 -22
  258. package/dist/templates/cc-native/_cc-native/lib-ts/tsconfig.json +2 -2
  259. package/dist/templates/cc-native/_cc-native/lib-ts/types.ts +14 -89
  260. package/dist/templates/cc-native/_cc-native/{plan-review/lib → lib-ts}/verdict.ts +72 -72
  261. package/dist/templates/cc-native/_cc-native/plan-review/CLAUDE.md +38 -1
  262. package/dist/templates/cc-native/_cc-native/plan-review/lib/__tests__/agent-selection.test.ts +345 -0
  263. package/dist/templates/cc-native/_cc-native/plan-review/lib/__tests__/preflight.test.ts +344 -0
  264. package/dist/templates/cc-native/_cc-native/plan-review/lib/agent-selection.ts +38 -16
  265. package/dist/templates/cc-native/_cc-native/plan-review/lib/preflight.ts +56 -26
  266. package/dist/templates/cc-native/_cc-native/scripts/council_debate.ts +242 -0
  267. package/dist/templates/cc-native/_cc-native/scripts/council_debate_simple.ts +294 -0
  268. package/dist/templates/cc-native/_cc-native/{plan-review/workflows → workflows}/specdev.md +9 -9
  269. package/dist/templates/core/.claude/skills/codex/SKILL.md +25 -0
  270. package/dist/templates/core/.claude/skills/devin/SKILL.md +25 -0
  271. package/dist/templates/core/.claude/skills/handoff/SKILL.md +11 -0
  272. package/dist/templates/core/.claude/skills/handoff-resume/SKILL.md +11 -0
  273. package/dist/templates/core/.claude/skills/meta-plan/SKILL.md +13 -0
  274. package/dist/templates/core/.codex/skills/codex/SKILL.md +13 -0
  275. package/dist/templates/core/.codex/skills/devin/SKILL.md +19 -0
  276. package/dist/templates/core/.codex/skills/handoff/SKILL.md +11 -0
  277. package/dist/templates/core/.codex/skills/handoff-resume/SKILL.md +11 -0
  278. package/dist/templates/core/.codex/skills/meta-plan/SKILL.md +13 -0
  279. package/dist/templates/core/.devin/AGENTS.md +5 -0
  280. package/dist/templates/core/.devin/config.json +12 -0
  281. package/dist/templates/core/.devin/skills/codex/SKILL.md +19 -0
  282. package/dist/templates/core/.devin/skills/devin/SKILL.md +13 -0
  283. package/dist/templates/core/.devin/skills/handoff/SKILL.md +11 -0
  284. package/dist/templates/core/.devin/skills/handoff-resume/SKILL.md +11 -0
  285. package/dist/templates/core/.devin/skills/meta-plan/SKILL.md +13 -0
  286. package/dist/templates/core/.windsurf/workflows/handoff-resume.md +9 -0
  287. package/dist/templates/{_shared → core}/.windsurf/workflows/handoff.md +1 -1
  288. package/dist/templates/{_shared → core}/.windsurf/workflows/meta-plan.md +1 -1
  289. package/dist/templates/core/hooks-ts/_utils/git-state.ts +2 -0
  290. package/dist/templates/{_shared → core}/hooks-ts/archive_plan.ts +15 -44
  291. package/dist/templates/core/hooks-ts/codex_explorer.ts +160 -0
  292. package/dist/templates/{_shared → core}/hooks-ts/context_monitor.ts +23 -55
  293. package/dist/templates/{_shared → core}/hooks-ts/file-suggestion.ts +5 -22
  294. package/dist/templates/{_shared → core}/hooks-ts/lint_after_edit.ts +7 -9
  295. package/dist/templates/core/hooks-ts/pre_compact.ts +36 -0
  296. package/dist/templates/{_shared → core}/hooks-ts/session_end.ts +38 -78
  297. package/dist/templates/{_shared → core}/hooks-ts/session_start.ts +5 -5
  298. package/dist/templates/core/hooks-ts/task_create_capture.ts +32 -0
  299. package/dist/templates/{_shared → core}/hooks-ts/task_update_capture.ts +9 -24
  300. package/dist/templates/core/hooks-ts/user_prompt_submit.ts +46 -0
  301. package/dist/templates/{_shared → core}/lib-ts/CLAUDE.md +27 -16
  302. package/dist/templates/{_shared → core}/lib-ts/context/CLAUDE.md +9 -6
  303. package/dist/templates/{_shared → core}/lib-ts/context/context-formatter.ts +16 -21
  304. package/dist/templates/{_shared → core}/lib-ts/context/context-selector.ts +8 -6
  305. package/dist/templates/{_shared → core}/lib-ts/context/context-store.ts +59 -20
  306. package/dist/templates/{_shared → core}/lib-ts/context/plan-manager.ts +19 -15
  307. package/dist/templates/{_shared → core}/lib-ts/context/task-tracker.ts +3 -3
  308. package/dist/templates/core/lib-ts/hooks/context-monitor-logic.ts +32 -0
  309. package/dist/templates/{_shared/lib-ts/base → core/lib-ts/hooks}/hook-utils.ts +179 -41
  310. package/dist/templates/core/lib-ts/hooks/prompt-binding-logic.ts +80 -0
  311. package/dist/templates/core/lib-ts/hooks/session-end-logic.ts +82 -0
  312. package/dist/templates/core/lib-ts/package.json +19 -0
  313. package/dist/templates/core/lib-ts/runtime/agent-launcher.ts +369 -0
  314. package/dist/templates/core/lib-ts/runtime/aiw-cli.ts +108 -0
  315. package/dist/templates/{_shared/lib-ts/base → core/lib-ts/runtime}/atomic-write.ts +12 -7
  316. package/dist/templates/{_shared/lib-ts/base → core/lib-ts/runtime}/cli-args.ts +24 -8
  317. package/dist/templates/{_shared/lib-ts/base → core/lib-ts/runtime}/constants.ts +326 -324
  318. package/dist/templates/core/lib-ts/runtime/executable-policy.ts +89 -0
  319. package/dist/templates/{_shared/lib-ts/base → core/lib-ts/runtime}/git-state.ts +6 -4
  320. package/dist/templates/{_shared/lib-ts/base → core/lib-ts/runtime}/inference.ts +60 -23
  321. package/dist/templates/{_shared/lib-ts/base → core/lib-ts/runtime}/lint-dispatch.ts +25 -23
  322. package/dist/templates/{_shared/lib-ts/base → core/lib-ts/runtime}/logger.ts +32 -29
  323. package/dist/templates/{_shared/lib-ts/base → core/lib-ts/runtime}/models.ts +9 -2
  324. package/dist/templates/core/lib-ts/runtime/platform-adapter.ts +33 -0
  325. package/dist/templates/{_shared/lib-ts/base → core/lib-ts/runtime}/preflight.ts +4 -3
  326. package/dist/templates/core/lib-ts/runtime/sentinel-ipc.ts +91 -0
  327. package/dist/templates/{_shared/lib-ts/base → core/lib-ts/runtime}/state-io.ts +20 -11
  328. package/dist/templates/core/lib-ts/runtime/stop-words.ts +185 -0
  329. package/dist/templates/core/lib-ts/runtime/subprocess-utils.ts +147 -0
  330. package/dist/templates/core/lib-ts/runtime/tmux-preflight.ts +93 -0
  331. package/dist/templates/{_shared/lib-ts/base → core/lib-ts/runtime}/utils.ts +34 -4
  332. package/dist/templates/core/lib-ts/schemas.ts +233 -0
  333. package/dist/templates/{_shared → core}/lib-ts/templates/formatters.ts +7 -5
  334. package/dist/templates/{_shared → core}/lib-ts/templates/plan-context.ts +2 -1
  335. package/dist/templates/{_shared → core}/lib-ts/tsconfig.json +3 -1
  336. package/dist/templates/{_shared → core}/lib-ts/types.ts +78 -77
  337. package/dist/templates/core/scripts/resolve-run.ts +93 -0
  338. package/dist/templates/{_shared → core}/scripts/resolve_context.ts +3 -3
  339. package/dist/templates/{_shared → core}/scripts/status_line.ts +26 -21
  340. package/dist/templates/core/skills/codex/CLAUDE.md +83 -0
  341. package/dist/templates/{_shared → core}/skills/codex/SKILL.md +27 -18
  342. package/dist/templates/{_shared → core}/skills/codex/lib/codex-watcher.ts +79 -113
  343. package/dist/templates/{_shared → core}/skills/codex/scripts/launch-codex.ts +134 -148
  344. package/dist/templates/{_shared → core}/skills/codex/scripts/watch-codex.ts +6 -4
  345. package/dist/templates/core/skills/devin/CLAUDE.md +122 -0
  346. package/dist/templates/core/skills/devin/SKILL.md +73 -0
  347. package/dist/templates/core/skills/devin/lib/devin-watcher.ts +300 -0
  348. package/dist/templates/core/skills/devin/scripts/launch-devin.ts +258 -0
  349. package/dist/templates/{_shared → core}/skills/handoff-system/CLAUDE.md +436 -433
  350. package/dist/templates/{_shared → core}/skills/handoff-system/lib/document-generator.ts +9 -7
  351. package/dist/templates/{_shared → core}/skills/handoff-system/lib/handoff-reader.ts +6 -4
  352. package/dist/templates/{_shared → core}/skills/handoff-system/scripts/resume_handoff.ts +10 -8
  353. package/dist/templates/{_shared → core}/skills/handoff-system/scripts/save_handoff.ts +12 -10
  354. package/dist/templates/{_shared → core}/skills/handoff-system/workflows/handoff-resume.md +2 -2
  355. package/dist/templates/{_shared → core}/skills/handoff-system/workflows/handoff.md +6 -5
  356. package/dist/templates/{_shared → core}/skills/meta-plan/CLAUDE.md +2 -1
  357. package/dist/templates/{_shared → core}/skills/meta-plan/workflows/meta-plan.md +8 -7
  358. package/oclif.manifest.json +89 -13
  359. package/package.json +13 -12
  360. package/dist/lib/base-command.d.ts +0 -114
  361. package/dist/lib/base-command.js +0 -153
  362. package/dist/lib/env-compat.d.ts +0 -18
  363. package/dist/lib/env-compat.js +0 -23
  364. package/dist/lib/stdin.d.ts +0 -48
  365. package/dist/lib/stdin.js +0 -60
  366. package/dist/templates/_shared/.claude/settings.json +0 -120
  367. package/dist/templates/_shared/.claude/skills/codex/SKILL.md +0 -35
  368. package/dist/templates/_shared/.claude/skills/handoff/SKILL.md +0 -13
  369. package/dist/templates/_shared/.claude/skills/handoff-resume/SKILL.md +0 -13
  370. package/dist/templates/_shared/.claude/skills/meta-plan/SKILL.md +0 -43
  371. package/dist/templates/_shared/.codex/workflows/codex.md +0 -11
  372. package/dist/templates/_shared/.codex/workflows/handoff.md +0 -226
  373. package/dist/templates/_shared/.codex/workflows/meta-plan.md +0 -347
  374. package/dist/templates/_shared/hooks-ts/_utils/git-state.ts +0 -2
  375. package/dist/templates/_shared/hooks-ts/pre_compact.ts +0 -49
  376. package/dist/templates/_shared/hooks-ts/task_create_capture.ts +0 -48
  377. package/dist/templates/_shared/hooks-ts/user_prompt_submit.ts +0 -93
  378. package/dist/templates/_shared/lib-ts/agent-exec/backends/headless.ts +0 -33
  379. package/dist/templates/_shared/lib-ts/agent-exec/backends/index.ts +0 -6
  380. package/dist/templates/_shared/lib-ts/agent-exec/backends/tmux.ts +0 -119
  381. package/dist/templates/_shared/lib-ts/agent-exec/execution-backend.ts +0 -50
  382. package/dist/templates/_shared/lib-ts/agent-exec/index.ts +0 -6
  383. package/dist/templates/_shared/lib-ts/agent-exec/structured-output.ts +0 -166
  384. package/dist/templates/_shared/lib-ts/base/launchers/tmux-launcher.ts +0 -173
  385. package/dist/templates/_shared/lib-ts/base/launchers/window-launcher.ts +0 -93
  386. package/dist/templates/_shared/lib-ts/base/launchers/wt-launcher.ts +0 -64
  387. package/dist/templates/_shared/lib-ts/base/pane-launcher.ts +0 -55
  388. package/dist/templates/_shared/lib-ts/base/sentinel-ipc.ts +0 -87
  389. package/dist/templates/_shared/lib-ts/base/stop-words.ts +0 -184
  390. package/dist/templates/_shared/lib-ts/base/subprocess-utils.ts +0 -249
  391. package/dist/templates/_shared/lib-ts/base/tmux-driver.ts +0 -341
  392. package/dist/templates/_shared/lib-ts/base/tmux-pane-placement.ts +0 -78
  393. package/dist/templates/_shared/lib-ts/package.json +0 -20
  394. package/dist/templates/_shared/scripts/resolve-run.ts +0 -62
  395. package/dist/templates/_shared/skills/codex/CLAUDE.md +0 -70
  396. package/dist/templates/cc-native/_cc-native/CLAUDE.md +0 -73
  397. package/dist/templates/cc-native/_cc-native/artifacts/CLAUDE.md +0 -64
  398. package/dist/templates/cc-native/_cc-native/lib-ts/CLAUDE.md +0 -70
  399. package/dist/templates/cc-native/_cc-native/plan-review/CODING-STANDARDS-CHECKLIST.md +0 -75
  400. package/dist/templates/cc-native/_cc-native/plan-review/agents/CLAUDE.md +0 -143
  401. package/dist/templates/cc-native/_cc-native/plan-review/agents/PLAN-ORCHESTRATOR.md +0 -213
  402. package/dist/templates/cc-native/_cc-native/plan-review/agents/plan-questions/PLAN-QUESTIONER.md +0 -70
  403. package/dist/templates/cc-native/_cc-native/plan-review/agents/plan-review/ARCH-EVOLUTION.md +0 -62
  404. package/dist/templates/cc-native/_cc-native/plan-review/agents/plan-review/ARCH-PATTERNS.md +0 -61
  405. package/dist/templates/cc-native/_cc-native/plan-review/agents/plan-review/ARCH-STRUCTURE.md +0 -62
  406. package/dist/templates/cc-native/_cc-native/plan-review/agents/plan-review/ASSUMPTION-TRACER.md +0 -56
  407. package/dist/templates/cc-native/_cc-native/plan-review/agents/plan-review/CLARITY-AUDITOR.md +0 -53
  408. package/dist/templates/cc-native/_cc-native/plan-review/agents/plan-review/COMPLETENESS-FEASIBILITY.md +0 -66
  409. package/dist/templates/cc-native/_cc-native/plan-review/agents/plan-review/COMPLETENESS-GAPS.md +0 -70
  410. package/dist/templates/cc-native/_cc-native/plan-review/agents/plan-review/COMPLETENESS-ORDERING.md +0 -62
  411. package/dist/templates/cc-native/_cc-native/plan-review/agents/plan-review/CONSTRAINT-VALIDATOR.md +0 -72
  412. package/dist/templates/cc-native/_cc-native/plan-review/agents/plan-review/DESIGN-ADR-VALIDATOR.md +0 -61
  413. package/dist/templates/cc-native/_cc-native/plan-review/agents/plan-review/DESIGN-SCALE-MATCHER.md +0 -64
  414. package/dist/templates/cc-native/_cc-native/plan-review/agents/plan-review/DEVILS-ADVOCATE.md +0 -56
  415. package/dist/templates/cc-native/_cc-native/plan-review/agents/plan-review/DOCUMENTATION-PHILOSOPHY.md +0 -86
  416. package/dist/templates/cc-native/_cc-native/plan-review/agents/plan-review/HANDOFF-READINESS.md +0 -59
  417. package/dist/templates/cc-native/_cc-native/plan-review/agents/plan-review/HIDDEN-COMPLEXITY.md +0 -58
  418. package/dist/templates/cc-native/_cc-native/plan-review/agents/plan-review/INCREMENTAL-DELIVERY.md +0 -66
  419. package/dist/templates/cc-native/_cc-native/plan-review/agents/plan-review/RISK-DEPENDENCY.md +0 -62
  420. package/dist/templates/cc-native/_cc-native/plan-review/agents/plan-review/RISK-FMEA.md +0 -66
  421. package/dist/templates/cc-native/_cc-native/plan-review/agents/plan-review/RISK-PREMORTEM.md +0 -71
  422. package/dist/templates/cc-native/_cc-native/plan-review/agents/plan-review/RISK-REVERSIBILITY.md +0 -74
  423. package/dist/templates/cc-native/_cc-native/plan-review/agents/plan-review/SCOPE-BOUNDARY.md +0 -77
  424. package/dist/templates/cc-native/_cc-native/plan-review/agents/plan-review/SIMPLICITY-GUARDIAN.md +0 -62
  425. package/dist/templates/cc-native/_cc-native/plan-review/agents/plan-review/SKEPTIC.md +0 -68
  426. package/dist/templates/cc-native/_cc-native/plan-review/agents/plan-review/TESTDRIVEN-BEHAVIOR-AUDITOR.md +0 -61
  427. package/dist/templates/cc-native/_cc-native/plan-review/agents/plan-review/TESTDRIVEN-CHARACTERIZATION.md +0 -71
  428. package/dist/templates/cc-native/_cc-native/plan-review/agents/plan-review/TESTDRIVEN-FIRST-VALIDATOR.md +0 -61
  429. package/dist/templates/cc-native/_cc-native/plan-review/agents/plan-review/TESTDRIVEN-PYRAMID-ANALYZER.md +0 -61
  430. package/dist/templates/cc-native/_cc-native/plan-review/agents/plan-review/TRADEOFF-COSTS.md +0 -67
  431. package/dist/templates/cc-native/_cc-native/plan-review/agents/plan-review/TRADEOFF-STAKEHOLDERS.md +0 -65
  432. package/dist/templates/cc-native/_cc-native/plan-review/agents/plan-review/VERIFY-COVERAGE.md +0 -74
  433. package/dist/templates/cc-native/_cc-native/plan-review/agents/plan-review/VERIFY-STRENGTH.md +0 -69
  434. package/dist/templates/cc-native/_cc-native/plan-review/lib/corroboration.ts +0 -172
  435. package/dist/templates/cc-native/_cc-native/plan-review/lib/reviewers/base/base-agent.ts +0 -7
@@ -0,0 +1,41 @@
1
+ /**
2
+ * PromptFileManager — owns prompt file lifecycle (creation, cleanup).
3
+ * Replaces scattered writeFileSync calls for prompt temp files.
4
+ */
5
+ import { writeFileSync } from 'node:fs';
6
+ import * as fs from 'node:fs';
7
+ import path from 'node:path';
8
+ export class PromptFileManager {
9
+ files = [];
10
+ tempDir;
11
+ now;
12
+ pid;
13
+ constructor(options) {
14
+ this.tempDir = options.tempDir;
15
+ this.now = options.now;
16
+ this.pid = options.pid;
17
+ }
18
+ /**
19
+ * Write prompt text to a temp file and return the path.
20
+ */
21
+ materialize(promptText) {
22
+ const filePath = path.join(this.tempDir, `aiwcli-prompt-${this.now()}-${this.pid}.txt`);
23
+ writeFileSync(filePath, promptText, { encoding: 'utf8', mode: 0o600 });
24
+ this.files.push(filePath);
25
+ return filePath;
26
+ }
27
+ /**
28
+ * Clean up all created prompt files. Call in finally block.
29
+ */
30
+ cleanup() {
31
+ for (const filePath of this.files) {
32
+ try {
33
+ fs.unlinkSync(filePath);
34
+ }
35
+ catch {
36
+ // Best-effort cleanup.
37
+ }
38
+ }
39
+ this.files.length = 0;
40
+ }
41
+ }
@@ -0,0 +1,67 @@
1
+ /**
2
+ * Shared agent-launcher utilities used by Codex, Devin, and future agent skills.
3
+ * Extracted from codex skill to avoid duplication across agent launch scripts.
4
+ */
5
+ import type { ContextState } from "../types.js";
6
+ export declare const POLL_INTERVAL_MS = 2000;
7
+ export declare const POLL_TIMEOUT_MS = 3000;
8
+ export declare const WAIT_TIMEOUT_MS_DEFAULT = 14400000;
9
+ type PaneBackend = "tmux" | "window" | "exec";
10
+ export interface PaneWatchTarget {
11
+ backend?: PaneBackend;
12
+ paneId?: string;
13
+ sentinelPath?: string;
14
+ }
15
+ export declare function sleep(ms: number): Promise<void>;
16
+ /**
17
+ * Print to stderr (shared by agent launch scripts).
18
+ */
19
+ export declare function eprint(...args: unknown[]): void;
20
+ /**
21
+ * Best-effort cleanup of a sentinel directory.
22
+ */
23
+ export declare function cleanupSentinel(sentinelPath: string | null | undefined): void;
24
+ /**
25
+ * Case-sensitive (or case-insensitive on Windows) path comparison.
26
+ */
27
+ export declare function samePath(a: string, b: string): boolean;
28
+ /**
29
+ * Heuristic check for LLM output that isn't a real summary.
30
+ */
31
+ export declare function looksLikeBadSummary(output: string): boolean;
32
+ /**
33
+ * Return a deterministic summary file path for a given agent prefix + task ID.
34
+ * Callers can advertise this path before the session finishes so consumers
35
+ * know where to look for the summary once it's written.
36
+ */
37
+ export declare function getWellKnownSummaryPath(prefix: string, taskId: string, projectRoot?: string): string;
38
+ export declare function persistSummary(summary: string, prefix: string, sessionId?: string, taskId?: string, projectRoot?: string): string | null;
39
+ /** Fallback plan discovery: scan all context plan dirs by mtime. */
40
+ export declare function findLatestPlanByMtime(projectRoot: string): string | null;
41
+ export declare function buildFileModeBootstrapPrompt(targetPath: string, sourceLabel: "plan" | "file", extraPrompt?: string, orientation?: string): string;
42
+ export declare function resolveContextForLaunch(contextFlag: string | undefined, projectRoot: string): ContextState | null;
43
+ export interface WritePromptFileOpts {
44
+ ctx?: ContextState | null;
45
+ extraPrompt?: string;
46
+ projectRoot: string;
47
+ tempFilePrefix: string;
48
+ }
49
+ export interface WriteFileRefPromptFileOpts extends WritePromptFileOpts {
50
+ fileReferencePath: string;
51
+ label: "plan" | "file";
52
+ }
53
+ export interface WriteInlinePromptFileOpts extends WritePromptFileOpts {
54
+ text: string;
55
+ }
56
+ /**
57
+ * Build a file-reference bootstrap prompt and write it to a temp file.
58
+ * Returns the temp file path.
59
+ */
60
+ export declare function writeFileRefPromptFile(opts: WriteFileRefPromptFileOpts): string;
61
+ /**
62
+ * Write inline text to a temp file, prepend context orientation, append extra prompt.
63
+ * Returns the temp file path.
64
+ */
65
+ export declare function writeInlinePromptFile(opts: WriteInlinePromptFileOpts): string;
66
+ export declare function waitForPaneClose(target: string | PaneWatchTarget, timeoutMs?: number): Promise<void>;
67
+ export {};
@@ -0,0 +1,262 @@
1
+ /**
2
+ * Shared agent-launcher utilities used by Codex, Devin, and future agent skills.
3
+ * Extracted from codex skill to avoid duplication across agent launch scripts.
4
+ */
5
+ import * as fs from "node:fs";
6
+ import * as os from "node:os";
7
+ import path from "node:path";
8
+ import { logDebug, logWarn } from "./logger.js";
9
+ import { execFileAsync, findExecutable } from "./subprocess-utils.js";
10
+ import { buildExternalAgentContext } from "../context/context-formatter.js";
11
+ import { getContextBySessionId, getContext } from "../context/context-store.js";
12
+ // ---------------------------------------------------------------------------
13
+ // Constants
14
+ // ---------------------------------------------------------------------------
15
+ export const POLL_INTERVAL_MS = 2000;
16
+ export const POLL_TIMEOUT_MS = 3000;
17
+ export const WAIT_TIMEOUT_MS_DEFAULT = 14_400_000;
18
+ // ---------------------------------------------------------------------------
19
+ // Generic Helpers
20
+ // ---------------------------------------------------------------------------
21
+ export function sleep(ms) {
22
+ return new Promise((resolve) => {
23
+ setTimeout(resolve, ms);
24
+ });
25
+ }
26
+ /**
27
+ * Print to stderr (shared by agent launch scripts).
28
+ */
29
+ export function eprint(...args) {
30
+ process.stderr.write(args.map(String).join(" ") + "\n");
31
+ }
32
+ /**
33
+ * Best-effort cleanup of a sentinel directory.
34
+ */
35
+ export function cleanupSentinel(sentinelPath) {
36
+ if (!sentinelPath)
37
+ return;
38
+ try {
39
+ const dir = path.dirname(sentinelPath);
40
+ fs.rmSync(dir, { recursive: true, force: true });
41
+ }
42
+ catch { /* best-effort */ }
43
+ }
44
+ /**
45
+ * Case-sensitive (or case-insensitive on Windows) path comparison.
46
+ */
47
+ export function samePath(a, b) {
48
+ const left = path.resolve(a);
49
+ const right = path.resolve(b);
50
+ if (process.platform === "win32") {
51
+ return left.toLowerCase() === right.toLowerCase();
52
+ }
53
+ return left === right;
54
+ }
55
+ /**
56
+ * Heuristic check for LLM output that isn't a real summary.
57
+ */
58
+ export function looksLikeBadSummary(output) {
59
+ const normalized = output.toLowerCase();
60
+ return (normalized.includes("don't see") ||
61
+ normalized.includes("no output") ||
62
+ normalized.includes("could you provide") ||
63
+ normalized.includes("paste"));
64
+ }
65
+ /**
66
+ * Return a deterministic summary file path for a given agent prefix + task ID.
67
+ * Callers can advertise this path before the session finishes so consumers
68
+ * know where to look for the summary once it's written.
69
+ */
70
+ export function getWellKnownSummaryPath(prefix, taskId, projectRoot) {
71
+ const sessionKey = projectRoot
72
+ ? path.basename(projectRoot)
73
+ : "unknown";
74
+ const dir = path.join(os.tmpdir(), "aiw-agent-output", sessionKey);
75
+ return path.join(dir, `${prefix}-${taskId}.md`).replaceAll("\\", "/");
76
+ }
77
+ export function persistSummary(summary, prefix, sessionId, taskId, projectRoot) {
78
+ try {
79
+ const suffix = sessionId
80
+ ? sessionId.replaceAll(/[^a-zA-Z0-9_-]/g, "").slice(0, 8)
81
+ : String(process.pid);
82
+ const filePath = path.join(os.tmpdir(), `${prefix}-summary-${Date.now()}-${suffix}.md`);
83
+ fs.writeFileSync(filePath, summary, "utf8");
84
+ // Also write to the well-known path for deterministic discovery.
85
+ if (taskId) {
86
+ try {
87
+ const wkPath = getWellKnownSummaryPath(prefix, taskId, projectRoot);
88
+ fs.mkdirSync(path.dirname(wkPath), { recursive: true });
89
+ fs.writeFileSync(wkPath, summary, "utf8");
90
+ }
91
+ catch {
92
+ logWarn("agent-launcher", "Failed to write well-known summary path");
93
+ }
94
+ }
95
+ return filePath.replaceAll("\\", "/");
96
+ }
97
+ catch (error) {
98
+ logWarn("agent-launcher", `Failed to persist summary: ${String(error)}`);
99
+ return null;
100
+ }
101
+ }
102
+ // ---------------------------------------------------------------------------
103
+ // Plan Discovery
104
+ // ---------------------------------------------------------------------------
105
+ /** Fallback plan discovery: scan all context plan dirs by mtime. */
106
+ export function findLatestPlanByMtime(projectRoot) {
107
+ const contextsDir = path.join(projectRoot, "_output", "contexts");
108
+ if (!fs.existsSync(contextsDir))
109
+ return null;
110
+ let best = null;
111
+ for (const ctxEntry of fs.readdirSync(contextsDir)) {
112
+ if (ctxEntry.startsWith("_"))
113
+ continue;
114
+ const plansDir = path.join(contextsDir, ctxEntry, "plans");
115
+ if (!fs.existsSync(plansDir))
116
+ continue;
117
+ for (const file of fs.readdirSync(plansDir)) {
118
+ if (!file.endsWith(".md"))
119
+ continue;
120
+ const fullPath = path.join(plansDir, file);
121
+ try {
122
+ const mtime = fs.statSync(fullPath).mtimeMs;
123
+ if (!best || mtime > best.mtime) {
124
+ best = { path: fullPath, mtime };
125
+ }
126
+ }
127
+ catch { /* skip unreadable */ }
128
+ }
129
+ }
130
+ return best?.path ?? null;
131
+ }
132
+ // ---------------------------------------------------------------------------
133
+ // Bootstrap Prompt Construction
134
+ // ---------------------------------------------------------------------------
135
+ export function buildFileModeBootstrapPrompt(targetPath, sourceLabel, extraPrompt, orientation) {
136
+ const absolutePath = path.resolve(targetPath);
137
+ const sourceTitle = sourceLabel === "plan" ? "Plan Source" : "File Source";
138
+ const sections = ["## Startup Brief", ""];
139
+ if (orientation?.trim()) {
140
+ sections.push(orientation.trim(), "", "---", "");
141
+ }
142
+ sections.push(`## ${sourceTitle}`, "", `Primary input path: ${absolutePath}`, "", "Read this file directly from disk before taking action.", "Treat its contents as the source of truth.", "Do not ask for the file contents to be pasted inline.");
143
+ if (extraPrompt?.trim()) {
144
+ sections.push("", "## Additional Instructions", "", extraPrompt.trim());
145
+ }
146
+ return sections.join("\n");
147
+ }
148
+ // ---------------------------------------------------------------------------
149
+ // Context Resolution
150
+ // ---------------------------------------------------------------------------
151
+ export function resolveContextForLaunch(contextFlag, projectRoot) {
152
+ if (contextFlag) {
153
+ return getContext(contextFlag, projectRoot) ?? null;
154
+ }
155
+ const sessionId = process.env.CLAUDE_SESSION_ID;
156
+ if (sessionId) {
157
+ return getContextBySessionId(sessionId, projectRoot) ?? null;
158
+ }
159
+ return null;
160
+ }
161
+ /**
162
+ * Build a file-reference bootstrap prompt and write it to a temp file.
163
+ * Returns the temp file path.
164
+ */
165
+ export function writeFileRefPromptFile(opts) {
166
+ let orientation = "";
167
+ if (opts.ctx) {
168
+ try {
169
+ orientation = buildExternalAgentContext(opts.ctx, opts.projectRoot);
170
+ }
171
+ catch {
172
+ logWarn("agent-launcher", `Context orientation build failed for ${opts.ctx.id}`);
173
+ }
174
+ }
175
+ const bootstrap = buildFileModeBootstrapPrompt(opts.fileReferencePath, opts.label, opts.extraPrompt, orientation);
176
+ const tempFile = path.join(os.tmpdir(), `${opts.tempFilePrefix}-file-ref-${Date.now()}.md`);
177
+ fs.writeFileSync(tempFile, bootstrap, "utf8");
178
+ return tempFile;
179
+ }
180
+ /**
181
+ * Write inline text to a temp file, prepend context orientation, append extra prompt.
182
+ * Returns the temp file path.
183
+ */
184
+ export function writeInlinePromptFile(opts) {
185
+ let content = opts.text;
186
+ if (opts.ctx) {
187
+ try {
188
+ const orientation = buildExternalAgentContext(opts.ctx, opts.projectRoot);
189
+ content = `${orientation}\n\n---\n\n${content}`;
190
+ }
191
+ catch {
192
+ logWarn("agent-launcher", `Context orientation prepend failed for ${opts.ctx.id}`);
193
+ }
194
+ }
195
+ if (opts.extraPrompt?.trim()) {
196
+ content = `${content}\n\n---\n\n## Additional Instructions\n\n${opts.extraPrompt}`;
197
+ }
198
+ const tempFile = path.join(os.tmpdir(), `${opts.tempFilePrefix}-prompt-${Date.now()}.md`);
199
+ fs.writeFileSync(tempFile, content, "utf8");
200
+ return tempFile;
201
+ }
202
+ // ---------------------------------------------------------------------------
203
+ // Pane Watching
204
+ // ---------------------------------------------------------------------------
205
+ async function waitForSentinelClose(sentinelPath, timeoutMs) {
206
+ const deadline = Date.now() + timeoutMs;
207
+ while (true) {
208
+ if (fs.existsSync(sentinelPath))
209
+ return;
210
+ if (Date.now() >= deadline) {
211
+ logDebug("agent-launcher", `watch timeout reached waiting for sentinel ${sentinelPath}`);
212
+ return;
213
+ }
214
+ const remainingMs = deadline - Date.now();
215
+ await sleep(Math.max(0, Math.min(POLL_INTERVAL_MS, remainingMs)));
216
+ }
217
+ }
218
+ function normalizeWatchTarget(target) {
219
+ if (typeof target === "string") {
220
+ return { backend: "tmux", paneId: target };
221
+ }
222
+ return target;
223
+ }
224
+ export async function waitForPaneClose(target, timeoutMs = WAIT_TIMEOUT_MS_DEFAULT) {
225
+ const watch = normalizeWatchTarget(target);
226
+ if (watch.sentinelPath) {
227
+ await waitForSentinelClose(watch.sentinelPath, timeoutMs);
228
+ return;
229
+ }
230
+ const backend = watch.backend ?? "tmux";
231
+ const paneId = watch.paneId ?? "";
232
+ if (backend !== "tmux") {
233
+ logDebug("agent-launcher", `No pane watcher for backend=${backend}; continuing without wait`);
234
+ return;
235
+ }
236
+ if (!paneId)
237
+ return;
238
+ const tmuxPath = findExecutable("tmux");
239
+ if (!tmuxPath) {
240
+ logWarn("agent-launcher", `tmux unavailable while watching pane ${paneId}`);
241
+ return;
242
+ }
243
+ const deadline = Date.now() + timeoutMs;
244
+ while (true) {
245
+ if (Date.now() >= deadline) {
246
+ logDebug("agent-launcher", `watch timeout reached for pane ${paneId} after ${timeoutMs}ms`);
247
+ return;
248
+ }
249
+ const result = await execFileAsync(tmuxPath, ["list-panes", "-a", "-F", "#{pane_id}"], {
250
+ timeout: POLL_TIMEOUT_MS,
251
+ });
252
+ if (result.exitCode !== 0) {
253
+ logDebug("agent-launcher", `list-panes failed; assuming pane closed (${result.stderr.trim() || "no stderr"})`);
254
+ return;
255
+ }
256
+ const activePaneIds = result.stdout.split(/\r?\n/).map((line) => line.trim()).filter(Boolean);
257
+ if (!activePaneIds.includes(paneId))
258
+ return;
259
+ const remainingMs = deadline - Date.now();
260
+ await sleep(Math.max(0, Math.min(POLL_INTERVAL_MS, remainingMs)));
261
+ }
262
+ }
@@ -0,0 +1,39 @@
1
+ /**
2
+ * Helper to discover and invoke the `aiw` CLI binary from template scripts.
3
+ *
4
+ * Reads the resolved binary path from `.aiwcli/.aiw-bin-path` (written by `aiw init`).
5
+ * Falls back to `aiw` on PATH if the file is missing.
6
+ */
7
+ export interface AiwLaunchOptions {
8
+ /** Launch codex instead of claude. */
9
+ codex?: boolean;
10
+ /** Launch devin instead of claude. */
11
+ devin?: boolean;
12
+ /** Working directory. */
13
+ cwd?: string;
14
+ /** Extra env vars to inject. */
15
+ env?: Record<string, string>;
16
+ /** Return JSON output. */
17
+ json?: boolean;
18
+ /** Path to prompt file. */
19
+ promptPath?: string;
20
+ /** Split direction: auto, h, or v. */
21
+ split?: "auto" | "h" | "v";
22
+ /** Timeout in ms (only relevant with --wait). */
23
+ timeoutMs?: number;
24
+ /** Block until pane exits. */
25
+ wait?: boolean;
26
+ }
27
+ export interface AiwLaunchResult {
28
+ backend: string;
29
+ exitCode: null | number;
30
+ launched: boolean;
31
+ paneId: null | string;
32
+ reason: null | string;
33
+ sentinelPath: null | string;
34
+ }
35
+ /**
36
+ * Shell out to `aiw launch` with structured options.
37
+ * Returns parsed JSON result when --json is used.
38
+ */
39
+ export declare function aiwLaunch(options: AiwLaunchOptions): Promise<AiwLaunchResult>;
@@ -0,0 +1,76 @@
1
+ /**
2
+ * Helper to discover and invoke the `aiw` CLI binary from template scripts.
3
+ *
4
+ * Reads the resolved binary path from `.aiwcli/.aiw-bin-path` (written by `aiw init`).
5
+ * Falls back to `aiw` on PATH if the file is missing.
6
+ */
7
+ import * as fs from "node:fs";
8
+ import path from "node:path";
9
+ import { getProjectRoot } from "./constants.js";
10
+ import { execFileAsync } from "./subprocess-utils.js";
11
+ function resolveAiwBin(cwd) {
12
+ const projectRoot = getProjectRoot(cwd ?? process.cwd());
13
+ const binPathFile = path.join(projectRoot, ".aiwcli", ".aiw-bin-path");
14
+ try {
15
+ const binPath = fs.readFileSync(binPathFile, "utf8").trim();
16
+ if (binPath && fs.existsSync(binPath))
17
+ return binPath;
18
+ }
19
+ catch {
20
+ // Fall through to PATH lookup
21
+ }
22
+ return "aiw";
23
+ }
24
+ /**
25
+ * Shell out to `aiw launch` with structured options.
26
+ * Returns parsed JSON result when --json is used.
27
+ */
28
+ export async function aiwLaunch(options) {
29
+ const bin = resolveAiwBin(options.cwd);
30
+ const args = ["launch"];
31
+ if (options.codex)
32
+ args.push("--codex");
33
+ if (options.devin)
34
+ args.push("--devin");
35
+ if (options.wait)
36
+ args.push("--wait");
37
+ args.push("--json");
38
+ if (options.split)
39
+ args.push("--split", options.split);
40
+ if (options.env && Object.keys(options.env).length > 0) {
41
+ args.push("--env", JSON.stringify(options.env));
42
+ }
43
+ if (options.promptPath)
44
+ args.push("--prompt-path", options.promptPath);
45
+ const result = await execFileAsync(bin, args, {
46
+ timeout: options.timeoutMs ?? 14_400_000,
47
+ env: process.env,
48
+ shell: process.platform === "win32",
49
+ });
50
+ return parseJsonResult(result);
51
+ }
52
+ function parseJsonResult(result) {
53
+ try {
54
+ const lines = result.stdout.trim().split(/\r?\n/);
55
+ const lastLine = lines.at(-1) ?? "";
56
+ const parsed = JSON.parse(lastLine);
57
+ return {
58
+ launched: Boolean(parsed.launched),
59
+ backend: String(parsed.backend ?? "exec"),
60
+ paneId: parsed.handle ?? parsed.paneId ?? null,
61
+ sentinelPath: parsed.sentinelPath ?? null,
62
+ exitCode: typeof parsed.exitCode === "number" ? parsed.exitCode : null,
63
+ reason: parsed.reason ?? null,
64
+ };
65
+ }
66
+ catch {
67
+ return {
68
+ launched: false,
69
+ backend: "exec",
70
+ paneId: null,
71
+ sentinelPath: null,
72
+ exitCode: result.exitCode,
73
+ reason: `Failed to parse aiw launch output: ${result.stderr || result.stdout}`,
74
+ };
75
+ }
76
+ }
@@ -0,0 +1,19 @@
1
+ /**
2
+ * Cross-platform atomic file writes with security.
3
+ * Crash-safe writes by writing to temp file then renaming.
4
+ * NOT for concurrent access — assumes single-session-per-context.
5
+ * See SPEC.md §4
6
+ */
7
+ /**
8
+ * Write file atomically with retry logic.
9
+ * Creates temp file, writes, fsyncs, renames.
10
+ * Returns [success, error].
11
+ * See SPEC.md §4.2
12
+ */
13
+ export declare function atomicWrite(filePath: string, content: string, maxAttempts?: number, backoffMs?: number[], fsync?: boolean): [boolean, null | string];
14
+ /**
15
+ * Append to file with retry logic.
16
+ * For JSONL files where each line is independent.
17
+ * See SPEC.md §4.3
18
+ */
19
+ export declare function atomicAppend(filePath: string, content: string, maxAttempts?: number, backoffMs?: number[], fsync?: boolean): [boolean, null | string];
@@ -0,0 +1,121 @@
1
+ /**
2
+ * Cross-platform atomic file writes with security.
3
+ * Crash-safe writes by writing to temp file then renaming.
4
+ * NOT for concurrent access — assumes single-session-per-context.
5
+ * See SPEC.md §4
6
+ */
7
+ import * as crypto from "node:crypto";
8
+ import * as fs from "node:fs";
9
+ import path from "node:path";
10
+ /**
11
+ * Write file atomically with retry logic.
12
+ * Creates temp file, writes, fsyncs, renames.
13
+ * Returns [success, error].
14
+ * See SPEC.md §4.2
15
+ */
16
+ export function atomicWrite(filePath, content, maxAttempts = 2, backoffMs = [500, 1000], fsync = true) {
17
+ // Ensure parent directory exists
18
+ const dir = path.dirname(filePath);
19
+ fs.mkdirSync(dir, { recursive: true });
20
+ const stem = path.basename(filePath, path.extname(filePath));
21
+ for (let attempt = 0; attempt < maxAttempts; attempt++) {
22
+ const tmpName = `.${stem}_${crypto.randomBytes(4).toString("hex")}.tmp`;
23
+ const tmpPath = path.join(dir, tmpName);
24
+ try {
25
+ // Write to temp file
26
+ const fd = fs.openSync(tmpPath, "w");
27
+ try {
28
+ fs.writeSync(fd, content, undefined, "utf8");
29
+ if (fsync)
30
+ fs.fsyncSync(fd);
31
+ }
32
+ finally {
33
+ fs.closeSync(fd);
34
+ }
35
+ // Set restrictive permissions (best-effort)
36
+ try {
37
+ fs.chmodSync(tmpPath, 0o600);
38
+ }
39
+ catch {
40
+ // May fail on some filesystems
41
+ }
42
+ // Atomic rename (cross-platform on modern Node/Bun)
43
+ fs.renameSync(tmpPath, filePath);
44
+ return [true, null];
45
+ }
46
+ catch (error) {
47
+ // Clean up temp file
48
+ try {
49
+ fs.unlinkSync(tmpPath);
50
+ }
51
+ catch {
52
+ // Best-effort cleanup
53
+ }
54
+ if (attempt < maxAttempts - 1) {
55
+ const waitMs = backoffMs[Math.min(attempt, backoffMs.length - 1)] ?? backoffMs.at(-1) ?? 500;
56
+ sleepSync(waitMs);
57
+ }
58
+ else {
59
+ const errType = error?.constructor?.name ?? "Error";
60
+ const errMsg = String(error).split("\n")[0]?.slice(0, 200) ?? "";
61
+ return [false, `${errType}: ${errMsg}`];
62
+ }
63
+ }
64
+ }
65
+ return [false, "Max retry attempts exceeded"];
66
+ }
67
+ /**
68
+ * Append to file with retry logic.
69
+ * For JSONL files where each line is independent.
70
+ * See SPEC.md §4.3
71
+ */
72
+ export function atomicAppend(filePath, content, maxAttempts = 2, backoffMs = [500, 1000], fsync = true) {
73
+ // Ensure parent directory exists
74
+ const dir = path.dirname(filePath);
75
+ fs.mkdirSync(dir, { recursive: true });
76
+ const isNewFile = !fs.existsSync(filePath);
77
+ for (let attempt = 0; attempt < maxAttempts; attempt++) {
78
+ try {
79
+ const fd = fs.openSync(filePath, "a");
80
+ try {
81
+ fs.writeSync(fd, content, undefined, "utf8");
82
+ if (fsync)
83
+ fs.fsyncSync(fd);
84
+ }
85
+ finally {
86
+ fs.closeSync(fd);
87
+ }
88
+ // Set permissions on newly created files (best-effort)
89
+ if (isNewFile) {
90
+ try {
91
+ fs.chmodSync(filePath, 0o600);
92
+ }
93
+ catch {
94
+ // May fail on some filesystems
95
+ }
96
+ }
97
+ return [true, null];
98
+ }
99
+ catch (error) {
100
+ if (attempt < maxAttempts - 1) {
101
+ const waitMs = backoffMs[Math.min(attempt, backoffMs.length - 1)] ?? backoffMs.at(-1) ?? 500;
102
+ sleepSync(waitMs);
103
+ }
104
+ else {
105
+ const errType = error?.constructor?.name ?? "Error";
106
+ const errMsg = String(error).split("\n")[0]?.slice(0, 200) ?? "";
107
+ return [false, `${errType}: ${errMsg}`];
108
+ }
109
+ }
110
+ }
111
+ return [false, "Max retry attempts exceeded"];
112
+ }
113
+ /**
114
+ * Synchronous sleep for retry backoff.
115
+ * Uses Atomics.wait() for CPU-friendly blocking instead of busy-wait.
116
+ */
117
+ function sleepSync(ms) {
118
+ const sab = new SharedArrayBuffer(4);
119
+ const i32 = new Int32Array(sab);
120
+ Atomics.wait(i32, 0, 0, ms);
121
+ }
@@ -0,0 +1,58 @@
1
+ /**
2
+ * Centralized CLI argument construction for agent subprocesses.
3
+ * Single source of truth for Claude CLI and Codex CLI flag patterns,
4
+ * platform quoting, model tier resolution, and env setup.
5
+ */
6
+ import type { PreflightCommandConfig } from "./preflight.js";
7
+ export type InvocationMode = "structured" | "print" | "preflight";
8
+ export type CliProvider = "claude" | "codex" | "devin";
9
+ export type ModelTier = "fast" | "standard" | "smart";
10
+ declare const VALID_SANDBOXES: readonly ["read-only", "workspace-write", "danger-full-access"];
11
+ export type CodexSandbox = (typeof VALID_SANDBOXES)[number];
12
+ export declare function isCodexSandbox(value: string): value is CodexSandbox;
13
+ export interface CliArgSpec {
14
+ provider: CliProvider;
15
+ model: string | ModelTier;
16
+ mode: InvocationMode;
17
+ jsonSchema?: Record<string, unknown>;
18
+ maxTurns?: number;
19
+ systemPrompt?: string;
20
+ sandbox?: CodexSandbox;
21
+ outputSchemaPath?: string;
22
+ outputFilePath?: string;
23
+ extraArgs?: string[];
24
+ }
25
+ /** Codex REPL spec — model optional (Codex uses its default when omitted). */
26
+ export interface CodexReplSpec {
27
+ provider: "codex";
28
+ mode: "repl";
29
+ model?: string | ModelTier;
30
+ sandbox?: CodexSandbox;
31
+ yolo?: boolean;
32
+ extraArgs?: string[];
33
+ }
34
+ export interface CliInvocation {
35
+ cliName: string;
36
+ args: string[];
37
+ needsShell: boolean;
38
+ env: Record<string, string | undefined>;
39
+ }
40
+ export declare const MODEL_TIERS: Record<ModelTier, string>;
41
+ export declare const CODEX_MODEL_TIERS: Record<ModelTier, string>;
42
+ export declare const DEVIN_MODEL_TIERS: Record<ModelTier, string>;
43
+ export declare const TIER_TIMEOUTS: Record<ModelTier, number>;
44
+ export declare function isModelTier(value: string): value is ModelTier;
45
+ export declare function resolveModel(model: string | ModelTier): string;
46
+ export declare function resolveModelForProvider(model: string | ModelTier, provider: CliProvider): string;
47
+ export declare function getTierTimeout(tier: ModelTier): number;
48
+ /** Resolve a Codex model: tier resolution + pass-through. No aliases (those are skill-specific). */
49
+ export declare function resolveCodexModel(input: string): string;
50
+ /** Resolve a Devin model: tier resolution + pass-through. No aliases (those are skill-specific). */
51
+ export declare function resolveDevinModel(input: string): string;
52
+ export declare function buildCliInvocation(spec: CliArgSpec | CodexReplSpec): CliInvocation;
53
+ export declare function preflightSpec(provider: CliProvider, model: string): CliArgSpec;
54
+ export declare function inferenceSpec(model: string | ModelTier): CliArgSpec;
55
+ export declare function reviewSpec(provider: CliProvider, model: string, schema: Record<string, unknown>, systemPrompt?: string): CliArgSpec;
56
+ export declare function codexReplSpec(model?: string, sandbox?: CodexSandbox, yolo?: boolean): CodexReplSpec;
57
+ export declare function preflightCommandConfig(provider: CliProvider): PreflightCommandConfig;
58
+ export { CLAUDE_MODELS, CODEX_MODELS, DEVIN_MODELS } from "./models.js";