a2acalling 0.6.47 → 0.6.49

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/bin/cli.js CHANGED
@@ -1954,6 +1954,19 @@ a2a add "${inviteUrl}" "${ownerText || 'friend'}" && a2a call "${ownerText || 'f
1954
1954
  return;
1955
1955
  }
1956
1956
 
1957
+ // Pre-start cleanup: kill any existing a2a server from a previous run
1958
+ try {
1959
+ const { killExistingServer } = require('../src/lib/pid-file');
1960
+ const cleanup = killExistingServer();
1961
+ if (cleanup.killed) {
1962
+ console.log(` Stopped previous server (PID ${cleanup.pid}).`);
1963
+ // Brief pause to let the port free up
1964
+ await new Promise(r => setTimeout(r, 500));
1965
+ }
1966
+ } catch (e) {
1967
+ // Best effort — continue with startup
1968
+ }
1969
+
1957
1970
  const isAlreadyListening = await isPortListening(serverPort, '127.0.0.1', { timeoutMs: 250 });
1958
1971
  let serverPid = null;
1959
1972
  if (!isAlreadyListening.listening) {
@@ -1987,7 +2000,15 @@ a2a add "${inviteUrl}" "${ownerText || 'friend'}" && a2a call "${ownerText || 'f
1987
2000
 
1988
2001
  if (serverPid) {
1989
2002
  console.log(' Server started.');
1990
- config.setOnboarding({ server_pid: serverPid, server_port: serverPort });
2003
+ const existingPids = (config.getOnboarding().server_pids || []).filter(p => {
2004
+ try { process.kill(p, 0); return true; } catch (e) { return false; }
2005
+ });
2006
+ if (!existingPids.includes(serverPid)) existingPids.push(serverPid);
2007
+ config.setOnboarding({
2008
+ server_pid: serverPid,
2009
+ server_pids: existingPids,
2010
+ server_port: serverPort
2011
+ });
1991
2012
  } else {
1992
2013
  console.log(' Using existing server.');
1993
2014
  }
@@ -2318,24 +2339,43 @@ a2a add "${inviteUrl}" "${ownerText || 'friend'}" && a2a call "${ownerText || 'f
2318
2339
  }
2319
2340
  }
2320
2341
 
2321
- // Kill server by PID from config (detached process started by quickstart)
2342
+ // Kill server by PID from config and PID file (detached process started by quickstart)
2322
2343
  // Then verify the port is actually freed; if not, find and kill whatever holds it.
2323
2344
  async function killServerPid() {
2324
- let pid, serverPort;
2345
+ let pid, serverPort, serverPids = [];
2325
2346
  try {
2326
2347
  const { A2AConfig } = require('../src/lib/config');
2327
2348
  const cfg = new A2AConfig();
2328
2349
  const onboarding = cfg.getOnboarding();
2329
2350
  pid = onboarding.server_pid;
2330
2351
  serverPort = onboarding.server_port;
2352
+ serverPids = Array.isArray(onboarding.server_pids) ? onboarding.server_pids : [];
2331
2353
  } catch (err) {
2332
- // Config read failed — not fatal, continue with pm2 path
2333
- return { ok: true, skipped: true };
2354
+ // Config read failed — not fatal, continue
2334
2355
  }
2335
2356
 
2336
- // Step 1: Try to kill the PID from config
2337
- if (pid) {
2338
- killPidSync(pid);
2357
+ // Step 0: Try PID file first (most reliable source)
2358
+ try {
2359
+ const { readPidFile, removePidFile } = require('../src/lib/pid-file');
2360
+ const filePid = readPidFile();
2361
+ if (filePid) {
2362
+ killPidSync(filePid);
2363
+ removePidFile();
2364
+ // If config PID is the same, don't double-kill
2365
+ if (filePid === pid) pid = null;
2366
+ }
2367
+ } catch (e) {
2368
+ // pid-file module load failed — continue with config PID
2369
+ }
2370
+
2371
+ // Step 1: Try to kill all tracked PIDs from config
2372
+ const allPids = new Set();
2373
+ if (pid) allPids.add(pid);
2374
+ for (const p of serverPids) {
2375
+ if (typeof p === 'number' && p > 0) allPids.add(p);
2376
+ }
2377
+ for (const p of allPids) {
2378
+ killPidSync(p);
2339
2379
  }
2340
2380
 
2341
2381
  // Step 2: Verify the port is freed
@@ -2359,7 +2399,13 @@ a2a add "${inviteUrl}" "${ownerText || 'friend'}" && a2a call "${ownerText || 'f
2359
2399
  }
2360
2400
  }
2361
2401
 
2362
- return { ok: true, pid, port: serverPort, skipped: !pid };
2402
+ // Clean up PID file if it still exists
2403
+ try {
2404
+ const { removePidFile } = require('../src/lib/pid-file');
2405
+ removePidFile();
2406
+ } catch (e) {}
2407
+
2408
+ return { ok: true, pid, port: serverPort, skipped: !pid && allPids.size === 0 };
2363
2409
  }
2364
2410
 
2365
2411
  process.stdout.write('Stopping server... ');
@@ -2445,8 +2491,30 @@ a2a add "${inviteUrl}" "${ownerText || 'friend'}" && a2a call "${ownerText || 'f
2445
2491
  const { execSync } = require('child_process');
2446
2492
  const path = require('path');
2447
2493
  const pkg = require('../package.json');
2494
+ const { A2AConfig } = require('../src/lib/config');
2448
2495
  const currentVersion = pkg.version;
2449
2496
  const checkOnly = args.flags.check || args.flags.c;
2497
+ const autoMode = args.flags.auto ? String(args.flags.auto).trim().toLowerCase() : null;
2498
+
2499
+ if (autoMode) {
2500
+ const config = new A2AConfig();
2501
+ if (autoMode === 'status') {
2502
+ const au = config.getAutoUpdate ? config.getAutoUpdate() : { enabled: true, intervalMs: 3600000, allowMajor: false };
2503
+ console.log('Auto-update configuration:\n');
2504
+ console.log(` Enabled: ${au.enabled ? 'yes' : 'no'}`);
2505
+ console.log(` Interval: ${Math.floor((au.intervalMs || 3600000) / 1000)}s`);
2506
+ console.log(` Allow major updates: ${au.allowMajor ? 'yes' : 'no'}`);
2507
+ console.log(` Last known good version: ${au.lastGoodVersion || '(none)'}`);
2508
+ return;
2509
+ }
2510
+ if (autoMode === 'on' || autoMode === 'off') {
2511
+ config.setAutoUpdate({ enabled: autoMode === 'on' });
2512
+ console.log(`Auto-update ${autoMode === 'on' ? 'enabled' : 'disabled'}.`);
2513
+ return;
2514
+ }
2515
+ console.error('Invalid --auto value. Use: on | off | status');
2516
+ process.exit(1);
2517
+ }
2450
2518
 
2451
2519
  console.log(`\n📦 A2A Update\n${'─'.repeat(50)}\n`);
2452
2520
  console.log(` Installed: v${currentVersion}`);
@@ -2635,6 +2703,7 @@ Server:
2635
2703
 
2636
2704
  update Update A2A to latest version (npm or git pull)
2637
2705
  --check, -c Check for updates without installing
2706
+ --auto Manage auto-update: on|off|status
2638
2707
 
2639
2708
  install Install A2A for OpenClaw
2640
2709
  setup Auto setup (gateway-aware dashboard install)