@adhdev/daemon-core 0.9.82-rc.366 → 0.9.82-rc.367

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.mjs CHANGED
@@ -311,10 +311,10 @@ function readInjected(value) {
311
311
  }
312
312
  function getDaemonBuildInfo() {
313
313
  if (cached) return cached;
314
- const commit = readInjected(true ? "c2224ab0c9d05e85b4cbf88e4fc696f3733ec397" : void 0) ?? "unknown";
315
- const commitShort = readInjected(true ? "c2224ab0" : void 0) ?? (commit !== "unknown" ? commit.slice(0, 7) : "unknown");
316
- const version = readInjected(true ? "0.9.82-rc.366" : void 0) ?? readInjected(typeof process !== "undefined" ? process.env?.ADHDEV_PKG_VERSION : void 0) ?? "unknown";
317
- const builtAt = readInjected(true ? "2026-06-24T02:22:36.214Z" : void 0);
314
+ const commit = readInjected(true ? "bb7e66dbc483232a27d1de42cf8ecba3eb0a818c" : void 0) ?? "unknown";
315
+ const commitShort = readInjected(true ? "bb7e66db" : void 0) ?? (commit !== "unknown" ? commit.slice(0, 7) : "unknown");
316
+ const version = readInjected(true ? "0.9.82-rc.367" : void 0) ?? readInjected(typeof process !== "undefined" ? process.env?.ADHDEV_PKG_VERSION : void 0) ?? "unknown";
317
+ const builtAt = readInjected(true ? "2026-06-24T04:45:13.384Z" : void 0);
318
318
  cached = builtAt ? { commit, commitShort, version, builtAt } : { commit, commitShort, version };
319
319
  return cached;
320
320
  }
@@ -2897,6 +2897,16 @@ function meshNodeIdMatches(node, candidateId) {
2897
2897
  if (!trimmed) return false;
2898
2898
  return normalizeMeshNodeId(node) === trimmed;
2899
2899
  }
2900
+ function normalizeMeshWorkspaceForCompare(dir) {
2901
+ if (typeof dir !== "string") return "";
2902
+ return dir.trim().replace(/[\\/]+/g, "/").replace(/\/+$/, "").toLowerCase();
2903
+ }
2904
+ function meshWorkspacesEquivalent(a, b) {
2905
+ const left = normalizeMeshWorkspaceForCompare(a);
2906
+ const right = normalizeMeshWorkspaceForCompare(b);
2907
+ if (!left || !right) return false;
2908
+ return left === right;
2909
+ }
2900
2910
  function machineCoreFromDaemonId(id) {
2901
2911
  const trimmed = readString3(id);
2902
2912
  if (!trimmed) return void 0;
@@ -12852,10 +12862,6 @@ function deliverTaskToSession(dispatchThunk, ctx) {
12852
12862
  }
12853
12863
  });
12854
12864
  }
