@askexenow/exe-os 0.9.0 → 0.9.1

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.
@@ -3,6 +3,12 @@ var __defProp = Object.defineProperty;
3
3
  var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
4
  var __getOwnPropNames = Object.getOwnPropertyNames;
5
5
  var __hasOwnProp = Object.prototype.hasOwnProperty;
6
+ var __require = /* @__PURE__ */ ((x) => typeof require !== "undefined" ? require : typeof Proxy !== "undefined" ? new Proxy(x, {
7
+ get: (a, b) => (typeof require !== "undefined" ? require : a)[b]
8
+ }) : x)(function(x) {
9
+ if (typeof require !== "undefined") return require.apply(this, arguments);
10
+ throw Error('Dynamic require of "' + x + '" is not supported');
11
+ });
6
12
  var __esm = (fn, res) => function __init() {
7
13
  return fn && (res = (0, fn[__getOwnPropNames(fn)[0]])(fn = 0)), res;
8
14
  };
@@ -547,6 +553,14 @@ var init_agent_config = __esm({
547
553
  });
548
554
 
549
555
  // src/lib/intercom-queue.ts
556
+ var intercom_queue_exports = {};
557
+ __export(intercom_queue_exports, {
558
+ clearQueueForAgent: () => clearQueueForAgent,
559
+ drainForSession: () => drainForSession,
560
+ drainQueue: () => drainQueue,
561
+ queueIntercom: () => queueIntercom,
562
+ readQueue: () => readQueue
563
+ });
550
564
  import { readFileSync as readFileSync4, writeFileSync as writeFileSync3, renameSync as renameSync2, existsSync as existsSync4, mkdirSync as mkdirSync3 } from "fs";
551
565
  import path4 from "path";
552
566
  import os3 from "os";
@@ -585,11 +599,80 @@ function queueIntercom(targetSession, reason) {
585
599
  }
586
600
  writeQueue(queue);
587
601
  }
