aiwcli 0.15.7 → 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 (272) hide show
  1. package/README.md +106 -1125
  2. package/bin/run.js +0 -4
  3. package/dist/capabilities/installation/control-plane/clear-command.d.ts +2 -0
  4. package/dist/capabilities/installation/control-plane/clear-command.js +32 -3
  5. package/dist/capabilities/installation/control-plane/init-command.js +2 -2
  6. package/dist/capabilities/launch/contracts.d.ts +39 -4
  7. package/dist/capabilities/launch/control-plane/execute-launch.js +158 -119
  8. package/dist/capabilities/launch/runtime-core/launch-decisions.d.ts +82 -0
  9. package/dist/capabilities/launch/runtime-core/launch-decisions.js +202 -0
  10. package/dist/commands/branch.d.ts +1 -1
  11. package/dist/commands/branch.js +1 -1
  12. package/dist/commands/launch.d.ts +0 -5
  13. package/dist/commands/launch.js +2 -37
  14. package/dist/lib/config.js +1 -2
  15. package/dist/lib/context/context-store.js +28 -2
  16. package/dist/lib/core-installer.d.ts +1 -1
  17. package/dist/lib/core-installer.js +6 -27
  18. package/dist/lib/debug.d.ts +0 -10
  19. package/dist/lib/debug.js +0 -10
  20. package/dist/lib/env-sanitizer.d.ts +25 -0
  21. package/dist/lib/env-sanitizer.js +46 -0
  22. package/dist/lib/errors.d.ts +0 -13
  23. package/dist/lib/errors.js +0 -15
  24. package/dist/lib/git-exclude-manager.js +1 -1
  25. package/dist/lib/hooks/context-monitor-logic.d.ts +6 -0
  26. package/dist/lib/hooks/context-monitor-logic.js +25 -0
  27. package/dist/lib/hooks/hook-utils.js +11 -0
  28. package/dist/lib/hooks/prompt-binding-logic.d.ts +7 -0
  29. package/dist/lib/hooks/prompt-binding-logic.js +50 -0
  30. package/dist/lib/hooks/session-end-logic.js +2 -14
  31. package/dist/lib/install-state.js +6 -13
  32. package/dist/lib/json-io.d.ts +12 -0
  33. package/dist/lib/json-io.js +30 -0
  34. package/dist/lib/multiplexer.d.ts +43 -35
  35. package/dist/lib/multiplexer.js +21 -2
  36. package/dist/lib/multiplexers/psmux.d.ts +14 -34
  37. package/dist/lib/multiplexers/psmux.js +70 -130
  38. package/dist/lib/multiplexers/tmux.d.ts +11 -19
  39. package/dist/lib/multiplexers/tmux.js +79 -120
  40. package/dist/lib/multiplexers/wezterm.d.ts +38 -0
  41. package/dist/lib/multiplexers/wezterm.js +225 -0
  42. package/dist/lib/mux-utils.d.ts +4 -3
  43. package/dist/lib/mux-utils.js +7 -13
  44. package/dist/lib/prompt-file-manager.d.ts +23 -0
  45. package/dist/lib/prompt-file-manager.js +41 -0
  46. package/dist/lib/runtime/agent-launcher.d.ts +67 -0
  47. package/dist/lib/runtime/agent-launcher.js +262 -0
  48. package/dist/lib/runtime/aiw-cli.d.ts +2 -0
  49. package/dist/lib/runtime/aiw-cli.js +3 -1
  50. package/dist/lib/runtime/cli-args.d.ts +5 -2
  51. package/dist/lib/runtime/cli-args.js +18 -3
  52. package/dist/lib/runtime/inference.js +3 -14
  53. package/dist/lib/runtime/models.d.ts +6 -0
  54. package/dist/lib/runtime/models.js +6 -0
  55. package/dist/lib/runtime/state-io.d.ts +2 -1
  56. package/dist/lib/runtime/state-io.js +9 -4
  57. package/dist/lib/runtime/utils.d.ts +8 -0
  58. package/dist/lib/runtime/utils.js +31 -1
  59. package/dist/lib/schemas.d.ts +250 -0
  60. package/dist/lib/schemas.js +216 -0
  61. package/dist/lib/sentinel-manager.d.ts +32 -0
  62. package/dist/lib/sentinel-manager.js +62 -0
  63. package/dist/lib/sentinel-wrapper.d.ts +1 -0
  64. package/dist/lib/sentinel-wrapper.js +12 -3
  65. package/dist/lib/settings-hierarchy.js +3 -20
  66. package/dist/lib/shell-adapters/bash-adapter.d.ts +18 -0
  67. package/dist/lib/shell-adapters/bash-adapter.js +69 -0
  68. package/dist/lib/shell-adapters/index.d.ts +5 -0
  69. package/dist/lib/shell-adapters/index.js +7 -0
  70. package/dist/lib/shell-adapters/powershell-adapter.d.ts +18 -0
  71. package/dist/lib/shell-adapters/powershell-adapter.js +62 -0
  72. package/dist/lib/shell-adapters/shell-adapter.d.ts +45 -0
  73. package/dist/lib/shell-adapters/shell-adapter.js +5 -0
  74. package/dist/lib/spawn-errors.d.ts +3 -0
  75. package/dist/lib/spawn-errors.js +15 -1
  76. package/dist/lib/spinner.d.ts +0 -5
  77. package/dist/lib/spinner.js +0 -16
  78. package/dist/lib/template-installer.d.ts +10 -0
  79. package/dist/lib/template-installer.js +4 -4
  80. package/dist/lib/terminal-strategy.d.ts +1 -0
  81. package/dist/lib/terminal-strategy.js +12 -6
  82. package/dist/lib/terminal.d.ts +7 -5
  83. package/dist/lib/terminal.js +42 -19
  84. package/dist/lib/tmux-primitives.d.ts +0 -2
  85. package/dist/lib/tmux-primitives.js +0 -4
  86. package/dist/lib/tmux-session.js +2 -1
  87. package/dist/lib/windsurf-hooks-hierarchy.js +6 -23
  88. package/dist/platform/launch.d.ts +2 -1
  89. package/dist/platform/launch.js +1 -0
  90. package/dist/templates/CLAUDE.md +0 -1
  91. package/dist/templates/cc-native/.claude/settings.json +0 -10
  92. package/dist/templates/cc-native/TEMPLATE-SCHEMA.md +11 -4
  93. package/dist/templates/cc-native/_cc-native/cc-native.config.json +3 -7
  94. package/dist/templates/cc-native/_cc-native/hooks/CLAUDE.md +26 -47
  95. package/dist/templates/cc-native/_cc-native/hooks/cc-native-plan-review.ts +7 -9
  96. package/dist/templates/cc-native/_cc-native/hooks/enhance_plan_post_write.ts +2 -3
  97. package/dist/templates/cc-native/_cc-native/hooks/mark_questions_asked.ts +2 -2
  98. package/dist/templates/cc-native/_cc-native/hooks/plan_questions_early.ts +0 -25
  99. package/dist/templates/cc-native/_cc-native/hooks/validate_task_prompt.ts +4 -4
  100. package/dist/templates/cc-native/_cc-native/lib-ts/.mocharc.json +9 -0
  101. package/dist/templates/cc-native/_cc-native/lib-ts/__tests__/aggregate-agents.test.ts +118 -0
  102. package/dist/templates/cc-native/_cc-native/lib-ts/__tests__/artifacts.test.ts +234 -0
  103. package/dist/templates/cc-native/_cc-native/lib-ts/__tests__/cc-native-state.test.ts +170 -0
  104. package/dist/templates/cc-native/_cc-native/lib-ts/__tests__/cli-output-parser.test.ts +73 -0
  105. package/dist/templates/cc-native/_cc-native/lib-ts/__tests__/config.test.ts +64 -0
  106. package/dist/templates/cc-native/_cc-native/lib-ts/__tests__/constants.test.ts +40 -0
  107. package/dist/templates/cc-native/_cc-native/lib-ts/__tests__/debug.test.ts +42 -0
  108. package/dist/templates/cc-native/_cc-native/lib-ts/__tests__/exports.test.ts +58 -0
  109. package/dist/templates/cc-native/_cc-native/lib-ts/__tests__/helpers.ts +107 -0
  110. package/dist/templates/cc-native/_cc-native/lib-ts/__tests__/hooks/add-plan-context.hook.test.ts +97 -0
  111. package/dist/templates/cc-native/_cc-native/lib-ts/__tests__/hooks/plan-questions.hook.test.ts +81 -0
  112. package/dist/templates/cc-native/_cc-native/lib-ts/__tests__/hooks/plan-review.hook.test.ts +71 -0
  113. package/dist/templates/cc-native/_cc-native/lib-ts/__tests__/json-parser.test.ts +99 -0
  114. package/dist/templates/cc-native/_cc-native/lib-ts/__tests__/orchestrator-agent.test.ts +288 -0
  115. package/dist/templates/cc-native/_cc-native/lib-ts/__tests__/orchestrator.test.ts +48 -0
  116. package/dist/templates/cc-native/_cc-native/lib-ts/__tests__/reviewers.test.ts +32 -0
  117. package/dist/templates/cc-native/_cc-native/lib-ts/__tests__/state.test.ts +124 -0
  118. package/dist/templates/cc-native/_cc-native/lib-ts/__tests__/verdict.test.ts +93 -0
  119. package/dist/templates/cc-native/_cc-native/lib-ts/agent-selection.ts +163 -0
  120. package/dist/templates/cc-native/_cc-native/lib-ts/aggregate-agents.ts +6 -14
  121. package/dist/templates/cc-native/_cc-native/{artifacts/lib → lib-ts/artifacts}/format.ts +597 -599
  122. package/dist/templates/cc-native/_cc-native/{artifacts/lib → lib-ts/artifacts}/index.ts +26 -26
  123. package/dist/templates/cc-native/_cc-native/{artifacts/lib → lib-ts/artifacts}/tracker.ts +106 -107
  124. package/dist/templates/cc-native/_cc-native/{artifacts/lib → lib-ts/artifacts}/write.ts +118 -119
  125. package/dist/templates/cc-native/_cc-native/lib-ts/artifacts.ts +21 -0
  126. package/dist/templates/cc-native/_cc-native/lib-ts/cc-native-state.ts +16 -15
  127. package/dist/templates/cc-native/_cc-native/lib-ts/cli-output-parser.ts +132 -10
  128. package/dist/templates/cc-native/_cc-native/lib-ts/constants.ts +6 -6
  129. package/dist/templates/cc-native/_cc-native/{plan-review/lib → lib-ts}/corroboration.ts +119 -119
  130. package/dist/templates/cc-native/_cc-native/lib-ts/debug.ts +1 -2
  131. package/dist/templates/cc-native/_cc-native/{plan-review/lib → lib-ts}/graduation.ts +132 -132
  132. package/dist/templates/cc-native/_cc-native/lib-ts/index.ts +88 -86
  133. package/dist/templates/cc-native/_cc-native/lib-ts/json-parser.ts +5 -6
  134. package/dist/templates/cc-native/_cc-native/{plan-review/lib → lib-ts}/orchestrator.ts +70 -70
  135. package/dist/templates/cc-native/_cc-native/{plan-review/lib → lib-ts}/output-builder.ts +130 -121
  136. package/dist/templates/cc-native/_cc-native/lib-ts/package-lock.json +1679 -0
  137. package/dist/templates/cc-native/_cc-native/lib-ts/package.json +24 -0
  138. package/dist/templates/cc-native/_cc-native/lib-ts/plan-discovery.ts +4 -4
  139. package/dist/templates/cc-native/_cc-native/lib-ts/plan-enhancement.ts +1 -6
  140. package/dist/templates/cc-native/_cc-native/{plan-review/lib → lib-ts}/plan-questions.ts +101 -101
  141. package/dist/templates/cc-native/_cc-native/{plan-review/lib → lib-ts}/review-pipeline.ts +511 -543
  142. package/dist/templates/cc-native/_cc-native/lib-ts/reviewers/__tests__/agent-providers.test.ts +262 -0
  143. package/dist/templates/cc-native/_cc-native/{plan-review/lib → lib-ts}/reviewers/agent.ts +71 -85
  144. package/dist/templates/{core/lib-ts/agent-exec → cc-native/_cc-native/lib-ts/reviewers/base}/base-agent.ts +138 -152
  145. package/dist/templates/cc-native/_cc-native/{plan-review/lib → lib-ts}/reviewers/index.ts +12 -12
  146. package/dist/templates/cc-native/_cc-native/{plan-review/lib → lib-ts}/reviewers/providers/claude-agent.ts +66 -57
  147. package/dist/templates/cc-native/_cc-native/{plan-review/lib → lib-ts}/reviewers/providers/codex-agent.ts +185 -200
  148. package/dist/templates/cc-native/_cc-native/{plan-review/lib → lib-ts}/reviewers/providers/gemini-agent.ts +39 -40
  149. package/dist/templates/cc-native/_cc-native/{plan-review/lib → lib-ts}/reviewers/providers/orchestrator-claude-agent.ts +196 -224
  150. package/dist/templates/cc-native/_cc-native/{plan-review/lib → lib-ts}/reviewers/schemas.ts +201 -201
  151. package/dist/templates/cc-native/_cc-native/{plan-review/lib → lib-ts}/reviewers/types.ts +21 -23
  152. package/dist/templates/cc-native/_cc-native/lib-ts/rlm/__tests__/hyde.test.ts +365 -0
  153. package/dist/templates/cc-native/_cc-native/lib-ts/rlm/__tests__/ollama-client.test.ts +223 -0
  154. package/dist/templates/cc-native/_cc-native/lib-ts/rlm/embedding-indexer.ts +12 -16
  155. package/dist/templates/cc-native/_cc-native/lib-ts/rlm/hyde.ts +3 -2
  156. package/dist/templates/cc-native/_cc-native/lib-ts/rlm/index.ts +31 -31
  157. package/dist/templates/cc-native/_cc-native/lib-ts/rlm/logger.ts +6 -7
  158. package/dist/templates/cc-native/_cc-native/lib-ts/rlm/ollama-client.ts +7 -9
  159. package/dist/templates/cc-native/_cc-native/lib-ts/rlm/retrieval-pipeline.ts +14 -17
  160. package/dist/templates/cc-native/_cc-native/lib-ts/rlm/transcript-indexer.ts +37 -41
  161. package/dist/templates/cc-native/_cc-native/lib-ts/rlm/transcript-loader.ts +33 -43
  162. package/dist/templates/cc-native/_cc-native/lib-ts/rlm/transcript-searcher.ts +20 -20
  163. package/dist/templates/cc-native/_cc-native/lib-ts/rlm/types.ts +8 -9
  164. package/dist/templates/cc-native/_cc-native/lib-ts/rlm/vector-store.ts +3 -4
  165. package/dist/templates/cc-native/_cc-native/lib-ts/settings.ts +50 -126
  166. package/dist/templates/cc-native/_cc-native/lib-ts/state.ts +19 -21
  167. package/dist/templates/cc-native/_cc-native/lib-ts/types.ts +13 -88
  168. package/dist/templates/cc-native/_cc-native/{plan-review/lib → lib-ts}/verdict.ts +72 -72
  169. package/dist/templates/cc-native/_cc-native/plan-review/CLAUDE.md +35 -0
  170. package/dist/templates/cc-native/_cc-native/plan-review/lib/agent-selection.ts +1 -1
  171. package/dist/templates/cc-native/_cc-native/scripts/council_debate.ts +242 -0
  172. package/dist/templates/cc-native/_cc-native/scripts/council_debate_simple.ts +294 -0
  173. package/dist/templates/cc-native/_cc-native/{plan-review/workflows → workflows}/specdev.md +9 -9
  174. package/dist/templates/core/.claude/skills/codex/SKILL.md +25 -0
  175. package/dist/templates/core/.claude/skills/devin/SKILL.md +25 -0
  176. package/dist/templates/core/.claude/skills/handoff/SKILL.md +11 -0
  177. package/dist/templates/core/.claude/skills/handoff-resume/SKILL.md +11 -0
  178. package/dist/templates/core/.claude/skills/meta-plan/SKILL.md +13 -0
  179. package/dist/templates/core/.codex/skills/codex/SKILL.md +13 -0
  180. package/dist/templates/core/.codex/skills/devin/SKILL.md +19 -0
  181. package/dist/templates/core/.codex/skills/handoff/SKILL.md +11 -0
  182. package/dist/templates/core/.codex/skills/handoff-resume/SKILL.md +11 -0
  183. package/dist/templates/core/.codex/{workflows/meta-plan.md → skills/meta-plan/SKILL.md} +6 -0
  184. package/dist/templates/core/{.cognition → .devin}/AGENTS.md +2 -2
  185. package/dist/templates/core/.devin/skills/codex/SKILL.md +19 -0
  186. package/dist/templates/core/.devin/skills/devin/SKILL.md +13 -0
  187. package/dist/templates/core/.devin/skills/handoff/SKILL.md +11 -0
  188. package/dist/templates/core/.devin/skills/handoff-resume/SKILL.md +11 -0
  189. package/dist/templates/core/.devin/skills/meta-plan/SKILL.md +13 -0
  190. package/dist/templates/core/.windsurf/workflows/handoff-resume.md +9 -0
  191. package/dist/templates/core/hooks-ts/archive_plan.ts +1 -21
  192. package/dist/templates/core/hooks-ts/file-suggestion.ts +1 -19
  193. package/dist/templates/core/hooks-ts/pre_compact.ts +5 -18
  194. package/dist/templates/core/lib-ts/context/context-store.ts +29 -2
  195. package/dist/templates/core/lib-ts/hooks/hook-utils.ts +11 -0
  196. package/dist/templates/core/lib-ts/hooks/session-end-logic.ts +2 -13
  197. package/dist/templates/core/lib-ts/runtime/agent-launcher.ts +74 -0
  198. package/dist/templates/core/lib-ts/runtime/aiw-cli.ts +4 -2
  199. package/dist/templates/core/lib-ts/runtime/cli-args.ts +18 -4
  200. package/dist/templates/core/lib-ts/runtime/inference.ts +3 -15
  201. package/dist/templates/core/lib-ts/runtime/models.ts +7 -0
  202. package/dist/templates/core/lib-ts/runtime/state-io.ts +9 -4
  203. package/dist/templates/core/lib-ts/runtime/utils.ts +30 -1
  204. package/dist/templates/core/lib-ts/schemas.ts +233 -0
  205. package/dist/templates/core/scripts/resolve-run.ts +34 -2
  206. package/dist/templates/core/scripts/status_line.ts +1 -1
  207. package/dist/templates/core/skills/codex/CLAUDE.md +9 -4
  208. package/dist/templates/core/skills/codex/SKILL.md +6 -0
  209. package/dist/templates/core/skills/codex/lib/codex-watcher.ts +3 -10
  210. package/dist/templates/core/skills/codex/scripts/launch-codex.ts +26 -26
  211. package/dist/templates/core/skills/devin/CLAUDE.md +63 -6
  212. package/dist/templates/core/skills/devin/lib/devin-watcher.ts +116 -96
  213. package/dist/templates/core/skills/devin/scripts/launch-devin.ts +22 -21
  214. package/dist/templates/core/skills/handoff-system/CLAUDE.md +1 -1
  215. package/oclif.manifest.json +4 -4
  216. package/package.json +4 -4
  217. package/dist/lib/base-command.d.ts +0 -1
  218. package/dist/lib/base-command.js +0 -1
  219. package/dist/lib/env-compat.d.ts +0 -18
  220. package/dist/lib/env-compat.js +0 -23
  221. package/dist/lib/launch-options.d.ts +0 -1
  222. package/dist/lib/launch-options.js +0 -1
  223. package/dist/lib/stdin.d.ts +0 -48
  224. package/dist/lib/stdin.js +0 -60
  225. package/dist/templates/cc-native/_cc-native/CLAUDE.md +0 -73
  226. package/dist/templates/cc-native/_cc-native/artifacts/CLAUDE.md +0 -64
  227. package/dist/templates/cc-native/_cc-native/lib-ts/CLAUDE.md +0 -70
  228. package/dist/templates/cc-native/_cc-native/plan-review/CODING-STANDARDS-CHECKLIST.md +0 -75
  229. package/dist/templates/cc-native/_cc-native/plan-review/agents/CLAUDE.md +0 -143
  230. package/dist/templates/cc-native/_cc-native/plan-review/agents/PLAN-ORCHESTRATOR.md +0 -213
  231. package/dist/templates/cc-native/_cc-native/plan-review/agents/plan-questions/PLAN-QUESTIONER.md +0 -70
  232. package/dist/templates/cc-native/_cc-native/plan-review/agents/plan-review/ARCH-EVOLUTION.md +0 -62
  233. package/dist/templates/cc-native/_cc-native/plan-review/agents/plan-review/ARCH-PATTERNS.md +0 -61
  234. package/dist/templates/cc-native/_cc-native/plan-review/agents/plan-review/ARCH-STRUCTURE.md +0 -62
  235. package/dist/templates/cc-native/_cc-native/plan-review/agents/plan-review/ASSUMPTION-TRACER.md +0 -56
  236. package/dist/templates/cc-native/_cc-native/plan-review/agents/plan-review/CLARITY-AUDITOR.md +0 -53
  237. package/dist/templates/cc-native/_cc-native/plan-review/agents/plan-review/COMPLETENESS-FEASIBILITY.md +0 -66
  238. package/dist/templates/cc-native/_cc-native/plan-review/agents/plan-review/COMPLETENESS-GAPS.md +0 -70
  239. package/dist/templates/cc-native/_cc-native/plan-review/agents/plan-review/COMPLETENESS-ORDERING.md +0 -62
  240. package/dist/templates/cc-native/_cc-native/plan-review/agents/plan-review/CONSTRAINT-VALIDATOR.md +0 -72
  241. package/dist/templates/cc-native/_cc-native/plan-review/agents/plan-review/DESIGN-ADR-VALIDATOR.md +0 -61
  242. package/dist/templates/cc-native/_cc-native/plan-review/agents/plan-review/DESIGN-SCALE-MATCHER.md +0 -64
  243. package/dist/templates/cc-native/_cc-native/plan-review/agents/plan-review/DEVILS-ADVOCATE.md +0 -56
  244. package/dist/templates/cc-native/_cc-native/plan-review/agents/plan-review/DOCUMENTATION-PHILOSOPHY.md +0 -86
  245. package/dist/templates/cc-native/_cc-native/plan-review/agents/plan-review/HANDOFF-READINESS.md +0 -59
  246. package/dist/templates/cc-native/_cc-native/plan-review/agents/plan-review/HIDDEN-COMPLEXITY.md +0 -58
  247. package/dist/templates/cc-native/_cc-native/plan-review/agents/plan-review/INCREMENTAL-DELIVERY.md +0 -66
  248. package/dist/templates/cc-native/_cc-native/plan-review/agents/plan-review/RISK-DEPENDENCY.md +0 -62
  249. package/dist/templates/cc-native/_cc-native/plan-review/agents/plan-review/RISK-FMEA.md +0 -66
  250. package/dist/templates/cc-native/_cc-native/plan-review/agents/plan-review/RISK-PREMORTEM.md +0 -71
  251. package/dist/templates/cc-native/_cc-native/plan-review/agents/plan-review/RISK-REVERSIBILITY.md +0 -74
  252. package/dist/templates/cc-native/_cc-native/plan-review/agents/plan-review/SCOPE-BOUNDARY.md +0 -77
  253. package/dist/templates/cc-native/_cc-native/plan-review/agents/plan-review/SIMPLICITY-GUARDIAN.md +0 -62
  254. package/dist/templates/cc-native/_cc-native/plan-review/agents/plan-review/SKEPTIC.md +0 -68
  255. package/dist/templates/cc-native/_cc-native/plan-review/agents/plan-review/TESTDRIVEN-BEHAVIOR-AUDITOR.md +0 -61
  256. package/dist/templates/cc-native/_cc-native/plan-review/agents/plan-review/TESTDRIVEN-CHARACTERIZATION.md +0 -71
  257. package/dist/templates/cc-native/_cc-native/plan-review/agents/plan-review/TESTDRIVEN-FIRST-VALIDATOR.md +0 -61
  258. package/dist/templates/cc-native/_cc-native/plan-review/agents/plan-review/TESTDRIVEN-PYRAMID-ANALYZER.md +0 -61
  259. package/dist/templates/cc-native/_cc-native/plan-review/agents/plan-review/TRADEOFF-COSTS.md +0 -67
  260. package/dist/templates/cc-native/_cc-native/plan-review/agents/plan-review/TRADEOFF-STAKEHOLDERS.md +0 -65
  261. package/dist/templates/cc-native/_cc-native/plan-review/agents/plan-review/VERIFY-COVERAGE.md +0 -74
  262. package/dist/templates/cc-native/_cc-native/plan-review/agents/plan-review/VERIFY-STRENGTH.md +0 -69
  263. package/dist/templates/cc-native/_cc-native/plan-review/lib/reviewers/base/base-agent.ts +0 -7
  264. package/dist/templates/core/.codex/workflows/codex.md +0 -17
  265. package/dist/templates/core/.codex/workflows/handoff.md +0 -5
  266. package/dist/templates/core/lib-ts/agent-exec/backends/headless.ts +0 -34
  267. package/dist/templates/core/lib-ts/agent-exec/backends/index.ts +0 -6
  268. package/dist/templates/core/lib-ts/agent-exec/backends/tmux.ts +0 -148
  269. package/dist/templates/core/lib-ts/agent-exec/execution-backend.ts +0 -50
  270. package/dist/templates/core/lib-ts/agent-exec/index.ts +0 -6
  271. package/dist/templates/core/lib-ts/agent-exec/structured-output.ts +0 -165
  272. /package/dist/templates/core/{.cognition → .devin}/config.json +0 -0
