aiwcli 0.12.6 → 0.12.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 (124) hide show
  1. package/bin/dev.cmd +3 -3
  2. package/bin/dev.js +16 -16
  3. package/bin/run.cmd +3 -3
  4. package/bin/run.js +21 -21
  5. package/dist/commands/branch.js +7 -2
  6. package/dist/lib/bmad-installer.js +37 -37
  7. package/dist/lib/terminal.d.ts +2 -0
  8. package/dist/lib/terminal.js +57 -7
  9. package/dist/templates/CLAUDE.md +205 -205
  10. package/dist/templates/_shared/.claude/commands/handoff-resume.md +12 -12
  11. package/dist/templates/_shared/.claude/commands/handoff.md +12 -12
  12. package/dist/templates/_shared/.claude/settings.json +65 -65
  13. package/dist/templates/_shared/.codex/workflows/handoff.md +226 -226
  14. package/dist/templates/_shared/.windsurf/workflows/handoff.md +226 -226
  15. package/dist/templates/_shared/handoff-system/CLAUDE.md +421 -421
  16. package/dist/templates/_shared/handoff-system/lib/document-generator.ts +215 -215
  17. package/dist/templates/_shared/handoff-system/lib/handoff-reader.ts +158 -158
  18. package/dist/templates/_shared/handoff-system/scripts/resume_handoff.ts +373 -373
  19. package/dist/templates/_shared/handoff-system/scripts/save_handoff.ts +469 -469
  20. package/dist/templates/_shared/handoff-system/workflows/handoff-resume.md +66 -66
  21. package/dist/templates/_shared/handoff-system/workflows/handoff.md +254 -254
  22. package/dist/templates/_shared/hooks-ts/_utils/git-state.ts +2 -2
  23. package/dist/templates/_shared/hooks-ts/archive_plan.ts +159 -159
  24. package/dist/templates/_shared/hooks-ts/context_monitor.ts +147 -147
  25. package/dist/templates/_shared/hooks-ts/file-suggestion.ts +128 -128
  26. package/dist/templates/_shared/hooks-ts/pre_compact.ts +49 -49
  27. package/dist/templates/_shared/hooks-ts/session_end.ts +196 -196
  28. package/dist/templates/_shared/hooks-ts/session_start.ts +163 -163
  29. package/dist/templates/_shared/hooks-ts/task_create_capture.ts +48 -48
  30. package/dist/templates/_shared/hooks-ts/task_update_capture.ts +74 -74
  31. package/dist/templates/_shared/hooks-ts/user_prompt_submit.ts +93 -93
  32. package/dist/templates/_shared/lib-ts/CLAUDE.md +367 -367
  33. package/dist/templates/_shared/lib-ts/base/atomic-write.ts +138 -138
  34. package/dist/templates/_shared/lib-ts/base/constants.ts +303 -303
  35. package/dist/templates/_shared/lib-ts/base/git-state.ts +58 -58
  36. package/dist/templates/_shared/lib-ts/base/hook-utils.ts +582 -582
  37. package/dist/templates/_shared/lib-ts/base/inference.ts +301 -301
  38. package/dist/templates/_shared/lib-ts/base/logger.ts +247 -247
  39. package/dist/templates/_shared/lib-ts/base/state-io.ts +202 -202
  40. package/dist/templates/_shared/lib-ts/base/stop-words.ts +184 -184
  41. package/dist/templates/_shared/lib-ts/base/utils.ts +184 -184
  42. package/dist/templates/_shared/lib-ts/context/context-formatter.ts +566 -566
  43. package/dist/templates/_shared/lib-ts/context/context-selector.ts +524 -524
  44. package/dist/templates/_shared/lib-ts/context/context-store.ts +712 -712
  45. package/dist/templates/_shared/lib-ts/context/plan-manager.ts +312 -312
  46. package/dist/templates/_shared/lib-ts/context/task-tracker.ts +185 -185
  47. package/dist/templates/_shared/lib-ts/package.json +20 -20
  48. package/dist/templates/_shared/lib-ts/templates/formatters.ts +102 -102
  49. package/dist/templates/_shared/lib-ts/templates/plan-context.ts +58 -58
  50. package/dist/templates/_shared/lib-ts/tsconfig.json +13 -13
  51. package/dist/templates/_shared/lib-ts/types.ts +186 -186
  52. package/dist/templates/_shared/scripts/resolve_context.ts +33 -33
  53. package/dist/templates/_shared/scripts/status_line.ts +690 -690
  54. package/dist/templates/cc-native/.claude/commands/cc-native/rlm/ask.md +136 -136
  55. package/dist/templates/cc-native/.claude/commands/cc-native/rlm/index.md +21 -21
  56. package/dist/templates/cc-native/.claude/commands/cc-native/rlm/overview.md +56 -56
  57. package/dist/templates/cc-native/.claude/commands/cc-native/specdev.md +10 -10
  58. package/dist/templates/cc-native/.windsurf/workflows/cc-native/fix.md +8 -8
  59. package/dist/templates/cc-native/.windsurf/workflows/cc-native/implement.md +8 -8
  60. package/dist/templates/cc-native/.windsurf/workflows/cc-native/research.md +8 -8
  61. package/dist/templates/cc-native/CC-NATIVE-README.md +189 -189
  62. package/dist/templates/cc-native/TEMPLATE-SCHEMA.md +304 -304
  63. package/dist/templates/cc-native/_cc-native/agents/CLAUDE.md +143 -143
  64. package/dist/templates/cc-native/_cc-native/agents/PLAN-ORCHESTRATOR.md +213 -213
  65. package/dist/templates/cc-native/_cc-native/agents/plan-questions/PLAN-QUESTIONER.md +70 -70
  66. package/dist/templates/cc-native/_cc-native/cc-native.config.json +96 -96
  67. package/dist/templates/cc-native/_cc-native/hooks/CLAUDE.md +247 -247
  68. package/dist/templates/cc-native/_cc-native/hooks/cc-native-plan-review.ts +76 -76
  69. package/dist/templates/cc-native/_cc-native/hooks/enhance_plan_post_subagent.ts +54 -54
  70. package/dist/templates/cc-native/_cc-native/hooks/enhance_plan_post_write.ts +51 -51
  71. package/dist/templates/cc-native/_cc-native/hooks/mark_questions_asked.ts +53 -53
  72. package/dist/templates/cc-native/_cc-native/hooks/plan_questions_early.ts +61 -61
  73. package/dist/templates/cc-native/_cc-native/lib-ts/agent-selection.ts +163 -163
  74. package/dist/templates/cc-native/_cc-native/lib-ts/aggregate-agents.ts +156 -156
  75. package/dist/templates/cc-native/_cc-native/lib-ts/artifacts/format.ts +597 -597
  76. package/dist/templates/cc-native/_cc-native/lib-ts/artifacts/index.ts +26 -26
  77. package/dist/templates/cc-native/_cc-native/lib-ts/artifacts/tracker.ts +107 -107
  78. package/dist/templates/cc-native/_cc-native/lib-ts/artifacts/write.ts +119 -119
  79. package/dist/templates/cc-native/_cc-native/lib-ts/artifacts.ts +21 -21
  80. package/dist/templates/cc-native/_cc-native/lib-ts/cc-native-state.ts +319 -319
  81. package/dist/templates/cc-native/_cc-native/lib-ts/cli-output-parser.ts +144 -144
  82. package/dist/templates/cc-native/_cc-native/lib-ts/config.ts +57 -57
  83. package/dist/templates/cc-native/_cc-native/lib-ts/constants.ts +83 -83
  84. package/dist/templates/cc-native/_cc-native/lib-ts/corroboration.ts +119 -119
  85. package/dist/templates/cc-native/_cc-native/lib-ts/debug.ts +79 -79
  86. package/dist/templates/cc-native/_cc-native/lib-ts/graduation.ts +132 -132
  87. package/dist/templates/cc-native/_cc-native/lib-ts/index.ts +116 -116
  88. package/dist/templates/cc-native/_cc-native/lib-ts/json-parser.ts +168 -168
  89. package/dist/templates/cc-native/_cc-native/lib-ts/orchestrator.ts +70 -70
  90. package/dist/templates/cc-native/_cc-native/lib-ts/output-builder.ts +130 -130
  91. package/dist/templates/cc-native/_cc-native/lib-ts/plan-discovery.ts +80 -80
  92. package/dist/templates/cc-native/_cc-native/lib-ts/plan-enhancement.ts +41 -41
  93. package/dist/templates/cc-native/_cc-native/lib-ts/plan-questions.ts +101 -101
  94. package/dist/templates/cc-native/_cc-native/lib-ts/review-pipeline.ts +511 -511
  95. package/dist/templates/cc-native/_cc-native/lib-ts/reviewers/agent.ts +71 -71
  96. package/dist/templates/cc-native/_cc-native/lib-ts/reviewers/base/base-agent.ts +217 -217
  97. package/dist/templates/cc-native/_cc-native/lib-ts/reviewers/index.ts +12 -12
  98. package/dist/templates/cc-native/_cc-native/lib-ts/reviewers/providers/claude-agent.ts +66 -66
  99. package/dist/templates/cc-native/_cc-native/lib-ts/reviewers/providers/codex-agent.ts +184 -184
  100. package/dist/templates/cc-native/_cc-native/lib-ts/reviewers/providers/gemini-agent.ts +39 -39
  101. package/dist/templates/cc-native/_cc-native/lib-ts/reviewers/providers/orchestrator-claude-agent.ts +196 -196
  102. package/dist/templates/cc-native/_cc-native/lib-ts/reviewers/schemas.ts +201 -201
  103. package/dist/templates/cc-native/_cc-native/lib-ts/reviewers/types.ts +21 -21
  104. package/dist/templates/cc-native/_cc-native/lib-ts/rlm/CLAUDE.md +480 -480
  105. package/dist/templates/cc-native/_cc-native/lib-ts/rlm/embedding-indexer.ts +287 -287
  106. package/dist/templates/cc-native/_cc-native/lib-ts/rlm/hyde.ts +148 -148
  107. package/dist/templates/cc-native/_cc-native/lib-ts/rlm/index.ts +54 -54
  108. package/dist/templates/cc-native/_cc-native/lib-ts/rlm/logger.ts +58 -58
  109. package/dist/templates/cc-native/_cc-native/lib-ts/rlm/ollama-client.ts +208 -208
  110. package/dist/templates/cc-native/_cc-native/lib-ts/rlm/retrieval-pipeline.ts +460 -460
  111. package/dist/templates/cc-native/_cc-native/lib-ts/rlm/transcript-indexer.ts +446 -446
  112. package/dist/templates/cc-native/_cc-native/lib-ts/rlm/transcript-loader.ts +280 -280
  113. package/dist/templates/cc-native/_cc-native/lib-ts/rlm/transcript-searcher.ts +274 -274
  114. package/dist/templates/cc-native/_cc-native/lib-ts/rlm/types.ts +201 -201
  115. package/dist/templates/cc-native/_cc-native/lib-ts/rlm/vector-store.ts +278 -278
  116. package/dist/templates/cc-native/_cc-native/lib-ts/settings.ts +184 -184
  117. package/dist/templates/cc-native/_cc-native/lib-ts/state.ts +275 -275
  118. package/dist/templates/cc-native/_cc-native/lib-ts/tsconfig.json +18 -18
  119. package/dist/templates/cc-native/_cc-native/lib-ts/types.ts +329 -329
  120. package/dist/templates/cc-native/_cc-native/lib-ts/verdict.ts +72 -72
  121. package/dist/templates/cc-native/_cc-native/workflows/specdev.md +9 -9
  122. package/oclif.manifest.json +1 -1
  123. package/package.json +108 -108
  124. package/dist/templates/cc-native/_cc-native/lib-ts/nul +0 -3
