@openagents-org/agent-launcher 0.2.65 → 0.2.67

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.65",
3
+ "version": "0.2.67",
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,12 +313,22 @@ class ClaudeAdapter extends BaseAdapter {
268
313
  this._log('Could not find openagents binary — MCP tools may not be available');
269
314
  }
270
315
 
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)
318
+ let mcpCommand = oaBin;
319
+ let mcpFinalArgs = mcpArgs;
320
+ const mcpResolved = this._resolveToNodeCmd(oaBin);
321
+ if (mcpResolved) {
322
+ mcpCommand = mcpResolved[0];
323
+ mcpFinalArgs = [mcpResolved[1], ...mcpArgs];
324
+ }
325
+
271
326
  const mcpConfig = {
272
327
  mcpServers: {
273
328
  'openagents-workspace': {
274
329
  type: 'stdio',
275
- command: oaBin,
276
- args: mcpArgs,
330
+ command: mcpCommand,
331
+ args: mcpFinalArgs,
277
332
  env: { OA_WORKSPACE_TOKEN: this.token },
278
333
  },
279
334
  },
@@ -349,22 +404,14 @@ class ClaudeAdapter extends BaseAdapter {
349
404
  delete cleanEnv.CLAUDE_CODE_SESSION;
350
405
 
351
406
  try {
352
- // On Windows, spawn node.exe directly instead of .cmd shims to avoid
353
- // visible console windows and Unicode path issues
354
- if (IS_WINDOWS && cmd[0].toLowerCase().endsWith('.cmd')) {
355
- // Resolve .cmd shim → actual JS entry point
356
- // npm shims use %dp0% (directory of the .cmd file) as a relative base
357
- const cmdDir = path.dirname(path.resolve(cmd[0]));
358
- const cmdContent = fs.readFileSync(cmd[0], 'utf-8');
359
- const jsMatch = cmdContent.match(/"?%dp0%\\([^"*?]+\.js)"?/i);
360
- if (jsMatch) {
361
- const jsPath = path.resolve(cmdDir, jsMatch[1]);
362
- const nodeExe = path.join(os.homedir(), '.openagents', 'nodejs', 'node.exe');
363
- const nodeBin = fs.existsSync(nodeExe) ? nodeExe : 'node';
364
- cmd = [nodeBin, jsPath, ...cmd.slice(1)];
365
- } else {
366
- cmd = ['cmd.exe', '/c', ...cmd];
367
- }
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];
368
415
  }
369
416
 
370
417
  const proc = spawn(cmd[0], cmd.slice(1), {