aiwcli 0.15.5 → 0.15.7

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 (299) hide show
  1. package/README.md +6 -3
  2. package/dist/capabilities/branch/adapters.d.ts +2 -0
  3. package/dist/capabilities/branch/adapters.js +21 -0
  4. package/dist/capabilities/branch/contracts.d.ts +57 -0
  5. package/dist/capabilities/branch/contracts.js +1 -0
  6. package/dist/capabilities/branch/control-plane.d.ts +2 -0
  7. package/dist/capabilities/branch/control-plane.js +343 -0
  8. package/dist/capabilities/branch/runtime-core.d.ts +5 -0
  9. package/dist/capabilities/branch/runtime-core.js +36 -0
  10. package/dist/capabilities/installation/control-plane/clean-command.d.ts +41 -0
  11. package/dist/capabilities/installation/control-plane/clean-command.js +196 -0
  12. package/dist/capabilities/installation/control-plane/clear-command.d.ts +160 -0
  13. package/dist/capabilities/installation/control-plane/clear-command.js +1220 -0
  14. package/dist/capabilities/installation/control-plane/init-command.d.ts +81 -0
  15. package/dist/capabilities/installation/control-plane/init-command.js +449 -0
  16. package/dist/capabilities/launch/contracts.d.ts +51 -0
  17. package/dist/capabilities/launch/contracts.js +1 -0
  18. package/dist/capabilities/launch/control-plane/execute-launch.d.ts +2 -0
  19. package/dist/capabilities/launch/control-plane/execute-launch.js +222 -0
  20. package/dist/capabilities/launch/runtime-core/launch-options.d.ts +14 -0
  21. package/dist/capabilities/launch/runtime-core/launch-options.js +69 -0
  22. package/dist/cli/base-command.d.ts +18 -0
  23. package/dist/cli/base-command.js +55 -0
  24. package/dist/commands/branch.d.ts +0 -20
  25. package/dist/commands/branch.js +24 -416
  26. package/dist/commands/clean.d.ts +1 -41
  27. package/dist/commands/clean.js +1 -196
  28. package/dist/commands/clear.d.ts +1 -161
  29. package/dist/commands/clear.js +1 -1121
  30. package/dist/commands/init/index.d.ts +1 -98
  31. package/dist/commands/init/index.js +4 -478
  32. package/dist/commands/launch.d.ts +36 -11
  33. package/dist/commands/launch.js +135 -159
  34. package/dist/lib/base-command.d.ts +1 -114
  35. package/dist/lib/base-command.js +1 -153
  36. package/dist/lib/claude-settings-types.d.ts +31 -19
  37. package/dist/lib/context/context-formatter.d.ts +74 -0
  38. package/dist/lib/context/context-formatter.js +493 -0
  39. package/dist/lib/context/context-selector.d.ts +42 -0
  40. package/dist/lib/context/context-selector.js +451 -0
  41. package/dist/lib/context/context-store.d.ts +100 -0
  42. package/dist/lib/context/context-store.js +618 -0
  43. package/dist/lib/context/plan-manager.d.ts +54 -0
  44. package/dist/lib/context/plan-manager.js +282 -0
  45. package/dist/lib/context/task-tracker.d.ts +44 -0
  46. package/dist/lib/context/task-tracker.js +146 -0
  47. package/dist/lib/core-ide-base.d.ts +4 -0
  48. package/dist/lib/core-ide-base.js +77 -0
  49. package/dist/lib/core-installer.d.ts +5 -0
  50. package/dist/lib/core-installer.js +54 -0
  51. package/dist/lib/git-exclude-manager.d.ts +2 -2
  52. package/dist/lib/git-exclude-manager.js +3 -3
  53. package/dist/lib/hooks/hook-utils.d.ts +143 -0
  54. package/dist/lib/hooks/hook-utils.js +609 -0
  55. package/dist/lib/hooks/session-end-logic.d.ts +5 -0
  56. package/dist/lib/hooks/session-end-logic.js +63 -0
  57. package/dist/lib/hooks-merger.js +25 -19
  58. package/dist/lib/ide-path-resolver.d.ts +19 -7
  59. package/dist/lib/ide-path-resolver.js +25 -9
  60. package/dist/lib/install-state.d.ts +34 -0
  61. package/dist/lib/install-state.js +161 -0
  62. package/dist/lib/launch-options.d.ts +1 -0
  63. package/dist/lib/launch-options.js +1 -0
  64. package/dist/lib/lsp-patch.d.ts +12 -0
  65. package/dist/lib/lsp-patch.js +156 -0
  66. package/dist/lib/multiplexer.d.ts +57 -0
  67. package/dist/lib/multiplexer.js +19 -0
  68. package/dist/lib/multiplexers/psmux.d.ts +75 -0
  69. package/dist/lib/multiplexers/psmux.js +384 -0
  70. package/dist/lib/multiplexers/tmux.d.ts +44 -0
  71. package/dist/lib/multiplexers/tmux.js +262 -0
  72. package/dist/lib/mux-utils.d.ts +5 -0
  73. package/dist/lib/mux-utils.js +42 -0
  74. package/dist/lib/paths.d.ts +2 -2
  75. package/dist/lib/paths.js +2 -2
  76. package/dist/lib/platform-commands.d.ts +27 -0
  77. package/dist/lib/platform-commands.js +49 -0
  78. package/dist/lib/runtime/aiw-cli.d.ts +37 -0
  79. package/dist/lib/runtime/aiw-cli.js +74 -0
  80. package/dist/lib/runtime/atomic-write.d.ts +19 -0
  81. package/dist/lib/runtime/atomic-write.js +121 -0
  82. package/dist/lib/runtime/cli-args.d.ts +55 -0
  83. package/dist/lib/runtime/cli-args.js +185 -0
  84. package/dist/lib/runtime/constants.d.ts +56 -0
  85. package/dist/lib/runtime/constants.js +230 -0
  86. package/dist/lib/runtime/executable-policy.d.ts +16 -0
  87. package/dist/lib/runtime/executable-policy.js +57 -0
  88. package/dist/lib/runtime/git-state.d.ts +9 -0
  89. package/dist/lib/runtime/git-state.js +59 -0
  90. package/dist/lib/runtime/inference.d.ts +37 -0
  91. package/dist/lib/runtime/inference.js +262 -0
  92. package/dist/lib/runtime/lint-dispatch.d.ts +40 -0
  93. package/dist/lib/runtime/lint-dispatch.js +285 -0
  94. package/dist/lib/runtime/logger.d.ts +66 -0
  95. package/dist/lib/runtime/logger.js +201 -0
  96. package/dist/lib/runtime/models.d.ts +14 -0
  97. package/dist/lib/runtime/models.js +14 -0
  98. package/dist/lib/runtime/platform-adapter.d.ts +7 -0
  99. package/dist/lib/runtime/platform-adapter.js +21 -0
  100. package/dist/lib/runtime/preflight.d.ts +24 -0
  101. package/dist/lib/runtime/preflight.js +65 -0
  102. package/dist/lib/runtime/sentinel-ipc.d.ts +14 -0
  103. package/dist/lib/runtime/sentinel-ipc.js +67 -0
  104. package/dist/lib/runtime/state-io.d.ts +30 -0
  105. package/dist/lib/runtime/state-io.js +174 -0
  106. package/dist/lib/runtime/stop-words.d.ts +20 -0
  107. package/dist/lib/runtime/stop-words.js +150 -0
  108. package/dist/lib/runtime/subprocess-utils.d.ts +29 -0
  109. package/dist/lib/runtime/subprocess-utils.js +96 -0
  110. package/dist/lib/runtime/tmux-preflight.d.ts +13 -0
  111. package/dist/lib/runtime/tmux-preflight.js +78 -0
  112. package/dist/lib/runtime/utils.d.ts +54 -0
  113. package/dist/lib/runtime/utils.js +162 -0
  114. package/dist/lib/sentinel-wrapper.d.ts +9 -0
  115. package/dist/lib/sentinel-wrapper.js +20 -0
  116. package/dist/lib/shell-quoting.d.ts +5 -0
  117. package/dist/lib/shell-quoting.js +17 -0
  118. package/dist/lib/spawn-errors.d.ts +6 -0
  119. package/dist/lib/spawn-errors.js +15 -0
  120. package/dist/lib/spawn.js +5 -11
  121. package/dist/lib/template-installer.d.ts +4 -5
  122. package/dist/lib/template-installer.js +36 -34
  123. package/dist/lib/template-resolver.d.ts +6 -7
  124. package/dist/lib/template-resolver.js +26 -21
  125. package/dist/lib/template-settings-reconstructor.d.ts +7 -2
  126. package/dist/lib/template-settings-reconstructor.js +76 -45
  127. package/dist/lib/terminal-strategy.d.ts +11 -0
  128. package/dist/lib/terminal-strategy.js +49 -0
  129. package/dist/lib/terminal.d.ts +28 -0
  130. package/dist/lib/terminal.js +162 -112
  131. package/dist/lib/tmux-pane-placement.d.ts +17 -0
  132. package/dist/lib/tmux-pane-placement.js +58 -0
  133. package/dist/lib/tmux-primitives.d.ts +5 -0
  134. package/dist/lib/tmux-primitives.js +15 -0
  135. package/dist/lib/tmux-session.d.ts +32 -0
  136. package/dist/lib/tmux-session.js +86 -0
  137. package/dist/lib/tty-detection.js +1 -1
  138. package/dist/lib/types.d.ts +168 -0
  139. package/dist/lib/types.js +6 -0
  140. package/dist/lib/version.d.ts +1 -1
  141. package/dist/lib/version.js +1 -1
  142. package/dist/platform/launch.d.ts +10 -0
  143. package/dist/platform/launch.js +10 -0
  144. package/dist/templates/CLAUDE.md +31 -40
  145. package/dist/templates/cc-native/.claude/settings.json +27 -27
  146. package/dist/templates/cc-native/CC-NATIVE-README.md +1 -1
  147. package/dist/templates/cc-native/TEMPLATE-SCHEMA.md +10 -9
  148. package/dist/templates/cc-native/_cc-native/CLAUDE.md +18 -18
  149. package/dist/templates/cc-native/_cc-native/artifacts/CLAUDE.md +3 -3
  150. package/dist/templates/cc-native/_cc-native/artifacts/lib/format.ts +14 -14
  151. package/dist/templates/cc-native/_cc-native/artifacts/lib/tracker.ts +1 -1
  152. package/dist/templates/cc-native/_cc-native/artifacts/lib/write.ts +3 -3
  153. package/dist/templates/cc-native/_cc-native/cc-native.config.json +3 -3
  154. package/dist/templates/cc-native/_cc-native/hooks/CLAUDE.md +16 -15
  155. package/dist/templates/cc-native/_cc-native/hooks/cc-native-plan-review.ts +3 -3
  156. package/dist/templates/cc-native/_cc-native/hooks/enhance_plan_post_subagent.ts +2 -2
  157. package/dist/templates/cc-native/_cc-native/hooks/enhance_plan_post_write.ts +2 -2
  158. package/dist/templates/cc-native/_cc-native/hooks/mark_questions_asked.ts +3 -3
  159. package/dist/templates/cc-native/_cc-native/hooks/plan_questions_early.ts +2 -2
  160. package/dist/templates/cc-native/_cc-native/hooks/validate_task_prompt.ts +3 -3
  161. package/dist/templates/cc-native/_cc-native/lib-ts/CLAUDE.md +8 -8
  162. package/dist/templates/cc-native/_cc-native/lib-ts/aggregate-agents.ts +1 -1
  163. package/dist/templates/cc-native/_cc-native/lib-ts/cc-native-state.ts +4 -4
  164. package/dist/templates/cc-native/_cc-native/lib-ts/cli-output-parser.ts +1 -1
  165. package/dist/templates/cc-native/_cc-native/lib-ts/config.ts +1 -1
  166. package/dist/templates/cc-native/_cc-native/lib-ts/debug.ts +1 -1
  167. package/dist/templates/cc-native/_cc-native/lib-ts/json-parser.ts +1 -1
  168. package/dist/templates/cc-native/_cc-native/lib-ts/plan-discovery.ts +2 -2
  169. package/dist/templates/cc-native/_cc-native/lib-ts/rlm/logger.ts +1 -1
  170. package/dist/templates/cc-native/_cc-native/lib-ts/rlm/retrieval-pipeline.ts +2 -2
  171. package/dist/templates/cc-native/_cc-native/lib-ts/rlm/types.ts +1 -1
  172. package/dist/templates/cc-native/_cc-native/lib-ts/settings.ts +8 -8
  173. package/dist/templates/cc-native/_cc-native/lib-ts/state.ts +3 -3
  174. package/dist/templates/cc-native/_cc-native/lib-ts/tsconfig.json +2 -2
  175. package/dist/templates/cc-native/_cc-native/lib-ts/types.ts +3 -3
  176. package/dist/templates/cc-native/_cc-native/plan-review/CLAUDE.md +3 -1
  177. package/dist/templates/cc-native/_cc-native/plan-review/lib/__tests__/agent-selection.test.ts +345 -0
  178. package/dist/templates/cc-native/_cc-native/plan-review/lib/__tests__/preflight.test.ts +344 -0
  179. package/dist/templates/cc-native/_cc-native/plan-review/lib/agent-selection.ts +37 -15
  180. package/dist/templates/cc-native/_cc-native/plan-review/lib/corroboration.ts +16 -69
  181. package/dist/templates/cc-native/_cc-native/plan-review/lib/orchestrator.ts +1 -1
  182. package/dist/templates/cc-native/_cc-native/plan-review/lib/output-builder.ts +1 -1
  183. package/dist/templates/cc-native/_cc-native/plan-review/lib/plan-questions.ts +2 -2
  184. package/dist/templates/cc-native/_cc-native/plan-review/lib/preflight.ts +56 -26
  185. package/dist/templates/cc-native/_cc-native/plan-review/lib/review-pipeline.ts +7 -7
  186. package/dist/templates/cc-native/_cc-native/plan-review/lib/reviewers/agent.ts +4 -4
  187. package/dist/templates/cc-native/_cc-native/plan-review/lib/reviewers/base/base-agent.ts +3 -3
  188. package/dist/templates/cc-native/_cc-native/plan-review/lib/reviewers/index.ts +1 -1
  189. package/dist/templates/cc-native/_cc-native/plan-review/lib/reviewers/providers/claude-agent.ts +2 -2
  190. package/dist/templates/cc-native/_cc-native/plan-review/lib/reviewers/providers/codex-agent.ts +4 -4
  191. package/dist/templates/cc-native/_cc-native/plan-review/lib/reviewers/providers/gemini-agent.ts +1 -1
  192. package/dist/templates/cc-native/_cc-native/plan-review/lib/reviewers/providers/orchestrator-claude-agent.ts +5 -6
  193. package/dist/templates/core/.codex/workflows/codex.md +17 -0
  194. package/dist/templates/core/.codex/workflows/handoff.md +5 -0
  195. package/dist/templates/core/.codex/workflows/meta-plan.md +7 -0
  196. package/dist/templates/core/.cognition/AGENTS.md +5 -0
  197. package/dist/templates/core/.cognition/config.json +12 -0
  198. package/dist/templates/{_shared → core}/.windsurf/workflows/handoff.md +1 -1
  199. package/dist/templates/{_shared → core}/.windsurf/workflows/meta-plan.md +1 -1
  200. package/dist/templates/core/hooks-ts/_utils/git-state.ts +2 -0
  201. package/dist/templates/{_shared → core}/hooks-ts/archive_plan.ts +14 -23
  202. package/dist/templates/core/hooks-ts/codex_explorer.ts +160 -0
  203. package/dist/templates/{_shared → core}/hooks-ts/context_monitor.ts +23 -55
  204. package/dist/templates/{_shared → core}/hooks-ts/file-suggestion.ts +4 -3
  205. package/dist/templates/{_shared → core}/hooks-ts/lint_after_edit.ts +7 -9
  206. package/dist/templates/{_shared → core}/hooks-ts/pre_compact.ts +5 -5
  207. package/dist/templates/{_shared → core}/hooks-ts/session_end.ts +38 -78
  208. package/dist/templates/{_shared → core}/hooks-ts/session_start.ts +5 -5
  209. package/dist/templates/core/hooks-ts/task_create_capture.ts +32 -0
  210. package/dist/templates/{_shared → core}/hooks-ts/task_update_capture.ts +9 -24
  211. package/dist/templates/core/hooks-ts/user_prompt_submit.ts +46 -0
  212. package/dist/templates/{_shared → core}/lib-ts/CLAUDE.md +27 -16
  213. package/dist/templates/{_shared → core}/lib-ts/agent-exec/backends/headless.ts +3 -2
  214. package/dist/templates/{_shared → core}/lib-ts/agent-exec/backends/tmux.ts +44 -15
  215. package/dist/templates/{_shared → core}/lib-ts/agent-exec/base-agent.ts +6 -4
  216. package/dist/templates/{_shared → core}/lib-ts/agent-exec/execution-backend.ts +1 -1
  217. package/dist/templates/{_shared → core}/lib-ts/agent-exec/index.ts +2 -2
  218. package/dist/templates/{_shared → core}/lib-ts/agent-exec/structured-output.ts +4 -5
  219. package/dist/templates/{_shared → core}/lib-ts/context/CLAUDE.md +9 -6
  220. package/dist/templates/{_shared → core}/lib-ts/context/context-formatter.ts +16 -21
  221. package/dist/templates/{_shared → core}/lib-ts/context/context-selector.ts +8 -6
  222. package/dist/templates/{_shared → core}/lib-ts/context/context-store.ts +32 -20
  223. package/dist/templates/{_shared → core}/lib-ts/context/plan-manager.ts +19 -15
  224. package/dist/templates/{_shared → core}/lib-ts/context/task-tracker.ts +3 -3
  225. package/dist/templates/core/lib-ts/hooks/context-monitor-logic.ts +32 -0
  226. package/dist/templates/{_shared/lib-ts/base → core/lib-ts/hooks}/hook-utils.ts +168 -41
  227. package/dist/templates/core/lib-ts/hooks/prompt-binding-logic.ts +80 -0
  228. package/dist/templates/core/lib-ts/hooks/session-end-logic.ts +93 -0
  229. package/dist/templates/core/lib-ts/package.json +19 -0
  230. package/dist/templates/core/lib-ts/runtime/agent-launcher.ts +295 -0
  231. package/dist/templates/core/lib-ts/runtime/aiw-cli.ts +106 -0
  232. package/dist/templates/{_shared/lib-ts/base → core/lib-ts/runtime}/atomic-write.ts +12 -7
  233. package/dist/templates/{_shared/lib-ts/base → core/lib-ts/runtime}/cli-args.ts +8 -6
  234. package/dist/templates/{_shared/lib-ts/base → core/lib-ts/runtime}/constants.ts +326 -324
  235. package/dist/templates/core/lib-ts/runtime/executable-policy.ts +89 -0
  236. package/dist/templates/{_shared/lib-ts/base → core/lib-ts/runtime}/git-state.ts +6 -4
  237. package/dist/templates/{_shared/lib-ts/base → core/lib-ts/runtime}/inference.ts +59 -10
  238. package/dist/templates/{_shared/lib-ts/base → core/lib-ts/runtime}/lint-dispatch.ts +25 -23
  239. package/dist/templates/{_shared/lib-ts/base → core/lib-ts/runtime}/logger.ts +32 -29
  240. package/dist/templates/{_shared/lib-ts/base → core/lib-ts/runtime}/models.ts +2 -2
  241. package/dist/templates/core/lib-ts/runtime/platform-adapter.ts +33 -0
  242. package/dist/templates/{_shared/lib-ts/base → core/lib-ts/runtime}/preflight.ts +4 -3
  243. package/dist/templates/core/lib-ts/runtime/sentinel-ipc.ts +91 -0
  244. package/dist/templates/{_shared/lib-ts/base → core/lib-ts/runtime}/state-io.ts +11 -7
  245. package/dist/templates/core/lib-ts/runtime/stop-words.ts +185 -0
  246. package/dist/templates/core/lib-ts/runtime/subprocess-utils.ts +147 -0
  247. package/dist/templates/core/lib-ts/runtime/tmux-preflight.ts +93 -0
  248. package/dist/templates/{_shared/lib-ts/base → core/lib-ts/runtime}/utils.ts +4 -3
  249. package/dist/templates/{_shared → core}/lib-ts/templates/formatters.ts +7 -5
  250. package/dist/templates/{_shared → core}/lib-ts/templates/plan-context.ts +2 -1
  251. package/dist/templates/{_shared → core}/lib-ts/tsconfig.json +3 -1
  252. package/dist/templates/{_shared → core}/lib-ts/types.ts +78 -77
  253. package/dist/templates/core/scripts/resolve-run.ts +61 -0
  254. package/dist/templates/{_shared → core}/scripts/resolve_context.ts +3 -3
  255. package/dist/templates/{_shared → core}/scripts/status_line.ts +25 -20
  256. package/dist/templates/core/skills/codex/CLAUDE.md +78 -0
  257. package/dist/templates/{_shared → core}/skills/codex/SKILL.md +21 -18
  258. package/dist/templates/{_shared → core}/skills/codex/lib/codex-watcher.ts +76 -103
  259. package/dist/templates/{_shared → core}/skills/codex/scripts/launch-codex.ts +119 -133
  260. package/dist/templates/{_shared → core}/skills/codex/scripts/watch-codex.ts +6 -4
  261. package/dist/templates/core/skills/devin/CLAUDE.md +65 -0
  262. package/dist/templates/core/skills/devin/SKILL.md +73 -0
  263. package/dist/templates/core/skills/devin/lib/devin-watcher.ts +280 -0
  264. package/dist/templates/core/skills/devin/scripts/launch-devin.ts +257 -0
  265. package/dist/templates/{_shared → core}/skills/handoff-system/CLAUDE.md +436 -433
  266. package/dist/templates/{_shared → core}/skills/handoff-system/lib/document-generator.ts +9 -7
  267. package/dist/templates/{_shared → core}/skills/handoff-system/lib/handoff-reader.ts +6 -4
  268. package/dist/templates/{_shared → core}/skills/handoff-system/scripts/resume_handoff.ts +10 -8
  269. package/dist/templates/{_shared → core}/skills/handoff-system/scripts/save_handoff.ts +12 -10
  270. package/dist/templates/{_shared → core}/skills/handoff-system/workflows/handoff-resume.md +2 -2
  271. package/dist/templates/{_shared → core}/skills/handoff-system/workflows/handoff.md +6 -5
  272. package/dist/templates/{_shared → core}/skills/meta-plan/CLAUDE.md +2 -1
  273. package/dist/templates/{_shared → core}/skills/meta-plan/workflows/meta-plan.md +8 -7
  274. package/oclif.manifest.json +89 -13
  275. package/package.json +13 -12
  276. package/dist/templates/_shared/.claude/settings.json +0 -120
  277. package/dist/templates/_shared/.claude/skills/codex/SKILL.md +0 -35
  278. package/dist/templates/_shared/.claude/skills/handoff/SKILL.md +0 -13
  279. package/dist/templates/_shared/.claude/skills/handoff-resume/SKILL.md +0 -13
  280. package/dist/templates/_shared/.claude/skills/meta-plan/SKILL.md +0 -43
  281. package/dist/templates/_shared/.codex/workflows/codex.md +0 -11
  282. package/dist/templates/_shared/.codex/workflows/handoff.md +0 -226
  283. package/dist/templates/_shared/.codex/workflows/meta-plan.md +0 -347
  284. package/dist/templates/_shared/hooks-ts/_utils/git-state.ts +0 -2
  285. package/dist/templates/_shared/hooks-ts/task_create_capture.ts +0 -48
  286. package/dist/templates/_shared/hooks-ts/user_prompt_submit.ts +0 -93
  287. package/dist/templates/_shared/lib-ts/base/launchers/tmux-launcher.ts +0 -173
  288. package/dist/templates/_shared/lib-ts/base/launchers/window-launcher.ts +0 -93
  289. package/dist/templates/_shared/lib-ts/base/launchers/wt-launcher.ts +0 -64
  290. package/dist/templates/_shared/lib-ts/base/pane-launcher.ts +0 -55
  291. package/dist/templates/_shared/lib-ts/base/sentinel-ipc.ts +0 -87
  292. package/dist/templates/_shared/lib-ts/base/stop-words.ts +0 -184
  293. package/dist/templates/_shared/lib-ts/base/subprocess-utils.ts +0 -249
  294. package/dist/templates/_shared/lib-ts/base/tmux-driver.ts +0 -341
  295. package/dist/templates/_shared/lib-ts/base/tmux-pane-placement.ts +0 -78
  296. package/dist/templates/_shared/lib-ts/package.json +0 -20
  297. package/dist/templates/_shared/scripts/resolve-run.ts +0 -62
  298. package/dist/templates/_shared/skills/codex/CLAUDE.md +0 -70
  299. /package/dist/templates/{_shared → core}/lib-ts/agent-exec/backends/index.ts +0 -0