588
- var QUEUE_PATH, TTL_MS, INTERCOM_LOG;
602
+ function drainQueue(isSessionBusy2, sendKeys) {
603
+ const queue = readQueue();
604
+ if (queue.length === 0) return { drained: 0, failed: 0 };
605
+ const remaining = [];
606
+ let drained = 0;
607
+ let failed = 0;
608
+ for (const item of queue) {
609
+ const age = Date.now() - new Date(item.queuedAt).getTime();
610
+ if (age > TTL_MS) {
611
+ logQueue(`EXPIRED \u2192 ${item.targetSession} (${Math.round(age / 6e4)}min old, reason: ${item.reason})`);
612
+ failed++;
613
+ continue;
614
+ }
615
+ try {
616
+ if (!isSessionBusy2(item.targetSession)) {
617
+ const success = sendKeys(item.targetSession);
618
+ if (success) {
619
+ logQueue(`DRAINED \u2192 ${item.targetSession} (after ${item.attempts} retries)`);
620
+ drained++;
621
+ continue;
622
+ }
623
+ }
624
+ } catch {
625
+ }
626
+ item.attempts++;
627
+ if (item.attempts >= MAX_RETRIES) {
628
+ logQueue(`FAILED \u2192 ${item.targetSession} (${MAX_RETRIES} retries exhausted, reason: ${item.reason})`);
629
+ failed++;
630
+ continue;
631
+ }
632
+ remaining.push(item);
633
+ }
634
+ writeQueue(remaining);
635
+ return { drained, failed };
636
+ }
637
+ function drainForSession(targetSession, sendKeys) {
638
+ const queue = readQueue();
639
+ const match = queue.findIndex((q) => q.targetSession === targetSession);
640
+ if (match < 0) return false;
641
+ const success = sendKeys(targetSession);
642
+ if (success) {
643
+ queue.splice(match, 1);
644
+ writeQueue(queue);
645
+ logQueue(`DRAINED \u2192 ${targetSession} (prompt-submit trigger)`);
646
+ return true;
647
+ }
648
+ return false;
649
+ }
650
+ function clearQueueForAgent(agentName) {
651
+ const queue = readQueue();
652
+ const before = queue.length;
653
+ const filtered = queue.filter((q) => !q.targetSession.startsWith(`${agentName}-`));
654
+ if (filtered.length < before) {
655
+ writeQueue(filtered);
656
+ logQueue(`CLEARED ${before - filtered.length} stale item(s) for ${agentName}`);
657
+ }
658
+ }
659
+ function logQueue(msg) {
660
+ const line = `[${(/* @__PURE__ */ new Date()).toISOString()}] [queue] ${msg}
661
+ `;
662
+ process.stderr.write(`[intercom-queue] ${msg}
663
+ `);
664
+ try {
665
+ const { appendFileSync: appendFileSync2 } = __require("fs");
666
+ appendFileSync2(INTERCOM_LOG, line);
667
+ } catch {
668
+ }
669
+ }
670
+ var QUEUE_PATH, MAX_RETRIES, TTL_MS, INTERCOM_LOG;
589
671
  var init_intercom_queue = __esm({
590
672
  "src/lib/intercom-queue.ts"() {
591
673
  "use strict";
592
674
  QUEUE_PATH = path4.join(os3.homedir(), ".exe-os", "intercom-queue.json");
675
+ MAX_RETRIES = 5;
593
676
  TTL_MS = 60 * 60 * 1e3;
594
677
  INTERCOM_LOG = path4.join(os3.homedir(), ".exe-os", "intercom.log");
595
678
  }
@@ -608,18 +691,18 @@ function delay(ms) {
608
691
  }
609
692
  async function retryOnBusy(fn, label) {
610
693
  let lastError;
611
- for (let attempt = 0; attempt <= MAX_RETRIES; attempt++) {
694
+ for (let attempt = 0; attempt <= MAX_RETRIES2; attempt++) {
612
695
  try {
613
696
  return await fn();
614
697
  } catch (err) {
615
698
  lastError = err;
616
- if (!isBusyError(err) || attempt === MAX_RETRIES) {
699
+ if (!isBusyError(err) || attempt === MAX_RETRIES2) {
617
700
  throw err;
618
701
  }
619
702
  const backoff = BASE_DELAY_MS * Math.pow(2, attempt);
620
703
  const jitter = Math.floor(Math.random() * MAX_JITTER_MS);
621
704
  process.stderr.write(
622
- `[exe-os] SQLITE_BUSY ${label} retry ${attempt + 1}/${MAX_RETRIES} \u2014 waiting ${backoff + jitter}ms
705
+ `[exe-os] SQLITE_BUSY ${label} retry ${attempt + 1}/${MAX_RETRIES2} \u2014 waiting ${backoff + jitter}ms
623
706
  `
624
707
  );
625
708
  await delay(backoff + jitter);
@@ -640,11 +723,11 @@ function wrapWithRetry(client) {
640
723
  }
641
724
  });
642
725
  }
643
- var MAX_RETRIES, BASE_DELAY_MS, MAX_JITTER_MS;
726
+ var MAX_RETRIES2, BASE_DELAY_MS, MAX_JITTER_MS;
644
727
  var init_db_retry = __esm({
645
728
  "src/lib/db-retry.ts"() {
646
729
  "use strict";
647
- MAX_RETRIES = 3;
730
+ MAX_RETRIES2 = 3;
648
731
  BASE_DELAY_MS = 200;
649
732
  MAX_JITTER_MS = 300;
650
733
  }
@@ -2939,6 +3022,13 @@ ${input.result}` : `\u26A0\uFE0F ${warning}`;
2939
3022
  await client.execute("PRAGMA wal_checkpoint(PASSIVE)");
2940
3023
  } catch {
2941
3024
  }
3025
+ if (input.status === "done" || input.status === "cancelled") {
3026
+ try {
3027
+ const { clearQueueForAgent: clearQueueForAgent2 } = await Promise.resolve().then(() => (init_intercom_queue(), intercom_queue_exports));
3028
+ clearQueueForAgent2(String(row.assigned_to));
3029
+ } catch {
3030
+ }
3031
+ }
2942
3032
  try {
2943
3033
  await writeCheckpoint({
2944
3034
  taskId,
@@ -537,6 +537,10 @@ async function cleanSettingsJsonMcp(settingsPath) {
537
537
  }
538
538
  async function mergeHooks(packageRoot, homeDir = os5.homedir()) {
539
539
  const settingsPath = path5.join(homeDir, ".claude", "settings.json");
540
+ const logsDir = path5.join(homeDir, ".exe-os", "logs");
541
+ const hookLogPath = path5.join(logsDir, "hooks.log");
542
+ const logSuffix = ` 2>> "${hookLogPath}"`;
543
+ await mkdir3(logsDir, { recursive: true });
540
544
  let settings = {};
541
545
  if (existsSync5(settingsPath)) {
542
546
  try {
@@ -560,11 +564,11 @@ async function mergeHooks(packageRoot, homeDir = os5.homedir()) {
560
564
  hooks: [
561
565
  {
562
566
  type: "command",
563
- command: `node "${path5.join(packageRoot, "dist", "hooks", "ingest.js")}"`
567
+ command: `node "${path5.join(packageRoot, "dist", "hooks", "ingest.js")}"${logSuffix}`
564
568
  },
565
569
  {
566
570
  type: "command",
567
- command: `node "${path5.join(packageRoot, "dist", "hooks", "error-recall.js")}"`
571
+ command: `node "${path5.join(packageRoot, "dist", "hooks", "error-recall.js")}"${logSuffix}`
568
572
  }
569
573
  ]
570
574
  },
@@ -576,7 +580,7 @@ async function mergeHooks(packageRoot, homeDir = os5.homedir()) {
576
580
  hooks: [
577
581
  {
578
582
  type: "command",
579
- command: `node "${path5.join(packageRoot, "dist", "hooks", "session-start.js")}"`,
583
+ command: `node "${path5.join(packageRoot, "dist", "hooks", "session-start.js")}"${logSuffix}`,
580
584
  timeout: 1e4
581
585
  }
582
586
  ]
@@ -589,7 +593,7 @@ async function mergeHooks(packageRoot, homeDir = os5.homedir()) {
589
593
  hooks: [
590
594
  {
591
595
  type: "command",
592
- command: `node "${path5.join(packageRoot, "dist", "hooks", "prompt-submit.js")}"`
596
+ command: `node "${path5.join(packageRoot, "dist", "hooks", "prompt-submit.js")}"${logSuffix}`
593
597
  }
594
598
  ]
595
599
  },
@@ -601,7 +605,7 @@ async function mergeHooks(packageRoot, homeDir = os5.homedir()) {
601
605
  hooks: [
602
606
  {
603
607
  type: "command",
604
- command: `node "${path5.join(packageRoot, "dist", "hooks", "exe-heartbeat-hook.js")}"`,
608
+ command: `node "${path5.join(packageRoot, "dist", "hooks", "exe-heartbeat-hook.js")}"${logSuffix}`,
605
609
  timeout: 5e3
606
610
  }
607
611
  ]
@@ -614,7 +618,7 @@ async function mergeHooks(packageRoot, homeDir = os5.homedir()) {
614
618
  hooks: [
615
619
  {
616
620
  type: "command",
617
- command: `node "${path5.join(packageRoot, "dist", "hooks", "stop.js")}"`
621
+ command: `node "${path5.join(packageRoot, "dist", "hooks", "stop.js")}"${logSuffix}`
618
622
  }
619
623
  ]
620
624
  },
@@ -627,7 +631,7 @@ async function mergeHooks(packageRoot, homeDir = os5.homedir()) {
627
631
  hooks: [
628
632
  {
629
633
  type: "command",
630
- command: `node "${path5.join(packageRoot, "dist", "hooks", "pre-tool-use.js")}"`
634
+ command: `node "${path5.join(packageRoot, "dist", "hooks", "pre-tool-use.js")}"${logSuffix}`
631
635
  }
632
636
  ]
633
637
  },
@@ -639,7 +643,7 @@ async function mergeHooks(packageRoot, homeDir = os5.homedir()) {
639
643
  hooks: [
640
644
  {
641
645
  type: "command",
642
- command: `node "${path5.join(packageRoot, "dist", "hooks", "subagent-stop.js")}"`
646
+ command: `node "${path5.join(packageRoot, "dist", "hooks", "subagent-stop.js")}"${logSuffix}`
643
647
  }
644
648
  ]
645
649
  },
@@ -651,7 +655,7 @@ async function mergeHooks(packageRoot, homeDir = os5.homedir()) {
651
655
  hooks: [
652
656
  {
653
657
  type: "command",
654
- command: `node "${path5.join(packageRoot, "dist", "hooks", "pre-compact.js")}"`,
658
+ command: `node "${path5.join(packageRoot, "dist", "hooks", "pre-compact.js")}"${logSuffix}`,
655
659
  timeout: 1e4
656
660
  }
657
661
  ]
@@ -664,7 +668,7 @@ async function mergeHooks(packageRoot, homeDir = os5.homedir()) {
664
668
  hooks: [
665
669
  {
666
670
  type: "command",
667
- command: `node "${path5.join(packageRoot, "dist", "hooks", "session-end.js")}"`
671
+ command: `node "${path5.join(packageRoot, "dist", "hooks", "session-end.js")}"${logSuffix}`
668
672
  }
669
673
  ]
670
674
  },
@@ -676,7 +680,7 @@ async function mergeHooks(packageRoot, homeDir = os5.homedir()) {
676
680
  hooks: [
677
681
  {
678
682
  type: "command",
679
- command: `node "${path5.join(packageRoot, "dist", "hooks", "notification.js")}"`
683
+ command: `node "${path5.join(packageRoot, "dist", "hooks", "notification.js")}"${logSuffix}`
680
684
  }
681
685
  ]
682
686
  },
@@ -688,7 +692,7 @@ async function mergeHooks(packageRoot, homeDir = os5.homedir()) {
688
692
  hooks: [
689
693
  {
690
694
  type: "command",
691
- command: `node "${path5.join(packageRoot, "dist", "hooks", "post-compact.js")}"`,
695
+ command: `node "${path5.join(packageRoot, "dist", "hooks", "post-compact.js")}"${logSuffix}`,
692
696
  timeout: 1e4
693
697
  }
694
698
  ]
@@ -701,7 +705,7 @@ async function mergeHooks(packageRoot, homeDir = os5.homedir()) {
701
705
  hooks: [
702
706
  {
703
707
  type: "command",
704
- command: `node "${path5.join(packageRoot, "dist", "hooks", "instructions-loaded.js")}"`
708
+ command: `node "${path5.join(packageRoot, "dist", "hooks", "instructions-loaded.js")}"${logSuffix}`
705
709
  }
706
710
  ]
707
711
  },
@@ -3,6 +3,12 @@ var __defProp = Object.defineProperty;
3
3
  var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
4
  var __getOwnPropNames = Object.getOwnPropertyNames;
5
5
  var __hasOwnProp = Object.prototype.hasOwnProperty;
6
+ var __require = /* @__PURE__ */ ((x) => typeof require !== "undefined" ? require : typeof Proxy !== "undefined" ? new Proxy(x, {
7
+ get: (a, b) => (typeof require !== "undefined" ? require : a)[b]
8
+ }) : x)(function(x) {
9
+ if (typeof require !== "undefined") return require.apply(this, arguments);
10
+ throw Error('Dynamic require of "' + x + '" is not supported');
11
+ });
6
12
  var __esm = (fn, res) => function __init() {
7
13
  return fn && (res = (0, fn[__getOwnPropNames(fn)[0]])(fn = 0)), res;
8
14
  };
@@ -559,6 +565,14 @@ var init_agent_config = __esm({
559
565
  });
560
566
 
561
567
  // src/lib/intercom-queue.ts
568
+ var intercom_queue_exports = {};
569
+ __export(intercom_queue_exports, {
570
+ clearQueueForAgent: () => clearQueueForAgent,
571
+ drainForSession: () => drainForSession,
572
+ drainQueue: () => drainQueue,
573
+ queueIntercom: () => queueIntercom,
574
+ readQueue: () => readQueue
575
+ });
562
576
  import { readFileSync as readFileSync4, writeFileSync as writeFileSync3, renameSync as renameSync2, existsSync as existsSync4, mkdirSync as mkdirSync3 } from "fs";
563
577
  import path4 from "path";
564
578
  import os3 from "os";
@@ -597,11 +611,80 @@ function queueIntercom(targetSession, reason) {
597
611
  }
598
612
  writeQueue(queue);
599
613
  }
600
- var QUEUE_PATH, TTL_MS, INTERCOM_LOG;
614
+ function drainQueue(isSessionBusy2, sendKeys) {
615
+ const queue = readQueue();
616
+ if (queue.length === 0) return { drained: 0, failed: 0 };
617
+ const remaining = [];
618
+ let drained = 0;
619
+ let failed = 0;
620
+ for (const item of queue) {
621
+ const age = Date.now() - new Date(item.queuedAt).getTime();
622
+ if (age > TTL_MS) {
623
+ logQueue(`EXPIRED \u2192 ${item.targetSession} (${Math.round(age / 6e4)}min old, reason: ${item.reason})`);
624
+ failed++;
625
+ continue;
626
+ }
627
+ try {
628
+ if (!isSessionBusy2(item.targetSession)) {
629
+ const success = sendKeys(item.targetSession);
630
+ if (success) {
631
+ logQueue(`DRAINED \u2192 ${item.targetSession} (after ${item.attempts} retries)`);
632
+ drained++;
633
+ continue;
634
+ }
635
+ }
636
+ } catch {
637
+ }
638
+ item.attempts++;
639
+ if (item.attempts >= MAX_RETRIES) {
640
+ logQueue(`FAILED \u2192 ${item.targetSession} (${MAX_RETRIES} retries exhausted, reason: ${item.reason})`);
641
+ failed++;
642
+ continue;
643
+ }
644
+ remaining.push(item);
645
+ }
646
+ writeQueue(remaining);
647
+ return { drained, failed };
648
+ }
649
+ function drainForSession(targetSession, sendKeys) {
650
+ const queue = readQueue();
651
+ const match = queue.findIndex((q) => q.targetSession === targetSession);
652
+ if (match < 0) return false;
653
+ const success = sendKeys(targetSession);
654
+ if (success) {
655
+ queue.splice(match, 1);
656
+ writeQueue(queue);
657
+ logQueue(`DRAINED \u2192 ${targetSession} (prompt-submit trigger)`);
658
+ return true;
659
+ }
660
+ return false;
661
+ }
662
+ function clearQueueForAgent(agentName) {
663
+ const queue = readQueue();
664
+ const before = queue.length;
665
+ const filtered = queue.filter((q) => !q.targetSession.startsWith(`${agentName}-`));
666
+ if (filtered.length < before) {
667
+ writeQueue(filtered);
668
+ logQueue(`CLEARED ${before - filtered.length} stale item(s) for ${agentName}`);
669
+ }
670
+ }
671
+ function logQueue(msg) {
672
+ const line = `[${(/* @__PURE__ */ new Date()).toISOString()}] [queue] ${msg}
673
+ `;
674
+ process.stderr.write(`[intercom-queue] ${msg}
675
+ `);
676
+ try {
677
+ const { appendFileSync: appendFileSync2 } = __require("fs");
678
+ appendFileSync2(INTERCOM_LOG, line);
679
+ } catch {
680
+ }
681
+ }
682
+ var QUEUE_PATH, MAX_RETRIES, TTL_MS, INTERCOM_LOG;
601
683
  var init_intercom_queue = __esm({
602
684
  "src/lib/intercom-queue.ts"() {
603
685
  "use strict";
604
686
  QUEUE_PATH = path4.join(os3.homedir(), ".exe-os", "intercom-queue.json");
687
+ MAX_RETRIES = 5;
605
688
  TTL_MS = 60 * 60 * 1e3;
606
689
  INTERCOM_LOG = path4.join(os3.homedir(), ".exe-os", "intercom.log");
607
690
  }
@@ -620,18 +703,18 @@ function delay(ms) {
620
703
  }
621
704
  async function retryOnBusy(fn, label) {
622
705
  let lastError;
623
- for (let attempt = 0; attempt <= MAX_RETRIES; attempt++) {
706
+ for (let attempt = 0; attempt <= MAX_RETRIES2; attempt++) {
624
707
  try {
625
708
  return await fn();
626
709
  } catch (err) {
627
710
  lastError = err;
628
- if (!isBusyError(err) || attempt === MAX_RETRIES) {
711
+ if (!isBusyError(err) || attempt === MAX_RETRIES2) {
629
712
  throw err;
630
713
  }
631
714
  const backoff = BASE_DELAY_MS * Math.pow(2, attempt);
632
715
  const jitter = Math.floor(Math.random() * MAX_JITTER_MS);
633
716
  process.stderr.write(
634
- `[exe-os] SQLITE_BUSY ${label} retry ${attempt + 1}/${MAX_RETRIES} \u2014 waiting ${backoff + jitter}ms
717
+ `[exe-os] SQLITE_BUSY ${label} retry ${attempt + 1}/${MAX_RETRIES2} \u2014 waiting ${backoff + jitter}ms
635
718
  `
636
719
  );
637
720
  await delay(backoff + jitter);
@@ -652,11 +735,11 @@ function wrapWithRetry(client) {
652
735
  }
653
736
  });
654
737
  }
655
- var MAX_RETRIES, BASE_DELAY_MS, MAX_JITTER_MS;
738
+ var MAX_RETRIES2, BASE_DELAY_MS, MAX_JITTER_MS;
656
739
  var init_db_retry = __esm({
657
740
  "src/lib/db-retry.ts"() {
658
741
  "use strict";
659
- MAX_RETRIES = 3;
742
+ MAX_RETRIES2 = 3;
660
743
  BASE_DELAY_MS = 200;
661
744
  MAX_JITTER_MS = 300;
662
745
  }
@@ -2935,6 +3018,13 @@ ${input.result}` : `\u26A0\uFE0F ${warning}`;
2935
3018
  await client.execute("PRAGMA wal_checkpoint(PASSIVE)");
2936
3019
  } catch {
2937
3020
  }
3021
+ if (input.status === "done" || input.status === "cancelled") {
3022
+ try {
3023
+ const { clearQueueForAgent: clearQueueForAgent2 } = await Promise.resolve().then(() => (init_intercom_queue(), intercom_queue_exports));
3024
+ clearQueueForAgent2(String(row.assigned_to));
3025
+ } catch {
3026
+ }
3027
+ }
2938
3028
  try {
2939
3029
  await writeCheckpoint({
2940
3030
  taskId,
@@ -2,6 +2,12 @@ var __defProp = Object.defineProperty;
2
2
  var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
3
3
  var __getOwnPropNames = Object.getOwnPropertyNames;
4
4
  var __hasOwnProp = Object.prototype.hasOwnProperty;
5
+ var __require = /* @__PURE__ */ ((x) => typeof require !== "undefined" ? require : typeof Proxy !== "undefined" ? new Proxy(x, {
6
+ get: (a, b) => (typeof require !== "undefined" ? require : a)[b]
7
+ }) : x)(function(x) {
8
+ if (typeof require !== "undefined") return require.apply(this, arguments);
9
+ throw Error('Dynamic require of "' + x + '" is not supported');
10
+ });
5
11
  var __esm = (fn, res) => function __init() {
6
12
  return fn && (res = (0, fn[__getOwnPropNames(fn)[0]])(fn = 0)), res;
7
13
  };
@@ -4767,6 +4773,14 @@ var init_agent_config = __esm({
4767
4773
  });
4768
4774
 
4769
4775
  // src/lib/intercom-queue.ts
4776
+ var intercom_queue_exports = {};
4777
+ __export(intercom_queue_exports, {
4778
+ clearQueueForAgent: () => clearQueueForAgent,
4779
+ drainForSession: () => drainForSession,
4780
+ drainQueue: () => drainQueue,
4781
+ queueIntercom: () => queueIntercom,
4782
+ readQueue: () => readQueue
4783
+ });
4770
4784
  import { readFileSync as readFileSync7, writeFileSync as writeFileSync4, renameSync as renameSync3, existsSync as existsSync8, mkdirSync as mkdirSync5 } from "fs";
4771
4785
  import path9 from "path";
4772
4786
  import os7 from "os";
@@ -4805,11 +4819,80 @@ function queueIntercom(targetSession, reason) {
4805
4819
  }
4806
4820
  writeQueue(queue);
4807
4821
  }
4808
- var QUEUE_PATH, TTL_MS, INTERCOM_LOG;
4822
+ function drainQueue(isSessionBusy2, sendKeys) {
4823
+ const queue = readQueue();
4824
+ if (queue.length === 0) return { drained: 0, failed: 0 };
4825
+ const remaining = [];
4826
+ let drained = 0;
4827
+ let failed = 0;
4828
+ for (const item of queue) {
4829
+ const age = Date.now() - new Date(item.queuedAt).getTime();
4830
+ if (age > TTL_MS) {
4831
+ logQueue(`EXPIRED \u2192 ${item.targetSession} (${Math.round(age / 6e4)}min old, reason: ${item.reason})`);
4832
+ failed++;
4833
+ continue;
4834
+ }
4835
+ try {
4836
+ if (!isSessionBusy2(item.targetSession)) {
4837
+ const success = sendKeys(item.targetSession);
4838
+ if (success) {
4839
+ logQueue(`DRAINED \u2192 ${item.targetSession} (after ${item.attempts} retries)`);
4840
+ drained++;
4841
+ continue;
4842
+ }
4843
+ }
4844
+ } catch {
4845
+ }
4846
+ item.attempts++;
4847
+ if (item.attempts >= MAX_RETRIES2) {
4848
+ logQueue(`FAILED \u2192 ${item.targetSession} (${MAX_RETRIES2} retries exhausted, reason: ${item.reason})`);
4849
+ failed++;
4850
+ continue;
4851
+ }
4852
+ remaining.push(item);
4853
+ }
4854
+ writeQueue(remaining);
4855
+ return { drained, failed };
4856
+ }
4857
+ function drainForSession(targetSession, sendKeys) {
4858
+ const queue = readQueue();
4859
+ const match = queue.findIndex((q) => q.targetSession === targetSession);
4860
+ if (match < 0) return false;
4861
+ const success = sendKeys(targetSession);
4862
+ if (success) {
4863
+ queue.splice(match, 1);
4864
+ writeQueue(queue);
4865
+ logQueue(`DRAINED \u2192 ${targetSession} (prompt-submit trigger)`);
4866
+ return true;
4867
+ }
4868
+ return false;
4869
+ }
4870
+ function clearQueueForAgent(agentName) {
4871
+ const queue = readQueue();
4872
+ const before = queue.length;
4873
+ const filtered = queue.filter((q) => !q.targetSession.startsWith(`${agentName}-`));
4874
+ if (filtered.length < before) {
4875
+ writeQueue(filtered);
4876
+ logQueue(`CLEARED ${before - filtered.length} stale item(s) for ${agentName}`);
4877
+ }
4878
+ }
4879
+ function logQueue(msg) {
4880
+ const line = `[${(/* @__PURE__ */ new Date()).toISOString()}] [queue] ${msg}
4881
+ `;
4882
+ process.stderr.write(`[intercom-queue] ${msg}
4883
+ `);
4884
+ try {
4885
+ const { appendFileSync: appendFileSync2 } = __require("fs");
4886
+ appendFileSync2(INTERCOM_LOG, line);
4887
+ } catch {
4888
+ }
4889
+ }
4890
+ var QUEUE_PATH, MAX_RETRIES2, TTL_MS, INTERCOM_LOG;
4809
4891
  var init_intercom_queue = __esm({
4810
4892
  "src/lib/intercom-queue.ts"() {
4811
4893
  "use strict";
4812
4894
  QUEUE_PATH = path9.join(os7.homedir(), ".exe-os", "intercom-queue.json");
4895
+ MAX_RETRIES2 = 5;
4813
4896
  TTL_MS = 60 * 60 * 1e3;
4814
4897
  INTERCOM_LOG = path9.join(os7.homedir(), ".exe-os", "intercom.log");
4815
4898
  }
@@ -5518,6 +5601,13 @@ ${input.result}` : `\u26A0\uFE0F ${warning}`;
5518
5601
  await client.execute("PRAGMA wal_checkpoint(PASSIVE)");
5519
5602
  } catch {
5520
5603
  }
5604
+ if (input.status === "done" || input.status === "cancelled") {
5605
+ try {
5606
+ const { clearQueueForAgent: clearQueueForAgent2 } = await Promise.resolve().then(() => (init_intercom_queue(), intercom_queue_exports));
5607
+ clearQueueForAgent2(String(row.assigned_to));
5608
+ } catch {
5609
+ }
5610
+ }
5521
5611
  try {
5522
5612
  await writeCheckpoint({
5523
5613
  taskId,
@@ -7757,7 +7847,7 @@ async function deliverLocalMessage(messageId) {
7757
7847
  return true;
7758
7848
  } catch {
7759
7849
  const newRetryCount = msg.retryCount + 1;
7760
- if (newRetryCount >= MAX_RETRIES2) {
7850
+ if (newRetryCount >= MAX_RETRIES3) {
7761
7851
  await markFailed(messageId, "session unavailable after 10 retries");
7762
7852
  } else {
7763
7853
  await client.execute({
@@ -7846,7 +7936,7 @@ async function retryPendingMessages() {
7846
7936
  sql: `SELECT * FROM messages
7847
7937
  WHERE status = 'pending' AND retry_count < ?
7848
7938
  ORDER BY id`,
7849
- args: [MAX_RETRIES2]
7939
+ args: [MAX_RETRIES3]
7850
7940
  });
7851
7941
  let delivered = 0;
7852
7942
  for (const row of result.rows) {
@@ -7859,13 +7949,13 @@ async function retryPendingMessages() {
7859
7949
  }
7860
7950
  return delivered;
7861
7951
  }
7862
- var MAX_RETRIES2, _wsClientSend;
7952
+ var MAX_RETRIES3, _wsClientSend;
7863
7953
  var init_messaging = __esm({
7864
7954
  "src/lib/messaging.ts"() {
7865
7955
  "use strict";
7866
7956
  init_database();
7867
7957
  init_tmux_routing();
7868
- MAX_RETRIES2 = 10;
7958
+ MAX_RETRIES3 = 10;
7869
7959
  _wsClientSend = null;
7870
7960
  }
7871
7961
  });