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,69 @@
1
+ /**
2
+ * BashAdapter — ShellAdapter for bash (Unix + MSYS2/Git Bash on Windows).
3
+ * Delegates to low-level primitives in shell-quoting.ts, sentinel-wrapper.ts, etc.
4
+ */
5
+ import { REPL_NESTING_VARS } from '../env-sanitizer.js';
6
+ import { execFileAsync, findExecutable } from '../runtime/subprocess-utils.js';
7
+ import { wrapSentinelSh } from '../sentinel-wrapper.js';
8
+ import { quoteForSh } from '../shell-quoting.js';
9
+ import { toMsysPosixPath } from '../tmux-primitives.js';
10
+ export class BashAdapter {
11
+ dialect = 'bash';
12
+ quote(value) {
13
+ return quoteForSh(value);
14
+ }
15
+ buildEnvPreamble(env) {
16
+ return Object.entries(env)
17
+ .map(([key, value]) => `${key}=${this.quote(value)}`)
18
+ .join(' ');
19
+ }
20
+ buildToolCommand(params) {
21
+ const { toolPath, args, env, mode, promptPath, promptText } = params;
22
+ const envPrefix = this.buildEnvPreamble(env);
23
+ const commandArgs = this.appendPromptArg(args, mode, promptText);
24
+ const argPart = commandArgs.map((arg) => this.quote(arg)).join(' ');
25
+ const base = [envPrefix, this.quote(toolPath), argPart]
26
+ .filter(Boolean)
27
+ .join(' ');
28
+ if (mode === 'exec' && promptPath) {
29
+ return `${base} < ${this.quote(promptPath)}`;
30
+ }
31
+ return base;
32
+ }
33
+ wrapSentinel(params) {
34
+ return wrapSentinelSh(params);
35
+ }
36
+ async resolveToolPath(toolName, nativePath) {
37
+ if (process.platform !== 'win32')
38
+ return nativePath;
39
+ // On Windows, resolve tool from bash's perspective (MSYS2/Git Bash PATH)
40
+ const bash = findExecutable('bash');
41
+ if (!bash)
42
+ return null;
43
+ const result = await execFileAsync(bash, ['-lc', `command -v ${toolName}`], {
44
+ timeout: 3000,
45
+ env: { ...process.env, MSYS_NO_PATHCONV: '1' },
46
+ });
47
+ return result.exitCode === 0 ? result.stdout.trim() || null : null;
48
+ }
49
+ buildNestingCleanup() {
50
+ const pathFix = 'export PATH="/usr/bin:/usr/local/bin:/mingw64/bin:$PATH";';
51
+ const unset = `unset ${REPL_NESTING_VARS.join(' ')};`;
52
+ return `${pathFix} ${unset}`;
53
+ }
54
+ normalizeCwd(cwd) {
55
+ return toMsysPosixPath(cwd);
56
+ }
57
+ wrapQuickExitRetry(command, toolPath, thresholdSec = 10) {
58
+ const warmup = `${toolPath} --version >/dev/null 2>&1`;
59
+ return `${warmup}; _qr_t0=$SECONDS; ${command}; if [ $((SECONDS - _qr_t0)) -lt ${thresholdSec} ]; then ${command}; fi`;
60
+ }
61
+ encodeForExecution(command) {
62
+ return command;
63
+ }
64
+ appendPromptArg(args, mode, promptText) {
65
+ if (mode !== 'repl' || promptText === undefined)
66
+ return args;
67
+ return [...args, promptText];
68
+ }
69
+ }
@@ -0,0 +1,5 @@
1
+ export { BashAdapter } from './bash-adapter.js';
2
+ export { PowerShellAdapter } from './powershell-adapter.js';
3
+ export type { SentinelWrapOptions, ShellAdapter, ToolCommandParams } from './shell-adapter.js';
4
+ import type { ShellAdapter } from './shell-adapter.js';
5
+ export declare function shellAdapterForBackend(backend: string): ShellAdapter;
@@ -0,0 +1,7 @@
1
+ export { BashAdapter } from './bash-adapter.js';
2
+ export { PowerShellAdapter } from './powershell-adapter.js';
3
+ import { BashAdapter } from './bash-adapter.js';
4
+ import { PowerShellAdapter } from './powershell-adapter.js';
5
+ export function shellAdapterForBackend(backend) {
6
+ return backend === 'psmux' ? new PowerShellAdapter() : new BashAdapter();
7
+ }
@@ -0,0 +1,18 @@
1
+ /**
2
+ * PowerShellAdapter — ShellAdapter for PowerShell (Windows, psmux backend).
3
+ * Delegates to low-level primitives in shell-quoting.ts, sentinel-wrapper.ts, etc.
4
+ */
5
+ import type { SentinelWrapOptions, ShellAdapter, ToolCommandParams } from './shell-adapter.js';
6
+ export declare class PowerShellAdapter implements ShellAdapter {
7
+ readonly dialect: "powershell";
8
+ quote(value: string): string;
9
+ buildEnvPreamble(env: Record<string, string>): string;
10
+ buildToolCommand(params: ToolCommandParams): string;
11
+ wrapSentinel(params: SentinelWrapOptions): string;
12
+ resolveToolPath(_toolName: string, nativePath: string): Promise<string | null>;
13
+ buildNestingCleanup(): string;
14
+ normalizeCwd(cwd: string): string;
15
+ wrapQuickExitRetry(command: string, _toolPath: string, _thresholdSec?: number): string;
16
+ encodeForExecution(command: string): string;
17
+ private appendPromptArg;
18
+ }
@@ -0,0 +1,62 @@
1
+ /**
2
+ * PowerShellAdapter — ShellAdapter for PowerShell (Windows, psmux backend).
3
+ * Delegates to low-level primitives in shell-quoting.ts, sentinel-wrapper.ts, etc.
4
+ */
5
+ import path from 'node:path';
6
+ import { REPL_NESTING_VARS } from '../env-sanitizer.js';
7
+ import { buildBootstrapPrompt } from '../mux-utils.js';
8
+ import { wrapSentinelPowerShell } from '../sentinel-wrapper.js';
9
+ import { quoteForPowerShell, toEncodedPowerShell } from '../shell-quoting.js';
10
+ export class PowerShellAdapter {
11
+ dialect = 'powershell';
12
+ quote(value) {
13
+ return quoteForPowerShell(value);
14
+ }
15
+ buildEnvPreamble(env) {
16
+ return Object.entries(env)
17
+ .map(([key, value]) => `$env:${key}=${this.quote(value)}`)
18
+ .join('; ');
19
+ }
20
+ buildToolCommand(params) {
21
+ const { toolPath, args, env, mode, promptPath } = params;
22
+ const envPrefix = this.buildEnvPreamble(env);
23
+ const commandArgs = this.appendPromptArg(args, mode, promptPath);
24
+ const argArray = commandArgs.map((arg) => this.quote(arg)).join(', ');
25
+ const invocation = `& ${this.quote(toolPath)}${argArray ? ` @(${argArray})` : ''}`;
26
+ const body = mode === 'exec' && promptPath
27
+ ? `Get-Content -Raw -Path ${this.quote(promptPath)} | ${invocation}`
28
+ : invocation;
29
+ return [envPrefix, body].filter(Boolean).join('; ');
30
+ }
31
+ wrapSentinel(params) {
32
+ return wrapSentinelPowerShell(params);
33
+ }
34
+ async resolveToolPath(_toolName, nativePath) {
35
+ return nativePath;
36
+ }
37
+ buildNestingCleanup() {
38
+ return REPL_NESTING_VARS
39
+ .map((v) => `Remove-Item Env:\\${v} -ErrorAction SilentlyContinue`)
40
+ .join('; ') + ';';
41
+ }
42
+ normalizeCwd(cwd) {
43
+ return cwd;
44
+ }
45
+ wrapQuickExitRetry(command, _toolPath, _thresholdSec) {
46
+ // Quick-exit retry not implemented for PowerShell — inline retry handles it
47
+ return command;
48
+ }
49
+ encodeForExecution(command) {
50
+ return toEncodedPowerShell(command);
51
+ }
52
+ appendPromptArg(args, mode, promptPath) {
53
+ if (mode !== 'repl' || !promptPath)
54
+ return args;
55
+ const absolutePromptPath = path.resolve(promptPath);
56
+ const formatted = process.platform === 'win32'
57
+ ? absolutePromptPath.replaceAll('\\', '/')
58
+ : absolutePromptPath;
59
+ const bootstrap = buildBootstrapPrompt(formatted);
60
+ return [...args, bootstrap];
61
+ }
62
+ }
@@ -0,0 +1,45 @@
1
+ /**
2
+ * ShellAdapter interface — abstracts shell-dialect differences for command building.
3
+ * BashAdapter and PowerShellAdapter implement this for their respective shells.
4
+ */
5
+ export interface ToolCommandParams {
6
+ toolPath: string;
7
+ args: string[];
8
+ env: Record<string, string>;
9
+ mode: 'exec' | 'repl';
10
+ promptPath?: string | undefined;
11
+ promptText?: string | undefined;
12
+ }
13
+ export interface SentinelWrapOptions {
14
+ command: string;
15
+ sentinelPath: string;
16
+ autoClose: boolean;
17
+ autoCloseCommand?: string | undefined;
18
+ holdPane: boolean;
19
+ holdMessage: string;
20
+ }
21
+ export interface ShellAdapter {
22
+ readonly dialect: 'bash' | 'powershell';
23
+ /** Quote a value for safe inclusion in a shell command. */
24
+ quote(value: string): string;
25
+ /** Build env var assignments as a command preamble (KEY=val for bash, $env:KEY=val for PS). */
26
+ buildEnvPreamble(env: Record<string, string>): string;
27
+ /** Build a complete tool invocation command (env + tool + args + prompt handling). */
28
+ buildToolCommand(params: ToolCommandParams): string;
29
+ /** Wrap a command with sentinel exit-code tracking and optional pane hold. */
30
+ wrapSentinel(params: SentinelWrapOptions): string;
31
+ /**
32
+ * Resolve a tool path for the shell dialect.
33
+ * On Windows with bash, resolves via `command -v` in bash.
34
+ * On Unix or PowerShell, returns nativePath as-is.
35
+ */
36
+ resolveToolPath(toolName: string, nativePath: string): Promise<string | null>;
37
+ /** Build a shell snippet that clears REPL nesting env vars. */
38
+ buildNestingCleanup(): string;
39
+ /** Normalize a cwd path for the shell dialect (e.g. Windows→POSIX for bash). */
40
+ normalizeCwd(cwd: string): string;
41
+ /** Wrap a command with warmup + quick-exit retry logic. */
42
+ wrapQuickExitRetry(command: string, toolPath: string, thresholdSec?: number): string;
43
+ /** Encode a command for safe execution (identity for bash, Base64 for PowerShell). */
44
+ encodeForExecution(command: string): string;
45
+ }
@@ -0,0 +1,5 @@
1
+ /**
2
+ * ShellAdapter interface — abstracts shell-dialect differences for command building.
3
+ * BashAdapter and PowerShellAdapter implement this for their respective shells.
4
+ */
5
+ export {};
@@ -0,0 +1,5 @@
1
+ export declare function quoteForSh(input: string): string;
2
+ export declare function quoteForPowerShell(input: string): string;
3
+ /** Wrap a PowerShell command using -EncodedCommand to avoid all quoting issues. */
4
+ export declare function toEncodedPowerShell(command: string): string;
5
+ export declare function escapeSingleQuotedPath(path: string, dialect: 'bash' | 'powershell'): string;
@@ -0,0 +1,17 @@
1
+ export function quoteForSh(input) {
2
+ return `'${input.replaceAll("'", "'\"'\"'")}'`;
3
+ }
4
+ export function quoteForPowerShell(input) {
5
+ return `'${input.replaceAll("'", "''")}'`;
6
+ }
7
+ /** Wrap a PowerShell command using -EncodedCommand to avoid all quoting issues. */
8
+ export function toEncodedPowerShell(command) {
9
+ const encoded = Buffer.from(command, 'utf16le').toString('base64');
10
+ return `powershell.exe -NoProfile -EncodedCommand ${encoded}`;
11
+ }
12
+ export function escapeSingleQuotedPath(path, dialect) {
13
+ if (dialect === 'powershell') {
14
+ return path.replaceAll("'", "''");
15
+ }
16
+ return path.replaceAll("'", String.raw `'\''`);
17
+ }
@@ -0,0 +1,9 @@
1
+ import { ProcessSpawnError } from './errors.js';
2
+ export declare function getInstallInstruction(command: string): string;
3
+ export declare function formatCommandNotFoundMessage(command: string): string;
4
+ export declare function formatPathWarning(command: string): string;
5
+ export declare function classifySpawnError(command: string, error: NodeJS.ErrnoException): ProcessSpawnError;
6
+ export declare function resolveWindowsSpawnArgs(command: string, args: string[], cmdExists: (commandName: string) => boolean): null | {
7
+ args: string[];
8
+ command: string;
9
+ };
@@ -0,0 +1,29 @@
1
+ import { ProcessSpawnError } from './errors.js';
2
+ const INSTALL_INSTRUCTIONS = {
3
+ claude: 'Install Claude Code from https://claude.ai/download.',
4
+ codex: 'Install Codex from npm.',
5
+ devin: 'Install Devin from https://cli.devin.ai.',
6
+ };
7
+ export function getInstallInstruction(command) {
8
+ return INSTALL_INSTRUCTIONS[command] ?? 'Check that the command exists and is executable.';
9
+ }
10
+ export function formatCommandNotFoundMessage(command) {
11
+ return `Command not found: ${command}. ${getInstallInstruction(command)}`;
12
+ }
13
+ export function formatPathWarning(command) {
14
+ return `${command} not found on PATH (${getInstallInstruction(command).replace(/\.$/, '')})`;
15
+ }
16
+ export function classifySpawnError(command, error) {
17
+ if (error.code === 'ENOENT') {
18
+ return new ProcessSpawnError(formatCommandNotFoundMessage(command), 'ENOENT');
19
+ }
20
+ if (error.code === 'EACCES') {
21
+ return new ProcessSpawnError(`Permission denied: ${command}. Check file permissions.`, 'EACCES');
22
+ }
23
+ return new ProcessSpawnError(`Failed to spawn ${command}: ${error.message}. Check that the command exists and is executable.`, error.code);
24
+ }
25
+ export function resolveWindowsSpawnArgs(command, args, cmdExists) {
26
+ if (!cmdExists(`${command}.cmd`))
27
+ return null;
28
+ return { command: 'cmd.exe', args: ['/c', command, ...args] };
29
+ }
package/dist/lib/spawn.js CHANGED
@@ -41,6 +41,7 @@
41
41
  import { execSync, spawn as nodeSpawn } from 'node:child_process';