@@ -1,42 +1,21 @@
1
1
  /**
2
2
  * TmuxMultiplexer — unified tmux backend.
3
- * Consolidates TmuxLauncher + launchInTmuxSession + command building from pane-driver.
3
+ * Composes with BashAdapter for command building.
4
+ * Owns: split direction resolution, tmux session config, Windows bootstrap.
4
5
  */
5
6
  import { execSync } from 'node:child_process';
6
7
  import * as fs from 'node:fs';
7
- import { cleanClaudeEnv, getLastLine, spawnAttached, splitFlagFromDimensions } from '../mux-utils.js';
8
+ import { sanitizedProcessEnv } from '../env-sanitizer.js';
9
+ import { PANE_HOLD_MESSAGE, getLastLine, spawnAttached, splitFlagFromDimensions } from '../mux-utils.js';
8
10
  import { isNonWindowsPlatform, isWindowsPlatform } from '../runtime/platform-adapter.js';
9
- import { cleanupSentinelIpc, createSentinelIpcPaths } from '../runtime/sentinel-ipc.js';
10
11
  import { execFileAsync, findExecutable } from '../runtime/subprocess-utils.js';
11
- import { wrapSentinelSh } from '../sentinel-wrapper.js';
12
+ import { BashAdapter } from '../shell-adapters/bash-adapter.js';
12
13
  import { findBestSplit, listPanes } from '../tmux-pane-placement.js';
