@adhdev/daemon-core 0.9.77-rc.50 → 0.9.77-rc.52

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
@@ -1207,6 +1207,7 @@ function claimNextTask(meshId, nodeId, sessionId) {
1207
1207
  entry.status = "assigned";
1208
1208
  entry.assignedNodeId = nodeId;
1209
1209
  entry.assignedSessionId = sessionId;
1210
+ entry.dispatchTimestamp = (/* @__PURE__ */ new Date()).toISOString();
1210
1211
  entry.updatedAt = (/* @__PURE__ */ new Date()).toISOString();
1211
1212
  writeQueue(meshId, queue);
1212
1213
  return entry;
@@ -1269,15 +1270,22 @@ function requeueTask(meshId, taskId, opts) {
1269
1270
  }
1270
1271
  function updateSessionTaskStatus(meshId, sessionId, status) {
1271
1272
  const queue = readQueue(meshId);
1273
+ let bestIdx = -1;
1274
+ let bestTime = 0;
1272
1275
  for (let i = queue.length - 1; i >= 0; i--) {
1273
1276
  if (queue[i].assignedSessionId === sessionId && queue[i].status === "assigned") {
1274
- queue[i].status = status;
1275
- queue[i].updatedAt = (/* @__PURE__ */ new Date()).toISOString();
1276
- writeQueue(meshId, queue);
1277
- return queue[i];
1277
+ const time = new Date(queue[i].dispatchTimestamp || queue[i].updatedAt).getTime();
1278
+ if (time > bestTime) {
1279
+ bestTime = time;
1280
+ bestIdx = i;
1281
+ }
1278
1282
  }
1279
1283
  }
1280
- return null;
1284
+ if (bestIdx === -1) return null;
1285
+ queue[bestIdx].status = status;
1286
+ queue[bestIdx].updatedAt = (/* @__PURE__ */ new Date()).toISOString();
1287
+ writeQueue(meshId, queue);
1288
+ return queue[bestIdx];
1281
1289
  }
1282
1290
  function getMeshQueueStats(meshId) {
1283
1291
  const queue = readQueue(meshId);
@@ -1673,7 +1681,9 @@ var init_logger = __esm({
1673
1681
  // src/mesh/mesh-events.ts
1674
1682
  var mesh_events_exports = {};
1675
1683
  __export(mesh_events_exports, {
1684
+ clearPendingMeshCoordinatorEvents: () => clearPendingMeshCoordinatorEvents,
1676
1685
  drainPendingMeshCoordinatorEvents: () => drainPendingMeshCoordinatorEvents,
1686
+ getPendingMeshCoordinatorEvents: () => getPendingMeshCoordinatorEvents,
1677
1687
  handleMeshForwardEvent: () => handleMeshForwardEvent,
1678
1688
  setupMeshEventForwarding: () => setupMeshEventForwarding,
1679
1689
  triggerMeshQueue: () => triggerMeshQueue,
@@ -1682,6 +1692,12 @@ __export(mesh_events_exports, {
1682
1692
  function drainPendingMeshCoordinatorEvents() {
1683
1693
  return pendingMeshCoordinatorEvents.splice(0);
1684
1694
  }
1695
+ function getPendingMeshCoordinatorEvents() {
1696
+ return pendingMeshCoordinatorEvents.slice();
1697
+ }
1698
+ function clearPendingMeshCoordinatorEvents() {
1699
+ pendingMeshCoordinatorEvents.splice(0);
1700
+ }
1685
1701
  function readNonEmptyString(value) {
1686
1702
  return typeof value === "string" && value.trim() ? value.trim() : "";
1687
1703
  }
@@ -7372,6 +7388,231 @@ function buildMeshLedgerReconciliationEvidence(meshId, replicas) {
7372
7388
 
7373
7389
  // src/index.ts
7374
7390
  init_mesh_work_queue();
7391
+
7392
+ // src/mesh/mesh-visualization.ts
7393
+ function isDirty(git) {
7394
+ if (!git) return false;
7395
+ return git.staged + git.modified + git.untracked + git.deleted + git.renamed > 0;
7396
+ }
7397
+ function dirtyFileCount(git) {
7398
+ if (!git) return 0;
7399
+ return git.staged + git.modified + git.untracked + git.deleted + git.renamed;
7400
+ }
7401
+ function detectOrphanReasons(node, defaultBranch) {
7402
+ const reasons = [];
7403
+ const git = node.git;
7404
+ if (!git) {
7405
+ reasons.push("No git status available");
7406
+ return reasons;
7407
+ }
7408
+ if (!git.isGitRepo) {
7409
+ reasons.push("Not a git repository");
7410
+ return reasons;
7411
+ }
7412
+ if (git.branch === null && git.headCommit) {
7413
+ reasons.push("Detached HEAD");
7414
+ }
7415
+ if (git.branch && !git.upstream) {
7416
+ if (defaultBranch && git.branch !== defaultBranch) {
7417
+ reasons.push(`No upstream: ${git.branch}`);
7418
+ }
7419
+ }
7420
+ if (git.branch && git.upstream === null && defaultBranch && git.branch !== defaultBranch) {
7421
+ if (!reasons.includes(`No upstream: ${git.branch}`)) {
7422
+ reasons.push(`No upstream: ${git.branch}`);
7423
+ }
7424
+ }
7425
+ if (node.error) {
7426
+ reasons.push(`Error: ${node.error}`);
7427
+ }
7428
+ return reasons;
7429
+ }
7430
+ function nodeHealthPriority(health) {
7431
+ switch (health) {
7432
+ case "online":
7433
+ return 0;
7434
+ case "dirty":
7435
+ return 1;
7436
+ case "degraded":
7437
+ return 2;
7438
+ case "wrong_branch":
7439
+ return 3;
7440
+ case "offline":
7441
+ return 4;
7442
+ case "unknown":
7443
+ return 5;
7444
+ default:
7445
+ return 5;
7446
+ }
7447
+ }
7448
+ function pickDominantHealth(healths) {
7449
+ if (healths.length === 0) return "unknown";
7450
+ return healths.reduce(
7451
+ (best, h) => nodeHealthPriority(h) > nodeHealthPriority(best) ? h : best
7452
+ );
7453
+ }
7454
+ function buildMeshGraph(status) {
7455
+ const nodes = [];
7456
+ const edges = [];
7457
+ const warnings = [];
7458
+ const branchToNodeIds = /* @__PURE__ */ new Map();
7459
+ for (const nodeStatus of status.nodes) {
7460
+ const git = nodeStatus.git;
7461
+ const branch = git?.branch || null;
7462
+ const orphanReasons = detectOrphanReasons(nodeStatus, null);
7463
+ const dirty = isDirty(git);
7464
+ const dfc = dirtyFileCount(git);
7465
+ let type = "worktreeNode";
7466
+ if (orphanReasons.length > 0) {
7467
+ type = "orphanNode";
7468
+ }
7469
+ const graphNode = {
7470
+ id: nodeStatus.nodeId,
7471
+ type,
7472
+ label: nodeStatus.machineLabel || nodeStatus.nodeId.slice(0, 8),
7473
+ workspace: nodeStatus.workspace,
7474
+ branch,
7475
+ health: nodeStatus.health,
7476
+ ahead: git?.ahead ?? 0,
7477
+ behind: git?.behind ?? 0,
7478
+ dirty,
7479
+ dirtyFiles: dfc,
7480
+ hasConflicts: git?.hasConflicts ?? false,
7481
+ activeSessionCount: nodeStatus.activeSessions?.length ?? 0,
7482
+ activeSessions: nodeStatus.activeSessions ?? [],
7483
+ providers: nodeStatus.providers ?? [],
7484
+ isOrphan: orphanReasons.length > 0,
7485
+ orphanReasons,
7486
+ source: nodeStatus
7487
+ };
7488
+ nodes.push(graphNode);
7489
+ if (branch) {
7490
+ const list = branchToNodeIds.get(branch) ?? [];
7491
+ list.push(graphNode.id);
7492
+ branchToNodeIds.set(branch, list);
7493
+ }
7494
+ }
7495
+ const branchUpstreamCounts = /* @__PURE__ */ new Map();
7496
+ for (const n of status.nodes) {
7497
+ const b = n.git?.branch;
7498
+ const upstream = n.git?.upstream;
7499
+ if (b && upstream) {
7500
+ branchUpstreamCounts.set(b, (branchUpstreamCounts.get(b) ?? 0) + 1);
7501
+ }
7502
+ }
7503
+ let inferredDefaultBranch = null;
7504
+ let bestCount = 0;
7505
+ for (const [b, count] of branchUpstreamCounts) {
7506
+ if (count > bestCount) {
7507
+ bestCount = count;
7508
+ inferredDefaultBranch = b;
7509
+ }
7510
+ }
7511
+ const defaultBranchNodeId = inferredDefaultBranch ? `__branch_${inferredDefaultBranch}` : null;
7512
+ if (defaultBranchNodeId && inferredDefaultBranch) {
7513
+ const branchNodes = branchToNodeIds.get(inferredDefaultBranch) ?? [];
7514
+ const branchHealths = branchNodes.map(
7515
+ (id) => nodes.find((n) => n.id === id).health
7516
+ );
7517
+ const defaultNode = {
7518
+ id: defaultBranchNodeId,
7519
+ type: "defaultBranchNode",
7520
+ label: inferredDefaultBranch,
7521
+ workspace: "",
7522
+ branch: inferredDefaultBranch,
7523
+ health: pickDominantHealth(branchHealths),
7524
+ ahead: 0,
7525
+ behind: 0,
7526
+ dirty: false,
7527
+ dirtyFiles: 0,
7528
+ hasConflicts: false,
7529
+ activeSessionCount: 0,
7530
+ activeSessions: [],
7531
+ providers: [],
7532
+ isOrphan: false,
7533
+ orphanReasons: [],
7534
+ nextStepHint: branchNodes.length > 0 ? `${branchNodes.length} node(s) on default branch` : void 0,
7535
+ source: {
7536
+ nodeId: defaultBranchNodeId,
7537
+ machineLabel: inferredDefaultBranch,
7538
+ workspace: "",
7539
+ health: "online",
7540
+ providers: [],
7541
+ activeSessions: []
7542
+ }
7543
+ };
7544
+ nodes.push(defaultNode);
7545
+ const seenBranches = /* @__PURE__ */ new Set();
7546
+ for (const n of nodes) {
7547
+ if (n.type === "defaultBranchNode") continue;
7548
+ if (!n.branch) continue;
7549
+ if (n.branch === inferredDefaultBranch) {
7550
+ edges.push({
7551
+ id: `${defaultBranchNodeId}--${n.id}`,
7552
+ source: defaultBranchNodeId,
7553
+ target: n.id,
7554
+ type: "parentBranch",
7555
+ label: "default"
7556
+ });
7557
+ continue;
7558
+ }
7559
+ if (seenBranches.has(n.branch)) continue;
7560
+ seenBranches.add(n.branch);
7561
+ edges.push({
7562
+ id: `${defaultBranchNodeId}--branch_${n.branch}`,
7563
+ source: defaultBranchNodeId,
7564
+ target: n.branch,
7565
+ type: "parentBranch",
7566
+ label: n.branch
7567
+ });
7568
+ }
7569
+ }
7570
+ for (const [branch, ids] of branchToNodeIds) {
7571
+ if (ids.length < 2) continue;
7572
+ for (let i = 1; i < ids.length; i++) {
7573
+ edges.push({
7574
+ id: `wt_${ids[0]}--${ids[i]}`,
7575
+ source: ids[0],
7576
+ target: ids[i],
7577
+ type: "worktreeLink",
7578
+ label: branch
7579
+ });
7580
+ }
7581
+ }
7582
+ const orphanCount = nodes.filter((n) => n.isOrphan).length;
7583
+ if (orphanCount > 0) {
7584
+ warnings.push(`${orphanCount} orphan node(s) detected`);
7585
+ }
7586
+ const conflictCount = nodes.filter((n) => n.hasConflicts).length;
7587
+ if (conflictCount > 0) {
7588
+ warnings.push(`${conflictCount} node(s) with merge conflicts`);
7589
+ }
7590
+ const offlineCount = nodes.filter((n) => n.health === "offline").length;
7591
+ if (offlineCount > 0) {
7592
+ warnings.push(`${offlineCount} node(s) offline`);
7593
+ }
7594
+ const stats = {
7595
+ totalNodes: status.nodes.length,
7596
+ onlineNodes: status.nodes.filter((n) => n.health === "online").length,
7597
+ dirtyNodes: nodes.filter((n) => n.dirty).length,
7598
+ orphanNodes: orphanCount,
7599
+ errorNodes: status.nodes.filter((n) => !!n.error).length,
7600
+ offlineNodes: offlineCount,
7601
+ totalActiveSessions: status.nodes.reduce((sum, n) => sum + (n.activeSessions?.length ?? 0), 0)
7602
+ };
7603
+ return {
7604
+ meshId: status.meshId,
7605
+ meshName: status.meshName,
7606
+ repoIdentity: status.repoIdentity,
7607
+ refreshedAt: status.refreshedAt,
7608
+ nodes,
7609
+ edges,
7610
+ stats,
7611
+ warnings
7612
+ };
7613
+ }
7614
+
7615
+ // src/index.ts
7375
7616
  init_mesh_events();
7376
7617
 
7377
7618
  // src/mesh/p2p-relay-failure.ts
@@ -9533,6 +9774,28 @@ var StatusMonitor = class {
9533
9774
  };
9534
9775
 
9535
9776
  // src/providers/chat-message-normalization.ts
9777
+ function extractFinalSummaryFromMessages(messages, maxChars = 500) {
9778
+ if (!Array.isArray(messages) || messages.length === 0) return "";
9779
+ for (let i = messages.length - 1; i >= 0; i--) {
9780
+ const msg = messages[i];
9781
+ if (!msg) continue;
9782
+ const classification = classifyChatMessageVisibility(msg);
9783
+ if (classification.isUserFacing && (msg.role === "assistant" || msg.role === "model")) {
9784
+ const text = flattenContent(msg.content).trim();
9785
+ if (text) return text.slice(0, maxChars);
9786
+ }
9787
+ }
9788
+ for (let i = messages.length - 1; i >= 0; i--) {
9789
+ const msg = messages[i];
9790
+ if (!msg) continue;
9791
+ const classification = classifyChatMessageVisibility(msg);
9792
+ if (classification.isUserFacing) {
9793
+ const text = flattenContent(msg.content).trim();
9794
+ if (text) return text.slice(0, maxChars);
9795
+ }
9796
+ }
9797
+ return "";
9798
+ }
9536
9799
  var BUILTIN_CHAT_MESSAGE_KINDS = ["standard", "thought", "tool", "terminal", "system"];
9537
9800
  var CHAT_MESSAGE_VISIBILITIES = ["user", "debug", "internal", "hidden"];
9538
9801
  var CHAT_MESSAGE_TRANSCRIPT_VISIBILITIES = ["visible", "chat", "user", "debug", "internal", "hidden"];
@@ -11544,7 +11807,8 @@ var ExtensionProviderInstance = class {
11544
11807
  ideType: this.ideType || this.type,
11545
11808
  agentType: this.type,
11546
11809
  agentName: this.agentName || this.provider.name,
11547
- extensionId: this.extensionId || this.type
11810
+ extensionId: this.extensionId || this.type,
11811
+ finalSummary: extractFinalSummaryFromMessages(data?.messages)
11548
11812
  });
11549
11813
  this.generatingStartedAt = 0;
11550
11814
  }
@@ -12312,7 +12576,7 @@ var IdeProviderInstance = class {
12312
12576
  } else if (agentStatus === "idle" && (lastStatus === "generating" || lastStatus === "waiting_approval")) {
12313
12577
  const startedAt = this.generatingStartedAt.get(agentKey);
12314
12578
  const duration = startedAt ? Math.round((now - startedAt) / 1e3) : 0;
12315
- this.pushEvent({ event: "agent:generating_completed", chatTitle, duration, timestamp: now, ideType: this.type });
12579
+ this.pushEvent({ event: "agent:generating_completed", chatTitle, duration, timestamp: now, ideType: this.type, finalSummary: extractFinalSummaryFromMessages(chatData?.messages) });
12316
12580
  this.generatingStartedAt.delete(agentKey);
12317
12581
  }
12318
12582
  this.lastAgentStatuses.set(agentKey, agentStatus);
@@ -17429,7 +17693,8 @@ var CliProviderInstance = class {
17429
17693
  event: "agent:generating_completed",
17430
17694
  chatTitle: pending.chatTitle,
17431
17695
  duration: pending.duration,
17432
- timestamp: pending.timestamp
17696
+ timestamp: pending.timestamp,
17697
+ finalSummary: extractFinalSummaryFromMessages(this.adapter?.getScriptParsedStatus()?.messages)
17433
17698
  });
17434
17699
  this.completedDebouncePending = null;
17435
17700
  this.completedDebounceTimer = null;
@@ -19177,7 +19442,7 @@ ${rawInput}` : rawInput;
19177
19442
  });
19178
19443
  } else if (newStatus === "idle" && (this.lastStatus === "generating" || this.lastStatus === "waiting_approval")) {
19179
19444
  const duration = this.generatingStartedAt ? Math.round((now - this.generatingStartedAt) / 1e3) : 0;
19180
- this.pushEvent({ event: "agent:generating_completed", chatTitle, duration, timestamp: now });
19445
+ this.pushEvent({ event: "agent:generating_completed", chatTitle, duration, timestamp: now, finalSummary: extractFinalSummaryFromMessages(this.messages) });
19181
19446
  this.generatingStartedAt = 0;
19182
19447
  } else if (newStatus === "stopped") {
19183
19448
  this.pushEvent({ event: "agent:stopped", chatTitle, timestamp: now });
@@ -33767,6 +34032,7 @@ export {
33767
34032
  buildChatTailDeliverySignature,
33768
34033
  buildCoordinatorSystemPrompt,
33769
34034
  buildMachineInfo,
34035
+ buildMeshGraph,
33770
34036
  buildMeshLedgerReconciliationEvidence,
33771
34037
  buildMeshLedgerReplicaEvidence,
33772
34038
  buildP2pRelayFailurePayload,
@@ -33786,6 +34052,7 @@ export {
33786
34052
  classifyHotChatSessionsForSubscriptionFlush,
33787
34053
  classifyP2pRelayFailure,
33788
34054
  clearDebugTrace,
34055
+ clearPendingMeshCoordinatorEvents,
33789
34056
  compareGitSnapshots,
33790
34057
  configureDebugTraceStore,
33791
34058
  connectCdpManager,
@@ -33801,6 +34068,7 @@ export {
33801
34068
  detectAllVersions,
33802
34069
  detectCLIs,
33803
34070
  detectIDEs,
34071
+ drainPendingMeshCoordinatorEvents,
33804
34072
  enqueueTask,
33805
34073
  ensureSessionHostReady,
33806
34074
  execNpmCommandSync,
@@ -33827,6 +34095,7 @@ export {
33827
34095
  getMeshByRepo,
33828
34096
  getMeshQueueStats,
33829
34097
  getNpmExecOptions,
34098
+ getPendingMeshCoordinatorEvents,
33830
34099
  getQueue,
33831
34100
  getRecentActivity,
33832
34101
  getRecentCommands,