42
42
  import { debug, debugSpawn } from './debug.js';
43
43
  import { ProcessSpawnError } from './errors.js';
44
+ import { classifySpawnError, resolveWindowsSpawnArgs } from './spawn-errors.js';
44
45
  /**
45
46
  * Spawn an external process and return its exit code.
46
47
  *
@@ -94,9 +95,10 @@ export async function spawnProcess(command, args = [], options = {}) {
94
95
  catch (error) {
95
96
  // If command not found and .cmd file exists, use cmd.exe wrapper
96
97
  // This avoids DEP0190 deprecation warning while supporting npm-installed commands
97
- if (error instanceof ProcessSpawnError && error.code === 'ENOENT' && commandExistsInPath(`${command}.cmd`)) {
98
+ const windowsSpawnArgs = resolveWindowsSpawnArgs(command, args, commandExistsInPath);
99
+ if (error instanceof ProcessSpawnError && error.code === 'ENOENT' && windowsSpawnArgs) {
98
100
  // Use cmd.exe /c to execute .cmd file without shell mode or deprecation warning
99
- return attemptSpawn('cmd.exe', ['/c', command, ...args], { cwd, stdio, detached, shell: false });
101
+ return attemptSpawn(windowsSpawnArgs.command, windowsSpawnArgs.args, { cwd, stdio, detached, shell: false });
100
102
  }
101
103
  throw error;
102
104
  }
@@ -126,15 +128,7 @@ function attemptSpawn(command, args, spawnOptions) {
126
128
  const childProcess = nodeSpawn(command, args, spawnOptions);
127
129
  // Handle spawn errors (ENOENT, EACCES, etc.)
128
130
  childProcess.on('error', (error) => {
129
- if (error.code === 'ENOENT') {
130
- reject(new ProcessSpawnError(`Command not found: ${command}. Install Claude Code from https://claude.ai/download.`, 'ENOENT'));
131
- }
132
- else if (error.code === 'EACCES') {
133
- reject(new ProcessSpawnError(`Permission denied: ${command}. Check file permissions.`, 'EACCES'));
134
- }
135
- else {
136
- reject(new ProcessSpawnError(`Failed to spawn ${command}: ${error.message}. Check that the command exists and is executable.`, error.code));
137
- }
131
+ reject(classifySpawnError(command, error));
138
132
  });
139
133
  // Capture exit code on process close
140
134
  childProcess.on('close', (code, signal) => {
@@ -12,8 +12,3 @@ import { type Ora } from 'ora';
12
12
  export declare function createSpinner(text: string, flags?: {
13
13
  quiet?: boolean;
14
14
  }): Ora;
15
- /**
16
- * Helper for common "loading" operations with spinner.
17
- * Automatically handles success/failure and cleanup.
18
- */
19
- export declare function withSpinner<T>(text: string, operation: () => Promise<T>): Promise<T>;
@@ -16,19 +16,3 @@ export function createSpinner(text, flags) {
16
16
  text,
17
17
  });
