@adhdev/daemon-core 0.9.82-rc.24 → 0.9.82-rc.26

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
@@ -1512,18 +1512,20 @@ function requeueTask(meshId, taskId, opts) {
1512
1512
  return entry;
1513
1513
  });
1514
1514
  }
1515
- function updateSessionTaskStatus(meshId, sessionId, status) {
1515
+ function updateSessionTaskStatus(meshId, sessionId, status, opts) {
1516
1516
  return withQueueLock(meshId, () => {
1517
1517
  const queue = readQueue(meshId);
1518
+ const occurredAtTime = opts?.occurredAt ? new Date(opts.occurredAt).getTime() : Number.NaN;
1519
+ const hasOccurredAt = Number.isFinite(occurredAtTime);
1518
1520
  let bestIdx = -1;
1519
1521
  let bestTime = 0;
1520
1522
  for (let i = queue.length - 1; i >= 0; i--) {
1521
- if (queue[i].assignedSessionId === sessionId && queue[i].status === "assigned") {
1522
- const time = new Date(queue[i].dispatchTimestamp || queue[i].updatedAt).getTime();
1523
- if (time > bestTime) {
1524
- bestTime = time;
1525
- bestIdx = i;
1526
- }
1523
+ if (queue[i].assignedSessionId !== sessionId || queue[i].status !== "assigned") continue;
1524
+ const time = new Date(queue[i].dispatchTimestamp || queue[i].updatedAt).getTime();
1525
+ if (hasOccurredAt && Number.isFinite(time) && time > occurredAtTime) continue;
1526
+ if (time > bestTime) {
1527
+ bestTime = time;
1528
+ bestIdx = i;
1527
1529
  }
1528
1530
  }
1529
1531
  if (bestIdx === -1) return null;
@@ -2047,6 +2049,38 @@ function shouldSuppressIntentionalCleanupStop(args) {
2047
2049
  if (isIntentionalCleanupStopMetadata(args.metadataEvent)) return true;
2048
2050
  return hasRecentIntentionalCleanupStop(args.meshId, args.sessionId, args.nodeId);
2049
2051
  }
2052
+ function readEventTimestamp(value) {
2053
+ if (typeof value === "number" && Number.isFinite(value)) return value;
2054
+ if (typeof value === "string" && value.trim()) {
2055
+ const numeric = Number(value);
2056
+ if (Number.isFinite(numeric)) return numeric;
2057
+ const parsed = Date.parse(value);
2058
+ if (Number.isFinite(parsed)) return parsed;
2059
+ }
2060
+ return null;
2061
+ }
2062
+ function buildMeshCompletionFingerprint(args) {
2063
+ const timestampPart = Number.isFinite(args.timestamp) ? String(args.timestamp) : readNonEmptyString(args.finalSummary).slice(0, 200);
2064
+ return [
2065
+ args.meshId,
2066
+ args.event,
2067
+ args.sessionId,
2068
+ args.providerType || "",
2069
+ args.providerSessionId || "",
2070
+ timestampPart
2071
+ ].join("::");
2072
+ }
2073
+ function isDuplicateMeshCompletionEvent(args) {
2074
+ const fingerprint = buildMeshCompletionFingerprint(args);
2075
+ if (!fingerprint) return false;
2076
+ const now = Date.now();
2077
+ for (const [key, seenAt] of recentCompletionFingerprints.entries()) {
2078
+ if (now - seenAt > RECENT_COMPLETION_FINGERPRINT_TTL_MS) recentCompletionFingerprints.delete(key);
2079
+ }
2080
+ if (recentCompletionFingerprints.has(fingerprint)) return true;
2081
+ recentCompletionFingerprints.set(fingerprint, now);
2082
+ return false;
2083
+ }
2050
2084
  function tryAssignQueueTask(components, meshId, nodeId, sessionId, providerType) {
2051
2085
  const task = claimNextTask(meshId, nodeId, sessionId);
2052
2086
  if (!task) {
@@ -2408,13 +2442,31 @@ function injectMeshSystemMessage(components, args) {
2408
2442
  LOG.info("MeshEvents", `Suppressed ${args.event} for intentionally cleanup-stopped session ${eventSessionId || "(unknown session)"}`);
2409
2443
  return { success: true, forwarded: 0, suppressed: true, intentionalCleanupStop: true };
2410
2444
  }
2445
+ const eventTimestamp = readEventTimestamp(args.metadataEvent.timestamp);
2446
+ if (args.event === "agent:generating_completed" && eventSessionId) {
2447
+ const duplicateCompletion = isDuplicateMeshCompletionEvent({
2448
+ meshId: args.meshId,
2449
+ event: args.event,
2450
+ sessionId: eventSessionId,
2451
+ providerType: readNonEmptyString(args.metadataEvent.providerType) || void 0,
2452
+ providerSessionId: readNonEmptyString(args.metadataEvent.providerSessionId) || void 0,
2453
+ timestamp: eventTimestamp,
2454
+ finalSummary: readNonEmptyString(args.metadataEvent.finalSummary) || void 0
2455
+ });
2456
+ if (duplicateCompletion) {
2457
+ LOG.info("MeshEvents", `Suppressed duplicate completion for mesh ${args.meshId} session ${eventSessionId}`);
2458
+ return { success: true, forwarded: 0, suppressed: true, duplicateCompletion: true };
2459
+ }
2460
+ }
2411
2461
  let completedTaskForLedger = null;
2412
2462
  if (args.event === "agent:generating_completed") {
2413
2463
  const sessionId = resolveEventSessionId(args.metadataEvent, args.sourceInstanceId);
2414
2464
  const nodeId = readNonEmptyString(args.nodeId) || readNonEmptyString(args.metadataEvent.meshNodeId);
2415
2465
  const providerType = readNonEmptyString(args.metadataEvent.providerType);
2416
2466
  if (sessionId) {
2417
- const completedTask = updateSessionTaskStatus(args.meshId, sessionId, "completed");
2467
+ const completedTask = updateSessionTaskStatus(args.meshId, sessionId, "completed", {
2468
+ occurredAt: eventTimestamp !== null ? new Date(eventTimestamp).toISOString() : void 0
2469
+ });
2418
2470
  completedTaskForLedger = completedTask ? { id: completedTask.id } : null;
2419
2471
  if (nodeId && providerType) {
2420
2472
  setImmediate(() => {
@@ -2628,6 +2680,7 @@ function handleMeshForwardEvent(components, payload) {
2628
2680
  providerType: readNonEmptyString(payload.providerType),
2629
2681
  providerSessionId: readNonEmptyString(payload.providerSessionId),
2630
2682
  finalSummary: readNonEmptyString(payload.finalSummary) || readNonEmptyString(payload.summary),
2683
+ ...payload.timestamp !== void 0 ? { timestamp: payload.timestamp } : {},
2631
2684
  intentional: payload.intentional === true,
2632
2685
  intentionalStop: payload.intentionalStop === true,
2633
2686
  operatorCleanup: payload.operatorCleanup === true,
@@ -2670,7 +2723,7 @@ function setupMeshEventForwarding(components) {
2670
2723
  });
2671
2724
  });
2672
2725
  }
2673
- var REMOTE_IDLE_SESSION_TTL_MS, remoteIdleSessions, MESH_COORDINATOR_EVENTS, EVENT_TO_LEDGER_KIND, INTENTIONAL_CLEANUP_STOP_SUPPRESSION_MS, autoLaunchInProgress, autoLaunchCooldownUntil, AUTO_LAUNCH_COOLDOWN_MS;
2726
+ var REMOTE_IDLE_SESSION_TTL_MS, remoteIdleSessions, MESH_COORDINATOR_EVENTS, EVENT_TO_LEDGER_KIND, INTENTIONAL_CLEANUP_STOP_SUPPRESSION_MS, RECENT_COMPLETION_FINGERPRINT_TTL_MS, recentCompletionFingerprints, autoLaunchInProgress, autoLaunchCooldownUntil, AUTO_LAUNCH_COOLDOWN_MS;
2674
2727
  var init_mesh_events = __esm({
2675
2728
  "src/mesh/mesh-events.ts"() {
2676
2729
  "use strict";
@@ -2697,6 +2750,8 @@ var init_mesh_events = __esm({
2697
2750
  "monitor:long_generating": "task_stalled"
2698
2751
  };
2699
2752
  INTENTIONAL_CLEANUP_STOP_SUPPRESSION_MS = 30 * 60 * 1e3;
2753
+ RECENT_COMPLETION_FINGERPRINT_TTL_MS = 10 * 60 * 1e3;
2754
+ recentCompletionFingerprints = /* @__PURE__ */ new Map();
2700
2755
  autoLaunchInProgress = /* @__PURE__ */ new Set();
2701
2756
  autoLaunchCooldownUntil = /* @__PURE__ */ new Map();
2702
2757
  AUTO_LAUNCH_COOLDOWN_MS = 5e3;
@@ -23804,49 +23859,7 @@ function readGitSubmodules(value) {
23804
23859
  }).filter((entry) => entry !== null);
23805
23860
  return submodules.length > 0 ? submodules : void 0;
23806
23861
  }
23807
- function buildCachedInlineMeshGitStatus(node) {
23808
- const cachedStatus = readObjectRecord(node?.cachedStatus);
23809
- const cachedGit = readObjectRecord(cachedStatus.git);
23810
- if (Object.keys(cachedGit).length) {
23811
- const conflictFiles2 = Array.isArray(cachedGit.conflictFiles) ? cachedGit.conflictFiles.filter((value) => typeof value === "string") : [];
23812
- const conflictCount2 = readNumberValue(cachedGit.conflicts) ?? conflictFiles2.length;
23813
- const hasConflicts2 = readBooleanValue(cachedGit.hasConflicts) ?? conflictCount2 > 0;
23814
- const isGitRepo2 = readBooleanValue(cachedGit.isGitRepo);
23815
- if (isGitRepo2 !== void 0) {
23816
- const submodules2 = readGitSubmodules(cachedGit.submodules);
23817
- return {
23818
- workspace: readStringValue(cachedGit.workspace, node?.workspace) || "",
23819
- repoRoot: readStringValue(cachedGit.repoRoot, node?.repoRoot, node?.workspace) || null,
23820
- isGitRepo: isGitRepo2,
23821
- branch: readStringValue(cachedGit.branch) ?? null,
23822
- headCommit: readStringValue(cachedGit.headCommit) ?? null,
23823
- headMessage: readStringValue(cachedGit.headMessage) ?? null,
23824
- upstream: readStringValue(cachedGit.upstream) ?? null,
23825
- ahead: readNumberValue(cachedGit.ahead) ?? 0,
23826
- behind: readNumberValue(cachedGit.behind) ?? 0,
23827
- staged: readNumberValue(cachedGit.staged) ?? 0,
23828
- modified: readNumberValue(cachedGit.modified) ?? 0,
23829
- untracked: readNumberValue(cachedGit.untracked) ?? 0,
23830
- deleted: readNumberValue(cachedGit.deleted) ?? 0,
23831
- renamed: readNumberValue(cachedGit.renamed) ?? 0,
23832
- hasConflicts: hasConflicts2,
23833
- conflictFiles: conflictFiles2,
23834
- stashCount: readNumberValue(cachedGit.stashCount) ?? 0,
23835
- lastCheckedAt: readNumberValue(cachedGit.lastCheckedAt) ?? Date.now(),
23836
- ...submodules2 ? { submodules: submodules2 } : {}
23837
- };
23838
- }
23839
- }
23840
- const rawGit = readObjectRecord(node?.lastGit ?? node?.last_git);
23841
- const gitResult = readObjectRecord(rawGit.result);
23842
- const directStatus = readObjectRecord(rawGit.status);
23843
- const nestedStatus = readObjectRecord(gitResult.status);
23844
- const rawProbe = readObjectRecord(node?.lastProbe ?? node?.last_probe);
23845
- const probeGit = readObjectRecord(rawProbe.git);
23846
- const probeGitResult = readObjectRecord(probeGit.result);
23847
- const probeDirectStatus = readObjectRecord(probeGit.status);
23848
- const probeNestedStatus = readObjectRecord(probeGitResult.status);
23849
- const status = Object.keys(directStatus).length ? directStatus : Object.keys(nestedStatus).length ? nestedStatus : Object.keys(probeDirectStatus).length ? probeDirectStatus : Object.keys(probeNestedStatus).length ? probeNestedStatus : {};
23862
+ function normalizeInlineMeshGitStatus(status, node, options) {
23850
23863
  const isGitRepo = readBooleanValue(status.isGitRepo);
23851
23864
  if (!Object.keys(status).length || isGitRepo === void 0) return void 0;
23852
23865
  const conflictFiles = Array.isArray(status.conflictFiles) ? status.conflictFiles.filter((value) => typeof value === "string") : [];
@@ -23871,10 +23884,31 @@ function buildCachedInlineMeshGitStatus(node) {
23871
23884
  hasConflicts,
23872
23885
  conflictFiles,
23873
23886
  stashCount: readNumberValue(status.stashCount) ?? 0,
23874
- lastCheckedAt: Date.now(),
23887
+ lastCheckedAt: options?.lastCheckedAt ?? readNumberValue(status.lastCheckedAt) ?? Date.now(),
23875
23888
  ...submodules ? { submodules } : {}
23876
23889
  };
23877
23890
  }
23891
+ function buildInlineMeshTransitGitStatus(node) {
23892
+ const rawGit = readObjectRecord(node?.lastGit ?? node?.last_git);
23893
+ const gitResult = readObjectRecord(rawGit.result);
23894
+ const directStatus = readObjectRecord(rawGit.status);
23895
+ const nestedStatus = readObjectRecord(gitResult.status);
23896
+ const rawProbe = readObjectRecord(node?.lastProbe ?? node?.last_probe);
23897
+ const probeGit = readObjectRecord(rawProbe.git);
23898
+ const probeGitResult = readObjectRecord(probeGit.result);
23899
+ const probeDirectStatus = readObjectRecord(probeGit.status);
23900
+ const probeNestedStatus = readObjectRecord(probeGitResult.status);
23901
+ const status = Object.keys(directStatus).length ? directStatus : Object.keys(nestedStatus).length ? nestedStatus : Object.keys(probeDirectStatus).length ? probeDirectStatus : Object.keys(probeNestedStatus).length ? probeNestedStatus : {};
23902
+ return normalizeInlineMeshGitStatus(status, node, { lastCheckedAt: Date.now() });
23903
+ }
23904
+ function buildCachedInlineMeshGitStatus(node) {
23905
+ const liveGit = buildInlineMeshTransitGitStatus(node);
23906
+ if (liveGit) return liveGit;
23907
+ const cachedStatus = readObjectRecord(node?.cachedStatus);
23908
+ const cachedGit = readObjectRecord(cachedStatus.git);
23909
+ if (!Object.keys(cachedGit).length) return void 0;
23910
+ return normalizeInlineMeshGitStatus(cachedGit, node);
23911
+ }
23878
23912
  function shouldDiscardCachedInlineMeshStatus(node) {
23879
23913
  const cachedStatus = readObjectRecord(node?.cachedStatus);
23880
23914
  if (!Object.keys(cachedStatus).length) return false;
@@ -24103,9 +24137,10 @@ function collectLiveMeshSessionRecords(args) {
24103
24137
  }
24104
24138
  function applyCachedInlineMeshNodeStatus(status, node) {
24105
24139
  const cachedStatus = readObjectRecord(node?.cachedStatus);
24106
- const git = buildCachedInlineMeshGitStatus(node);
24107
- const error = readStringValue(cachedStatus.error, node?.error);
24108
- const health = readStringValue(cachedStatus.health, node?.health);
24140
+ const liveGit = buildInlineMeshTransitGitStatus(node);
24141
+ const git = liveGit ?? buildCachedInlineMeshGitStatus(node);
24142
+ const error = liveGit ? void 0 : readStringValue(cachedStatus.error, node?.error);
24143
+ const health = liveGit ? void 0 : readStringValue(cachedStatus.health, node?.health);
24109
24144
  const machineStatus = readStringValue(cachedStatus.machineStatus, node?.machineStatus);
24110
24145
  const lastSeenAt = toIsoTimestamp(cachedStatus.lastSeenAt ?? cachedStatus.last_seen_at ?? node?.lastSeenAt ?? node?.last_seen_at);
24111
24146
  const updatedAt = toIsoTimestamp(cachedStatus.updatedAt ?? cachedStatus.updated_at ?? node?.updatedAt ?? node?.updated_at);