12855
- function normalizeMeshWorkspaceForCompare(dir) {
12856
- if (typeof dir !== "string") return "";
12857
- return dir.trim().replace(/[\\/]+/g, "/").replace(/\/+$/, "").toLowerCase();
12858
- }
12859
12865
  function tryAssignQueueTask(components, meshId, nodeId, sessionId, providerType) {
12860
12866
  const mesh = getMeshWithCache(components, meshId);
12861
12867
  const node = mesh?.nodes.find((n) => readMeshNodeId(n) === nodeId);
@@ -13707,7 +13713,10 @@ function injectMeshSystemMessage(components, args) {
13707
13713
  if (terminal?.kind === "task_completed" && !sessionHasActiveAssignment(args.meshId, eventSessionId)) {
13708
13714
  const newDispatchAfterTerminal = hasDispatchAfterTerminal(args.meshId, eventSessionId, terminal.id);
13709
13715
  const supersedesWeakTerminal = isWeakTerminalLedgerPayload(terminal.payload) && isGenuineCompletionEvidence(args.metadataEvent);
13710
- if (!newDispatchAfterTerminal && !supersedesWeakTerminal) {
13716
+ const terminalTaskId = readNonEmptyString2(terminal.payload.taskId);
13717
+ const eventTaskId = readNonEmptyString2(args.metadataEvent.taskId);
13718
+ const distinctTaskCompletion = !!eventTaskId && !!terminalTaskId && eventTaskId !== terminalTaskId;
13719
+ if (!newDispatchAfterTerminal && !supersedesWeakTerminal && !distinctTaskCompletion) {
13711
13720
  const terminalProviderSessionId = readNonEmptyString2(terminal.payload.providerSessionId);
13712
13721
  const terminalFinalSummary = readNonEmptyString2(terminal.payload.finalSummary);
13713
13722
  const eventProviderSessionId = readNonEmptyString2(args.metadataEvent.providerSessionId);
@@ -14153,6 +14162,16 @@ function forwardUnresolvedDelegateEvent(components, routing, event) {
14153
14162
  nodeId: readNonEmptyString2(routing.nodeId) || readNonEmptyString2(event.meshNodeId) || void 0,
14154
14163
  workspace: readNonEmptyString2(routing.workspace) || readNonEmptyString2(event.workspace) || void 0
14155
14164
  };
14165
+ const selfDaemonIds = resolveCoordinatorDrainDaemonIds(components);
14166
+ if (selfDaemonIds.some((self) => daemonIdsEquivalent(self, coordinatorDaemonId))) {
14167
+ try {
14168
+ handleMeshForwardEvent(components, payload);
14169
+ LOG.info("MeshEvents", `Self-addressed unresolved-delegate ${eventName} routed via local router (coordinator ${coordinatorDaemonId} is self) \u2014 outbox skipped`);
14170
+ } catch (e) {
14171
+ LOG.warn("MeshEvents", `Local route of self-addressed unresolved-delegate ${eventName} failed: ${e?.message || e}`);
14172
+ }
14173
+ return true;
14174
+ }
14156
14175
  const persisted = enqueueUnresolvedDelegateForward(coordinatorDaemonId, eventName, payload);
14157
14176
  const fwdTraceCtx = {
14158
14177
  taskId: payload.taskId,
@@ -14660,6 +14679,8 @@ async function retryUnresolvedDelegateForwards(components) {
14660
14679
  expireStaleUnresolvedDelegateForwards();
14661
14680
  const entries = peekUnresolvedDelegateForwards();
14662
14681
  if (entries.length === 0) return;
14682
+ const selfIds = resolveCoordinatorDaemonIds(components);
14683
+ const isSelfCoordinatorId = (id) => selfIds.some((self) => daemonIdsEquivalent(self, id));
14663
14684
  for (const entry of entries) {
14664
14685
  const entryTraceCtx = {
14665
14686
  taskId: entry.payload.taskId,
@@ -14667,6 +14688,23 @@ async function retryUnresolvedDelegateForwards(components) {
14667
14688
  nodeId: readNonEmptyString2(entry.payload.nodeId),
14668
14689
  event: readNonEmptyString2(entry.payload.event)
14669
14690
  };
14691
+ if (isSelfCoordinatorId(entry.coordinatorDaemonId)) {
14692
+ let localResult;
14693
+ try {
14694
+ traceMeshEventStage("forward_send", entryTraceCtx, `self \u2192 local router (${entry.coordinatorDaemonId})`);
14695
+ localResult = handleMeshForwardEvent(components, entry.payload);
14696
+ } catch (e) {
14697
+ LOG.warn("MeshReconcile", `Local route of self-addressed forward to ${entry.coordinatorDaemonId} threw: ${e?.message || e} \u2014 draining anyway to break the retry loop`);
14698
+ }
14699
+ ackUnresolvedDelegateForward(entry.id);
14700
+ if (localResult && localResult.success === false) {
14701
+ LOG.warn("MeshReconcile", `Self-addressed unresolved-delegate ${readNonEmptyString2(entry.payload.event)} rejected by local router (${readNonEmptyString2(localResult.error) || "no reason"}) \u2014 drained to break the self-forward retry loop`);
14702
+ traceMeshEventDrop("self_forward_local_rejected", entryTraceCtx, readNonEmptyString2(localResult.error) || "no reason");
14703
+ } else {
14704
+ LOG.info("MeshReconcile", `Self-addressed unresolved-delegate ${readNonEmptyString2(entry.payload.event)} routed via local router (coordinator ${entry.coordinatorDaemonId} is self) \u2014 drained`);
14705
+ }
14706
+ continue;
14707
+ }
14670
14708
  let result;
14671
14709
  try {
14672
14710
  traceMeshEventStage("forward_send", entryTraceCtx, `retry \u2192 ${entry.coordinatorDaemonId}`);
@@ -27858,6 +27896,7 @@ var CHAT_SOURCE_REGISTRY = new ChatSourceRegistry();
27858
27896
 
27859
27897
  // src/commands/chat-commands.ts
27860
27898
  init_chat_message_normalization();
27899
+ init_dist();
27861
27900
  var RECENT_SEND_WINDOW_MS = 1200;
27862
27901
  var READ_CHAT_PROVIDER_EVAL_TIMEOUT_MS = 25e3;
27863
27902
  var HOT_TAIL_MIN_LIMIT = 60;
@@ -28419,6 +28458,24 @@ function normalizeComparableWorkspace(value) {
28419
28458
  if (!text) return "";
28420
28459
  return path16.resolve(text);
28421
28460
  }
28461
+ function evaluateReadChatNodeWorkspaceScope(args) {
28462
+ const targetSessionId = typeof args.targetSessionId === "string" ? args.targetSessionId.trim() : "";
28463
+ if (!targetSessionId) return { scoped: false };
28464
+ const intended = normalizeMeshWorkspaceForCompare(args.intendedWorkspace);
28465
+ const actual = normalizeMeshWorkspaceForCompare(args.sessionWorkspace);
28466
+ if (!intended || !actual) return { scoped: false };
28467
+ if (intended === actual) return { scoped: false };
28468
+ return { scoped: true, intended, actual };
28469
+ }
28470
+ function resolveTargetSessionActualWorkspace(h, targetSessionId) {
28471
+ const registryWorkspace = h.ctx?.sessionRegistry?.get?.(targetSessionId)?.workspace;
28472
+ if (typeof registryWorkspace === "string" && registryWorkspace.trim()) return registryWorkspace;
28473
+ const adapter = h.getCliAdapter?.(targetSessionId);
28474
+ if (adapter && typeof adapter.workingDir === "string" && adapter.workingDir.trim()) return adapter.workingDir;
28475
+ const instanceWorkspace = getTargetInstance(h, { targetSessionId })?.getState?.()?.workspace;
28476
+ if (typeof instanceWorkspace === "string" && instanceWorkspace.trim()) return instanceWorkspace;
28477
+ return "";
28478
+ }
28422
28479
  function isCurrentRuntimePtySafelyAttributed(args) {
28423
28480
  if (args.adapter.cliType !== "codex-cli") return false;
28424
28481
  if (!Array.isArray(args.ptyMessages) || args.ptyMessages.length === 0) return false;
@@ -29233,6 +29290,24 @@ async function handleChatHistory(h, args) {
29233
29290
  }
29234
29291
  }
29235
29292
  async function handleReadChat(h, args) {
29293
+ {
29294
+ const guardSessionId = typeof args?.targetSessionId === "string" ? args.targetSessionId.trim() : "";
29295
+ if (guardSessionId && typeof args?.workspace === "string" && args.workspace.trim()) {
29296
+ const verdict = evaluateReadChatNodeWorkspaceScope({
29297
+ targetSessionId: guardSessionId,
29298
+ intendedWorkspace: args.workspace,
29299
+ sessionWorkspace: resolveTargetSessionActualWorkspace(h, guardSessionId)
29300
+ });
29301
+ if (verdict.scoped) {
29302
+ LOG.info("Command", `[read_chat] node scope mismatch: session ${guardSessionId} workspace "${verdict.actual}" \u2260 requested node workspace "${verdict.intended}" \u2014 refusing cross-worktree transcript`);
29303
+ return {
29304
+ success: false,
29305
+ code: "read_chat_session_node_scope_mismatch",
29306
+ error: `Session ${guardSessionId} belongs to a different worktree (workspace "${verdict.actual}") than the requested node (workspace "${verdict.intended}"). Refusing to return a cross-worktree transcript \u2014 target the node that owns this session.`
29307
+ };
29308
+ }
29309
+ }
29310
+ }
29236
29311
  let providerHint = args?.agentType || args?.providerType;
29237
29312
  if (!providerHint) {
29238
29313
  const targetSessionId = typeof args?.targetSessionId === "string" ? args.targetSessionId.trim() : "";
@@ -29621,10 +29696,19 @@ async function handleReadChat(h, args) {
29621
29696
  ptyStatusApprovalOnly: false
29622
29697
  });
29623
29698
  if (supportsNative && !decision.nativeSelected) {
29699
+ LOG.debug("Command", `[read_chat] soft pending: no live adapter and native history not safely mappable target=${String(args?.targetSessionId || "")} provider=${agentStr} reason=native_history_not_safely_available`);
29624
29700
  return {
29625
- success: false,
29701
+ success: true,
29702
+ pending: true,
29703
+ // Both signals are true here: we reached the history-only path
29704
+ // because no live adapter was found (`live_adapter_not_found`),
29705
+ // and native history is not safely mappable
29706
+ // (`native_history_not_safely_available`).
29707
+ reason: "native_history_not_safely_available",
29708
+ reasons: ["live_adapter_not_found", "native_history_not_safely_available"],
29626
29709
  code: "native_history_not_safely_available",
29627
- error: "Provider-native history was not safely available for the requested CLI session.",
29710
+ messages: [],
29711
+ status: "idle",
29628
29712
  providerSessionId: historyProviderSessionId,
29629
29713
  messageSource: decision.messageSource,
29630
29714
  transcriptProvenance: decision.messageSource
@@ -49129,6 +49213,7 @@ function readMeshTimeoutEnvMs(name, defaultMs) {
49129
49213
  }
49130
49214
  var MESH_DIRECT_PROBE_TIMEOUT_MS = readMeshTimeoutEnvMs("MESH_DIRECT_PROBE_TIMEOUT_MS", 25e3);
49131
49215
  var MESH_DIRECT_PROBE_RETRY_TIMEOUT_MS = readMeshTimeoutEnvMs("MESH_DIRECT_PROBE_RETRY_TIMEOUT_MS", 25e3);
49216
+ var MESH_DIRECT_PROBE_CONNECT_TIMEOUT_MS = readMeshTimeoutEnvMs("MESH_DIRECT_PROBE_CONNECT_TIMEOUT_MS", 45e3);
49132
49217
  var MESH_DIRECT_PROBE_REUSE_MS = readMeshTimeoutEnvMs("MESH_DIRECT_PROBE_REUSE_MS", 12e3);
49133
49218
  var MeshGitProbeCache = class {
49134
49219
  constructor(reuseMs, now = Date.now) {
@@ -49166,12 +49251,73 @@ var MeshGitProbeCache = class {
49166
49251
  }
49167
49252
  }
49168
49253
  };
49254
+ function awaitWithWarmupDeadline(work, opts) {
49255
+ const pollMs = Math.max(1, Math.min(opts.pollIntervalMs ?? 200, opts.connectTimeoutMs));
49256
+ return new Promise((resolve24, reject) => {
49257
+ let done = false;
49258
+ let poll;
49259
+ let responseTimer;
49260
+ const startedAt = Date.now();
49261
+ const cleanup = () => {
49262
+ if (poll) {
49263
+ clearInterval(poll);
49264
+ poll = void 0;
49265
+ }
49266
+ if (responseTimer) {
49267
+ clearTimeout(responseTimer);
49268
+ responseTimer = void 0;
49269
+ }
49270
+ };
49271
+ const settle = (fn) => {
49272
+ if (done) return;
49273
+ done = true;
49274
+ cleanup();
49275
+ fn();
49276
+ };
49277
+ const armResponse = () => {
49278
+ if (responseTimer || done) return;
49279
+ responseTimer = setTimeout(
49280
+ () => settle(() => reject(new Error("timeout"))),
49281
+ opts.responseTimeoutMs
49282
+ );
49283
+ if (typeof responseTimer.unref === "function") responseTimer.unref();
49284
+ };
49285
+ const onPoll = () => {
49286
+ if (done) return;
49287
+ if (opts.isConnected()) {
49288
+ if (poll) {
49289
+ clearInterval(poll);
49290
+ poll = void 0;
49291
+ }
49292
+ armResponse();
49293
+ return;
49294
+ }
49295
+ if (Date.now() - startedAt >= opts.connectTimeoutMs) {
49296
+ settle(() => reject(new Error("timeout")));
49297
+ }
49298
+ };
49299
+ if (opts.isConnected()) {
49300
+ armResponse();
49301
+ } else {
49302
+ poll = setInterval(onPoll, pollMs);
49303
+ if (typeof poll.unref === "function") poll.unref();
49304
+ }
49305
+ work.then(
49306
+ (val) => settle(() => resolve24(val)),
49307
+ (err) => settle(() => reject(err))
49308
+ );
49309
+ });
49310
+ }
49169
49311
  async function probeRemoteMeshGitStatus(args) {
49170
49312
  if (!args.dispatchMeshCommand) return null;
49171
- const remoteResult = await Promise.race([
49172
- args.dispatchMeshCommand(args.daemonId, "git_status", { workspace: args.workspace, refreshUpstream: true }),
49173
- new Promise((_, reject) => setTimeout(() => reject(new Error("timeout")), args.timeoutMs))
49174
- ]);
49313
+ const dispatch = args.dispatchMeshCommand(args.daemonId, "git_status", { workspace: args.workspace, refreshUpstream: true });
49314
+ const getConnection = args.getConnection;
49315
+ const isConnected = getConnection ? () => readMeshConnectionState(getConnection(args.daemonId)) === "connected" : () => true;
49316
+ const remoteResult = await awaitWithWarmupDeadline(dispatch, {
49317
+ isConnected,
49318
+ connectTimeoutMs: args.connectTimeoutMs,
49319
+ responseTimeoutMs: args.responseTimeoutMs
49320
+ });
49175
49321
  const remoteGit = remoteResult?.status ?? remoteResult?.git ?? remoteResult;
49176
49322
  if (!remoteGit || typeof remoteGit !== "object" || typeof remoteGit.isGitRepo !== "boolean") return null;
49177
49323
  const reporterPlatform = readStringValue(remoteResult?.reporterPlatform);
@@ -49206,7 +49352,9 @@ async function probeRemoteMeshGitStatusWithRetry(args) {
49206
49352
  dispatchMeshCommand: args.dispatchMeshCommand,
49207
49353
  daemonId: args.daemonId,
49208
49354
  workspace: args.workspace,
49209
- timeoutMs: attempt === 0 ? args.timeoutMs : args.retryTimeoutMs ?? args.timeoutMs
49355
+ responseTimeoutMs: attempt === 0 ? args.timeoutMs : args.retryTimeoutMs ?? args.timeoutMs,
49356
+ connectTimeoutMs: args.connectTimeoutMs ?? MESH_DIRECT_PROBE_CONNECT_TIMEOUT_MS,
49357
+ getConnection: args.getConnection
49210
49358
  });
49211
49359
  if (remoteGit) return remoteGit;
49212
49360
  } catch {
@@ -49289,6 +49437,7 @@ async function hydrateInlineMeshDirectTruth(args) {
49289
49437
  workspace,
49290
49438
  timeoutMs: MESH_DIRECT_PROBE_TIMEOUT_MS,
49291
49439
  retryTimeoutMs: MESH_DIRECT_PROBE_RETRY_TIMEOUT_MS,
49440
+ connectTimeoutMs: MESH_DIRECT_PROBE_CONNECT_TIMEOUT_MS,
49292
49441
  getConnection: args.getMeshPeerConnectionStatus
49293
49442
  });
49294
49443
  const remoteGit = args.probeCache ? await args.probeCache.probe(daemonId, workspace, runProbe) : await runProbe();
@@ -49340,13 +49489,13 @@ function liveSessionRecordMatchesMeshNode(record, meshId, nodeId, nodeWorkspace
49340
49489
  if (!recordNodeId || recordNodeId !== nodeId) return false;
49341
49490
  if (nodeIsMissingLocalWorktree) return false;
49342
49491
  const recordWorkspace = readStringValue(record?.workspace);
49343
- if (nodeWorkspace && recordWorkspace && recordWorkspace !== nodeWorkspace) return false;
49492
+ if (nodeWorkspace && recordWorkspace && !meshWorkspacesEquivalent(recordWorkspace, nodeWorkspace)) return false;
49344
49493
  const recordMeshId = readStringValue(record?.meta?.meshNodeFor);
49345
49494
  return !recordMeshId || recordMeshId === meshId;
49346
49495
  }
49347
49496
  function liveSessionRecordMatchesMeshWorkspace(record, meshId, workspace) {
49348
49497
  const recordWorkspace = readStringValue(record?.workspace);
49349
- if (!recordWorkspace || !workspace || recordWorkspace !== workspace) return false;
49498
+ if (!recordWorkspace || !workspace || !meshWorkspacesEquivalent(recordWorkspace, workspace)) return false;
49350
49499
  const recordMeshId = readStringValue(record?.meta?.meshNodeFor);
49351
49500
  if (recordMeshId) return recordMeshId === meshId;
49352
49501
  return record?.meta?.launchedByCoordinator === true || !!readStringValue(record?.meta?.meshNodeId);