18
18
  }
19
- /**
20
- * Helper for common "loading" operations with spinner.
21
- * Automatically handles success/failure and cleanup.
22
- */
23
- export async function withSpinner(text, operation) {
24
- const spinner = createSpinner(text).start();
25
- try {
26
- const result = await operation();
27
- spinner.succeed();
28
- return result;
29
- }
30
- catch (error) {
31
- spinner.fail();
32
- throw error;
33
- }
34
- }
@@ -34,10 +34,10 @@ interface TemplateInstallationStatus {
34
34
  existing: TemplateItemStatus[];
35
35
  /** Items that are missing from target directory */
36
36
  missing: TemplateItemStatus[];
37
- /** The method-specific workflow folder name (e.g., '_gsd', '_bmad') */
38
- workflowFolder: null | string;
39
- /** Whether the workflow folder exists */
40
- workflowFolderExists: boolean;
37
+ /** The method-specific runtime folder name (e.g., '_gsd', '_bmad') */
38
+ runtimeFolder: null | string;
39
+ /** Whether the runtime folder exists */
40
+ runtimeFolderExists: boolean;
41
41
  }
42
42
  /**
43
43
  * Result of template installation
@@ -74,12 +74,21 @@ export declare function shouldExclude(name: string): boolean;
74
74
  * @param excludeIdeFolders - If true, exclude IDE config folders (.claude, .windsurf, etc.)
75
75
  */
