@adhdev/daemon-standalone 0.9.82-rc.400 → 0.9.82-rc.402
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 +383 -208
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -30127,10 +30127,10 @@ var require_dist3 = __commonJS({
|
|
|
30127
30127
|
}
|
|
30128
30128
|
function getDaemonBuildInfo() {
|
|
30129
30129
|
if (cached2) return cached2;
|
|
30130
|
-
const commit = readInjected(true ? "
|
|
30131
|
-
const commitShort = readInjected(true ? "
|
|
30132
|
-
const version2 = readInjected(true ? "0.9.82-rc.
|
|
30133
|
-
const builtAt = readInjected(true ? "2026-06-
|
|
30130
|
+
const commit = readInjected(true ? "93b00efeec1fccd6550c1faf5fa838106caef4bb" : void 0) ?? "unknown";
|
|
30131
|
+
const commitShort = readInjected(true ? "93b00efe" : void 0) ?? (commit !== "unknown" ? commit.slice(0, 7) : "unknown");
|
|
30132
|
+
const version2 = readInjected(true ? "0.9.82-rc.402" : void 0) ?? readInjected(typeof process !== "undefined" ? process.env?.ADHDEV_PKG_VERSION : void 0) ?? "unknown";
|
|
30133
|
+
const builtAt = readInjected(true ? "2026-06-27T16:41:39.131Z" : void 0);
|
|
30134
30134
|
cached2 = builtAt ? { commit, commitShort, version: version2, builtAt } : { commit, commitShort, version: version2 };
|
|
30135
30135
|
return cached2;
|
|
30136
30136
|
}
|
|
@@ -31173,16 +31173,103 @@ var require_dist3 = __commonJS({
|
|
|
31173
31173
|
const parentDir = path42.dirname(repoRoot);
|
|
31174
31174
|
return path42.join(parentDir, WORKTREE_DIR_NAME, safeMeshName, safeBranch);
|
|
31175
31175
|
}
|
|
31176
|
+
async function tryGit(cwd, args) {
|
|
31177
|
+
try {
|
|
31178
|
+
const { stdout, stderr } = await execFileAsync2("git", args, {
|
|
31179
|
+
cwd,
|
|
31180
|
+
encoding: "utf8",
|
|
31181
|
+
timeout: GIT_TIMEOUT_MS,
|
|
31182
|
+
maxBuffer: GIT_MAX_BUFFER,
|
|
31183
|
+
windowsHide: true
|
|
31184
|
+
});
|
|
31185
|
+
return { ok: true, stdout: (stdout || "").trim(), stderr: (stderr || "").trim() };
|
|
31186
|
+
} catch (error48) {
|
|
31187
|
+
return {
|
|
31188
|
+
ok: false,
|
|
31189
|
+
stdout: typeof error48?.stdout === "string" ? error48.stdout.trim() : "",
|
|
31190
|
+
stderr: typeof error48?.stderr === "string" ? error48.stderr.trim() : error48?.message || ""
|
|
31191
|
+
};
|
|
31192
|
+
}
|
|
31193
|
+
}
|
|
31194
|
+
async function resolveWorktreeBaseStartPoint(repoRoot, baseBranch, remote) {
|
|
31195
|
+
const fetchResult = await tryGit(repoRoot, ["fetch", remote, baseBranch]);
|
|
31196
|
+
const fetched = fetchResult.ok;
|
|
31197
|
+
const localRev = await tryGit(repoRoot, ["rev-parse", "--verify", "--quiet", `refs/heads/${baseBranch}`]);
|
|
31198
|
+
const remoteRev = await tryGit(repoRoot, ["rev-parse", "--verify", "--quiet", `refs/remotes/${remote}/${baseBranch}`]);
|
|
31199
|
+
const localSha = localRev.ok && localRev.stdout ? localRev.stdout : void 0;
|
|
31200
|
+
const remoteSha = remoteRev.ok && remoteRev.stdout ? remoteRev.stdout : void 0;
|
|
31201
|
+
const remoteRef = `${remote}/${baseBranch}`;
|
|
31202
|
+
const base = {
|
|
31203
|
+
branch: baseBranch,
|
|
31204
|
+
remote,
|
|
31205
|
+
startRef: baseBranch,
|
|
31206
|
+
fetched,
|
|
31207
|
+
localSha,
|
|
31208
|
+
remoteSha,
|
|
31209
|
+
behindBy: 0,
|
|
31210
|
+
aheadBy: 0,
|
|
31211
|
+
action: "up_to_date"
|
|
31212
|
+
};
|
|
31213
|
+
const fetchWarn = fetched ? "" : ` (warning: git fetch ${remote} ${baseBranch} failed: ${fetchResult.stderr || "unknown error"})`;
|
|
31214
|
+
if (!remoteSha) {
|
|
31215
|
+
return {
|
|
31216
|
+
...base,
|
|
31217
|
+
action: "no_remote_ref_used_local",
|
|
31218
|
+
...fetched ? {} : { warning: `Could not fetch ${remoteRef}${fetchWarn}; worktree branched from local ${baseBranch}.` }
|
|
31219
|
+
};
|
|
31220
|
+
}
|
|
31221
|
+
if (!localSha) {
|
|
31222
|
+
return {
|
|
31223
|
+
...base,
|
|
31224
|
+
startRef: remoteRef,
|
|
31225
|
+
action: "no_local_ref_used_remote"
|
|
31226
|
+
};
|
|
31227
|
+
}
|
|
31228
|
+
if (localSha === remoteSha) {
|
|
31229
|
+
return base;
|
|
31230
|
+
}
|
|
31231
|
+
const localIsAncestor = (await tryGit(repoRoot, ["merge-base", "--is-ancestor", localSha, remoteSha])).ok;
|
|
31232
|
+
const remoteIsAncestor = (await tryGit(repoRoot, ["merge-base", "--is-ancestor", remoteSha, localSha])).ok;
|
|
31233
|
+
const behindBy = Number((await tryGit(repoRoot, ["rev-list", "--count", `${localSha}..${remoteSha}`])).stdout) || 0;
|
|
31234
|
+
const aheadBy = Number((await tryGit(repoRoot, ["rev-list", "--count", `${remoteSha}..${localSha}`])).stdout) || 0;
|
|
31235
|
+
if (localIsAncestor && !remoteIsAncestor) {
|
|
31236
|
+
return {
|
|
31237
|
+
...base,
|
|
31238
|
+
startRef: remoteRef,
|
|
31239
|
+
behindBy,
|
|
31240
|
+
aheadBy,
|
|
31241
|
+
action: "local_behind_used_remote",
|
|
31242
|
+
warning: `Base node local ${baseBranch} was behind ${remoteRef} by ${behindBy} commit(s); worktree branched from ${remoteRef} (${remoteSha.slice(0, 8)}) instead of stale local ${localSha.slice(0, 8)}.${fetchWarn}`
|
|
31243
|
+
};
|
|
31244
|
+
}
|
|
31245
|
+
if (remoteIsAncestor) {
|
|
31246
|
+
return { ...base, behindBy, aheadBy, action: "local_ahead_used_local" };
|
|
31247
|
+
}
|
|
31248
|
+
return {
|
|
31249
|
+
...base,
|
|
31250
|
+
behindBy,
|
|
31251
|
+
aheadBy,
|
|
31252
|
+
action: "diverged_used_local",
|
|
31253
|
+
warning: `Base node local ${baseBranch} (${localSha.slice(0, 8)}) has DIVERGED from ${remoteRef} (${remoteSha.slice(0, 8)}): behind ${behindBy}, ahead ${aheadBy}. Worktree branched from local; a rebase onto ${remoteRef} will be required before its push can fast-forward.${fetchWarn}`
|
|
31254
|
+
};
|
|
31255
|
+
}
|
|
31176
31256
|
async function createWorktree(opts) {
|
|
31177
31257
|
const { repoRoot, branch, baseBranch, meshName } = opts;
|
|
31258
|
+
const remote = (opts.remote || "origin").trim() || "origin";
|
|
31178
31259
|
const targetDir = opts.targetDir || resolveWorktreePath(repoRoot, meshName, branch);
|
|
31179
31260
|
if ((0, import_node_fs2.existsSync)(targetDir)) {
|
|
31180
31261
|
throw new Error(`Worktree target directory already exists: ${targetDir}`);
|
|
31181
31262
|
}
|
|
31182
31263
|
await (0, import_promises3.mkdir)(path42.dirname(targetDir), { recursive: true });
|
|
31264
|
+
let baseSync;
|
|
31265
|
+
let startRef = baseBranch;
|
|
31266
|
+
if (baseBranch && opts.syncBaseFromRemote !== false) {
|
|
31267
|
+
baseSync = await resolveWorktreeBaseStartPoint(repoRoot, baseBranch, remote);
|
|
31268
|
+
startRef = baseSync.startRef;
|
|
31269
|
+
}
|
|
31183
31270
|
const args = ["worktree", "add", targetDir, "-b", branch];
|
|
31184
|
-
if (
|
|
31185
|
-
args.push(
|
|
31271
|
+
if (startRef) {
|
|
31272
|
+
args.push(startRef);
|
|
31186
31273
|
}
|
|
31187
31274
|
try {
|
|
31188
31275
|
await execFileAsync2("git", args, {
|
|
@@ -31205,7 +31292,8 @@ var require_dist3 = __commonJS({
|
|
|
31205
31292
|
return {
|
|
31206
31293
|
success: true,
|
|
31207
31294
|
worktreePath: targetDir,
|
|
31208
|
-
branch
|
|
31295
|
+
branch,
|
|
31296
|
+
...baseSync ? { baseSync } : {}
|
|
31209
31297
|
};
|
|
31210
31298
|
}
|
|
31211
31299
|
async function removeWorktree(repoRoot, worktreePath, opts = {}) {
|
|
@@ -34175,6 +34263,177 @@ Valid status values: \`completed\` | \`failed\` | \`blocked\` | \`partial\`.`;
|
|
|
34175
34263
|
ledgerImportDone = /* @__PURE__ */ new Set();
|
|
34176
34264
|
}
|
|
34177
34265
|
});
|
|
34266
|
+
function resolveDeliveryDecision(sessionStatus, opts) {
|
|
34267
|
+
const status = (sessionStatus || "").trim().toLowerCase();
|
|
34268
|
+
if (!status) {
|
|
34269
|
+
return {
|
|
34270
|
+
decision: "rejected",
|
|
34271
|
+
reason: "unknown_session_status",
|
|
34272
|
+
message: "Session status is unknown. Delivery rejected (fail-closed). Use mesh_launch_session to start a fresh session."
|
|
34273
|
+
};
|
|
34274
|
+
}
|
|
34275
|
+
if (IMMEDIATE_DELIVERY_STATUSES.has(status)) {
|
|
34276
|
+
return {
|
|
34277
|
+
decision: "immediate",
|
|
34278
|
+
reason: `session_${status}`,
|
|
34279
|
+
message: `Session is ${status} \u2014 delivery allowed immediately.`
|
|
34280
|
+
};
|
|
34281
|
+
}
|
|
34282
|
+
if (BUSY_DELIVERY_STATUSES.has(status)) {
|
|
34283
|
+
if (opts?.allowBusyInjection) {
|
|
34284
|
+
return {
|
|
34285
|
+
decision: "immediate",
|
|
34286
|
+
reason: `session_${status}_busy_injection_allowed`,
|
|
34287
|
+
message: `Session is ${status} but provider supports busy injection. Delivered immediately.`
|
|
34288
|
+
};
|
|
34289
|
+
}
|
|
34290
|
+
if (status === "waiting_approval" && opts?.kind === "approval") {
|
|
34291
|
+
return {
|
|
34292
|
+
decision: "immediate",
|
|
34293
|
+
reason: "session_waiting_approval_approval_message",
|
|
34294
|
+
message: "Session is waiting for approval \u2014 approval message delivered immediately."
|
|
34295
|
+
};
|
|
34296
|
+
}
|
|
34297
|
+
return {
|
|
34298
|
+
decision: "queued",
|
|
34299
|
+
reason: `session_${status}_busy`,
|
|
34300
|
+
message: `Session is ${status}. Task queued for delivery when session becomes idle. Do not inject directly into a busy session.`
|
|
34301
|
+
};
|
|
34302
|
+
}
|
|
34303
|
+
if (TERMINAL_DELIVERY_STATUSES.has(status)) {
|
|
34304
|
+
return {
|
|
34305
|
+
decision: "rejected",
|
|
34306
|
+
reason: `session_${status}_terminal`,
|
|
34307
|
+
message: `Session is ${status} (terminal). Delivery rejected. Launch a new session before dispatching tasks.`
|
|
34308
|
+
};
|
|
34309
|
+
}
|
|
34310
|
+
return {
|
|
34311
|
+
decision: "rejected",
|
|
34312
|
+
reason: "unrecognized_session_status",
|
|
34313
|
+
message: `Session status '${sessionStatus}' is not recognized. Delivery rejected (fail-closed). Inspect session state before retrying.`
|
|
34314
|
+
};
|
|
34315
|
+
}
|
|
34316
|
+
function createSessionDelivery(opts) {
|
|
34317
|
+
const now = (/* @__PURE__ */ new Date()).toISOString();
|
|
34318
|
+
const id = (0, import_crypto5.randomUUID)();
|
|
34319
|
+
const record2 = {
|
|
34320
|
+
id,
|
|
34321
|
+
meshId: opts.meshId,
|
|
34322
|
+
nodeId: opts.nodeId,
|
|
34323
|
+
sessionId: opts.sessionId,
|
|
34324
|
+
providerType: opts.providerType,
|
|
34325
|
+
taskId: opts.taskId,
|
|
34326
|
+
kind: opts.kind,
|
|
34327
|
+
priority: opts.priority ?? 0,
|
|
34328
|
+
message: opts.message,
|
|
34329
|
+
status: opts.status,
|
|
34330
|
+
deliverAfter: opts.deliverAfter,
|
|
34331
|
+
expiresAt: opts.expiresAt,
|
|
34332
|
+
attemptCount: 0,
|
|
34333
|
+
sourceCoordinatorSessionId: opts.sourceCoordinatorSessionId,
|
|
34334
|
+
sourceCoordinatorDaemonId: opts.sourceCoordinatorDaemonId,
|
|
34335
|
+
createdAt: now,
|
|
34336
|
+
updatedAt: now
|
|
34337
|
+
};
|
|
34338
|
+
MeshRuntimeStore.getInstance().insertSessionDelivery({
|
|
34339
|
+
id,
|
|
34340
|
+
meshId: opts.meshId,
|
|
34341
|
+
nodeId: opts.nodeId,
|
|
34342
|
+
sessionId: opts.sessionId,
|
|
34343
|
+
providerType: opts.providerType,
|
|
34344
|
+
taskId: opts.taskId,
|
|
34345
|
+
kind: opts.kind,
|
|
34346
|
+
priority: opts.priority ?? 0,
|
|
34347
|
+
message: opts.message,
|
|
34348
|
+
status: opts.status,
|
|
34349
|
+
deliverAfter: opts.deliverAfter,
|
|
34350
|
+
expiresAt: opts.expiresAt,
|
|
34351
|
+
sourceCoordinatorSessionId: opts.sourceCoordinatorSessionId,
|
|
34352
|
+
sourceCoordinatorDaemonId: opts.sourceCoordinatorDaemonId,
|
|
34353
|
+
createdAt: now,
|
|
34354
|
+
updatedAt: now
|
|
34355
|
+
});
|
|
34356
|
+
return record2;
|
|
34357
|
+
}
|
|
34358
|
+
function updateSessionDeliveryStatus(id, status, opts) {
|
|
34359
|
+
try {
|
|
34360
|
+
MeshRuntimeStore.getInstance().updateSessionDeliveryStatus(id, status, opts);
|
|
34361
|
+
} catch {
|
|
34362
|
+
}
|
|
34363
|
+
}
|
|
34364
|
+
function getActiveSessionDeliveries(meshId, sessionId) {
|
|
34365
|
+
try {
|
|
34366
|
+
return MeshRuntimeStore.getInstance().getActiveSessionDeliveries(meshId, sessionId);
|
|
34367
|
+
} catch {
|
|
34368
|
+
return [];
|
|
34369
|
+
}
|
|
34370
|
+
}
|
|
34371
|
+
function recordCompletionConflict(opts) {
|
|
34372
|
+
try {
|
|
34373
|
+
MeshRuntimeStore.getInstance().recordCompletionConflict({
|
|
34374
|
+
id: (0, import_crypto5.randomUUID)(),
|
|
34375
|
+
meshId: opts.meshId,
|
|
34376
|
+
fingerprint: opts.fingerprint,
|
|
34377
|
+
conflictingTaskId: opts.conflictingTaskId,
|
|
34378
|
+
conflictingSessionId: opts.conflictingSessionId,
|
|
34379
|
+
originalTaskId: opts.originalTaskId,
|
|
34380
|
+
originalSessionId: opts.originalSessionId,
|
|
34381
|
+
event: opts.event,
|
|
34382
|
+
createdAt: (/* @__PURE__ */ new Date()).toISOString()
|
|
34383
|
+
});
|
|
34384
|
+
} catch {
|
|
34385
|
+
}
|
|
34386
|
+
}
|
|
34387
|
+
function getRecentCompletionConflicts(meshId, limitMs) {
|
|
34388
|
+
try {
|
|
34389
|
+
return MeshRuntimeStore.getInstance().getRecentCompletionConflicts(meshId, limitMs);
|
|
34390
|
+
} catch {
|
|
34391
|
+
return [];
|
|
34392
|
+
}
|
|
34393
|
+
}
|
|
34394
|
+
function markSessionDeliveriesTerminal(meshId, sessionId, terminalStatus) {
|
|
34395
|
+
try {
|
|
34396
|
+
const active = MeshRuntimeStore.getInstance().getActiveSessionDeliveries(meshId, sessionId);
|
|
34397
|
+
for (const delivery of active) {
|
|
34398
|
+
MeshRuntimeStore.getInstance().updateSessionDeliveryStatus(delivery.id, terminalStatus);
|
|
34399
|
+
}
|
|
34400
|
+
} catch {
|
|
34401
|
+
}
|
|
34402
|
+
}
|
|
34403
|
+
var import_crypto5;
|
|
34404
|
+
var IMMEDIATE_DELIVERY_STATUSES;
|
|
34405
|
+
var BUSY_DELIVERY_STATUSES;
|
|
34406
|
+
var TERMINAL_DELIVERY_STATUSES;
|
|
34407
|
+
var init_mesh_delivery_policy = __esm2({
|
|
34408
|
+
"src/mesh/mesh-delivery-policy.ts"() {
|
|
34409
|
+
"use strict";
|
|
34410
|
+
import_crypto5 = require("crypto");
|
|
34411
|
+
init_mesh_runtime_store();
|
|
34412
|
+
IMMEDIATE_DELIVERY_STATUSES = /* @__PURE__ */ new Set([
|
|
34413
|
+
"idle",
|
|
34414
|
+
"waiting_input",
|
|
34415
|
+
"ready"
|
|
34416
|
+
]);
|
|
34417
|
+
BUSY_DELIVERY_STATUSES = /* @__PURE__ */ new Set([
|
|
34418
|
+
"generating",
|
|
34419
|
+
"running",
|
|
34420
|
+
"streaming",
|
|
34421
|
+
"busy",
|
|
34422
|
+
"starting",
|
|
34423
|
+
"initializing",
|
|
34424
|
+
"waiting_approval"
|
|
34425
|
+
]);
|
|
34426
|
+
TERMINAL_DELIVERY_STATUSES = /* @__PURE__ */ new Set([
|
|
34427
|
+
"stopped",
|
|
34428
|
+
"failed",
|
|
34429
|
+
"terminated",
|
|
34430
|
+
"exited",
|
|
34431
|
+
"closed",
|
|
34432
|
+
"deleted",
|
|
34433
|
+
"error"
|
|
34434
|
+
]);
|
|
34435
|
+
}
|
|
34436
|
+
});
|
|
34178
34437
|
var mesh_work_queue_exports = {};
|
|
34179
34438
|
__export2(mesh_work_queue_exports, {
|
|
34180
34439
|
ACTIVE_MESH_QUEUE_STATUSES: () => ACTIVE_MESH_QUEUE_STATUSES,
|
|
@@ -34535,7 +34794,7 @@ Valid status values: \`completed\` | \`failed\` | \`blocked\` | \`partial\`.`;
|
|
|
34535
34794
|
if (!modeValidation.valid) {
|
|
34536
34795
|
throw new Error(`live_debug_readonly_guardrail_violation: forbidden operations (${modeValidation.violations.join(", ")})`);
|
|
34537
34796
|
}
|
|
34538
|
-
const id = typeof opts?.id === "string" && opts.id.trim() ? opts.id.trim() : (0,
|
|
34797
|
+
const id = typeof opts?.id === "string" && opts.id.trim() ? opts.id.trim() : (0, import_crypto6.randomUUID)();
|
|
34539
34798
|
const dependsOn = normalizeDependsOn(opts?.dependsOn);
|
|
34540
34799
|
return withQueueLock(meshId, () => {
|
|
34541
34800
|
if (MeshRuntimeStore.getInstance().findQueueEntryById(meshId, id)) {
|
|
@@ -34596,6 +34855,18 @@ Valid status values: \`completed\` | \`failed\` | \`blocked\` | \`partial\`.`;
|
|
|
34596
34855
|
updatedAt: now
|
|
34597
34856
|
};
|
|
34598
34857
|
MeshRuntimeStore.getInstance().insertQueueEntry(entry);
|
|
34858
|
+
try {
|
|
34859
|
+
createSessionDelivery({
|
|
34860
|
+
meshId,
|
|
34861
|
+
...opts.assignedNodeId ? { nodeId: opts.assignedNodeId } : {},
|
|
34862
|
+
...opts.assignedSessionId ? { sessionId: opts.assignedSessionId } : {},
|
|
34863
|
+
taskId,
|
|
34864
|
+
kind: "task",
|
|
34865
|
+
message,
|
|
34866
|
+
status: "delivered"
|
|
34867
|
+
});
|
|
34868
|
+
} catch {
|
|
34869
|
+
}
|
|
34599
34870
|
return entry;
|
|
34600
34871
|
});
|
|
34601
34872
|
}
|
|
@@ -34869,7 +35140,7 @@ Valid status values: \`completed\` | \`failed\` | \`blocked\` | \`partial\`.`;
|
|
|
34869
35140
|
return { rateLimitExceeded: false, callsInWindow: 0, advisory: null };
|
|
34870
35141
|
}
|
|
34871
35142
|
}
|
|
34872
|
-
var
|
|
35143
|
+
var import_crypto6;
|
|
34873
35144
|
var ACTIVE_MESH_QUEUE_STATUSES;
|
|
34874
35145
|
var HISTORICAL_MESH_QUEUE_STATUSES;
|
|
34875
35146
|
var MESH_TASK_MODES;
|
|
@@ -34883,13 +35154,14 @@ Valid status values: \`completed\` | \`failed\` | \`blocked\` | \`partial\`.`;
|
|
|
34883
35154
|
var init_mesh_work_queue = __esm2({
|
|
34884
35155
|
"src/mesh/mesh-work-queue.ts"() {
|
|
34885
35156
|
"use strict";
|
|
34886
|
-
|
|
35157
|
+
import_crypto6 = require("crypto");
|
|
34887
35158
|
init_mesh_host_ownership();
|
|
34888
35159
|
init_repo_mesh_types();
|
|
34889
35160
|
init_mesh_runtime_store();
|
|
34890
35161
|
init_mesh_config();
|
|
34891
35162
|
init_logger();
|
|
34892
35163
|
init_mesh_ledger();
|
|
35164
|
+
init_mesh_delivery_policy();
|
|
34893
35165
|
ACTIVE_MESH_QUEUE_STATUSES = ["pending", "assigned"];
|
|
34894
35166
|
HISTORICAL_MESH_QUEUE_STATUSES = ["completed", "failed", "cancelled"];
|
|
34895
35167
|
MESH_TASK_MODES = ["code_change", "validation", "live_debug_readonly", "launch_app", "convergence"];
|
|
@@ -35437,11 +35709,14 @@ Valid status values: \`completed\` | \`failed\` | \`blocked\` | \`partial\`.`;
|
|
|
35437
35709
|
}
|
|
35438
35710
|
/** A node may only execute one write task at a time (worktree isolation). */
|
|
35439
35711
|
hasActiveNodeAssignment(meshId, nodeId) {
|
|
35712
|
+
const nodeIdForms = expandDaemonIdForms(nodeId);
|
|
35713
|
+
if (nodeIdForms.length === 0) return false;
|
|
35714
|
+
const placeholders = nodeIdForms.map(() => "?").join(", ");
|
|
35440
35715
|
const row = this.db.prepare(`
|
|
35441
35716
|
SELECT 1 FROM mesh_queue
|
|
35442
|
-
WHERE mesh_id = ? AND status = 'assigned' AND assigned_node_id
|
|
35717
|
+
WHERE mesh_id = ? AND status = 'assigned' AND assigned_node_id IN (${placeholders})
|
|
35443
35718
|
LIMIT 1
|
|
35444
|
-
`).get(meshId,
|
|
35719
|
+
`).get(meshId, ...nodeIdForms);
|
|
35445
35720
|
return row !== void 0;
|
|
35446
35721
|
}
|
|
35447
35722
|
/**
|
|
@@ -36538,7 +36813,7 @@ Valid status values: \`completed\` | \`failed\` | \`blocked\` | \`partial\`.`;
|
|
|
36538
36813
|
if (input.status !== void 0 && !MESH_MISSION_STATUSES.includes(input.status)) {
|
|
36539
36814
|
throw new Error(`invalid_mission_status: '${input.status}' (valid: ${MESH_MISSION_STATUSES.join(", ")})`);
|
|
36540
36815
|
}
|
|
36541
|
-
const id = typeof input.id === "string" && input.id.trim() ? input.id.trim() : (0,
|
|
36816
|
+
const id = typeof input.id === "string" && input.id.trim() ? input.id.trim() : (0, import_crypto7.randomUUID)();
|
|
36542
36817
|
const store = MeshRuntimeStore.getInstance();
|
|
36543
36818
|
const existing = store.getMission(meshId, id);
|
|
36544
36819
|
const record2 = {
|
|
@@ -36654,14 +36929,14 @@ Valid status values: \`completed\` | \`failed\` | \`blocked\` | \`partial\`.`;
|
|
|
36654
36929
|
);
|
|
36655
36930
|
return lines.join("\n");
|
|
36656
36931
|
}
|
|
36657
|
-
var
|
|
36932
|
+
var import_crypto7;
|
|
36658
36933
|
var MESH_MISSION_STATUSES;
|
|
36659
36934
|
var GOAL_PREVIEW_MAX;
|
|
36660
36935
|
var COMPACT_STATUS_GOAL_PREVIEW_MAX;
|
|
36661
36936
|
var init_mesh_missions = __esm2({
|
|
36662
36937
|
"src/mesh/mesh-missions.ts"() {
|
|
36663
36938
|
"use strict";
|
|
36664
|
-
|
|
36939
|
+
import_crypto7 = require("crypto");
|
|
36665
36940
|
init_mesh_runtime_store();
|
|
36666
36941
|
init_mesh_work_queue();
|
|
36667
36942
|
init_mesh_task_stats();
|
|
@@ -39743,7 +40018,7 @@ Next step: ${nextStep}`;
|
|
|
39743
40018
|
let sqliteOk = false;
|
|
39744
40019
|
try {
|
|
39745
40020
|
MeshRuntimeStore.getInstance().insertPendingEvent({
|
|
39746
|
-
id: (0,
|
|
40021
|
+
id: (0, import_crypto8.randomUUID)(),
|
|
39747
40022
|
meshId: event.meshId,
|
|
39748
40023
|
coordinatorDaemonId: event.targetCoordinatorDaemonId ?? null,
|
|
39749
40024
|
event: event.event,
|
|
@@ -39933,7 +40208,7 @@ Next step: ${nextStep}`;
|
|
|
39933
40208
|
}
|
|
39934
40209
|
var import_fs10;
|
|
39935
40210
|
var import_path9;
|
|
39936
|
-
var
|
|
40211
|
+
var import_crypto8;
|
|
39937
40212
|
var REFINE_TERMINAL_EVENTS;
|
|
39938
40213
|
var TERMINAL_COMPLETION_EVENTS;
|
|
39939
40214
|
var MAX_PENDING_EVENTS_BYTES;
|
|
@@ -39943,7 +40218,7 @@ Next step: ${nextStep}`;
|
|
|
39943
40218
|
"use strict";
|
|
39944
40219
|
import_fs10 = require("fs");
|
|
39945
40220
|
import_path9 = require("path");
|
|
39946
|
-
|
|
40221
|
+
import_crypto8 = require("crypto");
|
|
39947
40222
|
init_logger();
|
|
39948
40223
|
init_mesh_ledger();
|
|
39949
40224
|
init_mesh_runtime_store();
|
|
@@ -39955,177 +40230,6 @@ Next step: ${nextStep}`;
|
|
|
39955
40230
|
MAX_PENDING_EVENTS_KEEP = 50;
|
|
39956
40231
|
}
|
|
39957
40232
|
});
|
|
39958
|
-
function resolveDeliveryDecision(sessionStatus, opts) {
|
|
39959
|
-
const status = (sessionStatus || "").trim().toLowerCase();
|
|
39960
|
-
if (!status) {
|
|
39961
|
-
return {
|
|
39962
|
-
decision: "rejected",
|
|
39963
|
-
reason: "unknown_session_status",
|
|
39964
|
-
message: "Session status is unknown. Delivery rejected (fail-closed). Use mesh_launch_session to start a fresh session."
|
|
39965
|
-
};
|
|
39966
|
-
}
|
|
39967
|
-
if (IMMEDIATE_DELIVERY_STATUSES.has(status)) {
|
|
39968
|
-
return {
|
|
39969
|
-
decision: "immediate",
|
|
39970
|
-
reason: `session_${status}`,
|
|
39971
|
-
message: `Session is ${status} \u2014 delivery allowed immediately.`
|
|
39972
|
-
};
|
|
39973
|
-
}
|
|
39974
|
-
if (BUSY_DELIVERY_STATUSES.has(status)) {
|
|
39975
|
-
if (opts?.allowBusyInjection) {
|
|
39976
|
-
return {
|
|
39977
|
-
decision: "immediate",
|
|
39978
|
-
reason: `session_${status}_busy_injection_allowed`,
|
|
39979
|
-
message: `Session is ${status} but provider supports busy injection. Delivered immediately.`
|
|
39980
|
-
};
|
|
39981
|
-
}
|
|
39982
|
-
if (status === "waiting_approval" && opts?.kind === "approval") {
|
|
39983
|
-
return {
|
|
39984
|
-
decision: "immediate",
|
|
39985
|
-
reason: "session_waiting_approval_approval_message",
|
|
39986
|
-
message: "Session is waiting for approval \u2014 approval message delivered immediately."
|
|
39987
|
-
};
|
|
39988
|
-
}
|
|
39989
|
-
return {
|
|
39990
|
-
decision: "queued",
|
|
39991
|
-
reason: `session_${status}_busy`,
|
|
39992
|
-
message: `Session is ${status}. Task queued for delivery when session becomes idle. Do not inject directly into a busy session.`
|
|
39993
|
-
};
|
|
39994
|
-
}
|
|
39995
|
-
if (TERMINAL_DELIVERY_STATUSES.has(status)) {
|
|
39996
|
-
return {
|
|
39997
|
-
decision: "rejected",
|
|
39998
|
-
reason: `session_${status}_terminal`,
|
|
39999
|
-
message: `Session is ${status} (terminal). Delivery rejected. Launch a new session before dispatching tasks.`
|
|
40000
|
-
};
|
|
40001
|
-
}
|
|
40002
|
-
return {
|
|
40003
|
-
decision: "rejected",
|
|
40004
|
-
reason: "unrecognized_session_status",
|
|
40005
|
-
message: `Session status '${sessionStatus}' is not recognized. Delivery rejected (fail-closed). Inspect session state before retrying.`
|
|
40006
|
-
};
|
|
40007
|
-
}
|
|
40008
|
-
function createSessionDelivery(opts) {
|
|
40009
|
-
const now = (/* @__PURE__ */ new Date()).toISOString();
|
|
40010
|
-
const id = (0, import_crypto8.randomUUID)();
|
|
40011
|
-
const record2 = {
|
|
40012
|
-
id,
|
|
40013
|
-
meshId: opts.meshId,
|
|
40014
|
-
nodeId: opts.nodeId,
|
|
40015
|
-
sessionId: opts.sessionId,
|
|
40016
|
-
providerType: opts.providerType,
|
|
40017
|
-
taskId: opts.taskId,
|
|
40018
|
-
kind: opts.kind,
|
|
40019
|
-
priority: opts.priority ?? 0,
|
|
40020
|
-
message: opts.message,
|
|
40021
|
-
status: opts.status,
|
|
40022
|
-
deliverAfter: opts.deliverAfter,
|
|
40023
|
-
expiresAt: opts.expiresAt,
|
|
40024
|
-
attemptCount: 0,
|
|
40025
|
-
sourceCoordinatorSessionId: opts.sourceCoordinatorSessionId,
|
|
40026
|
-
sourceCoordinatorDaemonId: opts.sourceCoordinatorDaemonId,
|
|
40027
|
-
createdAt: now,
|
|
40028
|
-
updatedAt: now
|
|
40029
|
-
};
|
|
40030
|
-
MeshRuntimeStore.getInstance().insertSessionDelivery({
|
|
40031
|
-
id,
|
|
40032
|
-
meshId: opts.meshId,
|
|
40033
|
-
nodeId: opts.nodeId,
|
|
40034
|
-
sessionId: opts.sessionId,
|
|
40035
|
-
providerType: opts.providerType,
|
|
40036
|
-
taskId: opts.taskId,
|
|
40037
|
-
kind: opts.kind,
|
|
40038
|
-
priority: opts.priority ?? 0,
|
|
40039
|
-
message: opts.message,
|
|
40040
|
-
status: opts.status,
|
|
40041
|
-
deliverAfter: opts.deliverAfter,
|
|
40042
|
-
expiresAt: opts.expiresAt,
|
|
40043
|
-
sourceCoordinatorSessionId: opts.sourceCoordinatorSessionId,
|
|
40044
|
-
sourceCoordinatorDaemonId: opts.sourceCoordinatorDaemonId,
|
|
40045
|
-
createdAt: now,
|
|
40046
|
-
updatedAt: now
|
|
40047
|
-
});
|
|
40048
|
-
return record2;
|
|
40049
|
-
}
|
|
40050
|
-
function updateSessionDeliveryStatus(id, status, opts) {
|
|
40051
|
-
try {
|
|
40052
|
-
MeshRuntimeStore.getInstance().updateSessionDeliveryStatus(id, status, opts);
|
|
40053
|
-
} catch {
|
|
40054
|
-
}
|
|
40055
|
-
}
|
|
40056
|
-
function getActiveSessionDeliveries(meshId, sessionId) {
|
|
40057
|
-
try {
|
|
40058
|
-
return MeshRuntimeStore.getInstance().getActiveSessionDeliveries(meshId, sessionId);
|
|
40059
|
-
} catch {
|
|
40060
|
-
return [];
|
|
40061
|
-
}
|
|
40062
|
-
}
|
|
40063
|
-
function recordCompletionConflict(opts) {
|
|
40064
|
-
try {
|
|
40065
|
-
MeshRuntimeStore.getInstance().recordCompletionConflict({
|
|
40066
|
-
id: (0, import_crypto8.randomUUID)(),
|
|
40067
|
-
meshId: opts.meshId,
|
|
40068
|
-
fingerprint: opts.fingerprint,
|
|
40069
|
-
conflictingTaskId: opts.conflictingTaskId,
|
|
40070
|
-
conflictingSessionId: opts.conflictingSessionId,
|
|
40071
|
-
originalTaskId: opts.originalTaskId,
|
|
40072
|
-
originalSessionId: opts.originalSessionId,
|
|
40073
|
-
event: opts.event,
|
|
40074
|
-
createdAt: (/* @__PURE__ */ new Date()).toISOString()
|
|
40075
|
-
});
|
|
40076
|
-
} catch {
|
|
40077
|
-
}
|
|
40078
|
-
}
|
|
40079
|
-
function getRecentCompletionConflicts(meshId, limitMs) {
|
|
40080
|
-
try {
|
|
40081
|
-
return MeshRuntimeStore.getInstance().getRecentCompletionConflicts(meshId, limitMs);
|
|
40082
|
-
} catch {
|
|
40083
|
-
return [];
|
|
40084
|
-
}
|
|
40085
|
-
}
|
|
40086
|
-
function markSessionDeliveriesTerminal(meshId, sessionId, terminalStatus) {
|
|
40087
|
-
try {
|
|
40088
|
-
const active = MeshRuntimeStore.getInstance().getActiveSessionDeliveries(meshId, sessionId);
|
|
40089
|
-
for (const delivery of active) {
|
|
40090
|
-
MeshRuntimeStore.getInstance().updateSessionDeliveryStatus(delivery.id, terminalStatus);
|
|
40091
|
-
}
|
|
40092
|
-
} catch {
|
|
40093
|
-
}
|
|
40094
|
-
}
|
|
40095
|
-
var import_crypto8;
|
|
40096
|
-
var IMMEDIATE_DELIVERY_STATUSES;
|
|
40097
|
-
var BUSY_DELIVERY_STATUSES;
|
|
40098
|
-
var TERMINAL_DELIVERY_STATUSES;
|
|
40099
|
-
var init_mesh_delivery_policy = __esm2({
|
|
40100
|
-
"src/mesh/mesh-delivery-policy.ts"() {
|
|
40101
|
-
"use strict";
|
|
40102
|
-
import_crypto8 = require("crypto");
|
|
40103
|
-
init_mesh_runtime_store();
|
|
40104
|
-
IMMEDIATE_DELIVERY_STATUSES = /* @__PURE__ */ new Set([
|
|
40105
|
-
"idle",
|
|
40106
|
-
"waiting_input",
|
|
40107
|
-
"ready"
|
|
40108
|
-
]);
|
|
40109
|
-
BUSY_DELIVERY_STATUSES = /* @__PURE__ */ new Set([
|
|
40110
|
-
"generating",
|
|
40111
|
-
"running",
|
|
40112
|
-
"streaming",
|
|
40113
|
-
"busy",
|
|
40114
|
-
"starting",
|
|
40115
|
-
"initializing",
|
|
40116
|
-
"waiting_approval"
|
|
40117
|
-
]);
|
|
40118
|
-
TERMINAL_DELIVERY_STATUSES = /* @__PURE__ */ new Set([
|
|
40119
|
-
"stopped",
|
|
40120
|
-
"failed",
|
|
40121
|
-
"terminated",
|
|
40122
|
-
"exited",
|
|
40123
|
-
"closed",
|
|
40124
|
-
"deleted",
|
|
40125
|
-
"error"
|
|
40126
|
-
]);
|
|
40127
|
-
}
|
|
40128
|
-
});
|
|
40129
40233
|
function findRecentTerminalLedgerEvidence(args) {
|
|
40130
40234
|
if (!args.sessionId && !args.nodeId) return null;
|
|
40131
40235
|
const entries = readLedgerEntries(args.meshId, { tail: 200 });
|
|
@@ -41683,7 +41787,14 @@ Next step: ${nextStep}`;
|
|
|
41683
41787
|
targetSessionId: sessionId,
|
|
41684
41788
|
cliType: providerType,
|
|
41685
41789
|
action: "send_chat",
|
|
41686
|
-
message: task.message
|
|
41790
|
+
message: task.message,
|
|
41791
|
+
meshContext: {
|
|
41792
|
+
meshId,
|
|
41793
|
+
nodeId,
|
|
41794
|
+
taskId: task.id,
|
|
41795
|
+
...readNonEmptyString2(loadConfig2().machineId) ? { coordinatorDaemonId: readNonEmptyString2(loadConfig2().machineId) } : {},
|
|
41796
|
+
...readNonEmptyString2(task.sourceCoordinatorSessionId) ? { coordinatorSessionId: readNonEmptyString2(task.sourceCoordinatorSessionId) } : {}
|
|
41797
|
+
}
|
|
41687
41798
|
}),
|
|
41688
41799
|
{
|
|
41689
41800
|
meshId,
|
|
@@ -49373,6 +49484,15 @@ ${cont}` : cont;
|
|
|
49373
49484
|
currentStatus = "starting";
|
|
49374
49485
|
isWaitingForResponse = false;
|
|
49375
49486
|
currentTurnScope = null;
|
|
49487
|
+
// ARCH-REFACTOR R1 (per-turn task identity): the mesh taskId bound to the most
|
|
49488
|
+
// recently STARTED turn. Unlike currentTurnScope (nulled the moment the turn
|
|
49489
|
+
// settles, before the completion event is even built), this persists past
|
|
49490
|
+
// completion and is only overwritten when the NEXT turn starts. That window is
|
|
49491
|
+
// exactly what the completion path needs: when a turn settles to idle, this still
|
|
49492
|
+
// holds THAT turn's taskId (the next task's turn cannot have started yet — it is
|
|
49493
|
+
// queued in pendingOutbound and only flushed asynchronously after idle), so the
|
|
49494
|
+
// completion event carries the correct id instead of the racy session scalar.
|
|
49495
|
+
currentTurnTaskId = null;
|
|
49376
49496
|
activeModal = null;
|
|
49377
49497
|
// ── Approval ─────────────────────────────────────
|
|
49378
49498
|
lastApprovalResolvedAt = 0;
|
|
@@ -49482,6 +49602,7 @@ ${cont}` : cont;
|
|
|
49482
49602
|
this.finishRetryCount = 0;
|
|
49483
49603
|
this.clearIdleFinishCandidate("send_message");
|
|
49484
49604
|
this.currentTurnScope = turnScope;
|
|
49605
|
+
this.currentTurnTaskId = typeof turnScope.taskId === "string" && turnScope.taskId.trim() ? turnScope.taskId : null;
|
|
49485
49606
|
this.responseEpoch += 1;
|
|
49486
49607
|
}
|
|
49487
49608
|
/** Called when PTY exits */
|
|
@@ -51433,15 +51554,18 @@ ${lastSnapshot}`;
|
|
|
51433
51554
|
}
|
|
51434
51555
|
async sendMessage(text, options = {}) {
|
|
51435
51556
|
if (options.force === true) {
|
|
51436
|
-
await this.forceSendMessage(text);
|
|
51557
|
+
await this.forceSendMessage(text, options.meshTaskId);
|
|
51437
51558
|
return;
|
|
51438
51559
|
}
|
|
51439
|
-
await this.sendMessageNow(text, true);
|
|
51560
|
+
await this.sendMessageNow(text, true, options.meshTaskId);
|
|
51440
51561
|
}
|
|
51441
|
-
async forceSendMessage(text) {
|
|
51562
|
+
async forceSendMessage(text, meshTaskId) {
|
|
51442
51563
|
if (!this.ptyProcess) throw new Error(`${this.cliName} is not running`);
|
|
51443
51564
|
const content = String(text || "");
|
|
51444
51565
|
if (!content.trim()) return;
|
|
51566
|
+
if (typeof meshTaskId === "string" && meshTaskId.trim()) {
|
|
51567
|
+
this.engine.currentTurnTaskId = meshTaskId;
|
|
51568
|
+
}
|
|
51445
51569
|
if (this.engine.currentStatus === "waiting_approval" || this.engine.hasActionableApproval()) {
|
|
51446
51570
|
LOG2.info("CLI", `[${this.cliType}] force-send held \u2014 session parked on approval modal (status=${this.engine.currentStatus})`);
|
|
51447
51571
|
return;
|
|
@@ -51454,7 +51578,7 @@ ${lastSnapshot}`;
|
|
|
51454
51578
|
async waitForForceSubmitSettle() {
|
|
51455
51579
|
await new Promise((resolve24) => setTimeout(resolve24, FORCE_SUBMIT_SETTLE_MS));
|
|
51456
51580
|
}
|
|
51457
|
-
enqueuePendingOutboundMessage(text, reason) {
|
|
51581
|
+
enqueuePendingOutboundMessage(text, reason, meshTaskId) {
|
|
51458
51582
|
const content = String(text || "");
|
|
51459
51583
|
const duplicate = this.pendingOutboundQueue.some((message2) => message2.content === content);
|
|
51460
51584
|
if (duplicate) {
|
|
@@ -51466,7 +51590,8 @@ ${lastSnapshot}`;
|
|
|
51466
51590
|
role: "user",
|
|
51467
51591
|
content,
|
|
51468
51592
|
queuedAt,
|
|
51469
|
-
source: "sendMessage"
|
|
51593
|
+
source: "sendMessage",
|
|
51594
|
+
...typeof meshTaskId === "string" && meshTaskId.trim() ? { meshTaskId } : {}
|
|
51470
51595
|
};
|
|
51471
51596
|
this.pendingOutboundQueue.push(message);
|
|
51472
51597
|
LOG2.info("CLI", `[${this.cliType}] queued outbound message while busy (${reason}); queue=${this.pendingOutboundQueue.length}`);
|
|
@@ -51509,7 +51634,7 @@ ${lastSnapshot}`;
|
|
|
51509
51634
|
if (this.engine.currentStatus !== "idle" || this.engine.isWaitingForResponse || this.engine.hasActionableApproval()) break;
|
|
51510
51635
|
const next = this.pendingOutboundQueue[0];
|
|
51511
51636
|
try {
|
|
51512
|
-
await this.sendMessageNow(next.content, false);
|
|
51637
|
+
await this.sendMessageNow(next.content, false, next.meshTaskId);
|
|
51513
51638
|
this.pendingOutboundQueue.shift();
|
|
51514
51639
|
this.onStatusChange?.();
|
|
51515
51640
|
} catch (error48) {
|
|
@@ -51522,7 +51647,7 @@ ${lastSnapshot}`;
|
|
|
51522
51647
|
this.pendingOutboundFlushInFlight = false;
|
|
51523
51648
|
}
|
|
51524
51649
|
}
|
|
51525
|
-
async sendMessageNow(text, allowQueue) {
|
|
51650
|
+
async sendMessageNow(text, allowQueue, meshTaskId) {
|
|
51526
51651
|
if (!this.ptyProcess) throw new Error(`${this.cliName} is not running`);
|
|
51527
51652
|
const allowInputDuringGeneration = this.provider.allowInputDuringGeneration === true;
|
|
51528
51653
|
const allowInterventionPrompt = allowInputDuringGeneration && this.engine.isWaitingForResponse && !this.engine.hasActionableApproval();
|
|
@@ -51542,7 +51667,7 @@ ${lastSnapshot}`;
|
|
|
51542
51667
|
})() : null;
|
|
51543
51668
|
const queueReason = this.shouldQueuePendingOutboundMessage(parsedStatusBeforeSend);
|
|
51544
51669
|
if (allowQueue && queueReason) {
|
|
51545
|
-
this.enqueuePendingOutboundMessage(text, queueReason);
|
|
51670
|
+
this.enqueuePendingOutboundMessage(text, queueReason, meshTaskId);
|
|
51546
51671
|
return;
|
|
51547
51672
|
}
|
|
51548
51673
|
if (!allowInterventionPrompt) {
|
|
@@ -51559,7 +51684,7 @@ ${lastSnapshot}`;
|
|
|
51559
51684
|
}
|
|
51560
51685
|
if (!this.ready) {
|
|
51561
51686
|
if (allowQueue) {
|
|
51562
|
-
this.enqueuePendingOutboundMessage(text, "not_ready_pending_prompt");
|
|
51687
|
+
this.enqueuePendingOutboundMessage(text, "not_ready_pending_prompt", meshTaskId);
|
|
51563
51688
|
return;
|
|
51564
51689
|
}
|
|
51565
51690
|
throw new Error(`${this.cliName} not ready (status: ${this.engine.currentStatus})`);
|
|
@@ -51573,7 +51698,7 @@ ${lastSnapshot}`;
|
|
|
51573
51698
|
const terminalLooksIdle = this.engine.currentStatus === "idle" && this.runDetectStatus(this.recentOutputBuffer) === "idle" && !this.engine.isWaitingForResponse && !this.engine.currentTurnScope && !this.engine.hasActionableApproval() && !parsedHasActionableModal;
|
|
51574
51699
|
if (!terminalLooksIdle) {
|
|
51575
51700
|
if (allowQueue) {
|
|
51576
|
-
this.enqueuePendingOutboundMessage(text, `parsed_status_${parsedSessionStatus}
|
|
51701
|
+
this.enqueuePendingOutboundMessage(text, `parsed_status_${parsedSessionStatus}`, meshTaskId);
|
|
51577
51702
|
return;
|
|
51578
51703
|
}
|
|
51579
51704
|
throw new Error(`${this.cliName} is still processing the previous prompt`);
|
|
@@ -51583,7 +51708,7 @@ ${lastSnapshot}`;
|
|
|
51583
51708
|
const snap = this.getSnapshot();
|
|
51584
51709
|
if (!this.engine.clearStaleIdleResponseGuard("send_message_guard", snap) && !this.engine.clearParsedIdleResponseGuard("send_message_parsed_idle_guard", parsedStatusBeforeSend, snap)) {
|
|
51585
51710
|
if (allowQueue) {
|
|
51586
|
-
this.enqueuePendingOutboundMessage(text, "waiting_for_response");
|
|
51711
|
+
this.enqueuePendingOutboundMessage(text, "waiting_for_response", meshTaskId);
|
|
51587
51712
|
return;
|
|
51588
51713
|
}
|
|
51589
51714
|
throw new Error(`${this.cliName} is still processing the previous prompt`);
|
|
@@ -51594,7 +51719,11 @@ ${lastSnapshot}`;
|
|
|
51594
51719
|
prompt: text,
|
|
51595
51720
|
startedAt: Date.now(),
|
|
51596
51721
|
bufferStart: this.accumulatedBuffer.length,
|
|
51597
|
-
rawBufferStart: this.accumulatedRawBuffer.length
|
|
51722
|
+
rawBufferStart: this.accumulatedRawBuffer.length,
|
|
51723
|
+
// ARCH-REFACTOR R1: bind this turn to its mesh task. engine.onTurnStarted
|
|
51724
|
+
// copies this into currentTurnTaskId so the turn's completion event carries
|
|
51725
|
+
// the right id even if a later task overwrites the session scalar meanwhile.
|
|
51726
|
+
...typeof meshTaskId === "string" && meshTaskId.trim() ? { taskId: meshTaskId } : {}
|
|
51598
51727
|
};
|
|
51599
51728
|
LOG2.info("CLI", `[${this.cliType}] sendMessage turn scope buffer=${turnScope.bufferStart} raw=${turnScope.rawBufferStart} prompt=${JSON.stringify(text).slice(0, 120)}`);
|
|
51600
51729
|
if (this.submitRetryTimer) {
|
|
@@ -51944,6 +52073,13 @@ ${lastSnapshot}`;
|
|
|
51944
52073
|
set currentTurnScope(v) {
|
|
51945
52074
|
this.engine.currentTurnScope = v;
|
|
51946
52075
|
}
|
|
52076
|
+
// ARCH-REFACTOR R1: the mesh taskId bound to the most recently started turn,
|
|
52077
|
+
// surviving past turn settle until the next turn starts. The provider instance
|
|
52078
|
+
// reads this when stamping completion events so they carry the completing turn's
|
|
52079
|
+
// task rather than the racy last-write-wins session scalar.
|
|
52080
|
+
get currentTurnTaskId() {
|
|
52081
|
+
return this.engine.currentTurnTaskId;
|
|
52082
|
+
}
|
|
51947
52083
|
get responseEpoch() {
|
|
51948
52084
|
return this.engine.responseEpoch;
|
|
51949
52085
|
}
|
|
@@ -70350,11 +70486,28 @@ ${body}
|
|
|
70350
70486
|
isMeshWorkerSession() {
|
|
70351
70487
|
return !!(this.settings.meshNodeFor || this.settings.meshActiveTaskId || this.settings.meshNodeId || this.settings.launchedByCoordinator);
|
|
70352
70488
|
}
|
|
70489
|
+
/**
|
|
70490
|
+
* ARCH-REFACTOR R1: the taskId to attribute the CURRENTLY-completing turn to.
|
|
70491
|
+
* Prefers the per-turn binding (engine.currentTurnTaskId, set when the turn was
|
|
70492
|
+
* submitted and surviving until the next turn starts) over the last-write-wins
|
|
70493
|
+
* session scalar (settings.meshActiveTaskId). The scalar is retained only as a
|
|
70494
|
+
* backward-compat alias for the "current/last assignment" and is the source of the
|
|
70495
|
+
* NOTIF-MISDELIVER / TASK-MSG-MISROUTE race: a second task attaching before this
|
|
70496
|
+
* turn completes overwrites it. Returns undefined for a non-task ad-hoc turn.
|
|
70497
|
+
*/
|
|
70498
|
+
completingTurnTaskId() {
|
|
70499
|
+
const turnTaskId = this.adapter?.currentTurnTaskId;
|
|
70500
|
+
if (typeof turnTaskId === "string" && turnTaskId.trim()) return turnTaskId;
|
|
70501
|
+
const scalar = this.settings.meshActiveTaskId;
|
|
70502
|
+
return typeof scalar === "string" && scalar.trim() ? scalar : void 0;
|
|
70503
|
+
}
|
|
70353
70504
|
// EVTTRACE correlation context for this session's completion lifecycle. taskId is
|
|
70354
70505
|
// the primary grep anchor; instanceId is the session fallback.
|
|
70355
70506
|
meshTraceCtx(event = "agent:generating_completed") {
|
|
70356
70507
|
return {
|
|
70357
|
-
|
|
70508
|
+
// ARCH-REFACTOR R1: trace the per-turn taskId (falling back to the scalar) so
|
|
70509
|
+
// EvtTrace anchors on the same id the completion event actually carries.
|
|
70510
|
+
taskId: this.completingTurnTaskId(),
|
|
70358
70511
|
sessionId: this.instanceId,
|
|
70359
70512
|
nodeId: this.settings.meshNodeId,
|
|
70360
70513
|
meshId: this.settings.meshNodeFor,
|
|
@@ -70413,6 +70566,8 @@ ${body}
|
|
|
70413
70566
|
chatTitle: pending.chatTitle,
|
|
70414
70567
|
duration: pending.duration,
|
|
70415
70568
|
timestamp: pending.timestamp,
|
|
70569
|
+
// ARCH-REFACTOR R1: attribute to the turn captured at idle-transition.
|
|
70570
|
+
...pending.taskId ? { taskId: pending.taskId } : {},
|
|
70416
70571
|
// When finalization is forced past the timeout on a `parsed_status:` block
|
|
70417
70572
|
// (the parser never confirmed a final assistant turn) we previously rode an
|
|
70418
70573
|
// empty `finalSummary` unconditionally. That empty value propagates to the
|
|
@@ -70438,6 +70593,8 @@ ${body}
|
|
|
70438
70593
|
chatTitle: pending.chatTitle,
|
|
70439
70594
|
duration: pending.duration,
|
|
70440
70595
|
timestamp: pending.timestamp,
|
|
70596
|
+
// ARCH-REFACTOR R1: attribute to the turn captured at idle-transition.
|
|
70597
|
+
...pending.taskId ? { taskId: pending.taskId } : {},
|
|
70441
70598
|
finalSummary: this.completionFinalSummary(this.adapter?.getScriptParsedStatus()?.messages)
|
|
70442
70599
|
});
|
|
70443
70600
|
this.completedDebouncePending = null;
|
|
@@ -70714,7 +70871,11 @@ ${body}
|
|
|
70714
70871
|
duration: duration3,
|
|
70715
70872
|
timestamp: now,
|
|
70716
70873
|
firstObservedAt: now,
|
|
70717
|
-
previousStatus: this.lastStatus
|
|
70874
|
+
previousStatus: this.lastStatus,
|
|
70875
|
+
// ARCH-REFACTOR R1: snapshot the completing turn's taskId NOW (sync),
|
|
70876
|
+
// before any follow-up task's flush can start a new turn and move
|
|
70877
|
+
// engine.currentTurnTaskId.
|
|
70878
|
+
...this.completingTurnTaskId() ? { taskId: this.completingTurnTaskId() } : {}
|
|
70718
70879
|
};
|
|
70719
70880
|
const ownsExternalHistory = !!this.adapter?.chatMessagesOwnedExternally;
|
|
70720
70881
|
const meshWorkerSession = this.isMeshWorkerSession();
|
|
@@ -70817,10 +70978,11 @@ ${body}
|
|
|
70817
70978
|
workspace: typeof event.workspace === "string" && event.workspace.trim() ? event.workspace : this.workingDir,
|
|
70818
70979
|
providerSessionId: typeof event.providerSessionId === "string" && event.providerSessionId.trim() ? event.providerSessionId : this.providerSessionId
|
|
70819
70980
|
};
|
|
70820
|
-
if (this.isMeshWorkerSession()
|
|
70981
|
+
if (this.isMeshWorkerSession()) {
|
|
70821
70982
|
const existingTaskId = typeof enrichedEvent.taskId === "string" && enrichedEvent.taskId.trim() ? enrichedEvent.taskId : void 0;
|
|
70822
70983
|
if (!existingTaskId) {
|
|
70823
|
-
|
|
70984
|
+
const resolved = this.completingTurnTaskId();
|
|
70985
|
+
if (resolved) enrichedEvent.taskId = resolved;
|
|
70824
70986
|
}
|
|
70825
70987
|
}
|
|
70826
70988
|
if (this.context?.emitProviderEvent) {
|
|
@@ -73692,11 +73854,15 @@ Run 'adhdev doctor' for detailed diagnostics.`
|
|
|
73692
73854
|
}
|
|
73693
73855
|
const message = input.textFallback;
|
|
73694
73856
|
if (!message) throw new Error("message required for send_chat");
|
|
73857
|
+
const meshTaskId = meshContext && typeof meshContext === "object" && typeof meshContext.taskId === "string" && meshContext.taskId.trim() ? meshContext.taskId : void 0;
|
|
73695
73858
|
const forceSend = args?.force === true || args?.forceSend === true;
|
|
73696
73859
|
if (forceSend && typeof adapter.forceSendMessage === "function") {
|
|
73697
|
-
await adapter.forceSendMessage(message);
|
|
73860
|
+
if (meshTaskId) await adapter.forceSendMessage(message, meshTaskId);
|
|
73861
|
+
else await adapter.forceSendMessage(message);
|
|
73698
73862
|
} else if (forceSend) {
|
|
73699
|
-
await adapter.sendMessage(message, { force: true });
|
|
73863
|
+
await adapter.sendMessage(message, meshTaskId ? { force: true, meshTaskId } : { force: true });
|
|
73864
|
+
} else if (meshTaskId) {
|
|
73865
|
+
await adapter.sendMessage(message, { meshTaskId });
|
|
73700
73866
|
} else {
|
|
73701
73867
|
await adapter.sendMessage(message);
|
|
73702
73868
|
}
|
|
@@ -78192,6 +78358,11 @@ ${formatManifestValidationIssues2(validation2.issues)}`);
|
|
|
78192
78358
|
baseBranch,
|
|
78193
78359
|
meshName: mesh.name
|
|
78194
78360
|
});
|
|
78361
|
+
if (result.baseSync?.warning) {
|
|
78362
|
+
console.warn(`[mesh] clone_mesh_node base sync (${result.baseSync.action}): ${result.baseSync.warning}`);
|
|
78363
|
+
} else if (result.baseSync && result.baseSync.action !== "up_to_date") {
|
|
78364
|
+
console.log(`[mesh] clone_mesh_node base sync: ${result.baseSync.action} (startRef=${result.baseSync.startRef})`);
|
|
78365
|
+
}
|
|
78195
78366
|
let node;
|
|
78196
78367
|
if (meshRecord.inline) {
|
|
78197
78368
|
const { randomUUID: randomUUID15 } = await import("crypto");
|
|
@@ -78382,6 +78553,8 @@ ${formatManifestValidationIssues2(validation2.issues)}`);
|
|
|
78382
78553
|
node,
|
|
78383
78554
|
worktreePath: result.worktreePath,
|
|
78384
78555
|
branch: result.branch,
|
|
78556
|
+
...result.baseSync ? { baseSync: result.baseSync } : {},
|
|
78557
|
+
...result.baseSync?.warning ? { baseStaleWarning: result.baseSync.warning } : {},
|
|
78385
78558
|
worktreeBootstrap: runningBootstrapState,
|
|
78386
78559
|
worktreeSetup: {
|
|
78387
78560
|
status: "running",
|
|
@@ -78397,6 +78570,8 @@ ${formatManifestValidationIssues2(validation2.issues)}`);
|
|
|
78397
78570
|
node,
|
|
78398
78571
|
worktreePath: result.worktreePath,
|
|
78399
78572
|
branch: result.branch,
|
|
78573
|
+
...result.baseSync ? { baseSync: result.baseSync } : {},
|
|
78574
|
+
...result.baseSync?.warning ? { baseStaleWarning: result.baseSync.warning } : {},
|
|
78400
78575
|
submodulesInitialized,
|
|
78401
78576
|
worktreeBootstrap: bootstrapState
|
|
78402
78577
|
};
|