13
- import { quoteForSh, toMsysPosixPath } from '../tmux-primitives.js';
14
- import { buildShellCommand, buildTmuxRuntimeBootstrapCommands } from '../tmux-session.js';
15
- /** @internal */
16
- export function buildEnvPrefix(env) {
17
- return Object.entries(env)
18
- .map(([key, value]) => `${key}=${quoteForSh(value)}`)
19
- .join(' ');
20
- }
21
- /** @internal */
22
- export function buildShToolCommand(params) {
23
- const { toolPath, args, env, mode, promptPath, promptText } = params;
24
- const envPrefix = buildEnvPrefix(env);
25
- const commandArgs = buildCommandArgs(args, mode, promptText);
26
- const argPart = commandArgs.map((arg) => quoteForSh(arg)).join(' ');
27
- const base = [envPrefix, quoteForSh(toolPath), argPart]
28
- .filter(Boolean)
29
- .join(' ');
30
- if (mode === 'exec' && promptPath) {
31
- return `${base} < ${quoteForSh(promptPath)}`;
32
- }
33
- return base;
34
- }
35
- /** @internal */
36
- export function buildCommandArgs(args, mode, promptText) {
37
- if (mode !== 'repl' || promptText === undefined)
38
- return args;
39
- return [...args, promptText];
14
+ import { toMsysPosixPath } from '../tmux-primitives.js';
15
+ import { buildShellCommand, buildTmuxRuntimeBootstrapCommands, configureTmuxSession } from '../tmux-session.js';
16
+ /** @internal — translate unified SplitDirection to tmux flag. */
17
+ export function toTmuxSplitFlag(direction) {
18
+ return direction === 'horizontal' ? '-h' : '-v';
40
19
  }
41
20
  /** @internal */
42
21
  export function withWindowsTmuxBootstrap(command, platform = process.platform) {
@@ -45,15 +24,25 @@ export function withWindowsTmuxBootstrap(command, platform = process.platform) {
45
24
  const bootstrap = buildTmuxRuntimeBootstrapCommands(platform).join('; ');
46
25
  return `${bootstrap}; ${command}`;
47
26
  }
48
- async function resolveToolForBash(toolName) {
49
- const bash = findExecutable('bash');
50
- if (!bash)
51
- return null;
52
- const result = await execFileAsync(bash, ['-lc', `command -v ${toolName}`], {
53
- timeout: 3000,
54
- env: { ...process.env, MSYS_NO_PATHCONV: '1' },
55
- });
56
- return result.exitCode === 0 ? result.stdout.trim() || null : null;
27
+ /** @internal */
28
+ export function buildTmuxSplitWindowArgs(params) {
29
+ const args = ['split-window', params.splitFlag, '-P', '-F', '#{pane_id}'];
30
+ if (params.cwd) {
31
+ args.push('-c', params.cwd);
32
+ }
33
+ if (params.splitTarget) {
34
+ args.push('-t', params.splitTarget);
35
+ }
36
+ args.push(params.command);
37
+ return args;
38
+ }
39
+ /** @internal */
40
+ export function buildTmuxCreateSessionArgs(params) {
41
+ const args = ['new-session'];
42
+ if (params.reattach)
43
+ args.push('-A');
44
+ args.push('-c', params.cwd, '-s', params.sessionName, params.shellCommand);
45
+ return args;
57
46
  }
58
47
  async function resolveAutoSplit(tmuxPath, splitTarget) {
59
48
  const explicitTarget = splitTarget?.trim();
@@ -83,31 +72,13 @@ async function resolveAutoSplit(tmuxPath, splitTarget) {
83
72
  splitTarget: placement.targetPane,
84
73
  };
85
74
  }
86
- /** @internal */
87
- export function buildTmuxSplitWindowArgs(params) {
88
- const args = ['split-window', params.splitFlag, '-P', '-F', '#{pane_id}'];
89
- if (params.cwd) {
90
- args.push('-c', params.cwd);
91
- }
92
- if (params.splitTarget) {
93
- args.push('-t', params.splitTarget);
94
- }
95
- args.push(params.command);
96
- return args;
97
- }
98
- /** @internal */
99
- export function buildTmuxCreateSessionArgs(params) {
100
- const args = ['new-session'];
101
- if (params.reattach)
102
- args.push('-A');
103
- args.push('-c', params.cwd, '-s', params.sessionName, params.shellCommand);
104
- return args;
105
- }
106
75
  export class TmuxMultiplexer {
107
76
  backend = 'tmux';
108
77
  tmuxPath;
78
+ shell;
109
79
  constructor(tmuxPath) {
110
80
  this.tmuxPath = tmuxPath;
81
+ this.shell = new BashAdapter();
111
82
  }
112
83
  static create() {
113
84
  const tmuxPath = findExecutable('tmux');
@@ -115,12 +86,21 @@ export class TmuxMultiplexer {
115
86
  return null;
116
87
  return new TmuxMultiplexer(tmuxPath);
117
88
  }
89
+ resolveStrategy(ctx) {
90
+ if (ctx.disableMux) {
91
+ return { strategy: 'inline', reason: 'Multiplexer disabled via --no-tmux' };
92
+ }
93
+ if (Boolean(process.env.TMUX)) {
94
+ return { strategy: 'split', reason: 'Inside tmux session' };
95
+ }
96
+ return { strategy: 'create-session', reason: 'Outside tmux — will create new session' };
97
+ }
118
98
  async createSession(options) {
119
- const { sessionName, reattach } = options;
99
+ const { sessionName, reattach, cwd } = options;
120
100
  if (!isNonWindowsPlatform()) {
121
- return { exitCode: -1, usedMux: false, reason: 'tmux not available on this platform' };
101
+ return { launched: false, exitCode: -1, backend: this.backend, reason: 'tmux not available on this platform' };
122
102
  }
123
- // Set default-terminal BEFORE session creation (batched into single invocation)
103
+ // Set default-terminal BEFORE session creation
124
104
  try {
125
105
  execSync(String.raw `tmux start-server \; set -g default-terminal "tmux-256color"`, { stdio: 'ignore', timeout: 3000 });
126
106
  }
@@ -139,119 +119,98 @@ export class TmuxMultiplexer {
139
119
  });
140
120
  const args = buildTmuxCreateSessionArgs({
141
121
  sessionName,
142
- cwd: process.cwd(),
122
+ cwd,
143
123
  shellCommand,
144
124
  reattach,
145
125
  });
146
- return spawnAttached('tmux', args, cleanClaudeEnv(), this.backend);
147
- }
148
- isInsideSession() {
149
- return Boolean(process.env.TMUX);
126
+ return spawnAttached('tmux', args, sanitizedProcessEnv(), this.backend);
150
127
  }
151
- async kill(paneId) {
152
- if (!paneId)
128
+ async kill(handle) {
129
+ if (!handle)
153
130
  return;
154
- await execFileAsync(this.tmuxPath, ['kill-pane', '-t', paneId], { timeout: 3000 });
131
+ await execFileAsync(this.tmuxPath, ['kill-pane', '-t', handle], { timeout: 3000 });
155
132
  }
156
- async splitPane(options) {
157
- const mode = options.mode ?? 'repl';
158
- const args = options.args ?? [];
159
- const envVars = options.env ?? {};
160
- const cwd = options.cwd ?? process.cwd();
133
+ async split(options) {
134
+ const { toolName, args, env, cwd, mode, sentinelPath } = options;
135
+ // Configure tmux session defaults (mouse, scrollback, color)
136
+ configureTmuxSession();
161
137
  // Resolve tool path
162
- const toolPath = findExecutable(options.toolName);
163
- if (!toolPath) {
164
- return { launched: false, backend: this.backend, reason: `${options.toolName} not found on PATH` };
138
+ const nativePath = findExecutable(toolName);
139
+ if (!nativePath) {
140
+ return { launched: false, backend: this.backend, reason: `${toolName} not found on PATH` };
165
141
  }
166
- // On Windows with tmux backend, resolve tool path from bash's perspective
167
- let effectiveToolPath = toolPath;
168
- if (isWindowsPlatform()) {
169
- const bashPath = await resolveToolForBash(options.toolName);
170
- if (bashPath) {
171
- effectiveToolPath = bashPath;
172
- }
173
- else {
174
- return { launched: false, backend: this.backend, reason: `${options.toolName} not found in bash PATH (required for tmux pane)` };
175
- }
142
+ const effectiveToolPath = await this.shell.resolveToolPath(toolName, nativePath);
143
+ if (!effectiveToolPath) {
144
+ return { launched: false, backend: this.backend, reason: `${toolName} not found in bash PATH (required for tmux pane)` };
176
145
  }
177
- // Sentinel IPC for exit code tracking
178
- const useSentinel = options.sentinel !== false;
179
- const sentinel = useSentinel ? createSentinelIpcPaths(`aiwcli-pane-${options.toolName}`) : null;
180
146
  // Inject COLORTERM=truecolor for tmux
181
- const effectiveEnvVars = { COLORTERM: 'truecolor', ...envVars };
147
+ const effectiveEnv = { COLORTERM: 'truecolor', ...env };
182
148
  try {
183
149
  const promptText = mode === 'repl' && options.promptPath
184
150
  ? fs.readFileSync(options.promptPath, 'utf8')
185
151
  : undefined;
186
- const baseCommand = buildShToolCommand({
152
+ let baseCommand = this.shell.buildToolCommand({
187
153
  toolPath: effectiveToolPath,
188
154
  args,
189
- env: effectiveEnvVars,
155
+ env: effectiveEnv,
190
156
  mode,
191
157
  promptText,
192
158
  ...(options.promptPath ? { promptPath: options.promptPath } : {}),
193
159
  });
194
- let paneCommand = baseCommand;
195
- if (sentinel) {
196
- const holdMessage = options.holdMessage ?? '[aiwcli] Driver exited. Pane held open.';
197
- paneCommand = wrapSentinelSh({
198
- command: baseCommand,
199
- sentinelPath: sentinel.sentinelPath,
200
- autoClose: Boolean(options.autoClose),
201
- holdPane: Boolean(options.holdPane),
202
- holdMessage,
203
- });
160
+ if (options.retryOnQuickExit) {
161
+ baseCommand = this.shell.wrapQuickExitRetry(baseCommand, this.shell.quote(effectiveToolPath));
204
162
  }
163
+ const holdMessage = PANE_HOLD_MESSAGE;
164
+ const paneCommand = this.shell.wrapSentinel({
165
+ command: baseCommand,
166
+ sentinelPath,
167
+ autoClose: false,
168
+ holdPane: false,
169
+ holdMessage,
170
+ });
205
171
  // Resolve split direction
206
- const splitDirection = options.split ?? 'auto';
172
+ const splitDirection = options.split;
207
173
  let splitFlag;
208
174
  let splitTarget;
209
175
  if (splitDirection === 'auto') {
210
176
  try {
211
- const resolved = await resolveAutoSplit(this.tmuxPath, options.splitTarget);
177
+ const resolved = await resolveAutoSplit(this.tmuxPath);
212
178
  splitFlag = resolved.splitFlag;
213
179
  splitTarget = resolved.splitTarget;
214
180
  }
215
181
  catch {
216
182
  splitFlag = '-h';
217
- splitTarget = options.splitTarget?.trim();
218
183
  }
219
184
  }
220
185
  else {
221
- splitFlag = splitDirection === 'v' ? '-v' : '-h';
222
- splitTarget = options.splitTarget?.trim();
186
+ splitFlag = toTmuxSplitFlag(splitDirection);
223
187
  }
224
188
  // Build tmux split-window command
225
- const cwdPath = cwd ? (process.platform === 'win32' ? toMsysPosixPath(cwd) : cwd) : undefined;
189
+ const cwdPath = isWindowsPlatform() ? toMsysPosixPath(cwd) : cwd;
226
190
  const bootstrappedCommand = withWindowsTmuxBootstrap(paneCommand);
227
191
  const tmuxArgs = buildTmuxSplitWindowArgs({
228
192
  splitFlag,
229
- command: `bash -lc ${quoteForSh(bootstrappedCommand)}`,
193
+ command: `bash -lc ${this.shell.quote(bootstrappedCommand)}`,
230
194
  cwd: cwdPath,
231
195
  splitTarget,
232
196
  });
233
197
  const split = await execFileAsync(this.tmuxPath, tmuxArgs, { timeout: 5000 });
234
198
  if (split.exitCode !== 0) {
235
- if (sentinel)
236
- cleanupSentinelIpc(sentinel);
237
199
  return {
238
200
  launched: false,
239
201
  backend: this.backend,
240
202
  reason: 'tmux split-window failed',
241
- stderr: split.stderr.trim() || undefined,
242
203
  };
243
204
  }
244
- const paneId = getLastLine(split.stdout) || undefined;
205
+ const handle = getLastLine(split.stdout) || undefined;
245
206
  return {
246
207
  launched: true,
247
208
  backend: this.backend,
248
- paneId,
249
- sentinelPath: sentinel?.sentinelPath,
209
+ handle,
210
+ sentinelPath,
250
211
  };
251
212
  }
252
213
  catch (error) {
253
- if (sentinel)
254
- cleanupSentinelIpc(sentinel);
255
214
  return {
256
215
  launched: false,
257
216
  backend: this.backend,
@@ -0,0 +1,38 @@
1
+ /**
2
+ * WeztermMultiplexer — WezTerm backend for Windows.
3
+ * Composes with BashAdapter for command building.
4
+ * Owns: REPL-context gating (resolveStrategy), WezTerm pane management,
5
+ * holdPane behavior, auto-close command.
6
+ */
7
+ import type { CreateSessionOptions, LaunchResult, Multiplexer, ResolvedStrategy, SplitOptions, StrategyContext } from '../multiplexer.js';
8
+ type WeztermSplitFlag = '--bottom' | '--right';
9
+ /** @internal — translate unified SplitDirection to wezterm flag. */
10
+ export declare function toWeztermSplitFlag(direction: 'horizontal' | 'vertical'): WeztermSplitFlag;
11
+ /** @internal */
12
+ export declare function buildWeztermSplitArgs(params: {
13
+ bashPath?: string | undefined;
14
+ command: string;
15
+ cwd?: string | undefined;
16
+ paneId?: string | undefined;
17
+ splitFlag: WeztermSplitFlag;
18
+ }): string[];
19
+ /** @internal */
20
+ export declare function buildWeztermSpawnArgs(params: {
21
+ bashPath?: string | undefined;
22
+ command: string;
23
+ cwd?: string | undefined;
24
+ }): string[];
25
+ /** @internal */
26
+ export declare function buildWeztermKillArgs(paneId: string): string[];
27
+ export declare class WeztermMultiplexer implements Multiplexer {
28
+ readonly backend: "wezterm";
29
+ private readonly weztermPath;
30
+ private readonly shell;
31
+ private constructor();
32
+ static create(): null | WeztermMultiplexer;
33
+ resolveStrategy(ctx: StrategyContext): ResolvedStrategy;
34
+ kill(handle: string): Promise<void>;
35
+ split(options: SplitOptions): Promise<LaunchResult>;
36
+ createSession(options: CreateSessionOptions): Promise<LaunchResult>;
37
+ }
38
+ export {};
@@ -0,0 +1,225 @@
1
+ /**
2
+ * WeztermMultiplexer — WezTerm backend for Windows.
3
+ * Composes with BashAdapter for command building.
4
+ * Owns: REPL-context gating (resolveStrategy), WezTerm pane management,
5
+ * holdPane behavior, auto-close command.
6
+ */
7
+ import * as fs from 'node:fs';
8
+ import { PANE_HOLD_MESSAGE, getLastLine, splitFlagFromDimensions } from '../mux-utils.js';
9
+ import { execFileAsync, findExecutable } from '../runtime/subprocess-utils.js';
10
+ import { BashAdapter } from '../shell-adapters/bash-adapter.js';
11
+ /** @internal — translate unified SplitDirection to wezterm flag. */
12
+ export function toWeztermSplitFlag(direction) {
13
+ return direction === 'horizontal' ? '--right' : '--bottom';
14
+ }
15
+ /** @internal */
16
+ export function buildWeztermSplitArgs(params) {
17
+ const args = ['cli', 'split-pane', params.splitFlag];
18
+ if (params.cwd) {
19
+ args.push('--cwd', params.cwd);
20
+ }
21
+ if (params.paneId) {
22
+ args.push('--pane-id', params.paneId);
23
+ }
24
+ // Use -c (not -lc): login shell profiles may exec another shell (e.g. zsh),
25
+ // preventing the command from running. Tool paths are already absolute.
26
+ args.push('--', params.bashPath ?? 'bash', '-c', params.command);
27
+ return args;
28
+ }
29
+ /** @internal */
30
+ export function buildWeztermSpawnArgs(params) {
31
+ const args = ['cli', 'spawn', '--new-window'];
32
+ if (params.cwd) {
33
+ args.push('--cwd', params.cwd);
34
+ }
35
+ args.push('--', params.bashPath ?? 'bash', '-c', params.command);
36
+ return args;
37
+ }
38
+ /** @internal */
39
+ export function buildWeztermKillArgs(paneId) {
40
+ return ['cli', 'kill-pane', '--pane-id', paneId];
41
+ }
42
+ /**
43
+ * Resolve Git Bash path on Windows. WezTerm may resolve bare `bash` to
44
+ * WSL's bash.exe instead of Git Bash.
45
+ */
46
+ function resolveGitBash() {
47
+ return findExecutable('bash');
48
+ }
49
+ async function resolveAutoSplit(weztermPath, currentPaneId) {
50
+ try {
51
+ const result = await execFileAsync(weztermPath, ['cli', 'list', '--format', 'json'], { timeout: 3000 });
52
+ if (result.exitCode !== 0)
53
+ return '--right';
54
+ const panes = JSON.parse(result.stdout);
55
+ const targetId = currentPaneId ?? process.env.WEZTERM_PANE;
56
+ if (!targetId)
57
+ return '--right';
58
+ const pane = panes.find((p) => String(p.pane_id) === targetId);
59
+ if (!pane?.size)
60
+ return '--right';
61
+ const muxFlag = splitFlagFromDimensions(pane.size.cols, pane.size.rows);
62
+ return muxFlag === '-h' ? '--right' : '--bottom';
63
+ }
64
+ catch {
65
+ return '--right';
66
+ }
67
+ }
68
+ export class WeztermMultiplexer {
69
+ backend = 'wezterm';
70
+ weztermPath;
71
+ shell;
72
+ constructor(weztermPath) {
73
+ this.weztermPath = weztermPath;
74
+ this.shell = new BashAdapter();
75
+ }
76
+ static create() {
77
+ if (!process.env.WEZTERM_PANE && process.env.TERM_PROGRAM !== 'WezTerm')
78
+ return null;
79
+ const weztermPath = findExecutable('wezterm');
80
+ if (!weztermPath)
81
+ return null;
82
+ return new WeztermMultiplexer(weztermPath);
83
+ }
84
+ resolveStrategy(ctx) {
85
+ if (ctx.disableMux) {
86
+ return { strategy: 'inline', reason: 'Multiplexer disabled via --no-tmux' };
87
+ }
88
+ // REPL-context gating: only split when called from a REPL session.
89
+ // From a shell (no REPL vars), launch inline.
90
+ if (!ctx.calledFromRepl) {
91
+ return { strategy: 'inline', reason: 'WezTerm shell — no REPL context, launching inline' };
92
+ }
93
+ return { strategy: 'split', reason: 'Inside WezTerm REPL — splitting pane' };
94
+ }
95
+ async kill(handle) {
96
+ if (!handle)
97
+ return;
98
+ await execFileAsync(this.weztermPath, buildWeztermKillArgs(handle), { timeout: 3000 });
99
+ }
100
+ async split(options) {
101
+ const { toolName, args, env, cwd, mode, sentinelPath } = options;
102
+ // Resolve tool path
103
+ const nativePath = findExecutable(toolName);
104
+ if (!nativePath) {
105
+ return { launched: false, backend: this.backend, reason: `${toolName} not found on PATH` };
106
+ }
107
+ const effectiveToolPath = await this.shell.resolveToolPath(toolName, nativePath);
108
+ if (!effectiveToolPath) {
109
+ return { launched: false, backend: this.backend, reason: `${toolName} not found in bash PATH (required for wezterm pane)` };
110
+ }
111
+ try {
112
+ const promptText = mode === 'repl' && options.promptPath
113
+ ? fs.readFileSync(options.promptPath, 'utf8')
114
+ : undefined;
115
+ let baseCommand = this.shell.buildToolCommand({
116
+ toolPath: effectiveToolPath,
117
+ args,
118
+ env,
119
+ mode,
120
+ promptText,
121
+ ...(options.promptPath ? { promptPath: options.promptPath } : {}),
122
+ });
123
+ if (options.retryOnQuickExit) {
124
+ baseCommand = this.shell.wrapQuickExitRetry(baseCommand, this.shell.quote(effectiveToolPath));
125
+ }
126
+ const gitBash = process.platform === 'win32' ? resolveGitBash() ?? undefined : undefined;
127
+ // WezTerm always holds pane and uses auto-close via wezterm kill-pane
128
+ const holdMessage = PANE_HOLD_MESSAGE;
129
+ let paneCommand = this.shell.wrapSentinel({
130
+ command: baseCommand,
131
+ sentinelPath,
132
+ autoClose: false,
133
+ autoCloseCommand: `wezterm cli kill-pane --pane-id $WEZTERM_PANE >/dev/null 2>&1 || true`,
134
+ holdPane: true,
135
+ holdMessage,
136
+ });
137
+ // Prepend nesting cleanup (PATH fix + unset REPL vars)
138
+ paneCommand = `${this.shell.buildNestingCleanup()} ${paneCommand}`;
139
+ // Resolve split direction
140
+ const splitDirection = options.split;
141
+ let splitFlag;
142
+ if (splitDirection === 'auto') {
143
+ splitFlag = await resolveAutoSplit(this.weztermPath);
144
+ }
145
+ else {
146
+ splitFlag = toWeztermSplitFlag(splitDirection);
147
+ }
148
+ const weztermArgs = buildWeztermSplitArgs({
149
+ splitFlag,
150
+ command: paneCommand,
151
+ cwd,
152
+ paneId: process.env.WEZTERM_PANE,
153
+ bashPath: gitBash,
154
+ });
155
+ const split = await execFileAsync(this.weztermPath, weztermArgs, { timeout: 5000 });
156
+ if (split.exitCode !== 0) {
157
+ return {
158
+ launched: false,
159
+ backend: this.backend,
160
+ reason: 'wezterm split-pane failed',
161
+ };
162
+ }
163
+ const handle = getLastLine(split.stdout) || undefined;
164
+ return {
165
+ launched: true,
166
+ backend: this.backend,
167
+ handle,
168
+ sentinelPath,
169
+ };
170
+ }
171
+ catch (error) {
172
+ return {
173
+ launched: false,
174
+ backend: this.backend,
175
+ reason: `pane launch failed: ${String(error)}`,
176
+ };
177
+ }
178
+ }
179
+ async createSession(options) {
180
+ const { toolPath, toolArgs, cwd } = options;
181
+ // On Windows, resolve tool path from bash's perspective
182
+ let effectiveToolPath = toolPath;
183
+ if (process.platform === 'win32') {
184
+ const toolName = toolPath.split(/[\\/]/).pop()?.replace(/\.exe$/i, '') ?? toolPath;
185
+ const bashPath = await this.shell.resolveToolPath(toolName, toolPath);
186
+ if (bashPath) {
187
+ effectiveToolPath = bashPath;
188
+ }
189
+ }
190
+ const baseCommand = this.shell.buildToolCommand({
191
+ toolPath: effectiveToolPath,
192
+ args: toolArgs,
193
+ env: {},
194
+ mode: 'repl',
195
+ promptText: options.promptText,
196
+ });
197
+ // Prepend nesting cleanup
198
+ const spawnCommand = `${this.shell.buildNestingCleanup()} ${baseCommand}`;
199
+ const weztermArgs = buildWeztermSpawnArgs({
200
+ command: spawnCommand,
201
+ cwd,
202
+ bashPath: process.platform === 'win32' ? resolveGitBash() ?? undefined : undefined,
203
+ });
204
+ try {
205
+ const result = await execFileAsync(this.weztermPath, weztermArgs, { timeout: 5000 });
206
+ if (result.exitCode !== 0) {
207
+ return {
208
+ launched: false,
209
+ exitCode: result.exitCode,
210
+ backend: this.backend,
211
+ reason: `wezterm spawn failed: ${result.stderr.trim() || 'unknown error'}`,
212
+ };
213
+ }
214
+ return { launched: true, exitCode: 0, backend: this.backend };
215
+ }
216
+ catch (error) {
217
+ return {
218
+ launched: false,
219
+ exitCode: -1,
220
+ backend: this.backend,
221
+ reason: `wezterm spawn failed: ${String(error)}`,
222
+ };
223
+ }
224
+ }
225
+ }
@@ -1,5 +1,6 @@
1
- import type { CreateSessionResult } from './multiplexer.js';
1
+ import type { LaunchResult } from './multiplexer.js';
2
2
  export declare function getLastLine(text: string): string;
3
- export declare function spawnAttached(command: string, args: string[], env: NodeJS.ProcessEnv | undefined, backendLabel: string): Promise<CreateSessionResult>;
3
+ export declare function spawnAttached(command: string, args: string[], env: NodeJS.ProcessEnv | undefined, backendLabel: string): Promise<LaunchResult>;
4
4
  export declare function splitFlagFromDimensions(width: number, height: number): '-h' | '-v';
5
- export declare function cleanClaudeEnv(extra?: Record<string, string>): NodeJS.ProcessEnv;
5
+ export declare const PANE_HOLD_MESSAGE = "[aiwcli] Driver exited. Pane held open.";
6
+ export declare function buildBootstrapPrompt(filePath: string): string;
@@ -1,5 +1,4 @@
1
1
  import { spawn } from 'node:child_process';
2
- import { getInternalSubprocessEnv } from './runtime/subprocess-utils.js';
3
2
  const CELL_ASPECT_RATIO = 2;
4
3
  export function getLastLine(text) {
5
4
  const lines = text.split(/\r?\n/).map((line) => line.trim()).filter(Boolean);
@@ -12,18 +11,18 @@ export function spawnAttached(command, args, env, backendLabel) {
12
11
  child = spawn(command, args, { stdio: 'inherit', env: env ?? process.env });
13
12
  }
14
13
  catch (error) {
15
- resolve({ exitCode: -1, usedMux: false, reason: error instanceof Error ? error.message : String(error) });
14
+ resolve({ launched: false, exitCode: -1, backend: backendLabel, reason: error instanceof Error ? error.message : String(error) });
16
15
  return;
17
16
  }
18
17
  child.on('error', (error) => {
19
- resolve({ exitCode: -1, usedMux: false, reason: error.message });
18
+ resolve({ launched: false, exitCode: -1, backend: backendLabel, reason: error.message });
20
19
  });
21
20
  child.on('close', (code) => {
22
21
  if (code === 0) {
23
- resolve({ exitCode: 0, usedMux: true });
22
+ resolve({ launched: true, exitCode: 0, backend: backendLabel });
24
23
  }
25
24
  else {
26
- resolve({ exitCode: code ?? 1, usedMux: false, reason: `${backendLabel} exited with code ${code ?? 1}` });
25
+ resolve({ launched: false, exitCode: code ?? 1, backend: backendLabel, reason: `${backendLabel} exited with code ${code ?? 1}` });
27
26
  }
28
27
  });
29
28
  });
@@ -31,12 +30,7 @@ export function spawnAttached(command, args, env, backendLabel) {
31
30
  export function splitFlagFromDimensions(width, height) {
32
31
  return width >= height * CELL_ASPECT_RATIO ? '-h' : '-v';
33
32
  }
34
- export function cleanClaudeEnv(extra) {
35
- const env = {
36
- ...getInternalSubprocessEnv(),
37
- ...extra,
38
- };
39
- delete env['CLAUDECODE'];
40
- delete env['CLAUDE_CODE_ENTRYPOINT'];
41
- return env;
33
+ export const PANE_HOLD_MESSAGE = '[aiwcli] Driver exited. Pane held open.';
34
+ export function buildBootstrapPrompt(filePath) {
35
+ return `Read startup instructions from this file path before taking action: ${filePath}. Use that file as the initial context.`;
42
36
  }
@@ -0,0 +1,23 @@
1
+ /**
2
+ * PromptFileManager — owns prompt file lifecycle (creation, cleanup).
3
+ * Replaces scattered writeFileSync calls for prompt temp files.
4
+ */
5
+ export declare class PromptFileManager {
6
+ private readonly files;
7
+ private readonly tempDir;
8
+ private readonly now;
9
+ private readonly pid;
10
+ constructor(options: {
11
+ tempDir: string;
12
+ now: () => number;
13
+ pid: number;
14
+ });
15
+ /**
16
+ * Write prompt text to a temp file and return the path.
17
+ */
18
+ materialize(promptText: string): string;
19
+ /**
20
+ * Clean up all created prompt files. Call in finally block.
21
+ */
22
+ cleanup(): void;
23
+ }