@askexenow/exe-os 0.9.7 → 0.9.8

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.
Files changed (95) hide show
  1. package/dist/bin/backfill-conversations.js +754 -79
  2. package/dist/bin/backfill-responses.js +752 -77
  3. package/dist/bin/backfill-vectors.js +752 -77
  4. package/dist/bin/cleanup-stale-review-tasks.js +657 -35
  5. package/dist/bin/cli.js +1388 -605
  6. package/dist/bin/exe-agent-config.js +123 -95
  7. package/dist/bin/exe-agent.js +41 -25
  8. package/dist/bin/exe-assign.js +732 -57
  9. package/dist/bin/exe-boot.js +784 -153
  10. package/dist/bin/exe-call.js +209 -138
  11. package/dist/bin/exe-cloud.js +35 -12
  12. package/dist/bin/exe-dispatch.js +692 -70
  13. package/dist/bin/exe-doctor.js +648 -26
  14. package/dist/bin/exe-export-behaviors.js +650 -20
  15. package/dist/bin/exe-forget.js +635 -13
  16. package/dist/bin/exe-gateway.js +1053 -271
  17. package/dist/bin/exe-heartbeat.js +665 -43
  18. package/dist/bin/exe-kill.js +646 -16
  19. package/dist/bin/exe-launch-agent.js +887 -97
  20. package/dist/bin/exe-link.js +658 -43
  21. package/dist/bin/exe-new-employee.js +378 -177
  22. package/dist/bin/exe-pending-messages.js +656 -34
  23. package/dist/bin/exe-pending-notifications.js +635 -13
  24. package/dist/bin/exe-pending-reviews.js +659 -37
  25. package/dist/bin/exe-rename.js +645 -30
  26. package/dist/bin/exe-review.js +635 -13
  27. package/dist/bin/exe-search.js +771 -88
  28. package/dist/bin/exe-session-cleanup.js +834 -150
  29. package/dist/bin/exe-settings.js +127 -91
  30. package/dist/bin/exe-start-codex.js +729 -94
  31. package/dist/bin/exe-start-opencode.js +717 -82
  32. package/dist/bin/exe-status.js +657 -35
  33. package/dist/bin/exe-team.js +635 -13
  34. package/dist/bin/git-sweep.js +720 -89
  35. package/dist/bin/graph-backfill.js +643 -13
  36. package/dist/bin/graph-export.js +646 -16
  37. package/dist/bin/install.js +596 -193
  38. package/dist/bin/scan-tasks.js +724 -93
  39. package/dist/bin/setup.js +1038 -210
  40. package/dist/bin/shard-migrate.js +645 -15
  41. package/dist/bin/wiki-sync.js +646 -16
  42. package/dist/gateway/index.js +1027 -245
  43. package/dist/hooks/bug-report-worker.js +891 -170
  44. package/dist/hooks/commit-complete.js +718 -87
  45. package/dist/hooks/error-recall.js +776 -93
  46. package/dist/hooks/exe-heartbeat-hook.js +85 -71
  47. package/dist/hooks/ingest-worker.js +840 -156
  48. package/dist/hooks/ingest.js +90 -73
  49. package/dist/hooks/instructions-loaded.js +669 -38
  50. package/dist/hooks/notification.js +661 -30
  51. package/dist/hooks/post-compact.js +674 -43
  52. package/dist/hooks/pre-compact.js +718 -87
  53. package/dist/hooks/pre-tool-use.js +872 -125
  54. package/dist/hooks/prompt-ingest-worker.js +758 -83
  55. package/dist/hooks/prompt-submit.js +1060 -319
  56. package/dist/hooks/response-ingest-worker.js +758 -83
  57. package/dist/hooks/session-end.js +721 -90
  58. package/dist/hooks/session-start.js +1031 -207
  59. package/dist/hooks/stop.js +680 -49
  60. package/dist/hooks/subagent-stop.js +674 -43
  61. package/dist/hooks/summary-worker.js +816 -132
  62. package/dist/index.js +1015 -232
  63. package/dist/lib/cloud-sync.js +663 -48
  64. package/dist/lib/consolidation.js +26 -3
  65. package/dist/lib/database.js +626 -18
  66. package/dist/lib/db.js +2261 -0
  67. package/dist/lib/device-registry.js +640 -25
  68. package/dist/lib/embedder.js +96 -43
  69. package/dist/lib/employee-templates.js +16 -0
  70. package/dist/lib/employees.js +259 -83
  71. package/dist/lib/exe-daemon-client.js +101 -63
  72. package/dist/lib/exe-daemon.js +894 -162
  73. package/dist/lib/hybrid-search.js +771 -88
  74. package/dist/lib/identity.js +27 -7
  75. package/dist/lib/messaging.js +55 -28
  76. package/dist/lib/reminders.js +21 -1
  77. package/dist/lib/schedules.js +636 -14
  78. package/dist/lib/skill-learning.js +21 -1
  79. package/dist/lib/store.js +643 -13
  80. package/dist/lib/task-router.js +82 -71
  81. package/dist/lib/tasks.js +98 -71
  82. package/dist/lib/tmux-routing.js +87 -60
  83. package/dist/lib/token-spend.js +26 -6
  84. package/dist/mcp/server.js +1784 -458
  85. package/dist/mcp/tools/complete-reminder.js +21 -1
  86. package/dist/mcp/tools/create-reminder.js +21 -1
  87. package/dist/mcp/tools/create-task.js +290 -164
  88. package/dist/mcp/tools/deactivate-behavior.js +24 -4
  89. package/dist/mcp/tools/list-reminders.js +21 -1
  90. package/dist/mcp/tools/list-tasks.js +195 -38
  91. package/dist/mcp/tools/send-message.js +58 -31
  92. package/dist/mcp/tools/update-task.js +75 -48
  93. package/dist/runtime/index.js +720 -89
  94. package/dist/tui/App.js +853 -123
  95. package/package.json +3 -2
