@adhdev/daemon-standalone 0.9.82-rc.195 → 0.9.82-rc.197
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/dist/index.js +588 -77
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
- package/public/assets/index-CDdoEZIp.js +105 -0
- package/public/assets/index-DNAiYM9S.css +1 -0
- package/public/index.html +2 -2
- package/vendor/mcp-server/index.js +49 -2
- package/vendor/mcp-server/index.js.map +1 -1
- package/public/assets/index-CBBYmxbw.js +0 -105
- package/public/assets/index-nXxZVWAP.css +0 -1
package/dist/index.js
CHANGED
|
@@ -38106,14 +38106,32 @@ Valid status values: \`completed\` | \`failed\` | \`blocked\` | \`partial\`.`;
|
|
|
38106
38106
|
function legacyQueuePath(meshId) {
|
|
38107
38107
|
return (0, import_path7.join)(getLedgerDir(), `${safeMeshId(meshId)}.queue.json`);
|
|
38108
38108
|
}
|
|
38109
|
+
function meshRuntimeStorePath() {
|
|
38110
|
+
const dir = getLedgerDir();
|
|
38111
|
+
const nextPath = (0, import_path7.join)(dir, "mesh-runtime.db");
|
|
38112
|
+
if ((0, import_fs7.existsSync)(nextPath)) return nextPath;
|
|
38113
|
+
const legacyPath = (0, import_path7.join)(dir, "beads.db");
|
|
38114
|
+
if (!(0, import_fs7.existsSync)(legacyPath)) return nextPath;
|
|
38115
|
+
try {
|
|
38116
|
+
(0, import_fs7.renameSync)(legacyPath, nextPath);
|
|
38117
|
+
for (const suffix of ["-wal", "-shm"]) {
|
|
38118
|
+
const legacyCompanion = `${legacyPath}${suffix}`;
|
|
38119
|
+
if ((0, import_fs7.existsSync)(legacyCompanion)) {
|
|
38120
|
+
(0, import_fs7.renameSync)(legacyCompanion, `${nextPath}${suffix}`);
|
|
38121
|
+
}
|
|
38122
|
+
}
|
|
38123
|
+
} catch {
|
|
38124
|
+
}
|
|
38125
|
+
return nextPath;
|
|
38126
|
+
}
|
|
38109
38127
|
var import_fs7;
|
|
38110
38128
|
var import_path7;
|
|
38111
38129
|
var import_module;
|
|
38112
38130
|
var import_meta;
|
|
38113
38131
|
var DatabaseCtor;
|
|
38114
|
-
var
|
|
38115
|
-
var
|
|
38116
|
-
"src/mesh/
|
|
38132
|
+
var MeshRuntimeStore;
|
|
38133
|
+
var init_mesh_runtime_store = __esm2({
|
|
38134
|
+
"src/mesh/mesh-runtime-store.ts"() {
|
|
38117
38135
|
"use strict";
|
|
38118
38136
|
import_fs7 = require("fs");
|
|
38119
38137
|
import_path7 = require("path");
|
|
@@ -38121,7 +38139,7 @@ Valid status values: \`completed\` | \`failed\` | \`blocked\` | \`partial\`.`;
|
|
|
38121
38139
|
init_mesh_ledger();
|
|
38122
38140
|
init_mesh_work_queue();
|
|
38123
38141
|
import_meta = {};
|
|
38124
|
-
|
|
38142
|
+
MeshRuntimeStore = class _MeshRuntimeStore {
|
|
38125
38143
|
static instance;
|
|
38126
38144
|
db;
|
|
38127
38145
|
dbPath;
|
|
@@ -38144,7 +38162,7 @@ Valid status values: \`completed\` | \`failed\` | \`blocked\` | \`partial\`.`;
|
|
|
38144
38162
|
}
|
|
38145
38163
|
static getInstance() {
|
|
38146
38164
|
if (!this.instance) {
|
|
38147
|
-
this.instance = new
|
|
38165
|
+
this.instance = new _MeshRuntimeStore(meshRuntimeStorePath());
|
|
38148
38166
|
}
|
|
38149
38167
|
return this.instance;
|
|
38150
38168
|
}
|
|
@@ -38209,6 +38227,49 @@ Valid status values: \`completed\` | \`failed\` | \`blocked\` | \`partial\`.`;
|
|
|
38209
38227
|
metadata TEXT,
|
|
38210
38228
|
PRIMARY KEY (node_id, session_id)
|
|
38211
38229
|
);
|
|
38230
|
+
|
|
38231
|
+
CREATE TABLE IF NOT EXISTS mesh_session_delivery (
|
|
38232
|
+
id TEXT PRIMARY KEY,
|
|
38233
|
+
mesh_id TEXT NOT NULL,
|
|
38234
|
+
node_id TEXT,
|
|
38235
|
+
session_id TEXT,
|
|
38236
|
+
provider_type TEXT,
|
|
38237
|
+
task_id TEXT,
|
|
38238
|
+
kind TEXT NOT NULL,
|
|
38239
|
+
priority INTEGER NOT NULL DEFAULT 0,
|
|
38240
|
+
message TEXT NOT NULL,
|
|
38241
|
+
status TEXT NOT NULL DEFAULT 'queued',
|
|
38242
|
+
deliver_after TEXT,
|
|
38243
|
+
expires_at TEXT,
|
|
38244
|
+
attempt_count INTEGER NOT NULL DEFAULT 0,
|
|
38245
|
+
source_coordinator_session_id TEXT,
|
|
38246
|
+
source_coordinator_daemon_id TEXT,
|
|
38247
|
+
last_error TEXT,
|
|
38248
|
+
created_at TEXT NOT NULL,
|
|
38249
|
+
updated_at TEXT NOT NULL
|
|
38250
|
+
);
|
|
38251
|
+
|
|
38252
|
+
CREATE INDEX IF NOT EXISTS idx_mesh_session_delivery_mesh_status
|
|
38253
|
+
ON mesh_session_delivery(mesh_id, status, created_at);
|
|
38254
|
+
CREATE INDEX IF NOT EXISTS idx_mesh_session_delivery_session
|
|
38255
|
+
ON mesh_session_delivery(mesh_id, session_id, status);
|
|
38256
|
+
CREATE INDEX IF NOT EXISTS idx_mesh_session_delivery_task
|
|
38257
|
+
ON mesh_session_delivery(mesh_id, task_id);
|
|
38258
|
+
|
|
38259
|
+
CREATE TABLE IF NOT EXISTS mesh_completion_conflicts (
|
|
38260
|
+
id TEXT PRIMARY KEY,
|
|
38261
|
+
mesh_id TEXT NOT NULL,
|
|
38262
|
+
fingerprint TEXT NOT NULL,
|
|
38263
|
+
conflicting_task_id TEXT,
|
|
38264
|
+
conflicting_session_id TEXT,
|
|
38265
|
+
original_task_id TEXT,
|
|
38266
|
+
original_session_id TEXT,
|
|
38267
|
+
event TEXT NOT NULL,
|
|
38268
|
+
created_at TEXT NOT NULL
|
|
38269
|
+
);
|
|
38270
|
+
|
|
38271
|
+
CREATE INDEX IF NOT EXISTS idx_mesh_completion_conflicts_mesh
|
|
38272
|
+
ON mesh_completion_conflicts(mesh_id, created_at);
|
|
38212
38273
|
`);
|
|
38213
38274
|
}
|
|
38214
38275
|
hasCompletionFingerprint(fingerprint) {
|
|
@@ -38229,13 +38290,13 @@ Valid status values: \`completed\` | \`failed\` | \`blocked\` | \`partial\`.`;
|
|
|
38229
38290
|
this.db.prepare("DELETE FROM mesh_completion_fingerprints WHERE expires_at <= ?").run(Date.now());
|
|
38230
38291
|
}
|
|
38231
38292
|
maybeCheckpointWal() {
|
|
38232
|
-
if (++this.walWriteCounter <
|
|
38293
|
+
if (++this.walWriteCounter < _MeshRuntimeStore.WAL_CHECK_INTERVAL) return;
|
|
38233
38294
|
this.walWriteCounter = 0;
|
|
38234
38295
|
try {
|
|
38235
38296
|
const walPath = `${this.dbPath}-wal`;
|
|
38236
38297
|
if (!(0, import_fs7.existsSync)(walPath)) return;
|
|
38237
38298
|
const size = (0, import_fs7.statSync)(walPath).size;
|
|
38238
|
-
if (size <
|
|
38299
|
+
if (size < _MeshRuntimeStore.WAL_MAX_BYTES) return;
|
|
38239
38300
|
process.stderr.write(
|
|
38240
38301
|
`[adhdev-mesh] WAL file ${Math.round(size / 1024 / 1024)}MB exceeds threshold; forcing checkpoint
|
|
38241
38302
|
`
|
|
@@ -38533,6 +38594,131 @@ Valid status values: \`completed\` | \`failed\` | \`blocked\` | \`partial\`.`;
|
|
|
38533
38594
|
pruneExpiredRemoteIdleSessions() {
|
|
38534
38595
|
this.db.prepare("DELETE FROM remote_idle_sessions WHERE expires_at <= ?").run(Date.now());
|
|
38535
38596
|
}
|
|
38597
|
+
// ── Session Delivery Queue ───────────────────────────────────────────────
|
|
38598
|
+
insertSessionDelivery(entry) {
|
|
38599
|
+
this.db.prepare(`
|
|
38600
|
+
INSERT OR REPLACE INTO mesh_session_delivery (
|
|
38601
|
+
id, mesh_id, node_id, session_id, provider_type, task_id, kind, priority,
|
|
38602
|
+
message, status, deliver_after, expires_at, attempt_count,
|
|
38603
|
+
source_coordinator_session_id, source_coordinator_daemon_id,
|
|
38604
|
+
last_error, created_at, updated_at
|
|
38605
|
+
) VALUES (
|
|
38606
|
+
@id, @meshId, @nodeId, @sessionId, @providerType, @taskId, @kind, @priority,
|
|
38607
|
+
@message, @status, @deliverAfter, @expiresAt, 0,
|
|
38608
|
+
@sourceCoordinatorSessionId, @sourceCoordinatorDaemonId,
|
|
38609
|
+
NULL, @createdAt, @updatedAt
|
|
38610
|
+
)
|
|
38611
|
+
`).run({
|
|
38612
|
+
id: entry.id,
|
|
38613
|
+
meshId: entry.meshId,
|
|
38614
|
+
nodeId: entry.nodeId ?? null,
|
|
38615
|
+
sessionId: entry.sessionId ?? null,
|
|
38616
|
+
providerType: entry.providerType ?? null,
|
|
38617
|
+
taskId: entry.taskId ?? null,
|
|
38618
|
+
kind: entry.kind,
|
|
38619
|
+
priority: entry.priority ?? 0,
|
|
38620
|
+
message: entry.message,
|
|
38621
|
+
status: entry.status,
|
|
38622
|
+
deliverAfter: entry.deliverAfter ?? null,
|
|
38623
|
+
expiresAt: entry.expiresAt ?? null,
|
|
38624
|
+
sourceCoordinatorSessionId: entry.sourceCoordinatorSessionId ?? null,
|
|
38625
|
+
sourceCoordinatorDaemonId: entry.sourceCoordinatorDaemonId ?? null,
|
|
38626
|
+
createdAt: entry.createdAt,
|
|
38627
|
+
updatedAt: entry.updatedAt
|
|
38628
|
+
});
|
|
38629
|
+
this.maybeCheckpointWal();
|
|
38630
|
+
}
|
|
38631
|
+
updateSessionDeliveryStatus(id, status, opts) {
|
|
38632
|
+
const now = (/* @__PURE__ */ new Date()).toISOString();
|
|
38633
|
+
if (opts?.incrementAttempt) {
|
|
38634
|
+
this.db.prepare(`
|
|
38635
|
+
UPDATE mesh_session_delivery
|
|
38636
|
+
SET status = @status, last_error = @lastError, attempt_count = attempt_count + 1, updated_at = @updatedAt
|
|
38637
|
+
WHERE id = @id
|
|
38638
|
+
`).run({ id, status, lastError: opts?.lastError ?? null, updatedAt: now });
|
|
38639
|
+
} else {
|
|
38640
|
+
this.db.prepare(`
|
|
38641
|
+
UPDATE mesh_session_delivery
|
|
38642
|
+
SET status = @status, last_error = @lastError, updated_at = @updatedAt
|
|
38643
|
+
WHERE id = @id
|
|
38644
|
+
`).run({ id, status, lastError: opts?.lastError ?? null, updatedAt: now });
|
|
38645
|
+
}
|
|
38646
|
+
}
|
|
38647
|
+
getActiveSessionDeliveries(meshId, sessionId) {
|
|
38648
|
+
const now = (/* @__PURE__ */ new Date()).toISOString();
|
|
38649
|
+
const sql = sessionId ? `SELECT * FROM mesh_session_delivery WHERE mesh_id = ? AND session_id = ? AND status NOT IN ('delivered','completed','failed','expired','cancelled') AND (expires_at IS NULL OR expires_at > ?) ORDER BY priority DESC, created_at ASC` : `SELECT * FROM mesh_session_delivery WHERE mesh_id = ? AND status NOT IN ('delivered','completed','failed','expired','cancelled') AND (expires_at IS NULL OR expires_at > ?) ORDER BY priority DESC, created_at ASC`;
|
|
38650
|
+
const rows = sessionId ? this.db.prepare(sql).all(meshId, sessionId, now) : this.db.prepare(sql).all(meshId, now);
|
|
38651
|
+
return rows.map((r) => ({
|
|
38652
|
+
id: r.id,
|
|
38653
|
+
meshId: r.mesh_id,
|
|
38654
|
+
nodeId: r.node_id,
|
|
38655
|
+
sessionId: r.session_id,
|
|
38656
|
+
providerType: r.provider_type,
|
|
38657
|
+
taskId: r.task_id,
|
|
38658
|
+
kind: r.kind,
|
|
38659
|
+
priority: r.priority,
|
|
38660
|
+
message: r.message,
|
|
38661
|
+
status: r.status,
|
|
38662
|
+
deliverAfter: r.deliver_after,
|
|
38663
|
+
expiresAt: r.expires_at,
|
|
38664
|
+
attemptCount: r.attempt_count,
|
|
38665
|
+
sourceCoordinatorSessionId: r.source_coordinator_session_id,
|
|
38666
|
+
sourceCoordinatorDaemonId: r.source_coordinator_daemon_id,
|
|
38667
|
+
lastError: r.last_error,
|
|
38668
|
+
createdAt: r.created_at,
|
|
38669
|
+
updatedAt: r.updated_at
|
|
38670
|
+
}));
|
|
38671
|
+
}
|
|
38672
|
+
expireStaleSessionDeliveries(meshId) {
|
|
38673
|
+
const now = (/* @__PURE__ */ new Date()).toISOString();
|
|
38674
|
+
this.db.prepare(`
|
|
38675
|
+
UPDATE mesh_session_delivery
|
|
38676
|
+
SET status = 'expired', updated_at = ?
|
|
38677
|
+
WHERE mesh_id = ? AND expires_at IS NOT NULL AND expires_at <= ?
|
|
38678
|
+
AND status NOT IN ('delivered','completed','failed','expired','cancelled')
|
|
38679
|
+
`).run(now, meshId, now);
|
|
38680
|
+
}
|
|
38681
|
+
deleteSessionDeliveries(meshId) {
|
|
38682
|
+
this.db.prepare("DELETE FROM mesh_session_delivery WHERE mesh_id = ?").run(meshId);
|
|
38683
|
+
}
|
|
38684
|
+
// ── Completion Conflict Diagnostics ──────────────────────────────────────
|
|
38685
|
+
recordCompletionConflict(entry) {
|
|
38686
|
+
this.db.prepare(`
|
|
38687
|
+
INSERT OR IGNORE INTO mesh_completion_conflicts
|
|
38688
|
+
(id, mesh_id, fingerprint, conflicting_task_id, conflicting_session_id,
|
|
38689
|
+
original_task_id, original_session_id, event, created_at)
|
|
38690
|
+
VALUES (@id, @meshId, @fingerprint, @conflictingTaskId, @conflictingSessionId,
|
|
38691
|
+
@originalTaskId, @originalSessionId, @event, @createdAt)
|
|
38692
|
+
`).run({
|
|
38693
|
+
id: entry.id,
|
|
38694
|
+
meshId: entry.meshId,
|
|
38695
|
+
fingerprint: entry.fingerprint,
|
|
38696
|
+
conflictingTaskId: entry.conflictingTaskId ?? null,
|
|
38697
|
+
conflictingSessionId: entry.conflictingSessionId ?? null,
|
|
38698
|
+
originalTaskId: entry.originalTaskId ?? null,
|
|
38699
|
+
originalSessionId: entry.originalSessionId ?? null,
|
|
38700
|
+
event: entry.event,
|
|
38701
|
+
createdAt: entry.createdAt
|
|
38702
|
+
});
|
|
38703
|
+
this.maybeCheckpointWal();
|
|
38704
|
+
}
|
|
38705
|
+
getRecentCompletionConflicts(meshId, limitMs = 60 * 60 * 1e3) {
|
|
38706
|
+
const cutoff = new Date(Date.now() - limitMs).toISOString();
|
|
38707
|
+
const rows = this.db.prepare(
|
|
38708
|
+
"SELECT * FROM mesh_completion_conflicts WHERE mesh_id = ? AND created_at >= ? ORDER BY created_at DESC LIMIT 50"
|
|
38709
|
+
).all(meshId, cutoff);
|
|
38710
|
+
return rows.map((r) => ({
|
|
38711
|
+
id: r.id,
|
|
38712
|
+
meshId: r.mesh_id,
|
|
38713
|
+
fingerprint: r.fingerprint,
|
|
38714
|
+
conflictingTaskId: r.conflicting_task_id,
|
|
38715
|
+
conflictingSessionId: r.conflicting_session_id,
|
|
38716
|
+
originalTaskId: r.original_task_id,
|
|
38717
|
+
originalSessionId: r.original_session_id,
|
|
38718
|
+
event: r.event,
|
|
38719
|
+
createdAt: r.created_at
|
|
38720
|
+
}));
|
|
38721
|
+
}
|
|
38536
38722
|
};
|
|
38537
38723
|
}
|
|
38538
38724
|
});
|
|
@@ -38544,7 +38730,7 @@ Valid status values: \`completed\` | \`failed\` | \`blocked\` | \`partial\`.`;
|
|
|
38544
38730
|
__clearDirectDispatchesForTests: () => __clearDirectDispatchesForTests,
|
|
38545
38731
|
__clearMeshQueueForTests: () => __clearMeshQueueForTests,
|
|
38546
38732
|
__replaceMeshQueueForTests: () => __replaceMeshQueueForTests,
|
|
38547
|
-
|
|
38733
|
+
__resetMeshRuntimeStoreForTests: () => __resetMeshRuntimeStoreForTests,
|
|
38548
38734
|
buildMeshNodeCapabilityTags: () => buildMeshNodeCapabilityTags,
|
|
38549
38735
|
cancelTask: () => cancelTask,
|
|
38550
38736
|
claimNextTask: () => claimNextTask,
|
|
@@ -38622,7 +38808,7 @@ Valid status values: \`completed\` | \`failed\` | \`blocked\` | \`partial\`.`;
|
|
|
38622
38808
|
return required2.every((tag) => available.has(tag));
|
|
38623
38809
|
}
|
|
38624
38810
|
function withQueueLock(_meshId, fn) {
|
|
38625
|
-
return
|
|
38811
|
+
return MeshRuntimeStore.getInstance().transaction(fn);
|
|
38626
38812
|
}
|
|
38627
38813
|
function enqueueTask(meshId, message, opts) {
|
|
38628
38814
|
requireMeshHostQueueOwner(opts);
|
|
@@ -38642,55 +38828,55 @@ Valid status values: \`completed\` | \`failed\` | \`blocked\` | \`partial\`.`;
|
|
|
38642
38828
|
createdAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
38643
38829
|
updatedAt: (/* @__PURE__ */ new Date()).toISOString()
|
|
38644
38830
|
};
|
|
38645
|
-
|
|
38831
|
+
MeshRuntimeStore.getInstance().insertQueueEntry(entry);
|
|
38646
38832
|
return entry;
|
|
38647
38833
|
}
|
|
38648
38834
|
function getQueue(meshId, opts) {
|
|
38649
|
-
return
|
|
38835
|
+
return MeshRuntimeStore.getInstance().getQueueEntries(meshId, opts?.status?.length ? opts.status : void 0);
|
|
38650
38836
|
}
|
|
38651
38837
|
function getMeshQueueRevision(meshId) {
|
|
38652
|
-
return
|
|
38838
|
+
return MeshRuntimeStore.getInstance().getQueueRevision(meshId);
|
|
38653
38839
|
}
|
|
38654
38840
|
function claimNextTask(meshId, nodeId, sessionId, capabilityTags) {
|
|
38655
|
-
return
|
|
38841
|
+
return MeshRuntimeStore.getInstance().claimNextQueueTask(meshId, nodeId, sessionId, capabilityTags);
|
|
38656
38842
|
}
|
|
38657
38843
|
function updateTaskStatus(meshId, taskId, status, opts) {
|
|
38658
38844
|
requireMeshHostQueueOwner(opts);
|
|
38659
38845
|
return withQueueLock(meshId, () => {
|
|
38660
|
-
const entry =
|
|
38846
|
+
const entry = MeshRuntimeStore.getInstance().findQueueEntryById(meshId, taskId);
|
|
38661
38847
|
if (!entry) return null;
|
|
38662
38848
|
entry.status = status;
|
|
38663
|
-
|
|
38849
|
+
MeshRuntimeStore.getInstance().updateQueueEntry(entry);
|
|
38664
38850
|
return entry;
|
|
38665
38851
|
});
|
|
38666
38852
|
}
|
|
38667
38853
|
function recordTaskAutoLaunch(meshId, taskId, autoLaunch) {
|
|
38668
38854
|
return withQueueLock(meshId, () => {
|
|
38669
|
-
const entry =
|
|
38855
|
+
const entry = MeshRuntimeStore.getInstance().findQueueEntryById(meshId, taskId);
|
|
38670
38856
|
if (!entry) return null;
|
|
38671
38857
|
const now = (/* @__PURE__ */ new Date()).toISOString();
|
|
38672
38858
|
entry.autoLaunch = { ...autoLaunch, updatedAt: now };
|
|
38673
|
-
|
|
38859
|
+
MeshRuntimeStore.getInstance().updateQueueEntry(entry);
|
|
38674
38860
|
return entry;
|
|
38675
38861
|
});
|
|
38676
38862
|
}
|
|
38677
38863
|
function cancelTask(meshId, taskId, opts) {
|
|
38678
38864
|
requireMeshHostQueueOwner(opts);
|
|
38679
38865
|
return withQueueLock(meshId, () => {
|
|
38680
|
-
const entry =
|
|
38866
|
+
const entry = MeshRuntimeStore.getInstance().findQueueEntryById(meshId, taskId);
|
|
38681
38867
|
if (!entry) return null;
|
|
38682
38868
|
const now = (/* @__PURE__ */ new Date()).toISOString();
|
|
38683
38869
|
entry.status = "cancelled";
|
|
38684
38870
|
entry.cancelledAt = now;
|
|
38685
38871
|
if (opts?.reason) entry.cancelReason = opts.reason;
|
|
38686
|
-
|
|
38872
|
+
MeshRuntimeStore.getInstance().updateQueueEntry(entry);
|
|
38687
38873
|
return entry;
|
|
38688
38874
|
});
|
|
38689
38875
|
}
|
|
38690
38876
|
function requeueTask(meshId, taskId, opts) {
|
|
38691
38877
|
requireMeshHostQueueOwner(opts);
|
|
38692
38878
|
return withQueueLock(meshId, () => {
|
|
38693
|
-
const entry =
|
|
38879
|
+
const entry = MeshRuntimeStore.getInstance().findQueueEntryById(meshId, taskId);
|
|
38694
38880
|
if (!entry) return null;
|
|
38695
38881
|
entry.status = "pending";
|
|
38696
38882
|
delete entry.assignedNodeId;
|
|
@@ -38704,22 +38890,22 @@ Valid status values: \`completed\` | \`failed\` | \`blocked\` | \`partial\`.`;
|
|
|
38704
38890
|
entry.requeuedAt = (/* @__PURE__ */ new Date()).toISOString();
|
|
38705
38891
|
entry.requeueCount = (entry.requeueCount || 0) + 1;
|
|
38706
38892
|
if (opts?.reason) entry.requeueReason = opts.reason;
|
|
38707
|
-
|
|
38893
|
+
MeshRuntimeStore.getInstance().updateQueueEntry(entry);
|
|
38708
38894
|
return entry;
|
|
38709
38895
|
});
|
|
38710
38896
|
}
|
|
38711
38897
|
function updateSessionTaskStatus(meshId, sessionId, status, opts) {
|
|
38712
38898
|
return withQueueLock(meshId, () => {
|
|
38713
38899
|
const occurredAtIso = opts?.occurredAt ? new Date(opts.occurredAt).toISOString() : void 0;
|
|
38714
|
-
const entry =
|
|
38900
|
+
const entry = MeshRuntimeStore.getInstance().findAssignedBySession(meshId, sessionId, occurredAtIso);
|
|
38715
38901
|
if (!entry) return null;
|
|
38716
38902
|
entry.status = status;
|
|
38717
|
-
|
|
38903
|
+
MeshRuntimeStore.getInstance().updateQueueEntry(entry);
|
|
38718
38904
|
return entry;
|
|
38719
38905
|
});
|
|
38720
38906
|
}
|
|
38721
38907
|
function getMeshQueueStats(meshId) {
|
|
38722
|
-
const rows =
|
|
38908
|
+
const rows = MeshRuntimeStore.getInstance().getQueueStatsByStatus(meshId);
|
|
38723
38909
|
const counts = {};
|
|
38724
38910
|
for (const r of rows) counts[r.status] = r.count;
|
|
38725
38911
|
const pending = counts["pending"] ?? 0;
|
|
@@ -38738,26 +38924,26 @@ Valid status values: \`completed\` | \`failed\` | \`blocked\` | \`partial\`.`;
|
|
|
38738
38924
|
cancelled,
|
|
38739
38925
|
activeCounts: { pending, assigned },
|
|
38740
38926
|
historicalCounts: { completed, failed, cancelled },
|
|
38741
|
-
activeAssignments:
|
|
38927
|
+
activeAssignments: MeshRuntimeStore.getInstance().getActiveAssignmentDetails(meshId)
|
|
38742
38928
|
};
|
|
38743
38929
|
}
|
|
38744
38930
|
function __replaceMeshQueueForTests(meshId, queue) {
|
|
38745
|
-
|
|
38746
|
-
|
|
38931
|
+
MeshRuntimeStore.getInstance().transaction(() => {
|
|
38932
|
+
MeshRuntimeStore.getInstance().replaceQueue(meshId, queue);
|
|
38747
38933
|
});
|
|
38748
38934
|
}
|
|
38749
38935
|
function __clearMeshQueueForTests(meshId) {
|
|
38750
|
-
|
|
38936
|
+
MeshRuntimeStore.getInstance().deleteQueue(meshId);
|
|
38751
38937
|
}
|
|
38752
38938
|
function __clearDirectDispatchesForTests(meshId) {
|
|
38753
|
-
|
|
38939
|
+
MeshRuntimeStore.getInstance().deleteDirectDispatches(meshId);
|
|
38754
38940
|
}
|
|
38755
|
-
function
|
|
38756
|
-
|
|
38941
|
+
function __resetMeshRuntimeStoreForTests() {
|
|
38942
|
+
MeshRuntimeStore.resetForTests();
|
|
38757
38943
|
}
|
|
38758
38944
|
function insertDirectDispatch(meshId, data) {
|
|
38759
38945
|
try {
|
|
38760
|
-
|
|
38946
|
+
MeshRuntimeStore.getInstance().insertDirectDispatch({ ...data, meshId });
|
|
38761
38947
|
} catch (e) {
|
|
38762
38948
|
process.stderr.write(`[adhdev-mesh] insertDirectDispatch failed for task ${data.taskId}: ${e?.message || e}
|
|
38763
38949
|
`);
|
|
@@ -38765,26 +38951,26 @@ Valid status values: \`completed\` | \`failed\` | \`blocked\` | \`partial\`.`;
|
|
|
38765
38951
|
}
|
|
38766
38952
|
function getActiveDirectDispatches(meshId) {
|
|
38767
38953
|
try {
|
|
38768
|
-
return
|
|
38954
|
+
return MeshRuntimeStore.getInstance().getActiveDirectDispatches(meshId);
|
|
38769
38955
|
} catch {
|
|
38770
38956
|
return [];
|
|
38771
38957
|
}
|
|
38772
38958
|
}
|
|
38773
38959
|
function updateDirectDispatchStatus(meshId, sessionId, status) {
|
|
38774
38960
|
try {
|
|
38775
|
-
|
|
38961
|
+
MeshRuntimeStore.getInstance().updateDirectDispatchStatus(meshId, sessionId, status);
|
|
38776
38962
|
} catch {
|
|
38777
38963
|
}
|
|
38778
38964
|
}
|
|
38779
38965
|
function cleanupTerminalDirectDispatches(olderThanMs = 7 * 24 * 60 * 6e4) {
|
|
38780
38966
|
try {
|
|
38781
|
-
|
|
38967
|
+
MeshRuntimeStore.getInstance().cleanupTerminalDirectDispatches(olderThanMs);
|
|
38782
38968
|
} catch {
|
|
38783
38969
|
}
|
|
38784
38970
|
}
|
|
38785
38971
|
function markStaleDirectDispatches(meshId, olderThanMs = 60 * 6e4) {
|
|
38786
38972
|
try {
|
|
38787
|
-
|
|
38973
|
+
MeshRuntimeStore.getInstance().markStaleDirectDispatches(meshId, olderThanMs);
|
|
38788
38974
|
} catch {
|
|
38789
38975
|
}
|
|
38790
38976
|
}
|
|
@@ -38798,7 +38984,7 @@ Valid status values: \`completed\` | \`failed\` | \`blocked\` | \`partial\`.`;
|
|
|
38798
38984
|
"use strict";
|
|
38799
38985
|
import_crypto5 = require("crypto");
|
|
38800
38986
|
init_mesh_host_ownership();
|
|
38801
|
-
|
|
38987
|
+
init_mesh_runtime_store();
|
|
38802
38988
|
ACTIVE_MESH_QUEUE_STATUSES = ["pending", "assigned"];
|
|
38803
38989
|
HISTORICAL_MESH_QUEUE_STATUSES = ["completed", "failed", "cancelled"];
|
|
38804
38990
|
MESH_TASK_MODES = ["code_change", "validation", "live_debug_readonly", "launch_app", "convergence"];
|
|
@@ -38949,6 +39135,168 @@ Valid status values: \`completed\` | \`failed\` | \`blocked\` | \`partial\`.`;
|
|
|
38949
39135
|
import_fs8 = require("fs");
|
|
38950
39136
|
}
|
|
38951
39137
|
});
|
|
39138
|
+
function resolveDeliveryDecision(sessionStatus, opts) {
|
|
39139
|
+
const status = (sessionStatus || "").trim().toLowerCase();
|
|
39140
|
+
if (!status) {
|
|
39141
|
+
return {
|
|
39142
|
+
decision: "rejected",
|
|
39143
|
+
reason: "unknown_session_status",
|
|
39144
|
+
message: "Session status is unknown. Delivery rejected (fail-closed). Use mesh_launch_session to start a fresh session."
|
|
39145
|
+
};
|
|
39146
|
+
}
|
|
39147
|
+
if (IMMEDIATE_DELIVERY_STATUSES.has(status)) {
|
|
39148
|
+
return {
|
|
39149
|
+
decision: "immediate",
|
|
39150
|
+
reason: `session_${status}`,
|
|
39151
|
+
message: `Session is ${status} \u2014 delivery allowed immediately.`
|
|
39152
|
+
};
|
|
39153
|
+
}
|
|
39154
|
+
if (BUSY_DELIVERY_STATUSES.has(status)) {
|
|
39155
|
+
if (opts?.allowBusyInjection) {
|
|
39156
|
+
return {
|
|
39157
|
+
decision: "immediate",
|
|
39158
|
+
reason: `session_${status}_busy_injection_allowed`,
|
|
39159
|
+
message: `Session is ${status} but provider supports busy injection. Delivered immediately.`
|
|
39160
|
+
};
|
|
39161
|
+
}
|
|
39162
|
+
if (status === "waiting_approval" && opts?.kind === "approval") {
|
|
39163
|
+
return {
|
|
39164
|
+
decision: "immediate",
|
|
39165
|
+
reason: "session_waiting_approval_approval_message",
|
|
39166
|
+
message: "Session is waiting for approval \u2014 approval message delivered immediately."
|
|
39167
|
+
};
|
|
39168
|
+
}
|
|
39169
|
+
return {
|
|
39170
|
+
decision: "queued",
|
|
39171
|
+
reason: `session_${status}_busy`,
|
|
39172
|
+
message: `Session is ${status}. Task queued for delivery when session becomes idle. Do not inject directly into a busy session.`
|
|
39173
|
+
};
|
|
39174
|
+
}
|
|
39175
|
+
if (TERMINAL_DELIVERY_STATUSES.has(status)) {
|
|
39176
|
+
return {
|
|
39177
|
+
decision: "rejected",
|
|
39178
|
+
reason: `session_${status}_terminal`,
|
|
39179
|
+
message: `Session is ${status} (terminal). Delivery rejected. Launch a new session before dispatching tasks.`
|
|
39180
|
+
};
|
|
39181
|
+
}
|
|
39182
|
+
return {
|
|
39183
|
+
decision: "rejected",
|
|
39184
|
+
reason: "unrecognized_session_status",
|
|
39185
|
+
message: `Session status '${sessionStatus}' is not recognized. Delivery rejected (fail-closed). Inspect session state before retrying.`
|
|
39186
|
+
};
|
|
39187
|
+
}
|
|
39188
|
+
function createSessionDelivery(opts) {
|
|
39189
|
+
const now = (/* @__PURE__ */ new Date()).toISOString();
|
|
39190
|
+
const id = (0, import_crypto6.randomUUID)();
|
|
39191
|
+
const record2 = {
|
|
39192
|
+
id,
|
|
39193
|
+
meshId: opts.meshId,
|
|
39194
|
+
nodeId: opts.nodeId,
|
|
39195
|
+
sessionId: opts.sessionId,
|
|
39196
|
+
providerType: opts.providerType,
|
|
39197
|
+
taskId: opts.taskId,
|
|
39198
|
+
kind: opts.kind,
|
|
39199
|
+
priority: opts.priority ?? 0,
|
|
39200
|
+
message: opts.message,
|
|
39201
|
+
status: opts.status,
|
|
39202
|
+
deliverAfter: opts.deliverAfter,
|
|
39203
|
+
expiresAt: opts.expiresAt,
|
|
39204
|
+
attemptCount: 0,
|
|
39205
|
+
sourceCoordinatorSessionId: opts.sourceCoordinatorSessionId,
|
|
39206
|
+
sourceCoordinatorDaemonId: opts.sourceCoordinatorDaemonId,
|
|
39207
|
+
createdAt: now,
|
|
39208
|
+
updatedAt: now
|
|
39209
|
+
};
|
|
39210
|
+
MeshRuntimeStore.getInstance().insertSessionDelivery({
|
|
39211
|
+
id,
|
|
39212
|
+
meshId: opts.meshId,
|
|
39213
|
+
nodeId: opts.nodeId,
|
|
39214
|
+
sessionId: opts.sessionId,
|
|
39215
|
+
providerType: opts.providerType,
|
|
39216
|
+
taskId: opts.taskId,
|
|
39217
|
+
kind: opts.kind,
|
|
39218
|
+
priority: opts.priority ?? 0,
|
|
39219
|
+
message: opts.message,
|
|
39220
|
+
status: opts.status,
|
|
39221
|
+
deliverAfter: opts.deliverAfter,
|
|
39222
|
+
expiresAt: opts.expiresAt,
|
|
39223
|
+
sourceCoordinatorSessionId: opts.sourceCoordinatorSessionId,
|
|
39224
|
+
sourceCoordinatorDaemonId: opts.sourceCoordinatorDaemonId,
|
|
39225
|
+
createdAt: now,
|
|
39226
|
+
updatedAt: now
|
|
39227
|
+
});
|
|
39228
|
+
return record2;
|
|
39229
|
+
}
|
|
39230
|
+
function updateSessionDeliveryStatus(id, status, opts) {
|
|
39231
|
+
try {
|
|
39232
|
+
MeshRuntimeStore.getInstance().updateSessionDeliveryStatus(id, status, opts);
|
|
39233
|
+
} catch {
|
|
39234
|
+
}
|
|
39235
|
+
}
|
|
39236
|
+
function getActiveSessionDeliveries(meshId, sessionId) {
|
|
39237
|
+
try {
|
|
39238
|
+
return MeshRuntimeStore.getInstance().getActiveSessionDeliveries(meshId, sessionId);
|
|
39239
|
+
} catch {
|
|
39240
|
+
return [];
|
|
39241
|
+
}
|
|
39242
|
+
}
|
|
39243
|
+
function recordCompletionConflict(opts) {
|
|
39244
|
+
try {
|
|
39245
|
+
MeshRuntimeStore.getInstance().recordCompletionConflict({
|
|
39246
|
+
id: (0, import_crypto6.randomUUID)(),
|
|
39247
|
+
meshId: opts.meshId,
|
|
39248
|
+
fingerprint: opts.fingerprint,
|
|
39249
|
+
conflictingTaskId: opts.conflictingTaskId,
|
|
39250
|
+
conflictingSessionId: opts.conflictingSessionId,
|
|
39251
|
+
originalTaskId: opts.originalTaskId,
|
|
39252
|
+
originalSessionId: opts.originalSessionId,
|
|
39253
|
+
event: opts.event,
|
|
39254
|
+
createdAt: (/* @__PURE__ */ new Date()).toISOString()
|
|
39255
|
+
});
|
|
39256
|
+
} catch {
|
|
39257
|
+
}
|
|
39258
|
+
}
|
|
39259
|
+
function getRecentCompletionConflicts(meshId, limitMs) {
|
|
39260
|
+
try {
|
|
39261
|
+
return MeshRuntimeStore.getInstance().getRecentCompletionConflicts(meshId, limitMs);
|
|
39262
|
+
} catch {
|
|
39263
|
+
return [];
|
|
39264
|
+
}
|
|
39265
|
+
}
|
|
39266
|
+
var import_crypto6;
|
|
39267
|
+
var IMMEDIATE_DELIVERY_STATUSES;
|
|
39268
|
+
var BUSY_DELIVERY_STATUSES;
|
|
39269
|
+
var TERMINAL_DELIVERY_STATUSES;
|
|
39270
|
+
var init_mesh_delivery_policy = __esm2({
|
|
39271
|
+
"src/mesh/mesh-delivery-policy.ts"() {
|
|
39272
|
+
"use strict";
|
|
39273
|
+
import_crypto6 = require("crypto");
|
|
39274
|
+
init_mesh_runtime_store();
|
|
39275
|
+
IMMEDIATE_DELIVERY_STATUSES = /* @__PURE__ */ new Set([
|
|
39276
|
+
"idle",
|
|
39277
|
+
"waiting_input",
|
|
39278
|
+
"ready"
|
|
39279
|
+
]);
|
|
39280
|
+
BUSY_DELIVERY_STATUSES = /* @__PURE__ */ new Set([
|
|
39281
|
+
"generating",
|
|
39282
|
+
"running",
|
|
39283
|
+
"streaming",
|
|
39284
|
+
"busy",
|
|
39285
|
+
"starting",
|
|
39286
|
+
"initializing",
|
|
39287
|
+
"waiting_approval"
|
|
39288
|
+
]);
|
|
39289
|
+
TERMINAL_DELIVERY_STATUSES = /* @__PURE__ */ new Set([
|
|
39290
|
+
"stopped",
|
|
39291
|
+
"failed",
|
|
39292
|
+
"terminated",
|
|
39293
|
+
"exited",
|
|
39294
|
+
"closed",
|
|
39295
|
+
"deleted",
|
|
39296
|
+
"error"
|
|
39297
|
+
]);
|
|
39298
|
+
}
|
|
39299
|
+
});
|
|
38952
39300
|
var mesh_events_exports = {};
|
|
38953
39301
|
__export2(mesh_events_exports, {
|
|
38954
39302
|
__resetIdleAutoFastForwardForTests: () => __resetIdleAutoFastForwardForTests,
|
|
@@ -38978,7 +39326,7 @@ Valid status values: \`completed\` | \`failed\` | \`blocked\` | \`partial\`.`;
|
|
|
38978
39326
|
}
|
|
38979
39327
|
function sweepExpiredRemoteIdleSessions() {
|
|
38980
39328
|
try {
|
|
38981
|
-
|
|
39329
|
+
MeshRuntimeStore.getInstance().pruneExpiredRemoteIdleSessions();
|
|
38982
39330
|
} catch {
|
|
38983
39331
|
}
|
|
38984
39332
|
}
|
|
@@ -39254,14 +39602,14 @@ Valid status values: \`completed\` | \`failed\` | \`blocked\` | \`partial\`.`;
|
|
|
39254
39602
|
}
|
|
39255
39603
|
function hasFingerprintSeen(fingerprint) {
|
|
39256
39604
|
try {
|
|
39257
|
-
return
|
|
39605
|
+
return MeshRuntimeStore.getInstance().hasCompletionFingerprint(fingerprint);
|
|
39258
39606
|
} catch {
|
|
39259
39607
|
return false;
|
|
39260
39608
|
}
|
|
39261
39609
|
}
|
|
39262
39610
|
function recordFingerprintSeen(fingerprint) {
|
|
39263
39611
|
try {
|
|
39264
|
-
const db =
|
|
39612
|
+
const db = MeshRuntimeStore.getInstance();
|
|
39265
39613
|
db.recordCompletionFingerprint(fingerprint, RECENT_COMPLETION_FINGERPRINT_TTL_MS);
|
|
39266
39614
|
db.sweepExpiredFingerprints();
|
|
39267
39615
|
} catch {
|
|
@@ -39292,7 +39640,18 @@ Valid status values: \`completed\` | \`failed\` | \`blocked\` | \`partial\`.`;
|
|
|
39292
39640
|
function isDuplicateMeshCompletionEvent(args) {
|
|
39293
39641
|
const fingerprint = buildMeshCompletionFingerprint(args);
|
|
39294
39642
|
if (!fingerprint) return false;
|
|
39295
|
-
if (hasFingerprintSeen(fingerprint))
|
|
39643
|
+
if (hasFingerprintSeen(fingerprint)) {
|
|
39644
|
+
if (args.taskId) {
|
|
39645
|
+
recordCompletionConflict({
|
|
39646
|
+
meshId: args.meshId,
|
|
39647
|
+
fingerprint,
|
|
39648
|
+
conflictingTaskId: args.taskId,
|
|
39649
|
+
conflictingSessionId: args.sessionId,
|
|
39650
|
+
event: args.event
|
|
39651
|
+
});
|
|
39652
|
+
}
|
|
39653
|
+
return true;
|
|
39654
|
+
}
|
|
39296
39655
|
recordFingerprintSeen(fingerprint);
|
|
39297
39656
|
return false;
|
|
39298
39657
|
}
|
|
@@ -39543,20 +39902,33 @@ Valid status values: \`completed\` | \`failed\` | \`blocked\` | \`partial\`.`;
|
|
|
39543
39902
|
if (node?.daemonId && components.dispatchMeshCommand) {
|
|
39544
39903
|
const isLocalNode = components.cliManager.adapters.has(sessionId);
|
|
39545
39904
|
if (!isLocalNode) {
|
|
39905
|
+
const delivery2 = createSessionDelivery({
|
|
39906
|
+
meshId,
|
|
39907
|
+
nodeId,
|
|
39908
|
+
sessionId,
|
|
39909
|
+
providerType,
|
|
39910
|
+
taskId: task.id,
|
|
39911
|
+
kind: "task",
|
|
39912
|
+
message: task.message,
|
|
39913
|
+
status: "delivering"
|
|
39914
|
+
});
|
|
39546
39915
|
components.dispatchMeshCommand(node.daemonId, "agent_command", {
|
|
39547
39916
|
targetSessionId: sessionId,
|
|
39548
39917
|
cliType: providerType,
|
|
39549
39918
|
action: "send_chat",
|
|
39550
39919
|
message: task.message
|
|
39920
|
+
}).then(() => {
|
|
39921
|
+
updateSessionDeliveryStatus(delivery2.id, "delivered");
|
|
39551
39922
|
}).catch((e) => {
|
|
39552
39923
|
LOG2.error("MeshQueue", `Failed to dispatch task via P2P to remote node ${nodeId}: ${e?.message}`);
|
|
39924
|
+
updateSessionDeliveryStatus(delivery2.id, "failed", { lastError: e?.message, incrementAttempt: true });
|
|
39553
39925
|
updateTaskStatus(meshId, task.id, "pending");
|
|
39554
39926
|
try {
|
|
39555
39927
|
appendLedgerEntry(meshId, {
|
|
39556
39928
|
kind: "dispatch_failed",
|
|
39557
39929
|
nodeId,
|
|
39558
39930
|
sessionId,
|
|
39559
|
-
payload: { taskId: task.id, error: e?.message, retryable: true }
|
|
39931
|
+
payload: { taskId: task.id, deliveryId: delivery2.id, error: e?.message, retryable: true }
|
|
39560
39932
|
});
|
|
39561
39933
|
} catch {
|
|
39562
39934
|
}
|
|
@@ -39564,13 +39936,26 @@ Valid status values: \`completed\` | \`failed\` | \`blocked\` | \`partial\`.`;
|
|
|
39564
39936
|
return true;
|
|
39565
39937
|
}
|
|
39566
39938
|
}
|
|
39939
|
+
const delivery = createSessionDelivery({
|
|
39940
|
+
meshId,
|
|
39941
|
+
nodeId,
|
|
39942
|
+
sessionId,
|
|
39943
|
+
providerType,
|
|
39944
|
+
taskId: task.id,
|
|
39945
|
+
kind: "task",
|
|
39946
|
+
message: task.message,
|
|
39947
|
+
status: "delivering"
|
|
39948
|
+
});
|
|
39567
39949
|
components.cliManager.handleCliCommand("agent_command", {
|
|
39568
39950
|
targetSessionId: sessionId,
|
|
39569
39951
|
cliType: providerType,
|
|
39570
39952
|
action: "send_chat",
|
|
39571
39953
|
message: task.message
|
|
39954
|
+
}).then(() => {
|
|
39955
|
+
updateSessionDeliveryStatus(delivery.id, "delivered");
|
|
39572
39956
|
}).catch((e) => {
|
|
39573
39957
|
LOG2.error("MeshQueue", `Failed to dispatch task locally to node ${nodeId}: ${e?.message}`);
|
|
39958
|
+
updateSessionDeliveryStatus(delivery.id, "failed", { lastError: e?.message, incrementAttempt: true });
|
|
39574
39959
|
updateTaskStatus(meshId, task.id, "failed");
|
|
39575
39960
|
});
|
|
39576
39961
|
return true;
|
|
@@ -39881,7 +40266,7 @@ Valid status values: \`completed\` | \`failed\` | \`blocked\` | \`partial\`.`;
|
|
|
39881
40266
|
}
|
|
39882
40267
|
let remoteSessions = [];
|
|
39883
40268
|
try {
|
|
39884
|
-
remoteSessions =
|
|
40269
|
+
remoteSessions = MeshRuntimeStore.getInstance().getRemoteIdleSessions();
|
|
39885
40270
|
} catch {
|
|
39886
40271
|
}
|
|
39887
40272
|
for (const idle of remoteSessions) {
|
|
@@ -39891,7 +40276,7 @@ Valid status values: \`completed\` | \`failed\` | \`blocked\` | \`partial\`.`;
|
|
|
39891
40276
|
const assigned = tryAssignQueueTask(components, meshId, idle.nodeId, idle.sessionId, idle.providerType);
|
|
39892
40277
|
if (assigned) {
|
|
39893
40278
|
try {
|
|
39894
|
-
|
|
40279
|
+
MeshRuntimeStore.getInstance().deleteRemoteIdleSession(idle.nodeId, idle.sessionId);
|
|
39895
40280
|
} catch {
|
|
39896
40281
|
}
|
|
39897
40282
|
}
|
|
@@ -40093,7 +40478,7 @@ Next step: ${nextStep}`;
|
|
|
40093
40478
|
if (intentionalCleanupStop) {
|
|
40094
40479
|
if (eventSessionId && eventNodeId) {
|
|
40095
40480
|
try {
|
|
40096
|
-
|
|
40481
|
+
MeshRuntimeStore.getInstance().deleteRemoteIdleSession(eventNodeId, eventSessionId);
|
|
40097
40482
|
} catch {
|
|
40098
40483
|
}
|
|
40099
40484
|
}
|
|
@@ -40175,7 +40560,9 @@ Next step: ${nextStep}`;
|
|
|
40175
40560
|
finalSummary: readNonEmptyString2(args.metadataEvent.finalSummary) || void 0,
|
|
40176
40561
|
// Scope dedup to the coordinator daemon so two coordinators for the same mesh
|
|
40177
40562
|
// don't suppress each other's completion events via shared fingerprint table.
|
|
40178
|
-
coordinatorDaemonId: workerCoordinatorDaemonId || void 0
|
|
40563
|
+
coordinatorDaemonId: workerCoordinatorDaemonId || void 0,
|
|
40564
|
+
taskId: readNonEmptyString2(args.metadataEvent.taskId) || void 0,
|
|
40565
|
+
nodeId: eventNodeId || void 0
|
|
40179
40566
|
});
|
|
40180
40567
|
if (duplicateCompletion) {
|
|
40181
40568
|
LOG2.info("MeshEvents", `Suppressed duplicate completion for mesh ${args.meshId} session ${eventSessionId}`);
|
|
@@ -40191,7 +40578,9 @@ Next step: ${nextStep}`;
|
|
|
40191
40578
|
providerSessionId: readNonEmptyString2(args.metadataEvent.providerSessionId) || void 0,
|
|
40192
40579
|
timestamp: eventTimestamp,
|
|
40193
40580
|
finalSummary: readNonEmptyString2(args.metadataEvent.finalSummary) || void 0,
|
|
40194
|
-
coordinatorDaemonId: workerCoordinatorDaemonId || void 0
|
|
40581
|
+
coordinatorDaemonId: workerCoordinatorDaemonId || void 0,
|
|
40582
|
+
taskId: readNonEmptyString2(args.metadataEvent.taskId) || void 0,
|
|
40583
|
+
nodeId: eventNodeId || void 0
|
|
40195
40584
|
});
|
|
40196
40585
|
if (duplicateStopped) {
|
|
40197
40586
|
LOG2.info("MeshEvents", `Suppressed duplicate stopped event for mesh ${args.meshId} session ${eventSessionId}`);
|
|
@@ -40261,14 +40650,14 @@ Next step: ${nextStep}`;
|
|
|
40261
40650
|
if (sessionId && nodeId && providerType) {
|
|
40262
40651
|
sweepExpiredRemoteIdleSessions();
|
|
40263
40652
|
try {
|
|
40264
|
-
|
|
40653
|
+
MeshRuntimeStore.getInstance().setRemoteIdleSession(nodeId, sessionId, providerType, Date.now() + REMOTE_IDLE_SESSION_TTL_MS);
|
|
40265
40654
|
} catch {
|
|
40266
40655
|
}
|
|
40267
40656
|
setImmediate(() => {
|
|
40268
40657
|
maybeAutoFastForwardIdleNode(components, { meshId: args.meshId, nodeId, sessionId, providerType }).finally(() => {
|
|
40269
40658
|
try {
|
|
40270
40659
|
const assigned = tryAssignQueueTask(components, args.meshId, nodeId, sessionId, providerType);
|
|
40271
|
-
if (assigned)
|
|
40660
|
+
if (assigned) MeshRuntimeStore.getInstance().deleteRemoteIdleSession(nodeId, sessionId);
|
|
40272
40661
|
} catch (e) {
|
|
40273
40662
|
LOG2.warn("MeshQueue", `Failed to assign idle queue task after maintenance for ${nodeId}: ${e?.message || e}`);
|
|
40274
40663
|
}
|
|
@@ -40280,7 +40669,7 @@ Next step: ${nextStep}`;
|
|
|
40280
40669
|
const nodeId = readNonEmptyString2(args.nodeId) || readNonEmptyString2(args.metadataEvent.meshNodeId);
|
|
40281
40670
|
if (sessionId && nodeId) {
|
|
40282
40671
|
try {
|
|
40283
|
-
|
|
40672
|
+
MeshRuntimeStore.getInstance().deleteRemoteIdleSession(nodeId, sessionId);
|
|
40284
40673
|
} catch {
|
|
40285
40674
|
}
|
|
40286
40675
|
}
|
|
@@ -40292,7 +40681,7 @@ Next step: ${nextStep}`;
|
|
|
40292
40681
|
const nodeId = readNonEmptyString2(args.nodeId) || readNonEmptyString2(args.metadataEvent.meshNodeId);
|
|
40293
40682
|
if (sessionId && nodeId) {
|
|
40294
40683
|
try {
|
|
40295
|
-
|
|
40684
|
+
MeshRuntimeStore.getInstance().deleteRemoteIdleSession(nodeId, sessionId);
|
|
40296
40685
|
} catch {
|
|
40297
40686
|
}
|
|
40298
40687
|
}
|
|
@@ -40582,8 +40971,9 @@ Next step: ${nextStep}`;
|
|
|
40582
40971
|
init_logger();
|
|
40583
40972
|
init_mesh_ledger();
|
|
40584
40973
|
init_mesh_work_queue();
|
|
40585
|
-
|
|
40974
|
+
init_mesh_runtime_store();
|
|
40586
40975
|
init_mesh_fast_forward();
|
|
40976
|
+
init_mesh_delivery_policy();
|
|
40587
40977
|
REMOTE_IDLE_SESSION_TTL_MS = 5 * 60 * 1e3;
|
|
40588
40978
|
meshByWorkspaceCache = /* @__PURE__ */ new Map();
|
|
40589
40979
|
MESH_WORKSPACE_CACHE_TTL_MS = 5e3;
|
|
@@ -43527,11 +43917,12 @@ ${cont}` : cont;
|
|
|
43527
43917
|
}
|
|
43528
43918
|
applyGenerating(ctx) {
|
|
43529
43919
|
const { modal, parsedMessages, lastParsedAssistant, parsedStatus, prevStatus } = ctx;
|
|
43920
|
+
const noActiveTurn = !this.currentTurnScope;
|
|
43921
|
+
if (!this.isWaitingForResponse && noActiveTurn && !modal) return;
|
|
43530
43922
|
this.clearIdleFinishCandidate("generating");
|
|
43531
43923
|
this.cancelPendingIdleFinish("generating_signal_returned");
|
|
43532
43924
|
const snap = this.transport.getSnapshot();
|
|
43533
43925
|
const effectiveScreenText = snap.screenText || snap.accumulatedBuffer;
|
|
43534
|
-
const noActiveTurn = !this.currentTurnScope;
|
|
43535
43926
|
const looksIdleChrome = /(^|\n)\s*[❯›>]\s*(?:\n|$)/m.test(effectiveScreenText);
|
|
43536
43927
|
const parsedShowsLiveProgress = parsedStatus === "generating" && !!lastParsedAssistant;
|
|
43537
43928
|
if (prevStatus === "idle" && !this.isWaitingForResponse && noActiveTurn && !modal && looksIdleChrome && !parsedShowsLiveProgress) return;
|
|
@@ -43791,7 +44182,25 @@ ${cont}` : cont;
|
|
|
43791
44182
|
const parsedStatus = typeof parsed?.status === "string" ? parsed.status.trim() : "";
|
|
43792
44183
|
if (parsedStatus !== "idle") return true;
|
|
43793
44184
|
if (parsed?.activeModal || parsed?.modal) return true;
|
|
43794
|
-
|
|
44185
|
+
const messages = Array.isArray(parsed?.messages) ? parsed.messages : [];
|
|
44186
|
+
let lastUserIdx = -1;
|
|
44187
|
+
for (let i = messages.length - 1; i >= 0; i--) {
|
|
44188
|
+
if (messages[i]?.role === "user") {
|
|
44189
|
+
lastUserIdx = i;
|
|
44190
|
+
break;
|
|
44191
|
+
}
|
|
44192
|
+
}
|
|
44193
|
+
if (lastUserIdx < 0) {
|
|
44194
|
+
if (messages.length === 0) return false;
|
|
44195
|
+
return !this.parsedStatusHasFinalStandardAssistantMessage(parsed);
|
|
44196
|
+
}
|
|
44197
|
+
const hasCurrentTurnAssistant = messages.slice(lastUserIdx + 1).some((m) => {
|
|
44198
|
+
if (!m || m.role !== "assistant") return false;
|
|
44199
|
+
if (typeof m.content !== "string" || !m.content.trim()) return false;
|
|
44200
|
+
const kind = typeof m.kind === "string" && m.kind.trim() ? m.kind.trim() : "standard";
|
|
44201
|
+
return kind === "standard" && m.meta?.streaming !== true;
|
|
44202
|
+
});
|
|
44203
|
+
return !hasCurrentTurnAssistant;
|
|
43795
44204
|
}
|
|
43796
44205
|
rescheduleTranscriptFinishCheck(reason) {
|
|
43797
44206
|
this.clearIdleFinishCandidate(reason);
|
|
@@ -46123,6 +46532,7 @@ ${lastSnapshot}`;
|
|
|
46123
46532
|
createInteractionId: () => createInteractionId,
|
|
46124
46533
|
createMesh: () => createMesh,
|
|
46125
46534
|
createNativeHistoryDispatcher: () => createNativeHistoryDispatcher,
|
|
46535
|
+
createSessionDelivery: () => createSessionDelivery,
|
|
46126
46536
|
createWorktree: () => createWorktree,
|
|
46127
46537
|
deleteMesh: () => deleteMesh,
|
|
46128
46538
|
detectAllVersions: () => detectAllVersions,
|
|
@@ -46146,6 +46556,7 @@ ${lastSnapshot}`;
|
|
|
46146
46556
|
forwardAgentStreamsToIdeInstance: () => forwardAgentStreamsToIdeInstance2,
|
|
46147
46557
|
getAIExtensions: () => getAIExtensions,
|
|
46148
46558
|
getActiveDirectDispatches: () => getActiveDirectDispatches,
|
|
46559
|
+
getActiveSessionDeliveries: () => getActiveSessionDeliveries,
|
|
46149
46560
|
getAvailableIdeIds: () => getAvailableIdeIds,
|
|
46150
46561
|
getCoordinatorForSession: () => getCoordinatorForSession,
|
|
46151
46562
|
getCurrentDaemonLogPath: () => getCurrentDaemonLogPath,
|
|
@@ -46168,6 +46579,7 @@ ${lastSnapshot}`;
|
|
|
46168
46579
|
getQueue: () => getQueue,
|
|
46169
46580
|
getRecentActivity: () => getRecentActivity,
|
|
46170
46581
|
getRecentCommands: () => getRecentCommands,
|
|
46582
|
+
getRecentCompletionConflicts: () => getRecentCompletionConflicts,
|
|
46171
46583
|
getRecentDebugTrace: () => getRecentDebugTrace,
|
|
46172
46584
|
getRecentLogs: () => getRecentLogs,
|
|
46173
46585
|
getSavedProviderSessions: () => getSavedProviderSessions,
|
|
@@ -46255,6 +46667,7 @@ ${lastSnapshot}`;
|
|
|
46255
46667
|
readLedgerEntries: () => readLedgerEntries,
|
|
46256
46668
|
readLedgerSlice: () => readLedgerSlice,
|
|
46257
46669
|
reconcileDirectDispatchCompletionFromTranscript: () => reconcileDirectDispatchCompletionFromTranscript,
|
|
46670
|
+
recordCompletionConflict: () => recordCompletionConflict,
|
|
46258
46671
|
recordDebugTrace: () => recordDebugTrace,
|
|
46259
46672
|
registerExtensionProviders: () => registerExtensionProviders,
|
|
46260
46673
|
registerMeshCoordinator: () => registerMeshCoordinator,
|
|
@@ -46268,6 +46681,7 @@ ${lastSnapshot}`;
|
|
|
46268
46681
|
resolveChatMessageKind: () => resolveChatMessageKind,
|
|
46269
46682
|
resolveCurrentGlobalInstallSurface: () => resolveCurrentGlobalInstallSurface,
|
|
46270
46683
|
resolveDebugRuntimeConfig: () => resolveDebugRuntimeConfig,
|
|
46684
|
+
resolveDeliveryDecision: () => resolveDeliveryDecision,
|
|
46271
46685
|
resolveGitRepository: () => resolveGitRepository,
|
|
46272
46686
|
resolveMeshHostStatus: () => resolveMeshHostStatus,
|
|
46273
46687
|
resolveMeshRefineValidationPlan: () => resolveMeshRefineValidationPlan,
|
|
@@ -46297,6 +46711,7 @@ ${lastSnapshot}`;
|
|
|
46297
46711
|
updateDirectDispatchStatus: () => updateDirectDispatchStatus,
|
|
46298
46712
|
updateMesh: () => updateMesh,
|
|
46299
46713
|
updateNode: () => updateNode,
|
|
46714
|
+
updateSessionDeliveryStatus: () => updateSessionDeliveryStatus,
|
|
46300
46715
|
updateSessionTaskStatus: () => updateSessionTaskStatus,
|
|
46301
46716
|
updateTaskStatus: () => updateTaskStatus,
|
|
46302
46717
|
upsertSavedProviderSession: () => upsertSavedProviderSession,
|
|
@@ -46567,14 +46982,19 @@ ${lastSnapshot}`;
|
|
|
46567
46982
|
if (question.multiSelect) throw new Error("Claude TUI multi-select prompts are not supported yet");
|
|
46568
46983
|
const answer = response.answers[question.questionId];
|
|
46569
46984
|
if (!answer) throw new Error(`Missing answer for ${question.questionId}`);
|
|
46570
|
-
|
|
46571
|
-
if (
|
|
46572
|
-
|
|
46573
|
-
|
|
46574
|
-
|
|
46575
|
-
steps.push(
|
|
46985
|
+
const freeformText = answer.freeformText?.trim() ?? "";
|
|
46986
|
+
if (freeformText) {
|
|
46987
|
+
const typeOptionIndex = question.options.findIndex((o) => /^Type something\.?$/i.test(o.label));
|
|
46988
|
+
const optionNumber = typeOptionIndex >= 0 ? typeOptionIndex + 1 : question.options.length;
|
|
46989
|
+
steps.push(String(optionNumber));
|
|
46990
|
+
for (const ch of freeformText) steps.push(ch);
|
|
46991
|
+
steps.push("\r");
|
|
46992
|
+
} else {
|
|
46993
|
+
if (answer.selectedLabels.length !== 1) throw new Error(`Expected one selected label for ${question.questionId}`);
|
|
46994
|
+
const selectedIndex = question.options.findIndex((option) => option.label === answer.selectedLabels[0]);
|
|
46995
|
+
if (selectedIndex < 0) throw new Error(`Unknown option for ${question.questionId}: ${answer.selectedLabels[0]}`);
|
|
46996
|
+
steps.push(String(selectedIndex + 1));
|
|
46576
46997
|
}
|
|
46577
|
-
steps.push("\r");
|
|
46578
46998
|
}
|
|
46579
46999
|
steps.push("\r");
|
|
46580
47000
|
return steps;
|
|
@@ -49091,6 +49511,7 @@ ${lastSnapshot}`;
|
|
|
49091
49511
|
}
|
|
49092
49512
|
init_mesh_host_ownership();
|
|
49093
49513
|
init_mesh_events();
|
|
49514
|
+
init_mesh_delivery_policy();
|
|
49094
49515
|
var NO_FALLBACK_REASON = "Repo Mesh command/data-plane is P2P-only; WS/REST command fallback is intentionally disabled to preserve the transport boundary.";
|
|
49095
49516
|
var P2P_NEXT_ACTION = "Check daemon/P2P health, wait briefly for connection establishment, then do one bounded retry or requeue the mesh task after clearing stale target session metadata.";
|
|
49096
49517
|
var NON_P2P_NEXT_ACTION = "Inspect the provider/command error and fix the underlying logic or configuration before retrying.";
|
|
@@ -54797,6 +55218,7 @@ ${effect.notification.body || ""}`.trim();
|
|
|
54797
55218
|
if (hasApprovalButtons(opts?.activeModal)) return "waiting_approval";
|
|
54798
55219
|
const normalized = String(status || "idle").trim().toLowerCase();
|
|
54799
55220
|
if (normalized === "waiting_approval") return "waiting_approval";
|
|
55221
|
+
if (normalized === "waiting_choice") return "waiting_choice";
|
|
54800
55222
|
if (WORKING_STATUSES.has(normalized)) return "generating";
|
|
54801
55223
|
if (normalized === "error") return "error";
|
|
54802
55224
|
if (normalized === "stopped") return "stopped";
|
|
@@ -60765,10 +61187,47 @@ ${formatManifestValidationIssues2(validation.issues)}`,
|
|
|
60765
61187
|
for (const sec of spec.layout.sections) {
|
|
60766
61188
|
let from = 0;
|
|
60767
61189
|
let to = total;
|
|
60768
|
-
if (sec.
|
|
61190
|
+
if (sec.anchor_regex !== void 0) {
|
|
61191
|
+
try {
|
|
61192
|
+
const re = new RegExp(sec.anchor_regex, sec.anchor_flags ?? "");
|
|
61193
|
+
const prevRe = sec.anchor_context?.prev !== void 0 ? new RegExp(sec.anchor_context.prev, sec.anchor_context.prev_flags ?? "") : null;
|
|
61194
|
+
const nextRe = sec.anchor_context?.next !== void 0 ? new RegExp(sec.anchor_context.next, sec.anchor_context.next_flags ?? "") : null;
|
|
61195
|
+
const matches = (i) => re.test(lines[i]) && (prevRe === null || i > 0 && prevRe.test(lines[i - 1])) && (nextRe === null || i < total - 1 && nextRe.test(lines[i + 1]));
|
|
61196
|
+
let idx = -1;
|
|
61197
|
+
if (sec.anchor_last) {
|
|
61198
|
+
for (let i = total - 1; i >= 0; i--) {
|
|
61199
|
+
if (matches(i)) {
|
|
61200
|
+
idx = i;
|
|
61201
|
+
break;
|
|
61202
|
+
}
|
|
61203
|
+
}
|
|
61204
|
+
} else {
|
|
61205
|
+
for (let i = 0; i < total; i++) {
|
|
61206
|
+
if (matches(i)) {
|
|
61207
|
+
idx = i;
|
|
61208
|
+
break;
|
|
61209
|
+
}
|
|
61210
|
+
}
|
|
61211
|
+
}
|
|
61212
|
+
if (idx !== -1) {
|
|
61213
|
+
from = idx;
|
|
61214
|
+
to = total;
|
|
61215
|
+
if (sec.until_regex !== void 0) {
|
|
61216
|
+
try {
|
|
61217
|
+
const ure = new RegExp(sec.until_regex, sec.until_regex_flags ?? "");
|
|
61218
|
+
const end = lines.findIndex((l, i) => i > idx && ure.test(l));
|
|
61219
|
+
if (end !== -1) to = end;
|
|
61220
|
+
} catch {
|
|
61221
|
+
}
|
|
61222
|
+
} else if (sec.lines !== void 0) {
|
|
61223
|
+
to = Math.min(total, from + sec.lines);
|
|
61224
|
+
}
|
|
61225
|
+
}
|
|
61226
|
+
} catch {
|
|
61227
|
+
}
|
|
61228
|
+
} else if (sec.from_top !== void 0) {
|
|
60769
61229
|
from = resolveSize(sec.from_top, total);
|
|
60770
|
-
}
|
|
60771
|
-
if (sec.from_bottom !== void 0) {
|
|
61230
|
+
} else if (sec.from_bottom !== void 0) {
|
|
60772
61231
|
const sz = resolveSize(sec.from_bottom, total);
|
|
60773
61232
|
from = total - sz;
|
|
60774
61233
|
to = total;
|
|
@@ -61082,6 +61541,9 @@ ${formatManifestValidationIssues2(validation.issues)}`,
|
|
|
61082
61541
|
"type": "string",
|
|
61083
61542
|
"minLength": 1
|
|
61084
61543
|
},
|
|
61544
|
+
"requiresFinalAssistantBeforeIdle": {
|
|
61545
|
+
"type": "boolean"
|
|
61546
|
+
},
|
|
61085
61547
|
"debounce": {
|
|
61086
61548
|
"type": "object",
|
|
61087
61549
|
"additionalProperties": false,
|
|
@@ -61096,7 +61558,8 @@ ${formatManifestValidationIssues2(validation.issues)}`,
|
|
|
61096
61558
|
"section": { "type": "string", "minLength": 1 },
|
|
61097
61559
|
"regex": { "type": "string", "minLength": 1 },
|
|
61098
61560
|
"flags": { "type": "string" },
|
|
61099
|
-
"hold_ms": { "type": "integer", "minimum": 0 }
|
|
61561
|
+
"hold_ms": { "type": "integer", "minimum": 0 },
|
|
61562
|
+
"force_after_ms": { "type": "integer", "minimum": 0 }
|
|
61100
61563
|
}
|
|
61101
61564
|
}
|
|
61102
61565
|
}
|
|
@@ -61144,7 +61607,23 @@ ${formatManifestValidationIssues2(validation.issues)}`,
|
|
|
61144
61607
|
"type": "string"
|
|
61145
61608
|
}
|
|
61146
61609
|
}
|
|
61147
|
-
}
|
|
61610
|
+
},
|
|
61611
|
+
"anchor_regex": { "type": "string", "minLength": 1 },
|
|
61612
|
+
"anchor_flags": { "type": "string" },
|
|
61613
|
+
"anchor_last": { "type": "boolean" },
|
|
61614
|
+
"anchor_context": {
|
|
61615
|
+
"type": "object",
|
|
61616
|
+
"additionalProperties": false,
|
|
61617
|
+
"properties": {
|
|
61618
|
+
"prev": { "type": "string" },
|
|
61619
|
+
"prev_flags": { "type": "string" },
|
|
61620
|
+
"next": { "type": "string" },
|
|
61621
|
+
"next_flags": { "type": "string" }
|
|
61622
|
+
}
|
|
61623
|
+
},
|
|
61624
|
+
"lines": { "type": "integer", "minimum": 1 },
|
|
61625
|
+
"until_regex": { "type": "string", "minLength": 1 },
|
|
61626
|
+
"until_regex_flags": { "type": "string" }
|
|
61148
61627
|
}
|
|
61149
61628
|
},
|
|
61150
61629
|
"sectionRegex": {
|
|
@@ -61576,6 +62055,7 @@ ${formatManifestValidationIssues2(validation.issues)}`,
|
|
|
61576
62055
|
function resolveSpecPath(providerDir) {
|
|
61577
62056
|
return path18.join(providerDir, "spec.json");
|
|
61578
62057
|
}
|
|
62058
|
+
init_logger();
|
|
61579
62059
|
var STARTUP_GRACE_MS = 2500;
|
|
61580
62060
|
var BUSY_HOLD_MS = 6e3;
|
|
61581
62061
|
var SUBMIT_DELAY_FLOOR_MS = 200;
|
|
@@ -61603,9 +62083,16 @@ ${formatManifestValidationIssues2(validation.issues)}`,
|
|
|
61603
62083
|
return null;
|
|
61604
62084
|
}
|
|
61605
62085
|
}
|
|
61606
|
-
function matchesCompletionIdleTargetState(spec, ev, screen) {
|
|
62086
|
+
function matchesCompletionIdleTargetState(spec, ev, screen, cursor) {
|
|
61607
62087
|
const target = spec.states.find((state) => state.id === spec.default_state) ?? spec.states.find((state) => state.id === "idle");
|
|
61608
|
-
if (!target?.when
|
|
62088
|
+
if (!target?.when) return false;
|
|
62089
|
+
const hasCursorGuard = target.when.cursor_row_min !== void 0 || target.when.cursor_row_max !== void 0 || target.when.cursor_col_min !== void 0 || target.when.cursor_col_max !== void 0;
|
|
62090
|
+
if (hasCursorGuard && cursor !== void 0) {
|
|
62091
|
+
const { cursor_row_min, cursor_row_max, cursor_col_min, cursor_col_max } = target.when;
|
|
62092
|
+
const cursorOk = (cursor_row_min === void 0 || cursor.row >= cursor_row_min) && (cursor_row_max === void 0 || cursor.row <= cursor_row_max) && (cursor_col_min === void 0 || cursor.col >= cursor_col_min) && (cursor_col_max === void 0 || cursor.col <= cursor_col_max);
|
|
62093
|
+
if (cursorOk) return true;
|
|
62094
|
+
}
|
|
62095
|
+
if (!target.when.regex) return false;
|
|
61609
62096
|
const haystack = target.when.section ? ev.sections.find((section) => section.id === target.when.section)?.text ?? "" : screen;
|
|
61610
62097
|
if (!haystack) return false;
|
|
61611
62098
|
try {
|
|
@@ -61767,6 +62254,7 @@ ${formatManifestValidationIssues2(validation.issues)}`,
|
|
|
61767
62254
|
if (this.busyExpiryTimer) clearTimeout(this.busyExpiryTimer);
|
|
61768
62255
|
this.busyExpiryTimer = setTimeout(() => {
|
|
61769
62256
|
this.busyExpiryTimer = null;
|
|
62257
|
+
LOG2.debug("SpecDriver", `[${this.opts.specPath.split("/").slice(-3).join("/")}] busyExpiry fired holdMs=${holdMs}`);
|
|
61770
62258
|
this.reevaluate();
|
|
61771
62259
|
}, Math.max(holdMs + 50, 100));
|
|
61772
62260
|
}
|
|
@@ -61791,11 +62279,16 @@ ${formatManifestValidationIssues2(validation.issues)}`,
|
|
|
61791
62279
|
if (completionKey !== this.completionIdleKey) {
|
|
61792
62280
|
this.completionIdleKey = completionKey;
|
|
61793
62281
|
this.completionIdleFirstSeenAt = now;
|
|
62282
|
+
LOG2.debug("SpecDriver", `[${this.opts.specPath.split("/").slice(-3).join("/")}] completion_idle_after matched: key="${completionKey}"`);
|
|
61794
62283
|
}
|
|
61795
62284
|
const holdMs = Math.max(0, completionIdleRule.hold_ms || 0);
|
|
62285
|
+
const forceAfterMs = typeof completionIdleRule.force_after_ms === "number" ? completionIdleRule.force_after_ms : null;
|
|
61796
62286
|
const ageMs = now - this.completionIdleFirstSeenAt;
|
|
61797
62287
|
if (ageMs >= holdMs) {
|
|
61798
|
-
|
|
62288
|
+
const targetMatches = matchesCompletionIdleTargetState(this.spec, ev, screen, cursor);
|
|
62289
|
+
const forced = !targetMatches && forceAfterMs !== null && ageMs >= holdMs + forceAfterMs;
|
|
62290
|
+
LOG2.debug("SpecDriver", `[${this.opts.specPath.split("/").slice(-3).join("/")}] completion_idle_after hold expired ageMs=${ageMs} targetState=${targetMatches} forced=${forced} screenTail="${screen.split(/\r?\n/).slice(-3).join("\\n").slice(-200)}"`);
|
|
62291
|
+
if (targetMatches || forced) {
|
|
61799
62292
|
const idle = this.spec.states.find((state) => state.id === this.spec.default_state) ?? this.spec.states.find((state) => state.id === "idle");
|
|
61800
62293
|
evState = idle ? { id: idle.id, label: idle.label, title: null } : { id: "idle", label: "Ready", title: null };
|
|
61801
62294
|
} else {
|
|
@@ -62926,16 +63419,19 @@ ${formatManifestValidationIssues2(validation.issues)}`,
|
|
|
62926
63419
|
controlValues: this.controlValues
|
|
62927
63420
|
});
|
|
62928
63421
|
const activeChatStatus = parseErrorMessage ? "error" : autoApproveActive && parsedStatus?.status === "waiting_approval" ? "generating" : adapterStatus.status !== "idle" ? visibleStatus : suppressStaleParsedBusyStatus ? visibleStatus : parsedChatStatus || visibleStatus;
|
|
63422
|
+
const hasInteractivePrompt = !!this.activeInteractivePrompt;
|
|
63423
|
+
const finalStatus = hasInteractivePrompt ? "waiting_choice" : visibleStatus;
|
|
63424
|
+
const finalChatStatus = hasInteractivePrompt ? "waiting_choice" : activeChatStatus;
|
|
62929
63425
|
return {
|
|
62930
63426
|
type: this.type,
|
|
62931
63427
|
name: this.provider.name,
|
|
62932
63428
|
category: "cli",
|
|
62933
|
-
status:
|
|
63429
|
+
status: finalStatus,
|
|
62934
63430
|
mode: this.presentationMode,
|
|
62935
63431
|
activeChat: {
|
|
62936
63432
|
id: activeChatId,
|
|
62937
63433
|
title: parsedStatus?.title || dirName,
|
|
62938
|
-
status:
|
|
63434
|
+
status: finalChatStatus,
|
|
62939
63435
|
messages: statusMessages,
|
|
62940
63436
|
activeModal: autoApproveActive ? null : parsedStatus?.activeModal ?? adapterStatus.activeModal,
|
|
62941
63437
|
activeInteractivePrompt: this.activeInteractivePrompt,
|
|
@@ -63406,6 +63902,7 @@ ${formatManifestValidationIssues2(validation.issues)}`,
|
|
|
63406
63902
|
const adapterOwnsMessagesElsewhere = this.adapter?.chatMessagesOwnedExternally === true;
|
|
63407
63903
|
const finalAssistantEvidence = this.completionFinalAssistantEvidence(parsed?.messages);
|
|
63408
63904
|
const allowMissingAssistantTimeout = !!(this.settings.meshNodeFor || this.settings.meshActiveTaskId || this.settings.launchedByCoordinator);
|
|
63905
|
+
LOG2.debug("CLI", `[${this.type}] finalAssistantEvidence: present=${finalAssistantEvidence.present} source=${finalAssistantEvidence.source} adapterOwnsMessagesElsewhere=${adapterOwnsMessagesElsewhere} parsedStatus=${parsedStatus}`);
|
|
63409
63906
|
if (!finalAssistantEvidence.present) {
|
|
63410
63907
|
if (adapterOwnsMessagesElsewhere) {
|
|
63411
63908
|
if (finalAssistantEvidence.source === "external-native") {
|
|
@@ -63414,6 +63911,10 @@ ${formatManifestValidationIssues2(validation.issues)}`,
|
|
|
63414
63911
|
LOG2.info("CLI", `[${this.type}] external transcript probe: msgCount=${probe.msgCount} lastRole=${probe.lastRole || "none"} lastKind=${probe.lastKind || "none"} contentLen=${probe.contentLen} sourceMtime=${probe.sourceMtimeMs ?? "unknown"} mtimeAge=${probe.mtimeAgeMs ?? "unknown"}ms`);
|
|
63415
63912
|
pending.loggedTranscriptProbe = true;
|
|
63416
63913
|
}
|
|
63914
|
+
LOG2.debug("CLI", `[${this.type}] external-native probe result: lastRole=${probe?.lastRole} contentLen=${probe?.contentLen}`);
|
|
63915
|
+
if (probe?.lastRole === "assistant" && (probe.contentLen ?? 0) > 0) {
|
|
63916
|
+
return null;
|
|
63917
|
+
}
|
|
63417
63918
|
if (this.type === "antigravity-cli") {
|
|
63418
63919
|
return null;
|
|
63419
63920
|
}
|
|
@@ -63423,6 +63924,7 @@ ${formatManifestValidationIssues2(validation.issues)}`,
|
|
|
63423
63924
|
return { reason: "missing_final_assistant", terminal: true, allowTimeout: allowMissingAssistantTimeout };
|
|
63424
63925
|
}
|
|
63425
63926
|
} else {
|
|
63927
|
+
LOG2.debug("CLI", `[${this.type}] missing_final_assistant (not ownsExternal) requiresFinalAssistant=${!!this.provider.requiresFinalAssistantBeforeIdle}`);
|
|
63426
63928
|
return {
|
|
63427
63929
|
reason: "missing_final_assistant",
|
|
63428
63930
|
terminal: this.provider.requiresFinalAssistantBeforeIdle === true,
|
|
@@ -63456,6 +63958,7 @@ ${formatManifestValidationIssues2(validation.issues)}`,
|
|
|
63456
63958
|
const latestAutoApproveActive = latestStatus.status === "waiting_approval" && this.shouldAutoApprove();
|
|
63457
63959
|
const externalNativeFinal = this.getExternalNativeFinalReconciliation(void 0, latestStatus);
|
|
63458
63960
|
const latestVisibleStatus = externalNativeFinal && isCliGeneratingLikeStatus(latestStatus.status) ? "idle" : latestAutoApproveActive ? "generating" : latestStatus.status;
|
|
63961
|
+
LOG2.debug("CLI", `[${this.type}] flush attempt: adapterStatus=${latestStatus.status} latestVisible=${latestVisibleStatus} externalNativeFinal=${!!externalNativeFinal} generatingStartedAt=${this.generatingStartedAt} isWaitingForResponse=${!!this.adapter?.isWaitingForResponse} hasPartial=${!!this.adapter.getPartialResponse?.()}`);
|
|
63459
63962
|
if (latestVisibleStatus !== "idle") {
|
|
63460
63963
|
LOG2.info("CLI", `[${this.type}] cancelled pending completed (resumed ${latestVisibleStatus})`);
|
|
63461
63964
|
this.completedDebouncePending = null;
|
|
@@ -63466,6 +63969,7 @@ ${formatManifestValidationIssues2(validation.issues)}`,
|
|
|
63466
63969
|
if (block2) {
|
|
63467
63970
|
const blockReason = block2.reason;
|
|
63468
63971
|
const waitedMs = Date.now() - pending.firstObservedAt;
|
|
63972
|
+
LOG2.debug("CLI", `[${this.type}] finalization block: reason=${blockReason} terminal=${block2.terminal} waitedMs=${waitedMs} maxWait=${COMPLETED_FINALIZATION_MAX_WAIT_MS}`);
|
|
63469
63973
|
if (block2.terminal && !block2.allowTimeout || waitedMs < COMPLETED_FINALIZATION_MAX_WAIT_MS) {
|
|
63470
63974
|
if (pending.loggedBlockReason !== blockReason) {
|
|
63471
63975
|
LOG2.info("CLI", `[${this.type}] waiting to emit completed until transcript finalizes (${blockReason})`);
|
|
@@ -63580,9 +64084,13 @@ ${formatManifestValidationIssues2(validation.issues)}`,
|
|
|
63580
64084
|
if (newStatus !== this.lastStatus) {
|
|
63581
64085
|
LOG2.info("CLI", `[${this.type}] status: ${this.lastStatus} \u2192 ${newStatus}`);
|
|
63582
64086
|
if (this.lastStatus === "idle" && newStatus === "generating") {
|
|
64087
|
+
if (this.completedDebouncePending && this.generatingStartedAt === 0) {
|
|
64088
|
+
LOG2.debug("CLI", `[${this.type}] ignoring post-completion PTY generating blip (generatingStartedAt=0)`);
|
|
64089
|
+
return;
|
|
64090
|
+
}
|
|
63583
64091
|
this.suppressIdleHistoryReplay = false;
|
|
63584
64092
|
if (this.completedDebouncePending) {
|
|
63585
|
-
LOG2.info("CLI", `[${this.type}] cancelled pending completed (resumed generating)`);
|
|
64093
|
+
LOG2.info("CLI", `[${this.type}] cancelled pending completed (resumed generating) generatingStartedAt=${this.generatingStartedAt} isWaitingForResponse=${!!this.adapter?.isWaitingForResponse}`);
|
|
63586
64094
|
if (this.completedDebounceTimer) {
|
|
63587
64095
|
clearTimeout(this.completedDebounceTimer);
|
|
63588
64096
|
this.completedDebounceTimer = null;
|
|
@@ -63680,7 +64188,10 @@ ${formatManifestValidationIssues2(validation.issues)}`,
|
|
|
63680
64188
|
firstObservedAt: now,
|
|
63681
64189
|
previousStatus: this.lastStatus
|
|
63682
64190
|
};
|
|
63683
|
-
this.
|
|
64191
|
+
const ownsExternalHistory = !!this.adapter?.chatMessagesOwnedExternally;
|
|
64192
|
+
const flushDelay = ownsExternalHistory ? 0 : 3e3;
|
|
64193
|
+
LOG2.debug("CLI", `[${this.type}] set completedDebouncePending duration=${duration3}s ownsExternalHistory=${ownsExternalHistory} flushDelay=${flushDelay}ms generatingStartedAt=${this.generatingStartedAt}`);
|
|
64194
|
+
this.scheduleCompletedDebounceFlush(flushDelay);
|
|
63684
64195
|
}
|
|
63685
64196
|
} else if (newStatus === "idle" && this.lastStatus === "starting") {
|
|
63686
64197
|
this.pushEvent({ event: "agent:ready", chatTitle, timestamp: now });
|
|
@@ -76032,9 +76543,9 @@ ${e?.stderr || ""}`
|
|
|
76032
76543
|
});
|
|
76033
76544
|
let node;
|
|
76034
76545
|
if (meshRecord.inline) {
|
|
76035
|
-
const { randomUUID:
|
|
76546
|
+
const { randomUUID: randomUUID12 } = await import("crypto");
|
|
76036
76547
|
node = {
|
|
76037
|
-
id: `node_${
|
|
76548
|
+
id: `node_${randomUUID12().replace(/-/g, "")}`,
|
|
76038
76549
|
workspace: result.worktreePath,
|
|
76039
76550
|
repoRoot: result.worktreePath,
|
|
76040
76551
|
daemonId: sourceNode.daemonId,
|
|
@@ -84440,7 +84951,7 @@ data: ${JSON.stringify(msg.data)}
|
|
|
84440
84951
|
});
|
|
84441
84952
|
}
|
|
84442
84953
|
};
|
|
84443
|
-
var
|
|
84954
|
+
var import_crypto7 = require("crypto");
|
|
84444
84955
|
var import_session_host_core42 = require_dist2();
|
|
84445
84956
|
var BASE_KEY_SEQUENCES = {
|
|
84446
84957
|
enter: "\r",
|
|
@@ -84538,7 +85049,7 @@ data: ${JSON.stringify(msg.data)}
|
|
|
84538
85049
|
const sessionId = String(options.sessionId || "").trim();
|
|
84539
85050
|
if (!sessionId) throw new Error("sessionId is required");
|
|
84540
85051
|
const mode = options.mode || "read";
|
|
84541
|
-
const clientId = options.clientId || `raw-terminal-${process.pid}-${(0,
|
|
85052
|
+
const clientId = options.clientId || `raw-terminal-${process.pid}-${(0, import_crypto7.randomUUID)().slice(0, 8)}`;
|
|
84542
85053
|
const client = options.client || new import_session_host_core42.SessionHostClient({ endpoint: options.endpoint });
|
|
84543
85054
|
await client.connect();
|
|
84544
85055
|
const attachResponse = await client.request({
|