76
76
  export declare function copyDir(src: string, dest: string, excludeIdeFolders?: boolean): Promise<void>;
77
+ /**
78
+ * Merge source directory into destination, skipping existing files.
79
+ * Unlike copyDir, this preserves existing files in destination.
80
+ *
81
+ * @param src - Source directory path
82
+ * @param dest - Destination directory path
83
+ */
84
+ export declare function mergeDirectory(src: string, dest: string, options?: {
85
+ exclude?: (name: string) => boolean;
86
+ }): Promise<void>;
77
87
  /**
78
88
  * Install template with IDE-specific folder selection.
79
89
  *
80
90
  * Template structure:
81
91
  * - Non-dot folders (e.g., _bmad/, GSR/) → .aiwcli/ (always overwritten)
82
- * - _shared/ → .aiwcli/_shared/ (always overwritten)
83
92
  * - IDE dot folders (e.g., .claude/) → decomposed into method-owned subdirs
84
93
  *
85
94
  * Settings reconstruction is handled separately by the caller via reconstructIdeSettings().
@@ -1,5 +1,5 @@
1
1
  import { promises as fs } from 'node:fs';
2
- import { dirname, join } from 'node:path';
2
+ import { join } from 'node:path';
3
3
  import { IdePathResolver } from './ide-path-resolver.js';
4
4
  import { pathExists } from './paths.js';
5
5
  /**
@@ -17,11 +17,11 @@ export async function checkTemplateStatus(templatePath, targetDir, ides, templat
17
17
  const missing = [];
18
18
  // Scan template directory
19
19
  const entries = await fs.readdir(templatePath, { withFileTypes: true });
20
- // Identify workflow folder based on template name
20
+ // Identify method runtime folder based on template name
21
21
  // Convention: _templatename (e.g., _gsd, _bmad)
22
- const workflowFolderName = `_${templateName}`;
23
- let workflowFolder = null;
24
- let workflowFolderExists = false;
22
+ const runtimeFolderName = `_${templateName}`;
23
+ let runtimeFolder = null;
24
+ let runtimeFolderExists = false;
25
25
  // Filter entries to only include relevant items (skip non-selected IDE folders and excluded patterns)
26
26
  const relevantEntries = entries.filter((entry) => {
27
27
  // Skip excluded patterns (test files, cache, etc.)
@@ -58,17 +58,17 @@ export async function checkTemplateStatus(templatePath, targetDir, ides, templat
58
58
  else {
59
59
  missing.push(status);
60
60
  }
61
- // Track workflow folder
62
- if (status.name === workflowFolderName) {
63
- workflowFolder = workflowFolderName;
64
- workflowFolderExists = status.exists;
61
+ // Track method runtime folder
62
+ if (status.name === runtimeFolderName) {
63
+ runtimeFolder = runtimeFolderName;
64
+ runtimeFolderExists = status.exists;
65
65
  }
66
66
  }
67
67
  return {
68
68
  existing,
69
69
  missing,
70
- workflowFolder,
71
- workflowFolderExists,
70
+ runtimeFolder,
71
+ runtimeFolderExists,
72
72
  };
73
73
  }
74
74
  /**
@@ -101,7 +101,7 @@ export async function copyDir(src, dest, excludeIdeFolders = false) {
101
101
  if (shouldExclude(entry.name)) {
102
102
  return false;
103
103
  }
104
- // Exclude IDE config folders if requested (used for _shared folder)
104
+ // Exclude IDE config folders if requested (used for core folder)
105
105
  // These folders are used for settings merging, not direct installation
106
106
  if (excludeIdeFolders && entry.isDirectory() && entry.name.startsWith('.')) {
107
107
  return false;
@@ -128,16 +128,16 @@ export async function copyDir(src, dest, excludeIdeFolders = false) {
128
128
  * @param src - Source directory path
129
129
  * @param dest - Destination directory path
130
130
  */