@@ -103,7 +103,11 @@ var _socket = null;
103
103
  var _connected = false;
104
104
  var _buffer = "";
105
105
  var _requestCount = 0;
106
+ var _consecutiveFailures = 0;
106
107
  var HEALTH_CHECK_INTERVAL = 100;
108
+ var MAX_RETRIES_BEFORE_RESTART = 3;
109
+ var RETRY_DELAYS_MS = [1e3, 3e3, 5e3];
110
+ var MIN_DAEMON_AGE_MS = 3e4;
107
111
  var _pending = /* @__PURE__ */ new Map();
108
112
  var MAX_BUFFER = 1e7;
109
113
  function handleData(chunk) {
@@ -345,98 +349,132 @@ async function pingDaemon() {
345
349
  return null;
346
350
  }
347
351
  function killAndRespawnDaemon() {
348
- process.stderr.write("[exed-client] Killing daemon for restart...\n");
349
- if (existsSync2(PID_PATH)) {
350
- try {
351
- const pid = parseInt(readFileSync2(PID_PATH, "utf8").trim(), 10);
352
- if (pid > 0) {
353
- try {
354
- process.kill(pid, "SIGKILL");
355
- } catch {
352
+ if (!acquireSpawnLock()) {
353
+ process.stderr.write("[exed-client] Another process is already restarting daemon \u2014 skipping\n");
354
+ if (_socket) {
355
+ _socket.destroy();
356
+ _socket = null;
357
+ }
358
+ _connected = false;
359
+ _buffer = "";
360
+ return;
361
+ }
362
+ try {
363
+ process.stderr.write("[exed-client] Killing daemon for restart...\n");
364
+ if (existsSync2(PID_PATH)) {
365
+ try {
366
+ const pid = parseInt(readFileSync2(PID_PATH, "utf8").trim(), 10);
367
+ if (pid > 0) {
368
+ try {
369
+ process.kill(pid, "SIGKILL");
370
+ } catch {
371
+ }
356
372
  }
373
+ } catch {
357
374
  }
375
+ }
376
+ if (_socket) {
377
+ _socket.destroy();
378
+ _socket = null;
379
+ }
380
+ _connected = false;
381
+ _buffer = "";
382
+ try {
383
+ unlinkSync(PID_PATH);
358
384
  } catch {
359
385
  }
386
+ try {
387
+ unlinkSync(SOCKET_PATH);
388
+ } catch {
389
+ }
390
+ spawnDaemon();
391
+ } finally {
392
+ releaseSpawnLock();
360
393
  }
361
- if (_socket) {
362
- _socket.destroy();
363
- _socket = null;
364
- }
365
- _connected = false;
366
- _buffer = "";
394
+ }
395
+ function isDaemonTooYoung() {
367
396
  try {
368
- unlinkSync(PID_PATH);
397
+ const stat = statSync(PID_PATH);
398
+ return Date.now() - stat.mtimeMs < MIN_DAEMON_AGE_MS;
369
399
  } catch {
400
+ return false;
370
401
  }
371
- try {
372
- unlinkSync(SOCKET_PATH);
373
- } catch {
402
+ }
403
+ async function retryThenRestart(doRequest, label) {
404
+ const result = await doRequest();
405
+ if (!result.error) {
406
+ _consecutiveFailures = 0;
407
+ return result;
408
+ }
409
+ _consecutiveFailures++;
410
+ for (let i = 0; i < MAX_RETRIES_BEFORE_RESTART; i++) {
411
+ const delayMs = RETRY_DELAYS_MS[i] ?? 5e3;
412
+ process.stderr.write(`[exed-client] ${label} failed (${result.error}), retry ${i + 1}/${MAX_RETRIES_BEFORE_RESTART} in ${delayMs}ms
413
+ `);
414
+ await new Promise((r) => setTimeout(r, delayMs));
415
+ if (!_connected) {
416
+ if (!await connectToSocket()) continue;
417
+ }
418
+ const retry = await doRequest();
419
+ if (!retry.error) {
420
+ _consecutiveFailures = 0;
421
+ return retry;
422
+ }
423
+ _consecutiveFailures++;
424
+ }
425
+ if (isDaemonTooYoung()) {
426
+ process.stderr.write(`[exed-client] ${label}: daemon too young (< ${MIN_DAEMON_AGE_MS / 1e3}s) \u2014 skipping restart
427
+ `);
428
+ return { error: result.error };
429
+ }
430
+ process.stderr.write(`[exed-client] ${label}: ${_consecutiveFailures} consecutive failures \u2014 restarting daemon
431
+ `);
432
+ killAndRespawnDaemon();
433
+ const start = Date.now();
434
+ let delay = 200;
435
+ while (Date.now() - start < CONNECT_TIMEOUT_MS) {
436
+ await new Promise((r) => setTimeout(r, delay));
437
+ if (await connectToSocket()) break;
438
+ delay = Math.min(delay * 2, 3e3);
374
439
  }
375
- spawnDaemon();
440
+ if (!_connected) return { error: "Daemon restart failed" };
441
+ const final = await doRequest();
442
+ if (!final.error) _consecutiveFailures = 0;
443
+ return final;
376
444
  }
377
445
  async function embedViaClient(text, priority = "high") {
378
446
  if (!_connected && !await connectEmbedDaemon()) return null;
379
447
  _requestCount++;
380
448
  if (_requestCount % HEALTH_CHECK_INTERVAL === 0) {
381
449
  const health = await pingDaemon();
382
- if (!health) {
450
+ if (!health && !isDaemonTooYoung()) {
383
451
  process.stderr.write(`[exed-client] Periodic health check failed at request ${_requestCount} \u2014 restarting daemon
384
452
  `);
385
453
  killAndRespawnDaemon();
386
454
  const start = Date.now();
387
- let delay = 200;
455
+ let d = 200;
388
456
  while (Date.now() - start < CONNECT_TIMEOUT_MS) {
389
- await new Promise((r) => setTimeout(r, delay));
457
+ await new Promise((r) => setTimeout(r, d));
390
458
  if (await connectToSocket()) break;
391
- delay = Math.min(delay * 2, 3e3);
459
+ d = Math.min(d * 2, 3e3);
392
460
  }
393
461
  if (!_connected) return null;
394
462
  }
395
463
  }
396
- const result = await sendRequest([text], priority);
397
- if (!result.error && result.vectors?.[0]) return result.vectors[0];
398
- if (result.error) {
399
- process.stderr.write(`[exed-client] Embed failed (${result.error}) \u2014 attempting restart
400
- `);
401
- killAndRespawnDaemon();
402
- const start = Date.now();
403
- let delay = 200;
404
- while (Date.now() - start < CONNECT_TIMEOUT_MS) {
405
- await new Promise((r) => setTimeout(r, delay));
406
- if (await connectToSocket()) break;
407
- delay = Math.min(delay * 2, 3e3);
408
- }
409
- if (!_connected) return null;
410
- const retry = await sendRequest([text], priority);
411
- if (!retry.error && retry.vectors?.[0]) return retry.vectors[0];
412
- process.stderr.write(`[exed-client] Embed retry also failed: ${retry.error ?? "no vector"}
413
- `);
414
- }
415
- return null;
464
+ const result = await retryThenRestart(
465
+ () => sendRequest([text], priority),
466
+ "Embed"
467
+ );
468
+ return !result.error && result.vectors?.[0] ? result.vectors[0] : null;
416
469
  }
417
470
  async function embedBatchViaClient(texts, priority = "high") {
418
471
  if (!_connected && !await connectEmbedDaemon()) return null;
419
472
  _requestCount++;
420
- const result = await sendRequest(texts, priority);
421
- if (!result.error && result.vectors) return result.vectors;
422
- if (result.error) {
423
- process.stderr.write(`[exed-client] Batch embed failed (${result.error}) \u2014 attempting restart
424
- `);
425
- killAndRespawnDaemon();
426
- const start = Date.now();
427
- let delay = 200;
428
- while (Date.now() - start < CONNECT_TIMEOUT_MS) {
429
- await new Promise((r) => setTimeout(r, delay));
430
- if (await connectToSocket()) break;
431
- delay = Math.min(delay * 2, 3e3);
432
- }
433
- if (!_connected) return null;
434
- const retry = await sendRequest(texts, priority);
435
- if (!retry.error && retry.vectors) return retry.vectors;
436
- process.stderr.write(`[exed-client] Batch retry also failed: ${retry.error ?? "no vectors"}
437
- `);
438
- }
439
- return null;
473
+ const result = await retryThenRestart(
474
+ () => sendRequest(texts, priority),
475
+ "Batch embed"
476
+ );
477
+ return !result.error && result.vectors ? result.vectors : null;
440
478
  }
441
479
  function disconnectClient() {
442
480
  if (_socket) {