neoagent 2.1.9 → 2.1.10

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/lib/manager.js CHANGED
@@ -70,6 +70,16 @@ function detectPlatform() {
70
70
  return 'other';
71
71
  }
72
72
 
73
+ function launchctlDomain() {
74
+ if (typeof process.getuid !== 'function') return null;
75
+ return `gui/${process.getuid()}`;
76
+ }
77
+
78
+ function launchctlServiceTarget() {
79
+ const domain = launchctlDomain();
80
+ return domain ? `${domain}/${SERVICE_LABEL}` : SERVICE_LABEL;
81
+ }
82
+
73
83
  function loadEnvPort() {
74
84
  try {
75
85
  const env = fs.readFileSync(ENV_FILE, 'utf8');
@@ -210,6 +220,49 @@ function killByPort(port) {
210
220
  return killed;
211
221
  }
212
222
 
223
+ function listNeoAgentServerProcesses() {
224
+ const res = runQuiet('ps', ['-axo', 'pid=,ppid=,command=']);
225
+ if (res.status !== 0) return [];
226
+
227
+ return res.stdout
228
+ .split('\n')
229
+ .map((line) => line.trim())
230
+ .filter(Boolean)
231
+ .map((line) => {
232
+ const match = line.match(/^(\d+)\s+(\d+)\s+(.*)$/);
233
+ if (!match) return null;
234
+ return {
235
+ pid: Number(match[1]),
236
+ ppid: Number(match[2]),
237
+ command: match[3],
238
+ };
239
+ })
240
+ .filter(Boolean)
241
+ .filter((entry) =>
242
+ entry.pid !== process.pid &&
243
+ /(^|\s)node(\s|$)/.test(entry.command) &&
244
+ (
245
+ entry.command.includes('/neoagent/server/index.js') ||
246
+ entry.command.includes(`${path.sep}NeoAgent${path.sep}server${path.sep}index.js`) ||
247
+ entry.command.includes(`${APP_DIR}${path.sep}server${path.sep}index.js`)
248
+ )
249
+ );
250
+ }
251
+
252
+ function killNeoAgentServerProcesses() {
253
+ const processes = listNeoAgentServerProcesses();
254
+ let killed = false;
255
+ for (const proc of processes) {
256
+ try {
257
+ process.kill(proc.pid, 'SIGTERM');
258
+ killed = true;
259
+ } catch {
260
+ // Ignore stale processes.
261
+ }
262
+ }
263
+ return { killed, processes };
264
+ }
265
+
213
266
  function isPortOpen(port) {
214
267
  return new Promise((resolve) => {
215
268
  const sock = new net.Socket();
@@ -338,8 +391,21 @@ function installMacService() {
338
391
 
339
392
  fs.writeFileSync(PLIST_DST, content);
340
393
 
341
- runQuiet('launchctl', ['unload', PLIST_DST]);
342
- runOrThrow('launchctl', ['load', PLIST_DST]);
394
+ const domain = launchctlDomain();
395
+ if (domain) {
396
+ runQuiet('launchctl', ['bootout', domain, PLIST_DST]);
397
+ const bootstrap = runQuiet('launchctl', ['bootstrap', domain, PLIST_DST]);
398
+ if (bootstrap.status !== 0) {
399
+ runQuiet('launchctl', ['unload', PLIST_DST]);
400
+ runOrThrow('launchctl', ['load', PLIST_DST]);
401
+ } else {
402
+ runQuiet('launchctl', ['enable', launchctlServiceTarget()]);
403
+ runQuiet('launchctl', ['kickstart', '-k', launchctlServiceTarget()]);
404
+ }
405
+ } else {
406
+ runQuiet('launchctl', ['unload', PLIST_DST]);
407
+ runOrThrow('launchctl', ['load', PLIST_DST]);
408
+ }
343
409
  logOk(`launchd service loaded (${SERVICE_LABEL})`);
344
410
  }
345
411
 
@@ -401,7 +467,7 @@ function cmdStart() {
401
467
  const platform = detectPlatform();
402
468
 
403
469
  if (platform === 'macos' && fs.existsSync(PLIST_DST)) {
404
- runQuiet('launchctl', ['load', PLIST_DST]);
470
+ installMacService();
405
471
  logOk('launchd start requested');
406
472
  return;
407
473
  }
@@ -420,39 +486,49 @@ function cmdStop() {
420
486
  const platform = detectPlatform();
421
487
 
422
488
  if (platform === 'macos' && fs.existsSync(PLIST_DST)) {
489
+ const domain = launchctlDomain();
490
+ if (domain) {
491
+ runQuiet('launchctl', ['bootout', domain, PLIST_DST]);
492
+ runQuiet('launchctl', ['bootout', launchctlServiceTarget()]);
493
+ }
423
494
  runQuiet('launchctl', ['unload', PLIST_DST]);
424
495
  logOk('launchd stop requested');
425
- return;
426
- }
427
-
428
- if (platform === 'linux' && fs.existsSync(SYSTEMD_UNIT)) {
496
+ } else if (platform === 'linux' && fs.existsSync(SYSTEMD_UNIT)) {
429
497
  runQuiet('systemctl', ['--user', 'stop', 'neoagent']);
430
498
  logOk('systemd stop requested');
431
- return;
432
- }
433
-
434
- const pidPath = PID_FILE;
435
- let stopped = false;
436
- if (fs.existsSync(pidPath)) {
437
- const pid = Number(fs.readFileSync(pidPath, 'utf8').trim());
438
- if (Number.isFinite(pid) && pid > 0) {
439
- try {
440
- process.kill(pid, 'SIGTERM');
441
- logOk(`Stopped pid ${pid}`);
442
- stopped = true;
443
- } catch {
444
- logWarn(`pid ${pid} not running`);
499
+ } else {
500
+ const pidPath = PID_FILE;
501
+ let stopped = false;
502
+ if (fs.existsSync(pidPath)) {
503
+ const pid = Number(fs.readFileSync(pidPath, 'utf8').trim());
504
+ if (Number.isFinite(pid) && pid > 0) {
505
+ try {
506
+ process.kill(pid, 'SIGTERM');
507
+ logOk(`Stopped pid ${pid}`);
508
+ stopped = true;
509
+ } catch {
510
+ logWarn(`pid ${pid} not running`);
511
+ }
445
512
  }
513
+ fs.rmSync(pidPath, { force: true });
446
514
  }
447
- fs.rmSync(pidPath, { force: true });
515
+
516
+ const port = loadEnvPort();
517
+ if (killByPort(port)) {
518
+ logOk(`Stopped process listening on port ${port}`);
519
+ stopped = true;
520
+ }
521
+ if (!stopped) logWarn('No running process found');
448
522
  }
449
523
 
450
524
  const port = loadEnvPort();
525
+ const { killed, processes } = killNeoAgentServerProcesses();
526
+ if (killed) {
527
+ logOk(`Stopped ${processes.length} extra NeoAgent process${processes.length === 1 ? '' : 'es'}`);
528
+ }
451
529
  if (killByPort(port)) {
452
530
  logOk(`Stopped process listening on port ${port}`);
453
- stopped = true;
454
531
  }
455
- if (!stopped) logWarn('No running process found');
456
532
  }
457
533
 
458
534
  function cmdRestart() {
@@ -496,15 +572,15 @@ async function cmdStatus() {
496
572
  logWarn(`not reachable on port ${port}`);
497
573
  }
498
574
 
499
- const gitVersion = runQuiet('git', ['describe', '--tags', '--always', '--dirty']);
500
- if (gitVersion.status === 0) {
501
- console.log(` version ${gitVersion.stdout.trim().replace(/^v/, '')}`);
502
- return;
503
- }
575
+ console.log(` install root ${APP_DIR}`);
576
+ console.log(` version ${currentInstalledVersionLabel()}`);
504
577
 
505
- const gitSha = runQuiet('git', ['rev-parse', '--short', 'HEAD']);
506
- if (gitSha.status === 0) {
507
- console.log(` version ${gitSha.stdout.trim()}`);
578
+ const processes = listNeoAgentServerProcesses();
579
+ if (processes.length > 0) {
580
+ console.log(` neoagent pids ${processes.map((proc) => proc.pid).join(', ')}`);
581
+ if (processes.length > 1) {
582
+ logWarn(`multiple NeoAgent server processes detected (${processes.length})`);
583
+ }
508
584
  }
509
585
  }
510
586
 
@@ -551,12 +627,12 @@ function cmdUpdate() {
551
627
  if (commandExists('npm')) {
552
628
  try {
553
629
  backupRuntimeData();
554
- runOrThrow('npm', ['install', '-g', 'neoagent@latest'], {
630
+ runOrThrow('npm', ['install', '-g', 'neoagent@latest', '--force'], {
555
631
  env: withInstallEnv()
556
632
  });
557
- logOk('npm global update completed');
633
+ logOk('npm global update completed (forced reinstall)');
558
634
  } catch {
559
- logWarn('npm global update failed. Run: npm install -g neoagent@latest');
635
+ logWarn('npm global update failed. Run: npm install -g neoagent@latest --force');
560
636
  }
561
637
  } else {
562
638
  logWarn('npm not found. Cannot perform global update.');
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "neoagent",
3
- "version": "2.1.9",
3
+ "version": "2.1.10",
4
4
  "description": "Proactive personal AI agent with no limits",
5
5
  "license": "MIT",
6
6
  "main": "server/index.js",
@@ -33,6 +33,7 @@ function buildHelmetOptions({ secureCookies }) {
33
33
  'https://fonts.googleapis.com',
34
34
  'https://fonts.gstatic.com',
35
35
  'https://www.gstatic.com',
36
+ 'https://api.qrserver.com',
36
37
  ...wsConnectSrc
37
38
  ],
38
39
  fontSrc: ["'self'", 'data:', 'https://fonts.gstatic.com'],
@@ -37,6 +37,6 @@ _flutter.buildConfig = {"engineRevision":"052f31d115eceda8cbff1b3481fcde4330c4ae
37
37
 
38
38
  _flutter.loader.load({
39
39
  serviceWorkerSettings: {
40
- serviceWorkerVersion: "3587732160" /* Flutter's service worker is deprecated and will be removed in a future Flutter release. */
40
+ serviceWorkerVersion: "2457264468" /* Flutter's service worker is deprecated and will be removed in a future Flutter release. */
41
41
  }
42
42
  });