@@ -27,38 +27,68 @@
27
27
  *
28
28
  * @module lib/terminal
29
29
  */
30
- import { execSync, spawn } from 'node:child_process';
31
- /**
32
- * Return a copy of process.env with Claude Code nesting-detection vars removed.
33
- *
34
- * Claude Code sets CLAUDECODE and CLAUDE_CODE_ENTRYPOINT when running. Child
35
- * processes that inherit these vars are blocked from launching their own Claude
36
- * Code instance ("cannot launch claude within claude").
37
- *
38
- * Source of truth: packages/cli/src/templates/_shared/lib-ts/base/subprocess-utils.ts
39
- * → getInternalSubprocessEnv() — if Claude Code adds more nesting-detection vars
40
- * in a future release, add them here too.
41
- */
42
- function cleanTerminalEnv() {
43
- const env = { ...process.env };
44
- delete env['CLAUDECODE'];
45
- delete env['CLAUDE_CODE_ENTRYPOINT'];
46
- return env;
30
+ import { spawn } from 'node:child_process';
31
+ import { existsSync } from 'node:fs';
32
+ import path from 'node:path';
33
+ import { cleanClaudeEnv } from './mux-utils.js';
34
+ import { isCommandAvailable } from './runtime/executable-policy.js';
35
+ import { isWindowsPlatform } from './runtime/platform-adapter.js';
36
+ import { findMsysBash } from './runtime/tmux-preflight.js';
37
+ import { escapeSingleQuotedPath } from './shell-quoting.js';
38
+ import { detectPowerShell, findAvailableLinuxTerminal, isWSL, resolveWindowsTerminalStrategy, } from './terminal-strategy.js';
39
+ /** @internal */
40
+ export function resolveTerminalPlatform(platform, isWSLResult) {
41
+ if (isWindowsPlatform(platform))
42
+ return 'windows';
43
+ if (platform === 'darwin')
44
+ return 'darwin';
45
+ if (isWSLResult)
46
+ return 'wsl';
47
+ return 'linux';
47
48
  }
48
- /**
49
- * Detect which PowerShell is available on Windows.
50
- * Prefers PowerShell 7 (pwsh) over legacy PowerShell.
51
- *
52
- * @returns 'pwsh' if PowerShell 7 is available, 'powershell' otherwise
53
- */
54
- function detectPowerShell() {
55
- try {
56
- execSync('where pwsh', { stdio: 'ignore' });
57
- return 'pwsh';
58
- }
59
- catch {
60
- return 'powershell';
61
- }
49
+ /** @internal */
50
+ export function buildMacTerminalSpawnArgs(cwd, command) {
51
+ const escapedPath = escapeSingleQuotedPath(cwd, 'bash');
52
+ const fullCommand = `cd '${escapedPath}' && ${command}`;
53
+ const escapedCommand = fullCommand.replaceAll('\\', '\\\\').replaceAll('"', String.raw `\"`);
54
+ return {
55
+ command: 'osascript',
56
+ args: ['-e', `tell application "Terminal" to do script "${escapedCommand}"`],
57
+ };
58
+ }
59
+ /** @internal */
60
+ export function buildWindowsTerminalSpawnArgs(cwd, command, powershellCmd) {
61
+ return {
62
+ command: 'wt',
63
+ args: ['-d', cwd, powershellCmd, '-NoExit', '-Command', command],
64
+ };
65
+ }
66
+ /** @internal */
67
+ export function buildPowerShellFallbackSpawnArgs(cwd, command, powershellCmd) {
68
+ const escapedPath = escapeSingleQuotedPath(cwd, 'powershell');
69
+ const psCommand = `Start-Process ${powershellCmd} -ArgumentList '-NoExit','-Command',"cd '${escapedPath}'; ${command}"`;
70
+ return {
71
+ command: powershellCmd,
72
+ args: ['-Command', psCommand],
73
+ };
74
+ }
75
+ /** @internal */
76
+ export function buildLinuxTerminalSpawnArgs(cwd, command, terminalInfo) {
77
+ const escapedPath = escapeSingleQuotedPath(cwd, 'bash');
78
+ const fullCommand = `cd '${escapedPath}' && ${command}`;
79
+ return {
80
+ command: terminalInfo.cmd,
81
+ args: terminalInfo.getArgs(fullCommand),
82
+ };
83
+ }
84
+ /** @internal */
85
+ export function buildWSLTerminalSpawnArgs(cwd, command) {
86
+ const escapedPath = escapeSingleQuotedPath(cwd, 'bash');
87
+ const bashCmd = `cd '${escapedPath}' && ${command}; exec bash`;
88
+ return {
89
+ command: 'wt.exe',
90
+ args: ['wsl.exe', '--', 'bash', '-c', bashCmd],
91
+ };
62
92
  }
63
93
  /**
64
94
  * Launch PowerShell fallback when Windows Terminal is not available.
@@ -70,13 +100,12 @@ function detectPowerShell() {
70
100
  */
71
101
  async function launchPowerShellFallback(cwd, command, powershellCmd, debugLog) {
72
102
  return new Promise((resolve) => {
73
- const escapedPath = cwd.replaceAll("'", "''");
74
- const psCommand = `Start-Process ${powershellCmd} -ArgumentList '-NoExit','-Command',"cd '${escapedPath}'; ${command}"`;
75
- debugLog?.(`Launching PowerShell fallback with command: ${psCommand}`);
76
- const terminal = spawn(powershellCmd, ['-Command', psCommand], {
103
+ const spawnArgs = buildPowerShellFallbackSpawnArgs(cwd, command, powershellCmd);
104
+ debugLog?.(`Launching PowerShell fallback with command: ${spawnArgs.args[1]}`);
105
+ const terminal = spawn(spawnArgs.command, spawnArgs.args, {
77
106
  detached: true,
78
107
  stdio: 'ignore',
79
- env: cleanTerminalEnv(),
108
+ env: cleanClaudeEnv(),
80
109
  });
81
110
  terminal.on('error', (err) => {
82
111
  resolve({ success: false, error: `Failed to launch PowerShell: ${err.message}` });
@@ -90,32 +119,91 @@ async function launchPowerShellFallback(cwd, command, powershellCmd, debugLog) {
90
119
  *
91
120
  * @param cwd - Working directory
92
121
  * @param command - Command to execute
122
+ * @param shellPreference - Preferred shell for Windows launches
93
123
  * @param debugLog - Optional debug logging function
94
124
  */
95
- async function launchWindowsTerminal(cwd, command, debugLog) {
96
- const powershellCmd = detectPowerShell();
97
- debugLog?.(`Detected PowerShell: ${powershellCmd}`);
98
- return new Promise((resolve) => {
99
- const terminal = spawn('wt', ['-d', cwd, powershellCmd, '-NoExit', '-Command', command], {
100
- detached: true,
101
- stdio: 'ignore',
102
- env: cleanTerminalEnv(),
103
- });
104
- terminal.on('error', (err) => {
105
- // If wt.exe not found, try fallback to Start-Process
106
- if (err.message.includes('ENOENT')) {
107
- debugLog?.('Windows Terminal not found, using PowerShell fallback');
108
- launchPowerShellFallback(cwd, command, powershellCmd, debugLog)
109
- .then(resolve)
110
- .catch(() => resolve({ success: false, error: 'Failed to launch PowerShell fallback' }));
125
+ async function launchWindowsTerminal(cwd, command, shellPreference, debugLog) {
126
+ const powershellCmd = detectPowerShell(isCommandAvailable);
127
+ debugLog?.(`Detected PowerShell: ${powershellCmd}; shell preference: ${shellPreference}`);
128
+ const gitBashPath = findMsysBash();
129
+ const minttyPath = gitBashPath
130
+ ? path.join(path.dirname(gitBashPath), 'mintty.exe')
131
+ : null;
132
+ const hasMintty = Boolean(minttyPath && existsSync(minttyPath));
133
+ const strategyOrder = resolveWindowsTerminalStrategy(shellPreference, gitBashPath, hasMintty, powershellCmd);
134
+ const tryStrategy = async (strategy) => {
135
+ if (strategy === 'powershell-fallback') {
136
+ debugLog?.('Using PowerShell fallback launcher');
137
+ return launchPowerShellFallback(cwd, command, powershellCmd, debugLog);
138
+ }
139
+ if (strategy === 'mintty') {
140
+ if (!minttyPath || !gitBashPath) {
141
+ return { success: false, error: 'mintty or Git Bash not found' };
111
142
  }
112
- else {
113
- resolve({ success: false, error: `Failed to launch terminal: ${err.message}` });
143
+ const escapedPath = escapeSingleQuotedPath(cwd, 'bash');
144
+ const bashCmd = `cd '${escapedPath}' && ${command}; exec bash`;
145
+ debugLog?.(`Using mintty for Windows terminal: ${minttyPath}`);
146
+ return new Promise((resolve) => {
147
+ const terminal = spawn(minttyPath, [gitBashPath, '-lc', bashCmd], {
148
+ detached: true,
149
+ stdio: 'ignore',
150
+ env: cleanClaudeEnv(),
151
+ windowsHide: true,
152
+ });
153
+ terminal.on('error', (err) => {
154
+ resolve({ success: false, error: `mintty launch failed: ${err.message}` });
155
+ });
156
+ terminal.unref();
157
+ resolve({ success: true });
158
+ });
159
+ }
160
+ if (strategy === 'git-bash-in-wt') {
161
+ if (!gitBashPath) {
162
+ return { success: false, error: 'Git Bash not found' };
114
163
  }
164
+ const escapedPath = escapeSingleQuotedPath(cwd, 'bash');
165
+ const bashCmd = `cd '${escapedPath}' && ${command}; exec bash`;
166
+ debugLog?.(`Using Git Bash for Windows terminal: ${gitBashPath}`);
167
+ return new Promise((resolve) => {
168
+ const terminal = spawn('wt', ['-d', cwd, gitBashPath, '-lc', bashCmd], {
169
+ detached: true,
170
+ stdio: 'ignore',
171
+ env: cleanClaudeEnv(),
172
+ });
173
+ terminal.on('error', (err) => {
174
+ resolve({ success: false, error: `Git Bash launch via wt failed: ${err.message}` });
175
+ });
176
+ terminal.unref();
177
+ resolve({ success: true });
178
+ });
179
+ }
180
+ debugLog?.('Using Windows Terminal with PowerShell');
181
+ return new Promise((resolve) => {
182
+ const spawnArgs = buildWindowsTerminalSpawnArgs(cwd, command, powershellCmd);
183
+ const terminal = spawn(spawnArgs.command, spawnArgs.args, {
184
+ detached: true,
185
+ stdio: 'ignore',
186
+ env: cleanClaudeEnv(),
187
+ });
188
+ terminal.on('error', (err) => {
189
+ resolve({ success: false, error: `Failed to launch terminal: ${err.message}` });
190
+ });
191
+ terminal.unref();
192
+ resolve({ success: true });
115
193
  });
116
- terminal.unref();
117
- resolve({ success: true });
118
- });
194
+ };
195
+ const tryStrategies = async (index = 0) => {
196
+ const strategy = strategyOrder[index];
197
+ if (!strategy) {
198
+ return { success: false, error: 'Failed to launch Windows terminal with all available strategies' };
199
+ }
200
+ const result = await tryStrategy(strategy);
201
+ if (result.success)
202
+ return result;
203
+ debugLog?.(`Strategy ${strategy} failed: ${result.error}`);
204
+ return tryStrategies(index + 1);
205
+ };
206
+ return tryStrategies();
119
207
  }
120
208
  /**
121
209
  * Launch macOS Terminal.app with command.
@@ -126,16 +214,12 @@ async function launchWindowsTerminal(cwd, command, debugLog) {
126
214
  */
127
215
  async function launchMacTerminal(cwd, command, debugLog) {
128
216
  return new Promise((resolve) => {
129
- // Escape single quotes for bash context
130
- const escapedPath = cwd.replaceAll("'", String.raw `'\''`);
131
- const fullCommand = `cd '${escapedPath}' && ${command}`;
132
- // Escape double quotes and backslashes for AppleScript context
133
- const escapedCommand = fullCommand.replaceAll('\\', '\\\\').replaceAll('"', String.raw `\"`);
134
- debugLog?.(`Launching macOS Terminal with command: ${fullCommand}`);
135
- const terminal = spawn('osascript', ['-e', `tell application "Terminal" to do script "${escapedCommand}"`], {
217
+ const spawnArgs = buildMacTerminalSpawnArgs(cwd, command);
218
+ debugLog?.(`Launching macOS Terminal with command: cd '${escapeSingleQuotedPath(cwd, 'bash')}' && ${command}`);
219
+ const terminal = spawn(spawnArgs.command, spawnArgs.args, {
136
220
  detached: true,
137
221
  stdio: 'ignore',
138
- env: cleanTerminalEnv(),
222
+ env: cleanClaudeEnv(),
139
223
  });
140
224
  terminal.on('error', (err) => {
141
225
  resolve({ success: false, error: `Failed to launch Terminal.app: ${err.message}` });
@@ -144,56 +228,24 @@ async function launchMacTerminal(cwd, command, debugLog) {
144
228
  resolve({ success: true });
145
229
  });
146
230
  }
147
- /**
148
- * Linux terminal emulator configurations.
149
- */
150
- const LINUX_TERMINALS = [
151
- { cmd: 'gnome-terminal', getArgs: (command) => ['--', 'bash', '-c', `${command}; exec bash`] },
152
- { cmd: 'konsole', getArgs: (command) => ['-e', `bash -c "${command}; exec bash"`] },
153
- { cmd: 'xterm', getArgs: (command) => ['-e', `bash -c "${command}; exec bash"`] },
154
- { cmd: 'x-terminal-emulator', getArgs: (command) => ['-e', `bash -c "${command}; exec bash"`] },
155
- ];
156
- /**
157
- * Find the first available Linux terminal emulator.
158
- * Checks gnome-terminal, konsole, xterm, x-terminal-emulator in order.
159
- *
160
- * @returns Terminal configuration if found, null otherwise
161
- */
162
- function findAvailableLinuxTerminal() {
163
- for (const terminal of LINUX_TERMINALS) {
164
- try {
165
- execSync(`which ${terminal.cmd}`, { stdio: 'ignore' });
166
- return terminal;
167
- }
168
- catch {
169
- // Terminal not found, try next
170
- continue;
171
- }
172
- }
173
- return null;
174
- }
175
- function isWSL() {
176
- return Boolean(process.env['WSL_DISTRO_NAME']);
177
- }
178
231
  /**
179
232
  * Launch Windows Terminal (wt.exe) from WSL, running the command inside a new bash session.
180
233
  *
181
234
  * Uses wt.exe → wsl.exe → bash so the new terminal inherits the correct WSL distro.
182
- * Claude Code nesting-detection vars are stripped via cleanTerminalEnv().
235
+ * Claude Code nesting-detection vars are stripped via cleanClaudeEnv().
183
236
  *
184
237
  * @param cwd - Working directory (WSL path)
185
238
  * @param command - Command to execute
186
239
  * @param debugLog - Optional debug logging function
187
240
  */
188
241
  async function launchWSLTerminal(cwd, command, debugLog) {
189
- const escapedPath = cwd.replaceAll("'", String.raw `'\''`);
190
- const bashCmd = `cd '${escapedPath}' && ${command}; exec bash`;
191
- debugLog?.(`Launching WSL via wt.exe with command: ${bashCmd}`);
242
+ const spawnArgs = buildWSLTerminalSpawnArgs(cwd, command);
243
+ debugLog?.(`Launching WSL via wt.exe with command: ${spawnArgs.args[4]}`);
192
244
  return new Promise((resolve) => {
193
- const proc = spawn('wt.exe', ['wsl.exe', '--', 'bash', '-c', bashCmd], {
245
+ const proc = spawn(spawnArgs.command, spawnArgs.args, {
194
246
  detached: true,
195
247
  stdio: 'ignore',
196
- env: cleanTerminalEnv(),
248
+ env: cleanClaudeEnv(),
197
249
  });
198
250
  proc.on('error', (err) => {
199
251
  resolve({ success: false, error: `wt.exe failed: ${err.message}` });
@@ -212,23 +264,21 @@ async function launchWSLTerminal(cwd, command, debugLog) {
212
264
  */
213
265
  async function launchLinuxTerminal(cwd, command, debugLog) {
214
266
  // Find available terminal first (synchronous)
215
- const terminal = findAvailableLinuxTerminal();
267
+ const terminal = findAvailableLinuxTerminal(isCommandAvailable);
216
268
  if (!terminal) {
217
269
  return {
218
270
  error: 'No supported terminal emulator found. Please install gnome-terminal, konsole, or xterm.',
219
271
  success: false,
220
272
  };
221
273
  }
222
- // Escape single quotes for bash shell
223
- const escapedPath = cwd.replaceAll("'", String.raw `'\''`);
224
- const fullCommand = `cd '${escapedPath}' && ${command}`;
225
- debugLog?.(`Launching ${terminal.cmd} with command: ${fullCommand}`);
274
+ const spawnArgs = buildLinuxTerminalSpawnArgs(cwd, command, terminal);
275
+ debugLog?.(`Launching ${terminal.cmd} with command: cd '${escapeSingleQuotedPath(cwd, 'bash')}' && ${command}`);
226
276
  // Launch terminal (single async operation)
227
277
  return new Promise((resolve) => {
228
- const proc = spawn(terminal.cmd, terminal.getArgs(fullCommand), {
278
+ const proc = spawn(spawnArgs.command, spawnArgs.args, {
229
279
  detached: true,
230
280
  stdio: 'ignore',
231
- env: cleanTerminalEnv(),
281
+ env: cleanClaudeEnv(),
232
282
  });
233
283
  proc.on('error', (err) => {
234
284
  resolve({ error: `Failed to launch ${terminal.cmd}: ${err.message}`, success: false });
@@ -269,12 +319,12 @@ async function launchLinuxTerminal(cwd, command, debugLog) {
269
319
  * ```
270
320
  */
271
321
  export async function launchTerminal(options) {
272
- const { cwd, command, debugLog } = options;
322
+ const { cwd, command, debugLog, windowsShellPreference = 'default' } = options;
273
323
  const { platform } = process;
274
324
  debugLog?.(`Launching terminal in ${cwd} with command: ${command}`);
275
325
  debugLog?.(`Platform: ${platform}`);
276
- if (platform === 'win32') {
277
- return launchWindowsTerminal(cwd, command, debugLog);
326
+ if (isWindowsPlatform(platform)) {
327
+ return launchWindowsTerminal(cwd, command, windowsShellPreference, debugLog);
278
328
  }
279
329
  if (platform === 'darwin') {
280
330
  return launchMacTerminal(cwd, command, debugLog);
@@ -0,0 +1,17 @@
1
+ /**
2
+ * BSP split algorithm for tmux pane placement.
3
+ * Extracted from template core/lib-ts/base/tmux-pane-placement.ts.
4
+ */
5
+ export type TmuxSplitFlag = '-h' | '-v';
6
+ export interface TmuxPaneInfo {
7
+ active: boolean;
8
+ height: number;
9
+ paneId: string;
10
+ width: number;
11
+ }
12
+ export interface PlacementResult {
13
+ splitFlag: TmuxSplitFlag;
14
+ targetPane: string;
15
+ }
16
+ export declare function listPanes(tmuxPath: string): Promise<TmuxPaneInfo[]>;
17
+ export declare function findBestSplit(panes: TmuxPaneInfo[]): null | PlacementResult;
@@ -0,0 +1,58 @@
1
+ /**
2
+ * BSP split algorithm for tmux pane placement.
3
+ * Extracted from template core/lib-ts/base/tmux-pane-placement.ts.
4
+ */
5
+ import { execFileAsync } from './runtime/subprocess-utils.js';
6
+ const LIST_PANES_FORMAT = '#{pane_id} #{pane_width} #{pane_height} #{pane_active}';
7
+ export async function listPanes(tmuxPath) {
8
+ const result = await execFileAsync(tmuxPath, ['list-panes', '-F', LIST_PANES_FORMAT], {
9
+ timeout: 3000,
10
+ });
11
+ if (result.exitCode !== 0)
12
+ return [];
13
+ const panes = [];
14
+ for (const rawLine of result.stdout.split(/\r?\n/)) {
15
+ const line = rawLine.trim();
16
+ if (!line)
17
+ continue;
18
+ const parts = line.split(/\s+/);
19
+ if (parts.length < 4)
20
+ continue;
21
+ const paneId = parts[0] ?? '';
22
+ const width = Number.parseInt(parts[1] ?? '', 10);
23
+ const height = Number.parseInt(parts[2] ?? '', 10);
24
+ const activeRaw = parts[3] ?? '';
25
+ if (!paneId || !Number.isFinite(width) || !Number.isFinite(height))
26
+ continue;
27
+ panes.push({
28
+ paneId,
29
+ width,
30
+ height,
31
+ active: activeRaw === '1',
32
+ });
33
+ }
34
+ return panes;
35
+ }
36
+ export function findBestSplit(panes) {
37
+ if (panes.length === 0)
38
+ return null;
39
+ let best = panes[0];
40
+ let bestArea = best.width * best.height;
41
+ for (let i = 1; i < panes.length; i++) {
42
+ const pane = panes[i];
43
+ if (!pane)
44
+ continue;
45
+ const area = pane.width * pane.height;
46
+ if (area > bestArea) {
47
+ best = pane;
48
+ bestArea = area;
49
+ }
50
+ }
51
+ const CELL_ASPECT_RATIO = 2;
52
+ const visualWidth = best.width;
53
+ const visualHeight = best.height * CELL_ASPECT_RATIO;
54
+ return {
55
+ targetPane: best.paneId,
56
+ splitFlag: visualWidth >= visualHeight ? '-h' : '-v',
57
+ };
58
+ }
@@ -0,0 +1,5 @@
1
+ export { quoteForSh } from './shell-quoting.js';
2
+ /** Fixed tmux server socket. Multiple named sessions share one server. */
3
+ export declare const TMUX_SOCKET_PATH: string;
4
+ /** Convert Windows path to MSYS2 POSIX path for tmux args. C:\foo\bar → /c/foo/bar */
5
+ export declare function toMsysPosixPath(winPath: string): string;
@@ -0,0 +1,15 @@
1
+ import * as os from 'node:os';
2
+ import path from 'node:path';
3
+ export { quoteForSh } from './shell-quoting.js';
4
+ /** Fixed tmux server socket. Multiple named sessions share one server. */
5
+ export const TMUX_SOCKET_PATH = path.join(os.tmpdir(), 'aiwcli-tmux.sock');
6
+ /** Convert Windows path to MSYS2 POSIX path for tmux args. C:\foo\bar → /c/foo/bar */
7
+ export function toMsysPosixPath(winPath) {
8
+ if (process.platform !== 'win32')
9
+ return winPath;
10
+ const normalized = winPath.replaceAll('\\', '/');
11
+ const match = normalized.match(/^([A-Za-z]):\/(.*)/u);
12
+ if (!match)
13
+ return normalized;
14
+ return `/${match[1].toLowerCase()}/${match[2]}`;
15
+ }
@@ -0,0 +1,32 @@
1
+ export interface TmuxSessionOptions {
2
+ /** Prepend tmux mouse enable command (default true). */
3
+ enableMouse?: boolean;
4
+ /** Platform override for deterministic tests. */
5
+ platform?: NodeJS.Platform | undefined;
6
+ /** Optional prompt text to deliver as a positional arg via temp file. */
7
+ promptText?: string | undefined;
8
+ reattach?: boolean;
9
+ sessionName: string;
10
+ /** CLI args (e.g. ['--dangerously-skip-permissions']). */
11
+ toolArgs: string[];
12
+ /** Absolute path to tool binary (or bare command name on Unix). */
13
+ toolPath: string;
14
+ }
15
+ export type TmuxColorMode = 'c256' | 'truecolor';
16
+ export declare function buildTmuxRuntimeBootstrapCommands(platform?: NodeJS.Platform, enableMouse?: boolean): string[];
17
+ /** Color mode policy for tmux-launched sessions. */
18
+ export declare function resolveTmuxColorMode(platform?: NodeJS.Platform): TmuxColorMode;
19
+ /**
20
+ * Resolve the absolute path to a tool binary (e.g. 'claude', 'codex').
21
+ * On Windows prefers .exe, then extensionless, then .cmd.
22
+ * Returns null when the tool is not on PATH.
23
+ */
24
+ export declare function findToolPath(name: string): null | string;
25
+ /** Build the shell command string from structured options. */
26
+ export declare function buildShellCommand(opts: TmuxSessionOptions): string;
27
+ /**
28
+ * Best-effort configure tmux session: mouse, scrollback, 256-color, and truecolor.
29
+ * Batches all settings into a single tmux invocation using \; command separator.
30
+ * Unix only — Windows uses psmux (native ConPTY handles mouse/color natively).
31
+ */
32
+ export declare function configureTmuxSession(): void;
@@ -0,0 +1,86 @@
1
+ import { execSync } from 'node:child_process';
2
+ import { writeFileSync } from 'node:fs';
3
+ import * as os from 'node:os';
4
+ import path from 'node:path';
5
+ import { resolveExecutable } from './runtime/executable-policy.js';
6
+ import { isNonWindowsPlatform, resolveTmuxColorModeForPlatform, } from './runtime/platform-adapter.js';
7
+ import { quoteForSh } from './tmux-primitives.js';
8
+ export function buildTmuxRuntimeBootstrapCommands(platform = process.platform, enableMouse = true) {
9
+ const commands = [];
10
+ if (enableMouse) {
11
+ commands.push('tmux set-option -g mouse on >/dev/null 2>&1 || true');
12
+ }
13
+ // Increase scrollback buffer from default 2000
14
+ commands.push('tmux set-option -g history-limit 50000 >/dev/null 2>&1 || true');
15
+ // Configure terminal overrides for truecolor on Unix.
16
+ // Note: default-terminal is set before session creation.
17
+ // Windows uses psmux (native ConPTY) which handles color/cursor natively.
18
+ if (isNonWindowsPlatform(platform)) {
19
+ commands.push('tmux set -a terminal-overrides ",xterm*:Tc,alacritty:Tc" >/dev/null 2>&1 || true');
20
+ }
21
+ return commands;
22
+ }
23
+ /** Color mode policy for tmux-launched sessions. */
24
+ export function resolveTmuxColorMode(platform = process.platform) {
25
+ return resolveTmuxColorModeForPlatform(platform);
26
+ }
27
+ /**
28
+ * Resolve the absolute path to a tool binary (e.g. 'claude', 'codex').
29
+ * On Windows prefers .exe, then extensionless, then .cmd.
30
+ * Returns null when the tool is not on PATH.
31
+ */
32
+ export function findToolPath(name) {
33
+ return resolveExecutable(name, { windowsProfile: 'exeThenExtensionlessThenCmd' });
34
+ }
35
+ /** Build the shell command string from structured options. */
36
+ export function buildShellCommand(opts) {
37
+ const { toolPath, toolArgs, promptText, enableMouse = true, platform = process.platform } = opts;
38
+ const colorMode = resolveTmuxColorMode(platform);
39
+ const parts = buildTmuxRuntimeBootstrapCommands(platform, enableMouse);
40
+ const cmdParts = [];
41
+ cmdParts.push(quoteForSh(toolPath));
42
+ for (const arg of toolArgs) {
43
+ cmdParts.push(quoteForSh(arg));
44
+ }
45
+ // Deliver prompt via temp file — avoids nested bash→tmux→sh quoting
46
+ if (promptText) {
47
+ const tmpFile = path.join(os.tmpdir(), `aiwcli-prompt-${Date.now()}-${process.pid}.txt`);
48
+ writeFileSync(tmpFile, promptText, { encoding: 'utf8', mode: 0o600 });
49
+ const bootstrap = `Read startup instructions from this file path before taking action: ${tmpFile}. Use that file as the initial context.`;
50
+ cmdParts.push(quoteForSh(bootstrap));
51
+ }
52
+ // Export COLORTERM only when truecolor is intentionally enabled.
53
+ if (colorMode === 'truecolor') {
54
+ parts.push('export COLORTERM=truecolor');
55
+ }
56
+ else {
57
+ parts.push('unset COLORTERM');
58
+ }
59
+ parts.push(`exec ${cmdParts.join(' ')}`);
60
+ return parts.join('; ');
61
+ }
62
+ /**
63
+ * Best-effort configure tmux session: mouse, scrollback, 256-color, and truecolor.
64
+ * Batches all settings into a single tmux invocation using \; command separator.
65
+ * Unix only — Windows uses psmux (native ConPTY handles mouse/color natively).
66
+ */
67
+ export function configureTmuxSession() {
68
+ if (!isNonWindowsPlatform())
69
+ return;
70
+ try {
71
+ execSync('tmux set-option -g mouse on \\; ' +
72
+ 'set-option -g history-limit 50000 \\; ' +
73
+ 'set -g default-terminal "tmux-256color" \\; ' +
74
+ 'set -a terminal-overrides ",xterm*:Tc,alacritty:Tc"', { stdio: 'ignore', timeout: 3000 });
75
+ }
76
+ catch {
77
+ // Fallback: tmux-256color may not be in terminfo — try screen-256color
78
+ try {
79
+ execSync('tmux set-option -g mouse on \\; ' +
80
+ 'set-option -g history-limit 50000 \\; ' +
81
+ 'set -g default-terminal "screen-256color" \\; ' +
82
+ 'set -a terminal-overrides ",xterm*:Tc,alacritty:Tc"', { stdio: 'ignore', timeout: 3000 });
83
+ }
84
+ catch { /* best-effort */ }
85
+ }
86
+ }
@@ -36,7 +36,7 @@ export function shouldUseColors(proc = process) {
36
36
  const env = proc.env ?? process.env;
37
37
  const noColor = env.NO_COLOR;
38
38
  const forceColor = env.FORCE_COLOR;
39
- // NO_COLOR takes precedence (any value disables colors)
39
+ // NO_COLOR takes precedence (unknown value disables colors)
40
40
  if (noColor !== undefined) {
41
41
  return false;
42
42
  }