@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 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 ? "2350563490670c1c560cc5cf6f863a9e61ef3f89" : void 0) ?? "unknown";
30131
- const commitShort = readInjected(true ? "23505634" : void 0) ?? (commit !== "unknown" ? commit.slice(0, 7) : "unknown");
30132
- const version2 = readInjected(true ? "0.9.82-rc.400" : void 0) ?? readInjected(typeof process !== "undefined" ? process.env?.ADHDEV_PKG_VERSION : void 0) ?? "unknown";
30133
- const builtAt = readInjected(true ? "2026-06-27T13:16:19.563Z" : void 0);
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 (baseBranch) {
31185
- args.push(baseBranch);
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, import_crypto5.randomUUID)();
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 import_crypto5;
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
- import_crypto5 = require("crypto");
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, nodeId);
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, import_crypto6.randomUUID)();
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 import_crypto6;
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
- import_crypto6 = require("crypto");
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, import_crypto7.randomUUID)(),
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 import_crypto7;
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
- import_crypto7 = require("crypto");
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
- taskId: this.settings.meshActiveTaskId,
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() && this.settings.meshActiveTaskId) {
70981
+ if (this.isMeshWorkerSession()) {
70821
70982
  const existingTaskId = typeof enrichedEvent.taskId === "string" && enrichedEvent.taskId.trim() ? enrichedEvent.taskId : void 0;
70822
70983
  if (!existingTaskId) {
70823
- enrichedEvent.taskId = this.settings.meshActiveTaskId;
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
  };