package/bin/dev.cmd CHANGED
@@ -1,3 +1,3 @@
1
- @echo off
2
-
3
- node --loader ts-node/esm --no-warnings=ExperimentalWarning "%~dp0\dev.js" %*
1
+ @echo off
2
+
3
+ node --loader ts-node/esm --no-warnings=ExperimentalWarning "%~dp0\dev.js" %*
package/bin/dev.js CHANGED
@@ -1,16 +1,16 @@
1
- #!/usr/bin/env -S node --loader ts-node/esm --disable-warning=ExperimentalWarning
2
-
3
- import {execute} from '@oclif/core'
4
-
5
- // Handle default command: inject 'launch' when no command is specified
6
- // but preserve --help and --version behavior for general CLI help
7
- const args = process.argv.slice(2)
8
- const firstArg = args[0] ?? ''
9
- const hasCommand = args.length > 0 && !firstArg.startsWith('-')
10
- const isHelpOrVersion = firstArg === '--help' || firstArg === '-h' || firstArg === '--version'
11
-
12
- await execute({
13
- development: true,
14
- dir: import.meta.url,
15
- args: hasCommand || isHelpOrVersion ? args : ['launch', ...args],
16
- })
1
+ #!/usr/bin/env -S node --loader ts-node/esm --disable-warning=ExperimentalWarning
2
+
3
+ import {execute} from '@oclif/core'
4
+
5
+ // Handle default command: inject 'launch' when no command is specified
6
+ // but preserve --help and --version behavior for general CLI help
7
+ const args = process.argv.slice(2)
8
+ const firstArg = args[0] ?? ''
9
+ const hasCommand = args.length > 0 && !firstArg.startsWith('-')
10
+ const isHelpOrVersion = firstArg === '--help' || firstArg === '-h' || firstArg === '--version'
11
+
12
+ await execute({
13
+ development: true,
14
+ dir: import.meta.url,
15
+ args: hasCommand || isHelpOrVersion ? args : ['launch', ...args],
16
+ })
package/bin/run.cmd CHANGED
@@ -1,3 +1,3 @@
1
- @echo off
2
-
3
- node "%~dp0\run.js" %*
1
+ @echo off
2
+
3
+ node "%~dp0\run.js" %*
package/bin/run.js CHANGED
@@ -1,22 +1,22 @@
1
1
  #!/usr/bin/env node
