@openagents-org/agent-launcher 0.2.66 → 0.2.68

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@openagents-org/agent-launcher",
3
- "version": "0.2.66",
3
+ "version": "0.2.68",
4
4
  "description": "OpenAgents Launcher — install, configure, and run AI coding agents from your terminal",
5
5
  "main": "src/index.js",
6
6
  "bin": {
@@ -105,6 +105,51 @@ class ClaudeAdapter extends BaseAdapter {
105
105
  }
106
106
  }
107
107
 
108
+ /**
109
+ * Find the portable Node.js binary.
110
+ */
111
+ _findNodeBin() {
112
+ const home = os.homedir();
113
+ const candidates = IS_WINDOWS
114
+ ? [path.join(home, '.openagents', 'nodejs', 'node.exe')]
115
+ : [path.join(home, '.openagents', 'nodejs', 'bin', 'node'),
116
+ path.join(home, '.openagents', 'nodejs', 'node')];
117
+ for (const c of candidates) {
118
+ if (fs.existsSync(c)) return c;
119
+ }
120
+ return 'node';
121
+ }
122
+
123
+ /**
124
+ * Resolve a binary shim/symlink to [nodeBin, jsEntryPoint].
125
+ * On Windows: parses .cmd shim to extract the JS path.
126
+ * On macOS/Linux: follows symlink to the actual .js file.
127
+ * Returns [nodeBin, jsPath] or null if resolution fails.
128
+ */
129
+ _resolveToNodeCmd(binPath) {
130
+ const nodeBin = this._findNodeBin();
131
+ if (IS_WINDOWS && binPath.toLowerCase().endsWith('.cmd')) {
132
+ const cmdDir = path.dirname(path.resolve(binPath));
133
+ const cmdContent = fs.readFileSync(binPath, 'utf-8');
134
+ const jsMatch = cmdContent.match(/%dp0%\\([^\s"*?]+\.js)/i);
135
+ if (jsMatch) {
136
+ return [nodeBin, path.resolve(cmdDir, jsMatch[1])];
137
+ }
138
+ } else {
139
+ // Unix: symlink → resolve to actual .js file
140
+ try {
141
+ let target = binPath;
142
+ if (fs.lstatSync(binPath).isSymbolicLink()) {
143
+ target = path.resolve(path.dirname(binPath), fs.readlinkSync(binPath));
144
+ }
145
+ if (target.endsWith('.js') || target.endsWith('.mjs')) {
146
+ return [nodeBin, target];
147
+ }
148
+ } catch {}
149
+ }
150
+ return null;
151
+ }
152
+
108
153
  _findClaudeBinary() {
109
154
  const home = os.homedir();
110
155
 
@@ -268,20 +313,14 @@ class ClaudeAdapter extends BaseAdapter {
268
313
  this._log('Could not find openagents binary — MCP tools may not be available');
269
314
  }
270
315
 
271
- // On Windows, .cmd shims can't be used as MCP server commands —
272
- // resolve to node.exe + the actual JS entry point
316
+ // Resolve shim/symlink to node + JS entry point for MCP server
317
+ // (.cmd shims and #!/usr/bin/env node shebangs both fail as MCP commands)
273
318
  let mcpCommand = oaBin;
274
319
  let mcpFinalArgs = mcpArgs;
275
- if (IS_WINDOWS && oaBin.toLowerCase().endsWith('.cmd')) {
276
- const cmdContent = fs.readFileSync(oaBin, 'utf-8');
277
- const jsMatch = cmdContent.match(/%dp0%\\([^\s"*?]+\.js)/i);
278
- if (jsMatch) {
279
- const cmdDir = path.dirname(path.resolve(oaBin));
280
- const jsPath = path.resolve(cmdDir, jsMatch[1]);
281
- const nodeExe = path.join(os.homedir(), '.openagents', 'nodejs', 'node.exe');
282
- mcpCommand = fs.existsSync(nodeExe) ? nodeExe : 'node';
283
- mcpFinalArgs = [jsPath, ...mcpArgs];
284
- }
320
+ const mcpResolved = this._resolveToNodeCmd(oaBin);
321
+ if (mcpResolved) {
322
+ mcpCommand = mcpResolved[0];
323
+ mcpFinalArgs = [mcpResolved[1], ...mcpArgs];
285
324
  }
286
325
 
287
326
  const mcpConfig = {
@@ -365,22 +404,14 @@ class ClaudeAdapter extends BaseAdapter {
365
404
  delete cleanEnv.CLAUDE_CODE_SESSION;
366
405
 
367
406
  try {
368
- // On Windows, spawn node.exe directly instead of .cmd shims to avoid
369
- // visible console windows and Unicode path issues
370
- if (IS_WINDOWS && cmd[0].toLowerCase().endsWith('.cmd')) {
371
- // Resolve .cmd shim → actual JS entry point
372
- // npm shims use %dp0% (directory of the .cmd file) as a relative base
373
- const cmdDir = path.dirname(path.resolve(cmd[0]));
374
- const cmdContent = fs.readFileSync(cmd[0], 'utf-8');
375
- const jsMatch = cmdContent.match(/"?%dp0%\\([^"*?]+\.js)"?/i);
376
- if (jsMatch) {
377
- const jsPath = path.resolve(cmdDir, jsMatch[1]);
378
- const nodeExe = path.join(os.homedir(), '.openagents', 'nodejs', 'node.exe');
379
- const nodeBin = fs.existsSync(nodeExe) ? nodeExe : 'node';
380
- cmd = [nodeBin, jsPath, ...cmd.slice(1)];
381
- } else {
382
- cmd = ['cmd.exe', '/c', ...cmd];
383
- }
407
+ // Always resolve shim/symlink to node + JS entry point.
408
+ // On Windows: .cmd shims need cmd.exe which creates visible windows.
409
+ // On macOS/Linux: #!/usr/bin/env node fails when node isn't on system PATH.
410
+ const resolved = this._resolveToNodeCmd(cmd[0]);
411
+ if (resolved) {
412
+ cmd = [resolved[0], resolved[1], ...cmd.slice(1)];
413
+ } else if (IS_WINDOWS && cmd[0].toLowerCase().endsWith('.cmd')) {
414
+ cmd = ['cmd.exe', '/c', ...cmd];
384
415
  }
385
416
 
386
417
  const proc = spawn(cmd[0], cmd.slice(1), {
@@ -453,11 +484,6 @@ class ClaudeAdapter extends BaseAdapter {
453
484
  }
454
485
  lastResponseText.push(block.text.trim());
455
486
  postedThinking = true;
456
- // Only send status preview for longer responses (short ones arrive too quickly)
457
- if (block.text.trim().length > 80) {
458
- const preview = block.text.trim().slice(0, 60) + '...';
459
- await this.sendStatus(msgChannel, preview);
460
- }
461
487
  } else if (block.type === 'tool_use') {
462
488
  hasToolUseSinceLastText = true;
463
489
  postedThinking = false;