ninja-terminals 2.4.1 → 2.4.2

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.
package/README.md CHANGED
@@ -14,6 +14,8 @@ Run the one-time setup command:
14
14
  npx --yes ninja-terminals --setup
15
15
  ```
16
16
 
17
+ > **On Windows?** Run it inside WSL2 — see [WINDOWS-SETUP.md](WINDOWS-SETUP.md).
18
+
17
19
  ## Quick Start
18
20
 
19
21
  ### As MCP Server (Recommended)
package/mcp-server.js CHANGED
@@ -43,7 +43,10 @@ const {
43
43
  const PREFERRED_HTTP_PORT = parseInt(process.env.HTTP_PORT || process.env.PORT || '3300', 10);
44
44
  let HTTP_PORT = PREFERRED_HTTP_PORT;
45
45
  const CLAUDE_CMD = process.env.CLAUDE_CMD || process.env.CLAUDE_CHROME_CMD || 'claude --chrome --model claude-opus-4-5-20251101';
46
- const SHELL = process.env.SHELL || '/bin/zsh';
46
+ // Windows has no $SHELL / /bin/zsh — default to PowerShell (handles drive
47
+ // changes via `cd` and emits clean ANSI for status detection).
48
+ const IS_WIN = process.platform === 'win32';
49
+ const SHELL = IS_WIN ? (process.env.NINJA_SHELL || 'powershell.exe') : (process.env.SHELL || '/bin/zsh');
47
50
  const PROJECT_DIR = __dirname;
48
51
  const INJECT_GUIDANCE = process.env.INJECT_GUIDANCE !== 'false';
49
52
 
@@ -155,15 +158,23 @@ function spawnTerminal(label, scope = [], cwd = null, tier = 'pro') {
155
158
  FORCE_COLOR: '1',
156
159
  CLICOLOR_FORCE: '1',
157
160
  HOME: os.homedir(),
158
- PATH: `${os.homedir()}/.local/bin:/opt/homebrew/bin:${process.env.PATH || ''}`,
161
+ // On Windows, keep the native PATH untouched (mac/linux bin dirs would
162
+ // corrupt it via the ';' delimiter). On POSIX, prepend the usual bins.
163
+ PATH: IS_WIN
164
+ ? (process.env.PATH || '')
165
+ : [`${os.homedir()}/.local/bin`, '/opt/homebrew/bin', process.env.PATH || '']
166
+ .filter(Boolean).join(path.delimiter),
159
167
  SHELL_SESSIONS_DISABLE: '1',
160
168
  NINJA_TERMINAL_ID: String(id),
161
169
  },
162
170
  });
163
171
 
164
- // Launch claude after shell starts
172
+ // Launch claude after shell starts. Two separate writes (cd, then command)
173
+ // instead of `&&` — works across bash/zsh/PowerShell/cmd, which disagree on
174
+ // command chaining (`&&` is unsupported in Windows PowerShell 5).
165
175
  setTimeout(() => {
166
- ptyProcess.write(`cd "${workDir}" && ${CLAUDE_CMD}\r`);
176
+ ptyProcess.write(`cd "${workDir}"\r`);
177
+ setTimeout(() => ptyProcess.write(`${CLAUDE_CMD}\r`), 250);
167
178
  }, 500);
168
179
 
169
180
  const terminal = {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "ninja-terminals",
3
- "version": "2.4.1",
3
+ "version": "2.4.2",
4
4
  "description": "MCP server for multi-terminal Claude Code orchestration with DAG task management, parallel execution, and self-improvement",
5
5
  "main": "server.js",
6
6
  "bin": {
package/server.js CHANGED
@@ -39,7 +39,10 @@ const PREFERRED_PORT = parseInt(process.env.PORT || process.env.HTTP_PORT || '33
39
39
  const BIND_HOST = process.env.NINJA_BIND_HOST || '127.0.0.1';
40
40
  const DEFAULT_TERMINALS = parseInt(process.env.DEFAULT_TERMINALS || '4', 10);
41
41
  const CLAUDE_CMD = process.env.CLAUDE_CMD || process.env.CLAUDE_CHROME_CMD || 'claude --chrome --model claude-opus-4-5-20251101';
42
- const SHELL = process.env.SHELL || '/bin/zsh';
42
+ // Windows has no $SHELL / /bin/zsh — default to PowerShell (handles drive
43
+ // changes via `cd` and emits clean ANSI for status detection).
44
+ const IS_WIN = process.platform === 'win32';
45
+ const SHELL = IS_WIN ? (process.env.NINJA_SHELL || 'powershell.exe') : (process.env.SHELL || '/bin/zsh');
43
46
  const PROJECT_DIR = __dirname;
44
47
  const DEFAULT_CWD = process.env.DEFAULT_CWD || null; // Set to target project path to avoid cross-project prompts
45
48
  const INJECT_GUIDANCE = process.env.INJECT_GUIDANCE !== 'false'; // Default true, set INJECT_GUIDANCE=false to disable
@@ -194,7 +197,7 @@ function spawnTerminal(label, scope = [], cwd = null, tier = 'pro', agentType =
194
197
  }
195
198
  }
196
199
 
197
- const ptyProcess = pty.spawn(SHELL, ['-l'], {
200
+ const ptyProcess = pty.spawn(SHELL, IS_WIN ? [] : ['-l'], {
198
201
  name: 'xterm-256color',
199
202
  cols,
200
203
  rows,
@@ -206,7 +209,12 @@ function spawnTerminal(label, scope = [], cwd = null, tier = 'pro', agentType =
206
209
  FORCE_COLOR: '1',
207
210
  CLICOLOR_FORCE: '1',
208
211
  HOME: require('os').homedir(),
209
- PATH: `${require('os').homedir()}/.local/bin:/opt/homebrew/bin:${process.env.PATH || ''}`,
212
+ // On Windows, keep the native PATH untouched (mac/linux bin dirs would
213
+ // corrupt it via the ';' delimiter). On POSIX, prepend the usual bins.
214
+ PATH: IS_WIN
215
+ ? (process.env.PATH || '')
216
+ : [`${require('os').homedir()}/.local/bin`, '/opt/homebrew/bin', process.env.PATH || '']
217
+ .filter(Boolean).join(path.delimiter),
210
218
  SHELL_SESSIONS_DISABLE: '1',
211
219
  NINJA_TERMINAL_ID: String(id),
212
220
  },
@@ -214,11 +222,13 @@ function spawnTerminal(label, scope = [], cwd = null, tier = 'pro', agentType =
214
222
 
215
223
  // After shell starts, cd to work dir and launch agent (if not shell)
216
224
  const agentCmd = AGENT_COMMANDS[agentType] || null;
225
+ // Two separate writes (cd, then command) instead of `&&` — works across
226
+ // bash/zsh/PowerShell/cmd, which disagree on chaining (`&&` is unsupported
227
+ // in Windows PowerShell 5).
217
228
  setTimeout(() => {
229
+ ptyProcess.write(`cd "${workDir}"\r`);
218
230
  if (agentCmd) {
219
- ptyProcess.write(`cd "${workDir}" && ${agentCmd}\r`);
220
- } else {
221
- ptyProcess.write(`cd "${workDir}"\r`);
231
+ setTimeout(() => ptyProcess.write(`${agentCmd}\r`), 250);
222
232
  }
223
233
  }, 500);
224
234