2
-
3
- // Load environment variable compatibility layer first
4
- const {loadEnvWithCompatibility} = await import('../dist/lib/env-compat.js')
5
- loadEnvWithCompatibility()
6
-
7
- import {execute} from '@oclif/core'
8
-
9
- // Handle default command: inject 'launch' when no command is specified
10
- // but preserve --help and --version behavior for general CLI help
11
- const args = process.argv.slice(2)
12
- const firstArg = args[0] ?? ''
13
- const hasCommand = args.length > 0 && !firstArg.startsWith('-')
14
- const isHelpOrVersion = firstArg === '--help' || firstArg === '-h' || firstArg === '--version' || firstArg === '-v'
15
-
16
- // Map -v to --version since oclif doesn't natively understand -v
17
- const resolvedArgs = firstArg === '-v' ? ['--version', ...args.slice(1)] : args
18
-
19
- await execute({
20
- dir: import.meta.url,
21
- args: hasCommand || isHelpOrVersion ? resolvedArgs : ['launch', ...resolvedArgs],
22
- })
2
+
3
+ // Load environment variable compatibility layer first
4
+ const {loadEnvWithCompatibility} = await import('../dist/lib/env-compat.js')
5
+ loadEnvWithCompatibility()
6
+
7
+ import {execute} from '@oclif/core'
8
+
9
+ // Handle default command: inject 'launch' when no command is specified
10
+ // but preserve --help and --version behavior for general CLI help
11
+ const args = process.argv.slice(2)
12
+ const firstArg = args[0] ?? ''
13
+ const hasCommand = args.length > 0 && !firstArg.startsWith('-')
14
+ const isHelpOrVersion = firstArg === '--help' || firstArg === '-h' || firstArg === '--version' || firstArg === '-v'
15
+
16
+ // Map -v to --version since oclif doesn't natively understand -v
17
+ const resolvedArgs = firstArg === '-v' ? ['--version', ...args.slice(1)] : args
18
+
19
+ await execute({
20
+ dir: import.meta.url,
21
+ args: hasCommand || isHelpOrVersion ? resolvedArgs : ['launch', ...resolvedArgs],
22
+ })
@@ -80,7 +80,12 @@ export default class BranchCommand extends BaseCommand {
80
80
  const { args, flags } = await this.parse(BranchCommand);
81
81
  // Validate that one of the flags is provided
82
82
  if (!flags.main && !flags.launch && !flags.delete) {
83
- this.error('Either --main, --launch, or --delete flag is required', { exit: EXIT_CODES.INVALID_USAGE });
83
+ if (args.branchName) {
84
+ // Bare positional arg = shorthand for --launch <name>
85
+ await this.handleWorktreeLaunch(args.branchName);
86
+ return;
87
+ }
88
+ this.error('Either provide a branch name directly (aiw branch <name>) or use --main, --launch, or --delete', { exit: EXIT_CODES.INVALID_USAGE });
84
89
  }
85
90
  // Route to appropriate handler
86
91
  if (flags.main) {
@@ -396,7 +401,7 @@ export default class BranchCommand extends BaseCommand {
396
401
  async handleWorktreeLaunch(branchName) {
397
402
  // Validate branch name
398
403
  if (!branchName || branchName.trim().length === 0) {
399
- this.error('Branch name is required when using --launch flag', { exit: EXIT_CODES.INVALID_USAGE });
404
+ this.error('Branch name is required. Usage: aiw branch <name> or aiw branch --launch <name>', { exit: EXIT_CODES.INVALID_USAGE });
400
405
  }
401
406
  // Validate branch name format (no spaces, special chars that could cause issues)
402
407
  const validBranchNamePattern = /^[a-zA-Z0-9._/-]+$/;
@@ -11,15 +11,15 @@ const BMAD_VERSION = '6.0.0-alpha.22';
11
11
  */
12
12
  function generateCoreConfig(username) {
13
13
  const now = new Date().toISOString();
14
- return `# CORE Module Configuration
15
- # Generated by AI Workflow CLI
16
- # Version: ${BMAD_VERSION}
17
- # Date: ${now}
18
-
19
- user_name: ${username}
20
- communication_language: English
21
- document_output_language: English
22
- output_folder: "{project-root}/_bmad-output"
14
+ return `# CORE Module Configuration
15
+ # Generated by AI Workflow CLI
16
+ # Version: ${BMAD_VERSION}
17
+ # Date: ${now}
18
+
19
+ user_name: ${username}
20
+ communication_language: English
21
+ document_output_language: English
22
+ output_folder: "{project-root}/_bmad-output"
23
23
  `;
24
24
  }
25
25
  /**
@@ -27,24 +27,24 @@ output_folder: "{project-root}/_bmad-output"
27
27
  */
28
28
  function generateBmmConfig(projectName, username) {
29
29
  const now = new Date().toISOString();
30
- return `# BMM Module Configuration
31
- # Generated by AI Workflow CLI
32
- # Version: ${BMAD_VERSION}
33
- # Date: ${now}
34
-
35
- project_name: ${projectName}
36
- user_skill_level: intermediate
37
- planning_artifacts: "{project-root}/_bmad-output/planning-artifacts"
38
- implementation_artifacts: "{project-root}/_bmad-output/implementation-artifacts"
39
- project_knowledge: "{project-root}/docs"
40
- tea_use_mcp_enhancements: false
41
- tea_use_playwright_utils: false
42
-
43
- # Core Configuration Values
44
- user_name: ${username}
45
- communication_language: English
46
- document_output_language: English
47
- output_folder: "{project-root}/_bmad-output"
30
+ return `# BMM Module Configuration
31
+ # Generated by AI Workflow CLI
32
+ # Version: ${BMAD_VERSION}
33
+ # Date: ${now}
34
+
35
+ project_name: ${projectName}
36
+ user_skill_level: intermediate
37
+ planning_artifacts: "{project-root}/_bmad-output/planning-artifacts"
38
+ implementation_artifacts: "{project-root}/_bmad-output/implementation-artifacts"
39
+ project_knowledge: "{project-root}/docs"
40
+ tea_use_mcp_enhancements: false
41
+ tea_use_playwright_utils: false
42
+
43
+ # Core Configuration Values
44
+ user_name: ${username}
45
+ communication_language: English
46
+ document_output_language: English
47
+ output_folder: "{project-root}/_bmad-output"
48
48
  `;
49
49
  }
50
50
  /**
@@ -52,16 +52,16 @@ output_folder: "{project-root}/_bmad-output"
52
52
  */
53
53
  function generateManifest() {
54
54
  const now = new Date().toISOString();
55
- return `installation:
56
- version: ${BMAD_VERSION}
57
- installDate: ${now}
58
- lastUpdated: ${now}
59
- installedBy: aiwcli
60
- modules:
61
- - core
62
- - bmm
63
- ides:
64
- - claude-code
55
+ return `installation:
56
+ version: ${BMAD_VERSION}
57
+ installDate: ${now}
58
+ lastUpdated: ${now}
59
+ installedBy: aiwcli
60
+ modules:
61
+ - core
62
+ - bmm
63
+ ides:
64
+ - claude-code
65
65
  `;
66
66
  }
67
67
  /**
@@ -7,6 +7,7 @@
7
7
  * ## Supported Platforms
8
8
  * - **Windows**: Windows Terminal (wt.exe) with PowerShell 7 (pwsh) fallback to PowerShell 5.1
9
9
  * - **macOS**: Terminal.app via AppleScript
10
+ * - **WSL**: Windows Terminal (wt.exe) via wsl.exe, falls back to Linux emulators
10
11
  * - **Linux**: gnome-terminal, konsole, xterm, x-terminal-emulator (in order of preference)
11
12
  *
12
13
  * ## Usage
@@ -64,6 +65,7 @@ interface TerminalLaunchResult {
64
65
  * terminal emulator:
65
66
  * - **Windows**: Windows Terminal (wt.exe) with PowerShell, falls back to PowerShell directly
66
67
  * - **macOS**: Terminal.app via AppleScript
68
+ * - **WSL**: Windows Terminal (wt.exe) via wsl.exe, falls back to Linux terminals
67
69
  * - **Linux**: Tries gnome-terminal, konsole, xterm, x-terminal-emulator in order
68
70
  *
69
71
  * The terminal is launched in detached mode, allowing the parent process to exit
@@ -7,6 +7,7 @@
7
7
  * ## Supported Platforms
8
8
  * - **Windows**: Windows Terminal (wt.exe) with PowerShell 7 (pwsh) fallback to PowerShell 5.1
9
9
  * - **macOS**: Terminal.app via AppleScript
10
+ * - **WSL**: Windows Terminal (wt.exe) via wsl.exe, falls back to Linux emulators
10
11
  * - **Linux**: gnome-terminal, konsole, xterm, x-terminal-emulator (in order of preference)
11
12
  *
12
13
  * ## Usage
@@ -28,14 +29,21 @@
28
29
  */
29
30
  import { execSync, spawn } from 'node:child_process';
30
31
  /**
31
- * Escape a shell argument for safe execution.
32
- * Wraps path in double quotes and escapes internal quotes.
32
+ * Return a copy of process.env with Claude Code nesting-detection vars removed.
33
33
  *
34
- * @param arg - Argument to escape
35
- * @returns Escaped argument safe for shell execution
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.
36
41
  */
37
- function escapeShellArg(arg) {
38
- return `"${arg.replaceAll('\\', '\\\\').replaceAll('"', String.raw `\"`)}"`;
42
+ function cleanTerminalEnv() {
43
+ const env = { ...process.env };
44
+ delete env['CLAUDECODE'];
45
+ delete env['CLAUDE_CODE_ENTRYPOINT'];
46
+ return env;
39
47
  }
40
48
  /**
41
49
  * Detect which PowerShell is available on Windows.
@@ -68,6 +76,7 @@ async function launchPowerShellFallback(cwd, command, powershellCmd, debugLog) {
68
76
  const terminal = spawn(powershellCmd, ['-Command', psCommand], {
69
77
  detached: true,
70
78
  stdio: 'ignore',
79
+ env: cleanTerminalEnv(),
71
80
  });
72
81
  terminal.on('error', (err) => {
73
82
  resolve({ success: false, error: `Failed to launch PowerShell: ${err.message}` });
@@ -90,6 +99,7 @@ async function launchWindowsTerminal(cwd, command, debugLog) {
90
99
  const terminal = spawn('wt', ['-d', cwd, powershellCmd, '-NoExit', '-Command', command], {
91
100
  detached: true,
92
101
  stdio: 'ignore',
102
+ env: cleanTerminalEnv(),
93
103
  });
94
104
  terminal.on('error', (err) => {
95
105
  // If wt.exe not found, try fallback to Start-Process
@@ -125,6 +135,7 @@ async function launchMacTerminal(cwd, command, debugLog) {
125
135
  const terminal = spawn('osascript', ['-e', `tell application "Terminal" to do script "${escapedCommand}"`], {
126
136
  detached: true,
127
137
  stdio: 'ignore',
138
+ env: cleanTerminalEnv(),
128
139
  });
129
140
  terminal.on('error', (err) => {
130
141
  resolve({ success: false, error: `Failed to launch Terminal.app: ${err.message}` });
@@ -161,6 +172,36 @@ function findAvailableLinuxTerminal() {
161
172
  }
162
173
  return null;
163
174
  }
175
+ function isWSL() {
176
+ return Boolean(process.env['WSL_DISTRO_NAME']);
177
+ }
178
+ /**
179
+ * Launch Windows Terminal (wt.exe) from WSL, running the command inside a new bash session.
180
+ *
181
+ * 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().
183
+ *
184
+ * @param cwd - Working directory (WSL path)
185
+ * @param command - Command to execute
186
+ * @param debugLog - Optional debug logging function
187
+ */
188
+ 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}`);
192
+ return new Promise((resolve) => {
193
+ const proc = spawn('wt.exe', ['wsl.exe', '--', 'bash', '-c', bashCmd], {
194
+ detached: true,
195
+ stdio: 'ignore',
196
+ env: cleanTerminalEnv(),
197
+ });
198
+ proc.on('error', (err) => {
199
+ resolve({ success: false, error: `wt.exe failed: ${err.message}` });
200
+ });
201
+ proc.unref();
202
+ resolve({ success: true });
203
+ });
204
+ }
164
205
  /**
165
206
  * Launch Linux terminal emulator with command.
166
207
  * Tries gnome-terminal, konsole, xterm, x-terminal-emulator in order.
@@ -187,6 +228,7 @@ async function launchLinuxTerminal(cwd, command, debugLog) {
187
228
  const proc = spawn(terminal.cmd, terminal.getArgs(fullCommand), {
188
229
  detached: true,
189
230
  stdio: 'ignore',
231
+ env: cleanTerminalEnv(),
190
232
  });
191
233
  proc.on('error', (err) => {
192
234
  resolve({ error: `Failed to launch ${terminal.cmd}: ${err.message}`, success: false });
@@ -202,6 +244,7 @@ async function launchLinuxTerminal(cwd, command, debugLog) {
202
244
  * terminal emulator:
203
245
  * - **Windows**: Windows Terminal (wt.exe) with PowerShell, falls back to PowerShell directly
204
246
  * - **macOS**: Terminal.app via AppleScript
247
+ * - **WSL**: Windows Terminal (wt.exe) via wsl.exe, falls back to Linux terminals
205
248
  * - **Linux**: Tries gnome-terminal, konsole, xterm, x-terminal-emulator in order
206
249
  *
207
250
  * The terminal is launched in detached mode, allowing the parent process to exit
@@ -236,6 +279,13 @@ export async function launchTerminal(options) {
236
279
  if (platform === 'darwin') {
237
280
  return launchMacTerminal(cwd, command, debugLog);
238
281
  }
239
- // Linux/Unix
282
+ // Linux/Unix — try WSL (wt.exe) first, fall back to native Linux terminals
283
+ if (isWSL()) {
284
+ debugLog?.('WSL detected, trying wt.exe');
285
+ const wslResult = await launchWSLTerminal(cwd, command, debugLog);
286
+ if (wslResult.success)
287
+ return wslResult;
288
+ debugLog?.(`wt.exe failed (${wslResult.error}), falling back to Linux terminals`);
289
+ }
240
290
  return launchLinuxTerminal(cwd, command, debugLog);
241
291
  }