@adhdev/daemon-standalone 0.9.77-rc.50 → 0.9.77-rc.57

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
@@ -177,7 +177,6 @@ var require_dist = __commonJS({
177
177
  }
178
178
  }
179
179
  };
180
- var import_crypto3 = require("crypto");
181
180
  var DEFAULT_SESSION_HOST_COLS = 80;
182
181
  var DEFAULT_SESSION_HOST_ROWS = 32;
183
182
  function normalizeSessionHostDimension(value, fallback) {
@@ -303,10 +302,20 @@ var require_dist = __commonJS({
303
302
  if (!record2.writeOwner) return "none";
304
303
  return `${record2.writeOwner.ownerType}:${record2.writeOwner.clientId}`;
305
304
  }
305
+ function generateUUID() {
306
+ if (typeof crypto !== "undefined" && crypto.randomUUID) {
307
+ return crypto.randomUUID();
308
+ }
309
+ return "xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx".replace(/[xy]/g, (c) => {
310
+ const r = Math.random() * 16 | 0;
311
+ const v = c === "x" ? r : r & 3 | 8;
312
+ return v.toString(16);
313
+ });
314
+ }
306
315
  var SessionHostRegistry = class {
307
316
  sessions = /* @__PURE__ */ new Map();
308
317
  createSession(payload) {
309
- const sessionId = payload.sessionId || (0, import_crypto3.randomUUID)();
318
+ const sessionId = payload.sessionId || generateUUID();
310
319
  if (this.sessions.has(sessionId)) {
311
320
  throw new Error(`Session already exists: ${sessionId}`);
312
321
  }
@@ -521,7 +530,16 @@ var require_dist = __commonJS({
521
530
  var os6 = __toESM2(require("os"));
522
531
  var path23 = __toESM2(require("path"));
523
532
  var net3 = __toESM2(require("net"));
524
- var import_crypto22 = require("crypto");
533
+ function generateUUID22() {
534
+ if (typeof crypto !== "undefined" && crypto.randomUUID) {
535
+ return crypto.randomUUID();
536
+ }
537
+ return "xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx".replace(/[xy]/g, (c) => {
538
+ const r = Math.random() * 16 | 0;
539
+ const v = c === "x" ? r : r & 3 | 8;
540
+ return v.toString(16);
541
+ });
542
+ }
525
543
  function getDefaultSessionHostEndpoint2(appName = "adhdev") {
526
544
  if (process.platform === "win32") {
527
545
  return {
@@ -612,7 +630,7 @@ var require_dist = __commonJS({
612
630
  async request(request) {
613
631
  await this.connect();
614
632
  if (!this.socket) throw new Error("Session host socket unavailable");
615
- const requestId = (0, import_crypto22.randomUUID)();
633
+ const requestId = generateUUID22();
616
634
  const envelope = {
617
635
  kind: "request",
618
636
  requestId,
@@ -22398,7 +22416,7 @@ ${error48.message || ""}`;
22398
22416
  };
22399
22417
  }
22400
22418
  function generateMachineId() {
22401
- return `${MACHINE_ID_PREFIX}${(0, import_crypto3.randomUUID)().replace(/-/g, "")}`;
22419
+ return `${MACHINE_ID_PREFIX}${(0, import_crypto2.randomUUID)().replace(/-/g, "")}`;
22402
22420
  }
22403
22421
  function isStableMachineId(machineId) {
22404
22422
  return typeof machineId === "string" && machineId.startsWith(MACHINE_ID_PREFIX);
@@ -22518,7 +22536,7 @@ ${error48.message || ""}`;
22518
22536
  var import_os2;
22519
22537
  var import_path2;
22520
22538
  var import_fs;
22521
- var import_crypto3;
22539
+ var import_crypto2;
22522
22540
  var DEFAULT_CONFIG;
22523
22541
  var MACHINE_ID_PREFIX;
22524
22542
  var init_config = __esm2({
@@ -22527,7 +22545,7 @@ ${error48.message || ""}`;
22527
22545
  import_os2 = require("os");
22528
22546
  import_path2 = require("path");
22529
22547
  import_fs = require("fs");
22530
- import_crypto3 = require("crypto");
22548
+ import_crypto2 = require("crypto");
22531
22549
  DEFAULT_CONFIG = {
22532
22550
  serverUrl: "https://api.adhf.dev",
22533
22551
  allowServerApiProxy: false,
@@ -22633,7 +22651,7 @@ ${error48.message || ""}`;
22633
22651
  if (!repoIdentity) throw new Error("Either repoRemoteUrl or repoIdentity is required");
22634
22652
  const now = (/* @__PURE__ */ new Date()).toISOString();
22635
22653
  const mesh = {
22636
- id: `mesh_${(0, import_crypto32.randomUUID)().replace(/-/g, "")}`,
22654
+ id: `mesh_${(0, import_crypto3.randomUUID)().replace(/-/g, "")}`,
22637
22655
  name: opts.name.trim().slice(0, 100),
22638
22656
  repoIdentity,
22639
22657
  repoRemoteUrl: opts.repoRemoteUrl,
@@ -22679,7 +22697,7 @@ ${error48.message || ""}`;
22679
22697
  throw new Error("This workspace is already in the mesh");
22680
22698
  }
22681
22699
  const node = {
22682
- id: `node_${(0, import_crypto32.randomUUID)().replace(/-/g, "")}`,
22700
+ id: `node_${(0, import_crypto3.randomUUID)().replace(/-/g, "")}`,
22683
22701
  workspace: opts.workspace.trim(),
22684
22702
  repoRoot: opts.repoRoot,
22685
22703
  daemonId: opts.daemonId,
@@ -22720,7 +22738,7 @@ ${error48.message || ""}`;
22720
22738
  }
22721
22739
  var import_fs2;
22722
22740
  var import_path22;
22723
- var import_crypto32;
22741
+ var import_crypto3;
22724
22742
  var SESSION_CLEANUP_MODES;
22725
22743
  var SPAWNED_SESSION_VISIBILITY_MODES;
22726
22744
  var init_mesh_config = __esm2({
@@ -22728,7 +22746,7 @@ ${error48.message || ""}`;
22728
22746
  "use strict";
22729
22747
  import_fs2 = require("fs");
22730
22748
  import_path22 = require("path");
22731
- import_crypto32 = require("crypto");
22749
+ import_crypto3 = require("crypto");
22732
22750
  init_config();
22733
22751
  init_repo_mesh_types();
22734
22752
  SESSION_CLEANUP_MODES = /* @__PURE__ */ new Set(["preserve", "stop", "delete_stopped", "stop_and_delete"]);
@@ -23315,6 +23333,7 @@ Follow these recovery rules:
23315
23333
  entry.status = "assigned";
23316
23334
  entry.assignedNodeId = nodeId;
23317
23335
  entry.assignedSessionId = sessionId;
23336
+ entry.dispatchTimestamp = (/* @__PURE__ */ new Date()).toISOString();
23318
23337
  entry.updatedAt = (/* @__PURE__ */ new Date()).toISOString();
23319
23338
  writeQueue(meshId, queue);
23320
23339
  return entry;
@@ -23377,15 +23396,22 @@ Follow these recovery rules:
23377
23396
  }
23378
23397
  function updateSessionTaskStatus(meshId, sessionId, status) {
23379
23398
  const queue = readQueue(meshId);
23399
+ let bestIdx = -1;
23400
+ let bestTime = 0;
23380
23401
  for (let i = queue.length - 1; i >= 0; i--) {
23381
23402
  if (queue[i].assignedSessionId === sessionId && queue[i].status === "assigned") {
23382
- queue[i].status = status;
23383
- queue[i].updatedAt = (/* @__PURE__ */ new Date()).toISOString();
23384
- writeQueue(meshId, queue);
23385
- return queue[i];
23403
+ const time3 = new Date(queue[i].dispatchTimestamp || queue[i].updatedAt).getTime();
23404
+ if (time3 > bestTime) {
23405
+ bestTime = time3;
23406
+ bestIdx = i;
23407
+ }
23386
23408
  }
23387
23409
  }
23388
- return null;
23410
+ if (bestIdx === -1) return null;
23411
+ queue[bestIdx].status = status;
23412
+ queue[bestIdx].updatedAt = (/* @__PURE__ */ new Date()).toISOString();
23413
+ writeQueue(meshId, queue);
23414
+ return queue[bestIdx];
23389
23415
  }
23390
23416
  function getMeshQueueStats(meshId) {
23391
23417
  const queue = readQueue(meshId);
@@ -23805,7 +23831,9 @@ Follow these recovery rules:
23805
23831
  });
23806
23832
  var mesh_events_exports = {};
23807
23833
  __export2(mesh_events_exports, {
23834
+ clearPendingMeshCoordinatorEvents: () => clearPendingMeshCoordinatorEvents,
23808
23835
  drainPendingMeshCoordinatorEvents: () => drainPendingMeshCoordinatorEvents,
23836
+ getPendingMeshCoordinatorEvents: () => getPendingMeshCoordinatorEvents,
23809
23837
  handleMeshForwardEvent: () => handleMeshForwardEvent,
23810
23838
  setupMeshEventForwarding: () => setupMeshEventForwarding,
23811
23839
  triggerMeshQueue: () => triggerMeshQueue,
@@ -23814,6 +23842,12 @@ Follow these recovery rules:
23814
23842
  function drainPendingMeshCoordinatorEvents() {
23815
23843
  return pendingMeshCoordinatorEvents.splice(0);
23816
23844
  }
23845
+ function getPendingMeshCoordinatorEvents() {
23846
+ return pendingMeshCoordinatorEvents.slice();
23847
+ }
23848
+ function clearPendingMeshCoordinatorEvents() {
23849
+ pendingMeshCoordinatorEvents.splice(0);
23850
+ }
23817
23851
  function readNonEmptyString(value) {
23818
23852
  return typeof value === "string" && value.trim() ? value.trim() : "";
23819
23853
  }
@@ -27643,6 +27677,7 @@ ${lastSnapshot}`;
27643
27677
  buildChatTailDeliverySignature: () => buildChatTailDeliverySignature,
27644
27678
  buildCoordinatorSystemPrompt: () => buildCoordinatorSystemPrompt,
27645
27679
  buildMachineInfo: () => buildMachineInfo2,
27680
+ buildMeshGraph: () => buildMeshGraph,
27646
27681
  buildMeshLedgerReconciliationEvidence: () => buildMeshLedgerReconciliationEvidence,
27647
27682
  buildMeshLedgerReplicaEvidence: () => buildMeshLedgerReplicaEvidence,
27648
27683
  buildP2pRelayFailurePayload: () => buildP2pRelayFailurePayload,
@@ -27662,6 +27697,7 @@ ${lastSnapshot}`;
27662
27697
  classifyHotChatSessionsForSubscriptionFlush: () => classifyHotChatSessionsForSubscriptionFlush2,
27663
27698
  classifyP2pRelayFailure: () => classifyP2pRelayFailure,
27664
27699
  clearDebugTrace: () => clearDebugTrace,
27700
+ clearPendingMeshCoordinatorEvents: () => clearPendingMeshCoordinatorEvents,
27665
27701
  compareGitSnapshots: () => compareGitSnapshots,
27666
27702
  configureDebugTraceStore: () => configureDebugTraceStore,
27667
27703
  connectCdpManager: () => connectCdpManager,
@@ -27677,6 +27713,7 @@ ${lastSnapshot}`;
27677
27713
  detectAllVersions: () => detectAllVersions,
27678
27714
  detectCLIs: () => detectCLIs,
27679
27715
  detectIDEs: () => detectIDEs,
27716
+ drainPendingMeshCoordinatorEvents: () => drainPendingMeshCoordinatorEvents,
27680
27717
  enqueueTask: () => enqueueTask,
27681
27718
  ensureSessionHostReady: () => ensureSessionHostReady2,
27682
27719
  execNpmCommandSync: () => execNpmCommandSync,
@@ -27703,6 +27740,7 @@ ${lastSnapshot}`;
27703
27740
  getMeshByRepo: () => getMeshByRepo,
27704
27741
  getMeshQueueStats: () => getMeshQueueStats,
27705
27742
  getNpmExecOptions: () => getNpmExecOptions,
27743
+ getPendingMeshCoordinatorEvents: () => getPendingMeshCoordinatorEvents,
27706
27744
  getQueue: () => getQueue,
27707
27745
  getRecentActivity: () => getRecentActivity,
27708
27746
  getRecentCommands: () => getRecentCommands,
@@ -29695,6 +29733,227 @@ ${lastSnapshot}`;
29695
29733
  };
29696
29734
  }
29697
29735
  init_mesh_work_queue();
29736
+ function isDirty(git) {
29737
+ if (!git) return false;
29738
+ return git.staged + git.modified + git.untracked + git.deleted + git.renamed > 0;
29739
+ }
29740
+ function dirtyFileCount(git) {
29741
+ if (!git) return 0;
29742
+ return git.staged + git.modified + git.untracked + git.deleted + git.renamed;
29743
+ }
29744
+ function detectOrphanReasons(node, defaultBranch) {
29745
+ const reasons = [];
29746
+ const git = node.git;
29747
+ if (!git) {
29748
+ reasons.push("No git status available");
29749
+ return reasons;
29750
+ }
29751
+ if (!git.isGitRepo) {
29752
+ reasons.push("Not a git repository");
29753
+ return reasons;
29754
+ }
29755
+ if (git.branch === null && git.headCommit) {
29756
+ reasons.push("Detached HEAD");
29757
+ }
29758
+ if (git.branch && !git.upstream) {
29759
+ if (defaultBranch && git.branch !== defaultBranch) {
29760
+ reasons.push(`No upstream: ${git.branch}`);
29761
+ }
29762
+ }
29763
+ if (git.branch && git.upstream === null && defaultBranch && git.branch !== defaultBranch) {
29764
+ if (!reasons.includes(`No upstream: ${git.branch}`)) {
29765
+ reasons.push(`No upstream: ${git.branch}`);
29766
+ }
29767
+ }
29768
+ if (node.error) {
29769
+ reasons.push(`Error: ${node.error}`);
29770
+ }
29771
+ return reasons;
29772
+ }
29773
+ function nodeHealthPriority(health) {
29774
+ switch (health) {
29775
+ case "online":
29776
+ return 0;
29777
+ case "dirty":
29778
+ return 1;
29779
+ case "degraded":
29780
+ return 2;
29781
+ case "wrong_branch":
29782
+ return 3;
29783
+ case "offline":
29784
+ return 4;
29785
+ case "unknown":
29786
+ return 5;
29787
+ default:
29788
+ return 5;
29789
+ }
29790
+ }
29791
+ function pickDominantHealth(healths) {
29792
+ if (healths.length === 0) return "unknown";
29793
+ return healths.reduce(
29794
+ (best, h) => nodeHealthPriority(h) > nodeHealthPriority(best) ? h : best
29795
+ );
29796
+ }
29797
+ function buildMeshGraph(status) {
29798
+ const nodes = [];
29799
+ const edges = [];
29800
+ const warnings = [];
29801
+ const branchToNodeIds = /* @__PURE__ */ new Map();
29802
+ for (const nodeStatus of status.nodes) {
29803
+ const git = nodeStatus.git;
29804
+ const branch = git?.branch || null;
29805
+ const orphanReasons = detectOrphanReasons(nodeStatus, null);
29806
+ const dirty = isDirty(git);
29807
+ const dfc = dirtyFileCount(git);
29808
+ let type = "worktreeNode";
29809
+ if (orphanReasons.length > 0) {
29810
+ type = "orphanNode";
29811
+ }
29812
+ const graphNode = {
29813
+ id: nodeStatus.nodeId,
29814
+ type,
29815
+ label: nodeStatus.machineLabel || nodeStatus.nodeId.slice(0, 8),
29816
+ workspace: nodeStatus.workspace,
29817
+ branch,
29818
+ health: nodeStatus.health,
29819
+ ahead: git?.ahead ?? 0,
29820
+ behind: git?.behind ?? 0,
29821
+ dirty,
29822
+ dirtyFiles: dfc,
29823
+ hasConflicts: git?.hasConflicts ?? false,
29824
+ activeSessionCount: nodeStatus.activeSessions?.length ?? 0,
29825
+ activeSessions: nodeStatus.activeSessions ?? [],
29826
+ providers: nodeStatus.providers ?? [],
29827
+ isOrphan: orphanReasons.length > 0,
29828
+ orphanReasons,
29829
+ source: nodeStatus
29830
+ };
29831
+ nodes.push(graphNode);
29832
+ if (branch) {
29833
+ const list = branchToNodeIds.get(branch) ?? [];
29834
+ list.push(graphNode.id);
29835
+ branchToNodeIds.set(branch, list);
29836
+ }
29837
+ }
29838
+ const branchUpstreamCounts = /* @__PURE__ */ new Map();
29839
+ for (const n of status.nodes) {
29840
+ const b = n.git?.branch;
29841
+ const upstream = n.git?.upstream;
29842
+ if (b && upstream) {
29843
+ branchUpstreamCounts.set(b, (branchUpstreamCounts.get(b) ?? 0) + 1);
29844
+ }
29845
+ }
29846
+ let inferredDefaultBranch = null;
29847
+ let bestCount = 0;
29848
+ for (const [b, count] of branchUpstreamCounts) {
29849
+ if (count > bestCount) {
29850
+ bestCount = count;
29851
+ inferredDefaultBranch = b;
29852
+ }
29853
+ }
29854
+ const defaultBranchNodeId = inferredDefaultBranch ? `__branch_${inferredDefaultBranch}` : null;
29855
+ if (defaultBranchNodeId && inferredDefaultBranch) {
29856
+ const branchNodes = branchToNodeIds.get(inferredDefaultBranch) ?? [];
29857
+ const branchHealths = branchNodes.map(
29858
+ (id) => nodes.find((n) => n.id === id).health
29859
+ );
29860
+ const defaultNode = {
29861
+ id: defaultBranchNodeId,
29862
+ type: "defaultBranchNode",
29863
+ label: inferredDefaultBranch,
29864
+ workspace: "",
29865
+ branch: inferredDefaultBranch,
29866
+ health: pickDominantHealth(branchHealths),
29867
+ ahead: 0,
29868
+ behind: 0,
29869
+ dirty: false,
29870
+ dirtyFiles: 0,
29871
+ hasConflicts: false,
29872
+ activeSessionCount: 0,
29873
+ activeSessions: [],
29874
+ providers: [],
29875
+ isOrphan: false,
29876
+ orphanReasons: [],
29877
+ nextStepHint: branchNodes.length > 0 ? `${branchNodes.length} node(s) on default branch` : void 0,
29878
+ source: {
29879
+ nodeId: defaultBranchNodeId,
29880
+ machineLabel: inferredDefaultBranch,
29881
+ workspace: "",
29882
+ health: "online",
29883
+ providers: [],
29884
+ activeSessions: []
29885
+ }
29886
+ };
29887
+ nodes.push(defaultNode);
29888
+ const seenBranches = /* @__PURE__ */ new Set();
29889
+ for (const n of nodes) {
29890
+ if (n.type === "defaultBranchNode") continue;
29891
+ if (!n.branch) continue;
29892
+ if (n.branch === inferredDefaultBranch) {
29893
+ edges.push({
29894
+ id: `${defaultBranchNodeId}--${n.id}`,
29895
+ source: defaultBranchNodeId,
29896
+ target: n.id,
29897
+ type: "parentBranch",
29898
+ label: "default"
29899
+ });
29900
+ continue;
29901
+ }
29902
+ if (seenBranches.has(n.branch)) continue;
29903
+ seenBranches.add(n.branch);
29904
+ edges.push({
29905
+ id: `${defaultBranchNodeId}--branch_${n.branch}`,
29906
+ source: defaultBranchNodeId,
29907
+ target: n.branch,
29908
+ type: "parentBranch",
29909
+ label: n.branch
29910
+ });
29911
+ }
29912
+ }
29913
+ for (const [branch, ids] of branchToNodeIds) {
29914
+ if (ids.length < 2) continue;
29915
+ for (let i = 1; i < ids.length; i++) {
29916
+ edges.push({
29917
+ id: `wt_${ids[0]}--${ids[i]}`,
29918
+ source: ids[0],
29919
+ target: ids[i],
29920
+ type: "worktreeLink",
29921
+ label: branch
29922
+ });
29923
+ }
29924
+ }
29925
+ const orphanCount = nodes.filter((n) => n.isOrphan).length;
29926
+ if (orphanCount > 0) {
29927
+ warnings.push(`${orphanCount} orphan node(s) detected`);
29928
+ }
29929
+ const conflictCount = nodes.filter((n) => n.hasConflicts).length;
29930
+ if (conflictCount > 0) {
29931
+ warnings.push(`${conflictCount} node(s) with merge conflicts`);
29932
+ }
29933
+ const offlineCount = nodes.filter((n) => n.health === "offline").length;
29934
+ if (offlineCount > 0) {
29935
+ warnings.push(`${offlineCount} node(s) offline`);
29936
+ }
29937
+ const stats = {
29938
+ totalNodes: status.nodes.length,
29939
+ onlineNodes: status.nodes.filter((n) => n.health === "online").length,
29940
+ dirtyNodes: nodes.filter((n) => n.dirty).length,
29941
+ orphanNodes: orphanCount,
29942
+ errorNodes: status.nodes.filter((n) => !!n.error).length,
29943
+ offlineNodes: offlineCount,
29944
+ totalActiveSessions: status.nodes.reduce((sum, n) => sum + (n.activeSessions?.length ?? 0), 0)
29945
+ };
29946
+ return {
29947
+ meshId: status.meshId,
29948
+ meshName: status.meshName,
29949
+ repoIdentity: status.repoIdentity,
29950
+ refreshedAt: status.refreshedAt,
29951
+ nodes,
29952
+ edges,
29953
+ stats,
29954
+ warnings
29955
+ };
29956
+ }
29698
29957
  init_mesh_events();
29699
29958
  var NO_FALLBACK_REASON = "Repo Mesh command/data-plane is P2P-only; WS/REST command fallback is intentionally disabled to preserve the transport boundary.";
29700
29959
  var P2P_NEXT_ACTION = "Check daemon/P2P health, wait briefly for connection establishment, then do one bounded retry or requeue the mesh task after clearing stale target session metadata.";
@@ -31828,6 +32087,28 @@ ${lastSnapshot}`;
31828
32087
  }
31829
32088
  }
31830
32089
  };
32090
+ function extractFinalSummaryFromMessages(messages, maxChars = 500) {
32091
+ if (!Array.isArray(messages) || messages.length === 0) return "";
32092
+ for (let i = messages.length - 1; i >= 0; i--) {
32093
+ const msg = messages[i];
32094
+ if (!msg) continue;
32095
+ const classification = classifyChatMessageVisibility(msg);
32096
+ if (classification.isUserFacing && (msg.role === "assistant" || msg.role === "model")) {
32097
+ const text = flattenContent(msg.content).trim();
32098
+ if (text) return text.slice(0, maxChars);
32099
+ }
32100
+ }
32101
+ for (let i = messages.length - 1; i >= 0; i--) {
32102
+ const msg = messages[i];
32103
+ if (!msg) continue;
32104
+ const classification = classifyChatMessageVisibility(msg);
32105
+ if (classification.isUserFacing) {
32106
+ const text = flattenContent(msg.content).trim();
32107
+ if (text) return text.slice(0, maxChars);
32108
+ }
32109
+ }
32110
+ return "";
32111
+ }
31831
32112
  var BUILTIN_CHAT_MESSAGE_KINDS = ["standard", "thought", "tool", "terminal", "system"];
31832
32113
  var CHAT_MESSAGE_VISIBILITIES = ["user", "debug", "internal", "hidden"];
31833
32114
  var CHAT_MESSAGE_TRANSCRIPT_VISIBILITIES = ["visible", "chat", "user", "debug", "internal", "hidden"];
@@ -33829,7 +34110,8 @@ ${cleanBody}`;
33829
34110
  ideType: this.ideType || this.type,
33830
34111
  agentType: this.type,
33831
34112
  agentName: this.agentName || this.provider.name,
33832
- extensionId: this.extensionId || this.type
34113
+ extensionId: this.extensionId || this.type,
34114
+ finalSummary: extractFinalSummaryFromMessages(data?.messages)
33833
34115
  });
33834
34116
  this.generatingStartedAt = 0;
33835
34117
  }
@@ -34589,7 +34871,7 @@ ${effect.notification.body || ""}`.trim();
34589
34871
  } else if (agentStatus === "idle" && (lastStatus === "generating" || lastStatus === "waiting_approval")) {
34590
34872
  const startedAt = this.generatingStartedAt.get(agentKey);
34591
34873
  const duration3 = startedAt ? Math.round((now - startedAt) / 1e3) : 0;
34592
- this.pushEvent({ event: "agent:generating_completed", chatTitle, duration: duration3, timestamp: now, ideType: this.type });
34874
+ this.pushEvent({ event: "agent:generating_completed", chatTitle, duration: duration3, timestamp: now, ideType: this.type, finalSummary: extractFinalSummaryFromMessages(chatData?.messages) });
34593
34875
  this.generatingStartedAt.delete(agentKey);
34594
34876
  }
34595
34877
  this.lastAgentStatuses.set(agentKey, agentStatus);
@@ -39652,7 +39934,8 @@ ${effect.notification.body || ""}`.trim();
39652
39934
  event: "agent:generating_completed",
39653
39935
  chatTitle: pending.chatTitle,
39654
39936
  duration: pending.duration,
39655
- timestamp: pending.timestamp
39937
+ timestamp: pending.timestamp,
39938
+ finalSummary: extractFinalSummaryFromMessages(this.adapter?.getScriptParsedStatus()?.messages)
39656
39939
  });
39657
39940
  this.completedDebouncePending = null;
39658
39941
  this.completedDebounceTimer = null;
@@ -41393,7 +41676,7 @@ ${rawInput}` : rawInput;
41393
41676
  });
41394
41677
  } else if (newStatus === "idle" && (this.lastStatus === "generating" || this.lastStatus === "waiting_approval")) {
41395
41678
  const duration3 = this.generatingStartedAt ? Math.round((now - this.generatingStartedAt) / 1e3) : 0;
41396
- this.pushEvent({ event: "agent:generating_completed", chatTitle, duration: duration3, timestamp: now });
41679
+ this.pushEvent({ event: "agent:generating_completed", chatTitle, duration: duration3, timestamp: now, finalSummary: extractFinalSummaryFromMessages(this.messages) });
41397
41680
  this.generatingStartedAt = 0;
41398
41681
  } else if (newStatus === "stopped") {
41399
41682
  this.pushEvent({ event: "agent:stopped", chatTitle, timestamp: now });
@@ -55833,7 +56116,7 @@ var import_ws = require("ws");
55833
56116
  var path4 = __toESM(require("path"));
55834
56117
  var fs3 = __toESM(require("fs"));
55835
56118
  var os5 = __toESM(require("os"));
55836
- var import_crypto2 = require("crypto");
56119
+ var import_crypto = require("crypto");
55837
56120
 
55838
56121
  // src/standalone-preferences.ts
55839
56122
  var fs = __toESM(require("fs"));
@@ -56077,8 +56360,17 @@ function shouldAutoRestoreHostedSessionsOnStartup(env2 = process.env) {
56077
56360
  var os3 = __toESM(require("os"), 1);
56078
56361
  var path22 = __toESM(require("path"), 1);
56079
56362
  var net = __toESM(require("net"), 1);
56080
- var import_crypto = require("crypto");
56081
56363
  var DEFAULT_SESSION_RING_BUFFER_MAX_BYTES = 4 * 1024 * 1024;
56364
+ function generateUUID2() {
56365
+ if (typeof crypto !== "undefined" && crypto.randomUUID) {
56366
+ return crypto.randomUUID();
56367
+ }
56368
+ return "xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx".replace(/[xy]/g, (c) => {
56369
+ const r = Math.random() * 16 | 0;
56370
+ const v = c === "x" ? r : r & 3 | 8;
56371
+ return v.toString(16);
56372
+ });
56373
+ }
56082
56374
  function getDefaultSessionHostEndpoint(appName = "adhdev") {
56083
56375
  if (process.platform === "win32") {
56084
56376
  return {
@@ -56169,7 +56461,7 @@ var SessionHostClient = class {
56169
56461
  async request(request) {
56170
56462
  await this.connect();
56171
56463
  if (!this.socket) throw new Error("Session host socket unavailable");
56172
- const requestId = (0, import_crypto.randomUUID)();
56464
+ const requestId = generateUUID2();
56173
56465
  const envelope = {
56174
56466
  kind: "request",
56175
56467
  requestId,
@@ -56470,18 +56762,18 @@ function saveStandaloneBindHostPreference(bindHost) {
56470
56762
  function saveStandaloneFontPreferences(fontPreferences) {
56471
56763
  return saveStandalonePreferences(getStandaloneConfigJsonPath(), { standaloneFontPreferences: fontPreferences }).standaloneFontPreferences;
56472
56764
  }
56473
- function createPasswordRecord(password, salt = (0, import_crypto2.randomBytes)(16).toString("hex")) {
56765
+ function createPasswordRecord(password, salt = (0, import_crypto.randomBytes)(16).toString("hex")) {
56474
56766
  return {
56475
- passwordHash: (0, import_crypto2.scryptSync)(`${password || ""}`, salt, PASSWORD_KEYLEN).toString("hex"),
56767
+ passwordHash: (0, import_crypto.scryptSync)(`${password || ""}`, salt, PASSWORD_KEYLEN).toString("hex"),
56476
56768
  passwordSalt: salt,
56477
56769
  updatedAt: (/* @__PURE__ */ new Date()).toISOString()
56478
56770
  };
56479
56771
  }
56480
56772
  function verifyPassword(password, config2) {
56481
56773
  if (!config2?.passwordHash || !config2.passwordSalt) return false;
56482
- const actual = Buffer.from((0, import_crypto2.scryptSync)(`${password || ""}`, config2.passwordSalt, PASSWORD_KEYLEN).toString("hex"), "utf8");
56774
+ const actual = Buffer.from((0, import_crypto.scryptSync)(`${password || ""}`, config2.passwordSalt, PASSWORD_KEYLEN).toString("hex"), "utf8");
56483
56775
  const expected = Buffer.from(config2.passwordHash, "utf8");
56484
- return actual.length === expected.length && (0, import_crypto2.timingSafeEqual)(actual, expected);
56776
+ return actual.length === expected.length && (0, import_crypto.timingSafeEqual)(actual, expected);
56485
56777
  }
56486
56778
  function loadStandalonePasswordConfig(filePath = getStandalonePasswordConfigPath()) {
56487
56779
  if (!fs3.existsSync(filePath)) return null;
@@ -56544,7 +56836,7 @@ function buildClearedSessionCookie(secure) {
56544
56836
  var StandaloneSessionStore = class {
56545
56837
  sessions = /* @__PURE__ */ new Map();
56546
56838
  create(ttlMs = DEFAULT_SESSION_TTL_MS) {
56547
- const id = (0, import_crypto2.randomBytes)(24).toString("hex");
56839
+ const id = (0, import_crypto.randomBytes)(24).toString("hex");
56548
56840
  this.sessions.set(id, Date.now() + ttlMs);
56549
56841
  return id;
56550
56842
  }