@openagents-org/agent-launcher 0.2.50 → 0.2.52

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.50",
3
+ "version": "0.2.52",
4
4
  "description": "OpenAgents Launcher — install, configure, and run AI coding agents from your terminal",
5
5
  "main": "src/index.js",
6
6
  "bin": {
@@ -55,32 +55,19 @@ class OpenClawAdapter extends BaseAdapter {
55
55
  // ------------------------------------------------------------------
56
56
 
57
57
  _findOpenclawBinary() {
58
+ // We know exactly where openclaw is — installed via --prefix ~/.openagents/nodejs
59
+ const home = process.env.USERPROFILE || process.env.HOME || '';
60
+ const portableDir = path.join(home, '.openagents', 'nodejs');
61
+ const mjs = path.join(portableDir, 'node_modules', 'openclaw', 'openclaw.mjs');
62
+ if (fs.existsSync(mjs)) return mjs;
63
+
64
+ // Fallback: check if openclaw is on PATH (system install)
58
65
  try {
59
66
  const cmd = IS_WINDOWS ? 'where openclaw' : 'which openclaw';
60
- const { getEnhancedEnv } = require('../paths');
61
- const result = execSync(cmd, { encoding: 'utf-8', timeout: 5000, env: getEnhancedEnv() })
67
+ const result = execSync(cmd, { encoding: 'utf-8', timeout: 5000, stdio: ['pipe', 'pipe', 'pipe'] })
62
68
  .split(/\r?\n/)[0].trim();
63
69
  if (result) return result;
64
70
  } catch {}
65
-
66
- // Check common npm global directories
67
- const dirs = [];
68
- if (IS_WINDOWS) {
69
- const appdata = process.env.APPDATA || '';
70
- if (appdata) dirs.push(path.join(appdata, 'npm'));
71
- // Portable Node.js installed by OpenAgents Launcher
72
- const home = process.env.USERPROFILE || process.env.HOME || '';
73
- if (home) dirs.push(path.join(home, '.openagents', 'nodejs'));
74
- } else {
75
- const home = process.env.HOME || '';
76
- dirs.push(path.join(home, '.openagents', 'nodejs', 'bin'), '/usr/local/bin');
77
- }
78
- for (const d of dirs) {
79
- for (const name of ['openclaw.cmd', 'openclaw']) {
80
- const candidate = path.join(d, name);
81
- if (fs.existsSync(candidate)) return candidate;
82
- }
83
- }
84
71
  return null;
85
72
  }
86
73
 
@@ -244,21 +231,21 @@ class OpenClawAdapter extends BaseAdapter {
244
231
  const stderrFd = fs.openSync(stderrFile, 'w');
245
232
  this._log('Spawn: stderr → ' + stderrFile);
246
233
 
247
- let spawnBin = binary;
248
- let spawnArgs = args;
249
- if (IS_WINDOWS) {
250
- // Avoid cmd.exe — it can't handle Unicode paths (Chinese/Japanese/Korean usernames)
251
- // Find node.exe + openclaw.mjs and spawn directly
252
- const portableNode = path.join(os.homedir(), '.openagents', 'nodejs', 'node.exe');
253
- const openclawMjs = path.join(os.homedir(), '.openagents', 'nodejs', 'node_modules', 'openclaw', 'openclaw.mjs');
254
- if (fs.existsSync(portableNode) && fs.existsSync(openclawMjs)) {
255
- spawnBin = portableNode;
256
- spawnArgs = [openclawMjs, ...args];
257
- } else {
258
- // Fallback to cmd.exe (works for ASCII-only paths)
259
- spawnBin = process.env.COMSPEC || 'cmd.exe';
260
- spawnArgs = ['/C', binary, ...args.map(a => a.includes(' ') ? `"${a}"` : a)];
261
- }
234
+ // Always spawn node + openclaw.mjs directly (no shims, no cmd.exe, cross-platform)
235
+ const portableDir = path.join(os.homedir(), '.openagents', 'nodejs');
236
+ const nodeBin = IS_WINDOWS
237
+ ? path.join(portableDir, 'node.exe')
238
+ : path.join(portableDir, 'bin', 'node');
239
+ const openclawMjs = path.join(portableDir, 'node_modules', 'openclaw', 'openclaw.mjs');
240
+
241
+ let spawnBin, spawnArgs;
242
+ if (fs.existsSync(nodeBin) && fs.existsSync(openclawMjs)) {
243
+ spawnBin = nodeBin;
244
+ spawnArgs = [openclawMjs, ...args];
245
+ } else {
246
+ // Fallback: try the binary path directly (system install)
247
+ spawnBin = binary;
248
+ spawnArgs = args;
262
249
  }
263
250
  const proc = spawn(spawnBin, spawnArgs, {
264
251
  stdio: ['ignore', 'pipe', stderrFd],
package/src/installer.js CHANGED
@@ -55,9 +55,11 @@ class Installer {
55
55
  if (binaryPath.startsWith(portableDir)) {
56
56
  const pkgDir = path.join(globalModules, npmPkg || binary);
57
57
  if (!fs.existsSync(path.join(pkgDir, 'package.json'))) {
58
- // Stale shim — clean it up
59
- for (const ext of ['', '.cmd', '.ps1']) {
60
- try { const p = path.join(portableDir, binary + ext); if (fs.existsSync(p)) fs.unlinkSync(p); } catch {}
58
+ // Stale shim — clean it up from all possible locations
59
+ for (const dir of [portableDir, path.join(globalModules, '.bin')]) {
60
+ for (const ext of ['', '.cmd', '.ps1']) {
61
+ try { const p = path.join(dir, binary + ext); if (fs.existsSync(p)) fs.unlinkSync(p); } catch {}
62
+ }
61
63
  }
62
64
  return false;
63
65
  }
@@ -272,9 +274,12 @@ class Installer {
272
274
  const binary = entry && entry.install ? entry.install.binary : agentType;
273
275
  if (!binary) return;
274
276
  const portableDir = path.join(os.homedir(), '.openagents', 'nodejs');
275
- for (const ext of ['', '.cmd', '.ps1']) {
276
- const shimPath = path.join(portableDir, binary + ext);
277
- try { if (fs.existsSync(shimPath)) fs.unlinkSync(shimPath); } catch {}
277
+ const binDir = path.join(portableDir, 'node_modules', '.bin');
278
+ for (const dir of [portableDir, binDir]) {
279
+ for (const ext of ['', '.cmd', '.ps1']) {
280
+ const shimPath = path.join(dir, binary + ext);
281
+ try { if (fs.existsSync(shimPath)) fs.unlinkSync(shimPath); } catch {}
282
+ }
278
283
  }
279
284
  }
280
285