131
- async function mergeDirectory(src, dest) {
131
+ export async function mergeDirectory(src, dest, options) {
132
132
  await fs.mkdir(dest, { recursive: true });
133
133
  const entries = await fs.readdir(src, { withFileTypes: true });
134
134
  const ops = entries
135
- .filter((entry) => !shouldExclude(entry.name))
135
+ .filter((entry) => !(options?.exclude?.(entry.name)))
136
136
  .map(async (entry) => {
137
137
  const srcPath = join(src, entry.name);
138
138
  const destPath = join(dest, entry.name);
139
139
  if (entry.isDirectory()) {
140
- await mergeDirectory(srcPath, destPath);
140
+ await mergeDirectory(srcPath, destPath, options);
141
141
  }
142
142
  else if (!(await pathExists(destPath))) {
143
143
  await fs.copyFile(srcPath, destPath);
@@ -150,7 +150,6 @@ async function mergeDirectory(src, dest) {
150
150
  *
151
151
  * Template structure:
152
152
  * - Non-dot folders (e.g., _bmad/, GSR/) → .aiwcli/ (always overwritten)
153
- * - _shared/ → .aiwcli/_shared/ (always overwritten)
154
153
  * - IDE dot folders (e.g., .claude/) → decomposed into method-owned subdirs
155
154
  *
156
155
  * Settings reconstruction is handled separately by the caller via reconstructIdeSettings().
@@ -205,27 +204,6 @@ export async function installTemplate(config) {
205
204
  });
206
205
  const nonDotResults = await Promise.all(nonDotInstalls);
207
206
  installedFolders.push(...nonDotResults);
208
- // Install root-level _shared directory (shared across all templates)
209
- // Exclude IDE config folders (.claude, .windsurf) - they are used for settings merging only
210
- const templatesRoot = dirname(templatePath);
211
- const rootSharedSrc = join(templatesRoot, '_shared');
212
- const rootSharedDest = join(containerDir, '_shared');
213
- if (await pathExists(rootSharedSrc)) {
214
- await copyDir(rootSharedSrc, rootSharedDest, true); // excludeIdeFolders = true
215
- installedFolders.push('_shared');
216
- // Copy shared IDE content (e.g., _shared/.claude/commands/handoff.md)
217
- // These are non-method-owned files that live in IDE folders
218
- const sharedIdeInstalls = ides.map(async (ide) => {
219
- const sharedIdeFolder = join(rootSharedSrc, `.${ide}`);
220
- if (await pathExists(sharedIdeFolder)) {
221
- const destIdeFolder = resolver.getIdeDir(ide);
222
- await fs.mkdir(destIdeFolder, { recursive: true });
223
- // Merge shared IDE content, skipping files that already exist
224
- await mergeDirectory(sharedIdeFolder, destIdeFolder);
225
- }
226
- });
227
- await Promise.all(sharedIdeInstalls);
228
- }
229
207
  // Install method-owned IDE content (decomposed approach)
230
208
  // Instead of copying entire .claude/ from template, only copy method-namespaced subdirectories
231
209
  const ideInstalls = ides.map(async (ide) => {
@@ -251,7 +229,7 @@ export async function installTemplate(config) {
251
229
  }
252
230
  else {
253
231
  // No method-namespaced child — copy the entire subdirectory, merging with existing
254
- await mergeDirectory(subdirSrc, subdirDest);
232
+ await mergeDirectory(subdirSrc, subdirDest, { exclude: shouldExclude });
255
233
  }
256
234
  });
257
235
  await Promise.all(subdirOps);
@@ -260,9 +238,33 @@ export async function installTemplate(config) {
260
238
  const ideResults = (await Promise.all(ideInstalls)).filter((result) => result !== null);
261
239
  installedFolders.push(...ideResults);
262
240
  // Settings reconstruction is handled by the caller via reconstructIdeSettings()
241
+ // Write resolved CLI binary path so template scripts can shell out to `aiw`
242
+ await writeAiwBinPath(containerDir);
263
243
  return {
264
244
  installedFolders,
265
245
  sharedSettingsMerged: false,
266
246
  templatePath,
267
247
  };
268
248
  }
249
+ /**
250
+ * Write the resolved `aiw` binary path to `.aiwcli/.aiw-bin-path`.
251
+ * Template scripts read this file to find the CLI binary for `aiw launch`.
252
+ */
253
+ async function writeAiwBinPath(containerDir) {
254
+ try {
255
+ // process.argv[1] is the main script entry point (e.g., /path/to/aiw/bin/run.js)
256
+ // Resolve to the bin directory to find the actual `aiw` executable
257
+ const { execSync } = await import('node:child_process');
258
+ const cmd = process.platform === 'win32' ? 'where aiw' : 'which aiw';
259
+ const resolved = execSync(cmd, { encoding: 'utf8', timeout: 3000, stdio: ['pipe', 'pipe', 'pipe'] })
260
+ .trim()
261
+ .split(/\r?\n/)[0]
262
+ ?.trim();
263
+ if (resolved) {
264
+ await fs.writeFile(join(containerDir, '.aiw-bin-path'), resolved, 'utf8');
265
+ }
266
+ }
267
+ catch {
268
+ // Best-effort — aiw will still be found on PATH at runtime
269
+ }
270
+ }
@@ -12,15 +12,14 @@
12
12
  */
13
13
  export declare function getTemplatePath(templateName: string): Promise<string>;
14
14
  /**
15
- * Get list of available template names by scanning the templates directory.
15
+ * Get list of available method template names by scanning the templates directory.
16
16
  *
17
- * @returns Array of template names (e.g., ['bmad', 'gsr'])
17
+ * @returns Array of method template names (e.g., ['bmad', 'cc-native'])
18
18
  * @throws Error if templates directory cannot be read (indicates corrupted installation)
19
19
  */
20
+ export declare function getAvailableTemplates(): Promise<string[]>;
20
21
  /**
21
- * Get the absolute path to the _shared template directory.
22
- *
23
- * @returns Absolute path to the _shared template
22
+ * Discover IDE names available in a template path by scanning top-level dot-folders.
23
+ * Example: .claude, .codex -> ['claude', 'codex']
24
24
  */
25
- export declare function getSharedTemplatePath(): string;
26
- export declare function getAvailableTemplates(): Promise<string[]>;
25
+ export declare function getTemplateIdeNamesByPath(templatePath: string): Promise<string[]>;
@@ -1,6 +1,12 @@
1
1
  import { promises as fs } from 'node:fs';
2
2
  import { dirname, join } from 'node:path';
3
3
  import { fileURLToPath } from 'node:url';
4
+ function getTemplatesRootDir() {
5
+ const currentFileUrl = import.meta.url;
6
+ const currentFilePath = fileURLToPath(currentFileUrl);
7
+ const currentDir = dirname(currentFilePath);
8
+ return join(currentDir, '..', 'templates');
9
+ }
4
10
  /**
5
11
  * Resolve the absolute path to a bundled template root.
6
12
  * Works in both development (src/) and production (dist/) contexts.
@@ -21,13 +27,10 @@ export async function getTemplatePath(templateName) {
21
27
  // Get the directory of this file
22
28
  // In dev: .../aiwcli/src/lib/
23
29
  // In prod: .../aiwcli/dist/lib/
24
- const currentFileUrl = import.meta.url;
25
- const currentFilePath = fileURLToPath(currentFileUrl);
26
- const currentDir = dirname(currentFilePath);
27
30
  // Go up one level and into templates/<templateName>
28
31
  // src/lib/ → src/templates/<templateName>/
29
32
  // dist/lib/ → dist/templates/<templateName>/
30
- const templatePath = join(currentDir, '..', 'templates', templateName);
33
+ const templatePath = join(getTemplatesRootDir(), templateName);
31
34
  // Validate template exists
32
35
  try {
33
36
  await fs.access(templatePath);
@@ -38,29 +41,18 @@ export async function getTemplatePath(templateName) {
38
41
  return templatePath;
39
42
  }
40
43
  /**
41
- * Get list of available template names by scanning the templates directory.
44
+ * Get list of available method template names by scanning the templates directory.
42
45
  *
43
- * @returns Array of template names (e.g., ['bmad', 'gsr'])
46
+ * @returns Array of method template names (e.g., ['bmad', 'cc-native'])
44
47
  * @throws Error if templates directory cannot be read (indicates corrupted installation)
45
48
  */
46
- /**
47
- * Get the absolute path to the _shared template directory.
48
- *
49
- * @returns Absolute path to the _shared template
50
- */
51
- export function getSharedTemplatePath() {
52
- const currentFilePath = fileURLToPath(import.meta.url);
53
- const currentDir = dirname(currentFilePath);
54
- return join(currentDir, '..', 'templates', '_shared');
55
- }
56
49
  export async function getAvailableTemplates() {
57
- const currentFileUrl = import.meta.url;
58
- const currentFilePath = fileURLToPath(currentFileUrl);
59
- const currentDir = dirname(currentFilePath);
60
- const templatesDir = join(currentDir, '..', 'templates');
50
+ const templatesDir = getTemplatesRootDir();
61
51
  try {
62
52
  const entries = await fs.readdir(templatesDir, { withFileTypes: true });
63
- return entries.filter((entry) => entry.isDirectory()).map((entry) => entry.name);
53
+ return entries
54
+ .filter((entry) => entry.isDirectory() && !entry.name.startsWith('_') && !RESERVED_TEMPLATE_NAMES.has(entry.name))
55
+ .map((entry) => entry.name);
64
56
  }
65
57
  catch (error) {
66
58
  const err = error;
@@ -68,3 +60,16 @@ export async function getAvailableTemplates() {
68
60
  `This indicates a corrupted installation. Please reinstall aiwcli.`);
69
61
  }
70
62
  }
63
+ /**
64
+ * Discover IDE names available in a template path by scanning top-level dot-folders.
65
+ * Example: .claude, .codex -> ['claude', 'codex']
66
+ */
67
+ export async function getTemplateIdeNamesByPath(templatePath) {
68
+ const entries = await fs.readdir(templatePath, { withFileTypes: true });
69
+ return entries
70
+ .filter((entry) => entry.isDirectory() && entry.name.startsWith('.'))
71
+ .map((entry) => entry.name.slice(1))
72
+ .filter((name) => name.length > 0)
73
+ .sort((a, b) => a.localeCompare(b));
74
+ }
75
+ const RESERVED_TEMPLATE_NAMES = new Set(['core']);