@adhdev/daemon-core 0.9.82-rc.475 → 0.9.82-rc.477

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
@@ -404,10 +404,10 @@ function readInjected(value) {
404
404
  }
405
405
  function getDaemonBuildInfo() {
406
406
  if (cached) return cached;
407
- const commit = readInjected(true ? "c7b88fafbc63d3fc0de4b93c74facdb5145b8be6" : void 0) ?? "unknown";
408
- const commitShort = readInjected(true ? "c7b88faf" : void 0) ?? (commit !== "unknown" ? commit.slice(0, 7) : "unknown");
409
- const version = readInjected(true ? "0.9.82-rc.475" : void 0) ?? readInjected(typeof process !== "undefined" ? process.env?.ADHDEV_PKG_VERSION : void 0) ?? "unknown";
410
- const builtAt = readInjected(true ? "2026-07-06T06:24:24.877Z" : void 0);
407
+ const commit = readInjected(true ? "e565a4d93874e580f3923a562a7a58229af17997" : void 0) ?? "unknown";
408
+ const commitShort = readInjected(true ? "e565a4d9" : void 0) ?? (commit !== "unknown" ? commit.slice(0, 7) : "unknown");
409
+ const version = readInjected(true ? "0.9.82-rc.477" : void 0) ?? readInjected(typeof process !== "undefined" ? process.env?.ADHDEV_PKG_VERSION : void 0) ?? "unknown";
410
+ const builtAt = readInjected(true ? "2026-07-06T18:09:09.172Z" : void 0);
411
411
  cached = builtAt ? { commit, commitShort, version, builtAt } : { commit, commitShort, version };
412
412
  return cached;
413
413
  }
@@ -16698,13 +16698,17 @@ function normalizeState(raw) {
16698
16698
  const sessionNotificationUnreadOverrides = Object.fromEntries(
16699
16699
  Object.entries(isPlainObject2(parsed.sessionNotificationUnreadOverrides) ? parsed.sessionNotificationUnreadOverrides : {}).filter(([, value]) => typeof value === "string" && value.length > 0)
16700
16700
  );
16701
+ const sessionProviderSessionPins = Object.fromEntries(
16702
+ Object.entries(isPlainObject2(parsed.sessionProviderSessionPins) ? parsed.sessionProviderSessionPins : {}).filter(([key2, value]) => typeof key2 === "string" && key2.length > 0 && typeof value === "string" && value.length > 0)
16703
+ );
16701
16704
  return {
16702
16705
  recentActivity,
16703
16706
  savedProviderSessions,
16704
16707
  sessionReads,
16705
16708
  sessionReadMarkers,
16706
16709
  sessionNotificationDismissals,
16707
- sessionNotificationUnreadOverrides
16710
+ sessionNotificationUnreadOverrides,
16711
+ sessionProviderSessionPins
16708
16712
  };
16709
16713
  }
16710
16714
  function loadState() {
@@ -16727,6 +16731,20 @@ function saveState(state) {
16727
16731
  function resetState() {
16728
16732
  saveState({ ...DEFAULT_STATE });
16729
16733
  }
16734
+ function loadPersistedProviderSessionPins() {
16735
+ return { ...loadState().sessionProviderSessionPins };
16736
+ }
16737
+ function recordPersistedProviderSessionPin(sessionId, providerSessionId) {
16738
+ const key2 = typeof sessionId === "string" ? sessionId.trim() : "";
16739
+ const value = typeof providerSessionId === "string" ? providerSessionId.trim() : "";
16740
+ if (!key2 || !value) return;
16741
+ const state = loadState();
16742
+ if (state.sessionProviderSessionPins[key2] === value) return;
16743
+ saveState({
16744
+ ...state,
16745
+ sessionProviderSessionPins: { ...state.sessionProviderSessionPins, [key2]: value }
16746
+ });
16747
+ }
16730
16748
  var DEFAULT_STATE;
16731
16749
  var init_state_store = __esm({
16732
16750
  "src/config/state-store.ts"() {
@@ -16738,7 +16756,8 @@ var init_state_store = __esm({
16738
16756
  sessionReads: {},
16739
16757
  sessionReadMarkers: {},
16740
16758
  sessionNotificationDismissals: {},
16741
- sessionNotificationUnreadOverrides: {}
16759
+ sessionNotificationUnreadOverrides: {},
16760
+ sessionProviderSessionPins: {}
16742
16761
  };
16743
16762
  }
16744
16763
  });
@@ -19294,6 +19313,16 @@ function evaluateMeshEventSuppression(args, ctx) {
19294
19313
  }
19295
19314
  return null;
19296
19315
  }
19316
+ function sourceWorkerAutoApproves(components, sessionId) {
19317
+ if (!sessionId) return false;
19318
+ try {
19319
+ const state = components.instanceManager?.getInstance?.(sessionId)?.getState?.();
19320
+ const settings = state?.settings || {};
19321
+ return settings.autoApprove === true;
19322
+ } catch {
19323
+ return false;
19324
+ }
19325
+ }
19297
19326
  function injectMeshSystemMessage(components, args) {
19298
19327
  const eventSessionId = resolveEventSessionId(args.metadataEvent, args.sourceInstanceId);
19299
19328
  const eventNodeId = readNonEmptyString2(args.nodeId) || readNonEmptyString2(args.metadataEvent.meshNodeId);
@@ -19352,6 +19381,11 @@ function injectMeshSystemMessage(components, args) {
19352
19381
  }
19353
19382
  }
19354
19383
  const eventTimestamp = readEventTimestamp(args.metadataEvent.timestamp);
19384
+ if (args.event === "agent:waiting_approval" && sourceWorkerAutoApproves(components, eventSessionId)) {
19385
+ LOG.info("MeshEvents", `Suppressed agent:waiting_approval for auto-approving worker session ${eventSessionId || "(unknown)"} (mesh ${args.meshId}) \u2014 modal is resolved locally, coordinator not notified`);
19386
+ traceMeshEventDrop("waiting_approval_auto_approving_worker", traceCtx);
19387
+ return { success: true, forwarded: 0, suppressed: true, autoApprovingWorkerApproval: true };
19388
+ }
19355
19389
  const suppression = evaluateMeshEventSuppression(args, {
19356
19390
  traceCtx,
19357
19391
  eventSessionId,
@@ -33663,6 +33697,7 @@ import { randomUUID as randomUUID11 } from "crypto";
33663
33697
  // src/commands/chat-commands-read.ts
33664
33698
  init_contracts2();
33665
33699
  import * as path16 from "path";
33700
+ init_state_store();
33666
33701
  init_coordinator_registry();
33667
33702
  init_logger();
33668
33703
  init_debug_trace();
@@ -34018,15 +34053,37 @@ init_chat_message_normalization();
34018
34053
  var HOT_TAIL_MIN_LIMIT = 60;
34019
34054
  var CLI_NATIVE_TRANSCRIPT_PROVIDERS = /* @__PURE__ */ new Set(["codex-cli", "claude-cli", "hermes-cli", "antigravity-cli"]);
34020
34055
  var lastBoundProviderSessionIdByMeshSession = /* @__PURE__ */ new Map();
34021
- function recordBoundProviderSessionId(meshSessionId, providerSessionId) {
34056
+ var persistedProviderSessionPinsHydrated = false;
34057
+ function hydratePersistedProviderSessionPinsOnce() {
34058
+ if (persistedProviderSessionPinsHydrated) return;
34059
+ persistedProviderSessionPinsHydrated = true;
34060
+ try {
34061
+ for (const [key2, value] of Object.entries(loadPersistedProviderSessionPins())) {
34062
+ if (!lastBoundProviderSessionIdByMeshSession.has(key2)) {
34063
+ lastBoundProviderSessionIdByMeshSession.set(key2, value);
34064
+ }
34065
+ }
34066
+ } catch {
34067
+ }
34068
+ }
34069
+ function recordBoundProviderSessionId(h, meshSessionId, providerSessionId) {
34022
34070
  const key2 = typeof meshSessionId === "string" ? meshSessionId.trim() : "";
34023
34071
  const value = typeof providerSessionId === "string" ? providerSessionId.trim() : "";
34024
34072
  if (!key2 || !value) return;
34073
+ try {
34074
+ h.ctx?.sessionRegistry?.setProviderSessionId?.(key2, value);
34075
+ } catch {
34076
+ }
34025
34077
  lastBoundProviderSessionIdByMeshSession.set(key2, value);
34078
+ try {
34079
+ recordPersistedProviderSessionPin(key2, value);
34080
+ } catch {
34081
+ }
34026
34082
  }
34027
34083
  function getBoundProviderSessionIdPin(meshSessionId) {
34028
34084
  const key2 = typeof meshSessionId === "string" ? meshSessionId.trim() : "";
34029
34085
  if (!key2) return void 0;
34086
+ hydratePersistedProviderSessionPinsOnce();
34030
34087
  const pinned = lastBoundProviderSessionIdByMeshSession.get(key2);
34031
34088
  return pinned && pinned.trim() ? pinned.trim() : void 0;
34032
34089
  }
@@ -34589,8 +34646,14 @@ function hasSafeNativeHistoryMapping(args) {
34589
34646
  if (!args.requireWorkspaceContentOverlap) return true;
34590
34647
  return hasOverlappingVisibleConversationText(args.nativeMessages, args.ptyMessages || []);
34591
34648
  }
34649
+ function effectiveReadSessionId(h, targetSessionId) {
34650
+ const explicit = typeof targetSessionId === "string" ? targetSessionId.trim() : "";
34651
+ if (explicit) return explicit;
34652
+ const current = h.currentSession?.sessionId;
34653
+ return typeof current === "string" ? current.trim() : "";
34654
+ }
34592
34655
  function sessionStartedAtMsFromRegistry(h, targetSessionId) {
34593
- const sid = typeof targetSessionId === "string" ? targetSessionId.trim() : "";
34656
+ const sid = effectiveReadSessionId(h, targetSessionId);
34594
34657
  if (!sid) return void 0;
34595
34658
  const target = h.ctx?.sessionRegistry?.get?.(sid);
34596
34659
  return typeof target?.spawnedAtMs === "number" ? target.spawnedAtMs : void 0;
@@ -34887,7 +34950,7 @@ async function handleChatHistory(h, args) {
34887
34950
  scripts: provider?.scripts,
34888
34951
  sessionStartedAtMs: sessionStartedAtMsFromRegistry(h, args?.targetSessionId),
34889
34952
  envOverrides: sessionSpawnEnvFromAdapter(h, args?.targetSessionId),
34890
- instanceId: typeof args?.targetSessionId === "string" ? args.targetSessionId : void 0,
34953
+ instanceId: effectiveReadSessionId(h, args?.targetSessionId) || void 0,
34891
34954
  pinnedProviderSessionId: getBoundProviderSessionIdPin(args?.targetSessionId)
34892
34955
  }) : readProviderChatHistory(agentStr, {
34893
34956
  canonicalHistory: provider?.nativeHistory,
@@ -34904,7 +34967,7 @@ async function handleChatHistory(h, args) {
34904
34967
  const messages = Array.isArray(result.messages) ? normalizeAndFilterNativeHistory(h, agentStr, args, result.messages, result?.providerSessionId) : [];
34905
34968
  const historyProviderSessionId = typeof result?.providerSessionId === "string" ? result.providerSessionId : readHistorySessionIdFromMessages(messages) || historySessionId;
34906
34969
  if (typeof result?.providerSessionId === "string" && result.providerSessionId.trim()) {
34907
- recordBoundProviderSessionId(args?.targetSessionId, result.providerSessionId.trim());
34970
+ recordBoundProviderSessionId(h, effectiveReadSessionId(h, args?.targetSessionId), result.providerSessionId.trim());
34908
34971
  }
34909
34972
  const safeMapping = hasSafeNativeHistoryMapping({
34910
34973
  historySessionId: lookup === "workspace" ? void 0 : historySessionId,
@@ -35028,10 +35091,15 @@ async function handleReadChat(h, args) {
35028
35091
  let nativeHistory = null;
35029
35092
  let nativeHistoryError;
35030
35093
  if (supportsNative) {
35094
+ const pinnedProviderSessionIdForRead = getBoundProviderSessionIdPin(targetSessionId);
35095
+ const nativeReadSessionIdIsRuntimeFallback = Boolean(
35096
+ targetSessionId && nativeHistoryReadSessionId === targetSessionId && !getExplicitHistorySessionId(args)
35097
+ );
35098
+ const effectiveNativeReadSessionId = nativeReadSessionIdIsRuntimeFallback ? pinnedProviderSessionIdForRead || void 0 : nativeHistoryReadSessionId;
35031
35099
  try {
35032
35100
  nativeHistory = readCliProviderNativeHistory(agentStr, {
35033
35101
  canonicalHistory: provider?.nativeHistory,
35034
- historySessionId: nativeHistoryReadSessionId,
35102
+ historySessionId: effectiveNativeReadSessionId,
35035
35103
  workspace,
35036
35104
  offset: 0,
35037
35105
  limit: nativeHistoryLimit,
@@ -35043,16 +35111,16 @@ async function handleReadChat(h, args) {
35043
35111
  envOverrides: sessionSpawnEnvFromAdapter(h, args?.targetSessionId),
35044
35112
  // Stable per-session identity for antigravity's conversation-claim
35045
35113
  // owner token (== session registry sessionId == instance instanceId).
35046
- instanceId: typeof args?.targetSessionId === "string" ? args.targetSessionId : void 0,
35047
- pinnedProviderSessionId: getBoundProviderSessionIdPin(targetSessionId),
35114
+ instanceId: effectiveReadSessionId(h, args?.targetSessionId) || void 0,
35115
+ pinnedProviderSessionId: pinnedProviderSessionIdForRead,
35048
35116
  // Last-resort only when no pin was ever recorded for this
35049
35117
  // session; the downstream workspace-overlap safety gate
35050
35118
  // still filters an aliased session out.
35051
- allowWorkspaceLatestFallback: !getBoundProviderSessionIdPin(targetSessionId)
35119
+ allowWorkspaceLatestFallback: !pinnedProviderSessionIdForRead
35052
35120
  });
35053
35121
  const resolvedProviderSessionId = typeof nativeHistory?.providerSessionId === "string" ? nativeHistory.providerSessionId.trim() : "";
35054
35122
  if (resolvedProviderSessionId) {
35055
- recordBoundProviderSessionId(targetSessionId, resolvedProviderSessionId);
35123
+ recordBoundProviderSessionId(h, effectiveReadSessionId(h, targetSessionId), resolvedProviderSessionId);
35056
35124
  }
35057
35125
  } catch (error) {
35058
35126
  nativeHistoryError = error;
@@ -35094,7 +35162,7 @@ async function handleReadChat(h, args) {
35094
35162
  excludeInProgressTurn: returnedStatus === "waiting_approval",
35095
35163
  sessionStartedAtMs,
35096
35164
  envOverrides: sessionSpawnEnvFromAdapter(h, args?.targetSessionId),
35097
- instanceId: typeof args?.targetSessionId === "string" ? args.targetSessionId : void 0
35165
+ instanceId: effectiveReadSessionId(h, args?.targetSessionId) || void 0
35098
35166
  });
35099
35167
  nativeHistoryError = void 0;
35100
35168
  nativeMessages = nativeHistory && Array.isArray(nativeHistory.messages) ? normalizeAndFilterNativeHistory(h, agentStr, args, nativeHistory.messages, nativeHistory.providerSessionId) : [];
@@ -35316,7 +35384,7 @@ async function handleReadChat(h, args) {
35316
35384
  scripts: provider?.scripts,
35317
35385
  sessionStartedAtMs: sessionStartedAtMsFromRegistry(h, args?.targetSessionId),
35318
35386
  envOverrides: sessionSpawnEnvFromAdapter(h, args?.targetSessionId),
35319
- instanceId: typeof args?.targetSessionId === "string" ? args.targetSessionId : void 0,
35387
+ instanceId: effectiveReadSessionId(h, args?.targetSessionId) || void 0,
35320
35388
  pinnedProviderSessionId: pinnedProviderSessionIdForHistory,
35321
35389
  // Last-resort only when no pin was ever recorded AND the
35322
35390
  // runtime fallback did not resolve a real provider session.
@@ -35335,7 +35403,7 @@ async function handleReadChat(h, args) {
35335
35403
  const historyMessages = Array.isArray(history?.messages) ? normalizeAndFilterNativeHistory(h, agentStr, args, history.messages, history?.providerSessionId) : [];
35336
35404
  const historyProviderSessionId = typeof history?.providerSessionId === "string" ? history.providerSessionId : readHistorySessionIdFromMessages(historyMessages) || effectiveHistorySessionIdForRead;
35337
35405
  if (typeof history?.providerSessionId === "string" && history.providerSessionId.trim()) {
35338
- recordBoundProviderSessionId(targetSid, history.providerSessionId.trim());
35406
+ recordBoundProviderSessionId(h, effectiveReadSessionId(h, targetSid), history.providerSessionId.trim());
35339
35407
  }
35340
35408
  const mappingSessionId = effectiveHistorySessionIdForRead;
35341
35409
  const safeMapping = supportsNative ? hasSafeNativeHistoryMapping({
@@ -43802,6 +43870,7 @@ function createCliAdapter(provider, workingDir, cliArgs, extraEnv, transportFact
43802
43870
  }
43803
43871
 
43804
43872
  // src/providers/cli-provider-instance.ts
43873
+ init_state_store();
43805
43874
  init_logger();
43806
43875
  init_debug_trace();
43807
43876
  init_debug_config();
@@ -43834,13 +43903,10 @@ function normalizeUuid(uuid) {
43834
43903
  return String(uuid || "").trim().toLowerCase();
43835
43904
  }
43836
43905
  function antigravityOwnerToken(workspace, sessionStartedAtMs, instanceId) {
43906
+ void workspace;
43907
+ void sessionStartedAtMs;
43837
43908
  const iid = typeof instanceId === "string" ? instanceId.trim() : "";
43838
- if (iid) return `iid:${iid}`;
43839
- if (typeof sessionStartedAtMs === "number" && sessionStartedAtMs > 0) {
43840
- const ws = String(workspace || "").trim().toLowerCase();
43841
- return `spawn:${ws}:${sessionStartedAtMs}`;
43842
- }
43843
- return "";
43909
+ return iid ? `iid:${iid}` : "";
43844
43910
  }
43845
43911
  function claimAntigravityConversation(uuid, owner, now = Date.now()) {
43846
43912
  const key2 = normalizeUuid(uuid);
@@ -44600,6 +44666,27 @@ var CliProviderInstance = class _CliProviderInstance {
44600
44666
  senderName: message.senderName,
44601
44667
  receivedAt: message.receivedAt
44602
44668
  })) : mergedMessages;
44669
+ const adapterOwnsMessagesElsewhereForTail = this.adapter?.chatMessagesOwnedExternally === true;
44670
+ if (adapterOwnsMessagesElsewhereForTail && this.lastCompletionSummary) {
44671
+ const summary = this.lastCompletionSummary;
44672
+ let hasTrailingAssistant = false;
44673
+ for (let i = statusMessages.length - 1; i >= 0; i -= 1) {
44674
+ const m = statusMessages[i];
44675
+ const role = typeof m?.role === "string" ? m.role : "";
44676
+ if (role === "system") continue;
44677
+ if (typeof m?.kind === "string" && m.kind === "tool") continue;
44678
+ hasTrailingAssistant = role === "assistant" && typeof m?.receivedAt === "number" && m.receivedAt >= summary.receivedAt - 1e3;
44679
+ break;
44680
+ }
44681
+ if (!hasTrailingAssistant) {
44682
+ statusMessages.push({
44683
+ role: "assistant",
44684
+ content: summary.content,
44685
+ kind: "standard",
44686
+ receivedAt: summary.receivedAt
44687
+ });
44688
+ }
44689
+ }
44603
44690
  const dirName = workingDirBasename(this.workingDir);
44604
44691
  const parsedChatStatus = typeof parsedStatus?.status === "string" && parsedStatus.status.trim() ? parsedStatus.status.trim() : void 0;
44605
44692
  const suppressStaleParsedBusyStatus = this.shouldSuppressStaleParsedBusyStatus(parsedStatus, adapterStatus);
@@ -45032,6 +45119,18 @@ var CliProviderInstance = class _CliProviderInstance {
45032
45119
  completedDebounceTimer = null;
45033
45120
  completedDebouncePending = null;
45034
45121
  lastExternalCompletionProbe = null;
45122
+ /**
45123
+ * The final assistant summary of the last completed turn, cached at
45124
+ * completion-emit time. For a native-source provider (antigravity) whose
45125
+ * assistant answer lives only in native-history — never in the PTY parse that
45126
+ * feeds activeChat.messages — the dashboard's preview / lastMessageRole /
45127
+ * completionMarker would otherwise never see the answer and show the session
45128
+ * stuck on the user prompt. getState() appends this cached assistant bubble to
45129
+ * the status messages when the PTY tail has none, so those fields reflect the
45130
+ * real last answer with ZERO per-tick native reads (the native read already ran
45131
+ * once at completion). Reset on the next turn's start.
45132
+ */
45133
+ lastCompletionSummary = null;
45035
45134
  async enforceFreshSessionLaunchIfNeeded() {
45036
45135
  const scriptName = getForcedNewSessionScriptName(this.provider, this.launchMode);
45037
45136
  if (!scriptName) return;
@@ -45095,8 +45194,15 @@ var CliProviderInstance = class _CliProviderInstance {
45095
45194
  readExternalCompletionMessages() {
45096
45195
  const adapterOwnsMessagesElsewhere = this.adapter?.chatMessagesOwnedExternally === true;
45097
45196
  if (!adapterOwnsMessagesElsewhere) return null;
45098
- if (!this.providerSessionId) return null;
45099
45197
  if (!isNativeSourceCanonicalHistory(this.provider.nativeHistory)) return null;
45198
+ let resolvedHandle = this.providerSessionId || "";
45199
+ if (!resolvedHandle) {
45200
+ try {
45201
+ const pinned = loadPersistedProviderSessionPins()[this.instanceId];
45202
+ if (typeof pinned === "string" && pinned.trim()) resolvedHandle = pinned.trim();
45203
+ } catch {
45204
+ }
45205
+ }
45100
45206
  if (this.lastExternalCompletionProbe?.sourcePath) {
45101
45207
  try {
45102
45208
  fs21.statSync(this.lastExternalCompletionProbe.sourcePath);
@@ -45105,13 +45211,18 @@ var CliProviderInstance = class _CliProviderInstance {
45105
45211
  }
45106
45212
  const restoredHistory = readProviderChatHistory(this.type, {
45107
45213
  canonicalHistory: this.provider.nativeHistory,
45108
- historySessionId: this.providerSessionId,
45214
+ historySessionId: resolvedHandle || void 0,
45109
45215
  workspace: this.workingDir,
45110
45216
  offset: 0,
45111
45217
  limit: Number.MAX_SAFE_INTEGER,
45112
45218
  historyBehavior: this.provider.historyBehavior,
45113
45219
  scripts: this.provider.scripts,
45114
45220
  sessionStartedAtMs: this.startedAt,
45221
+ // The claim owner token must match read_chat's so the exact-bind on our
45222
+ // own conversation stays idempotent rather than looking foreign, and so
45223
+ // the floor-based resolution above claims THIS session's db under its
45224
+ // own owner (never a sibling's).
45225
+ instanceId: this.instanceId,
45115
45226
  envOverrides: this.spawnedEnvOverrides(),
45116
45227
  forceRefresh: true
45117
45228
  });
@@ -45126,6 +45237,26 @@ var CliProviderInstance = class _CliProviderInstance {
45126
45237
  );
45127
45238
  return restoredHistory.messages;
45128
45239
  }
45240
+ /**
45241
+ * The content of the LAST visible assistant bubble in a message list, or ''
45242
+ * when the tail is not an assistant reply. Skips trailing system/tool/activity
45243
+ * bubbles; stops (returns '') at the first user/human message. Used only for
45244
+ * the dashboard tail-repair cache — a display value, not a completion decision.
45245
+ */
45246
+ lastVisibleAssistantSummary(messages) {
45247
+ if (!Array.isArray(messages)) return "";
45248
+ for (let i = messages.length - 1; i >= 0; i -= 1) {
45249
+ const m = messages[i];
45250
+ const role = typeof m?.role === "string" ? m.role : "";
45251
+ const kind = typeof m?.kind === "string" ? m.kind : "";
45252
+ if (role === "system") continue;
45253
+ if (kind === "tool" || kind === "activity") continue;
45254
+ if (role === "user" || role === "human") return "";
45255
+ if (role === "assistant") return flattenContent(m.content).trim();
45256
+ return "";
45257
+ }
45258
+ return "";
45259
+ }
45129
45260
  completionFinalAssistantEvidence(parsedMessages, turnStartedAt) {
45130
45261
  const turnClosed = !this.hasAdapterPendingResponse();
45131
45262
  if (this.completionHasFinalAssistantMessage(parsedMessages, turnStartedAt)) {
@@ -45137,8 +45268,13 @@ var CliProviderInstance = class _CliProviderInstance {
45137
45268
  }
45138
45269
  const externalMessages = this.readExternalCompletionMessages();
45139
45270
  if (externalMessages) {
45271
+ const present = turnClosed && this.completionHasFinalAssistantMessage(externalMessages, turnStartedAt);
45272
+ const lastVisibleAssistant = this.lastVisibleAssistantSummary(externalMessages);
45273
+ if (lastVisibleAssistant) {
45274
+ this.lastCompletionSummary = { content: lastVisibleAssistant, receivedAt: Date.now() };
45275
+ }
45140
45276
  return {
45141
- present: turnClosed && this.completionHasFinalAssistantMessage(externalMessages, turnStartedAt),
45277
+ present,
45142
45278
  messages: externalMessages,
45143
45279
  source: "external-native"
45144
45280
  };
@@ -45158,7 +45294,10 @@ var CliProviderInstance = class _CliProviderInstance {
45158
45294
  if (adapterOwnsMessagesElsewhere) {
45159
45295
  const externalMessages = this.readExternalCompletionMessages();
45160
45296
  const externalSummary = externalMessages ? extractFinalSummaryFromMessagesAfter(externalMessages, turnStartedAt) : "";
45161
- if (externalSummary) return externalSummary;
45297
+ if (externalSummary) {
45298
+ this.lastCompletionSummary = { content: externalSummary, receivedAt: Date.now() };
45299
+ return externalSummary;
45300
+ }
45162
45301
  return parsedSummary || void 0;
45163
45302
  }
45164
45303
  return parsedSummary || void 0;
@@ -45626,6 +45765,10 @@ var CliProviderInstance = class _CliProviderInstance {
45626
45765
  * the emitted event, exactly as each inline builder produced before.
45627
45766
  */
45628
45767
  emitGeneratingCompleted(opts) {
45768
+ const summary = typeof opts.finalSummary === "string" ? opts.finalSummary.trim() : "";
45769
+ if (summary) {
45770
+ this.lastCompletionSummary = { content: summary, receivedAt: opts.timestamp };
45771
+ }
45629
45772
  this.pushEvent({
45630
45773
  event: "agent:generating_completed",
45631
45774
  chatTitle: opts.chatTitle,
@@ -45910,6 +46053,7 @@ var CliProviderInstance = class _CliProviderInstance {
45910
46053
  this.completedDebouncePending = null;
45911
46054
  }
45912
46055
  if (!this.generatingStartedAt) this.generatingStartedAt = now;
46056
+ this.lastCompletionSummary = null;
45913
46057
  this.busyEpoch++;
45914
46058
  if (this.generatingDebounceTimer) clearTimeout(this.generatingDebounceTimer);
45915
46059
  this.generatingDebouncePending = { chatTitle, timestamp: now };
@@ -50882,6 +51026,13 @@ function createNativeHistoryDispatcher(reader) {
50882
51026
  if (requestedProviderSid && session.providerSessionId && session.providerSessionId !== requestedProviderSid) {
50883
51027
  return null;
50884
51028
  }
51029
+ let resolvedProviderSessionId = session.providerSessionId;
51030
+ if (reader === "antigravity-cli") {
51031
+ const onDiskUuid = extractAntigravityConversationUuid(session.sourcePath || sourcePath);
51032
+ if (onDiskUuid && (!resolvedProviderSessionId || resolvedProviderSessionId === sessionId)) {
51033
+ resolvedProviderSessionId = onDiskUuid;
51034
+ }
51035
+ }
50885
51036
  return {
50886
51037
  messages: session.messages.map((m) => ({
50887
51038
  role: normalizeRole2(m.role),
@@ -50890,7 +51041,7 @@ function createNativeHistoryDispatcher(reader) {
50890
51041
  kind: typeof m.kind === "string" ? m.kind : "standard",
50891
51042
  workspace: typeof m.workspace === "string" ? m.workspace : workspace || void 0
50892
51043
  })),
50893
- providerSessionId: session.providerSessionId,
51044
+ providerSessionId: resolvedProviderSessionId,
50894
51045
  sourcePath: session.sourcePath,
50895
51046
  sourceMtimeMs: session.sourceMtimeMs,
50896
51047
  nativeHistoryCoverage: session.nativeHistoryCoverage || "full"
@@ -51019,6 +51170,17 @@ function resolveRealPath(value) {
51019
51170
  return value;
51020
51171
  }
51021
51172
  }
51173
+ function extractAntigravityConversationUuid(sourcePath) {
51174
+ if (!sourcePath) return "";
51175
+ const segments = sourcePath.split(/[\\/]/);
51176
+ const base = segments[segments.length - 1] || "";
51177
+ const baseMatch = /^([0-9a-f-]+)\.(?:db|pb)$/i.exec(base);
51178
+ if (baseMatch && isUuidLikeSessionId2(baseMatch[1])) return baseMatch[1];
51179
+ for (const seg of segments) {
51180
+ if (isUuidLikeSessionId2(seg)) return seg;
51181
+ }
51182
+ return "";
51183
+ }
51022
51184
  var AGY_SPAWN_CLAIM_GRACE_MS = 2e3;
51023
51185
  function resolveAntigravityPath(workspace, sessionId, sessionStartedAtMs, instanceId) {
51024
51186
  const agyRoot = path34.join(os25.homedir(), ".gemini", "antigravity-cli");
@@ -51033,10 +51195,24 @@ function resolveAntigravityPath(workspace, sessionId, sessionStartedAtMs, instan
51033
51195
  const brainRoot2 = path34.join(agyRoot, "brain");
51034
51196
  if (fs26.existsSync(brainRoot2)) {
51035
51197
  const cutoff = spawnAwareCutoff(sessionStartedAtMs);
51036
- const entries = fs26.readdirSync(brainRoot2, { withFileTypes: true }).filter((e) => e.isDirectory() && isUuidLikeSessionId2(e.name)).filter((e) => !isAntigravityConversationClaimedByOther(e.name, owner)).map((e) => ({ uuid: e.name, p: path34.join(brainRoot2, e.name), mtime: safeMtime(path34.join(brainRoot2, e.name)) })).filter((e) => e.mtime >= cutoff).sort((a, b) => b.mtime - a.mtime);
51037
- for (const e of entries) {
51038
- const t = path34.join(e.p, ".system_generated", "logs", "transcript.jsonl");
51039
- if (fs26.existsSync(t) && safeSize(t) > 0) {
51198
+ const nonEmptyBrain = (uuid, p) => {
51199
+ const t = path34.join(p, ".system_generated", "logs", "transcript.jsonl");
51200
+ return fs26.existsSync(t) && safeSize(t) > 0 ? t : null;
51201
+ };
51202
+ const all = fs26.readdirSync(brainRoot2, { withFileTypes: true }).filter((e) => e.isDirectory() && isUuidLikeSessionId2(e.name)).filter((e) => !isAntigravityConversationClaimedByOther(e.name, owner)).map((e) => {
51203
+ const p = path34.join(brainRoot2, e.name);
51204
+ return { uuid: e.name, p, mtime: safeMtime(p), birth: safeBirthtime(p) };
51205
+ }).filter((e) => e.mtime >= cutoff);
51206
+ let ordered = [];
51207
+ if (sessionStartedAtMs > 0) {
51208
+ const floor = sessionStartedAtMs - AGY_SPAWN_CLAIM_GRACE_MS;
51209
+ ordered = all.filter((e) => (e.birth > 0 ? e.birth : e.mtime) >= floor).sort((a, b) => (a.birth || a.mtime) - (b.birth || b.mtime));
51210
+ } else {
51211
+ ordered = [...all].sort((a, b) => b.mtime - a.mtime);
51212
+ }
51213
+ for (const e of ordered) {
51214
+ const t = nonEmptyBrain(e.uuid, e.p);
51215
+ if (t) {
51040
51216
  if (owner) claimAntigravityConversation(e.uuid, owner);
51041
51217
  return t;
51042
51218
  }
@@ -51057,6 +51233,7 @@ function pickUnboundConversationDb(convRoot, sessionFloorMs, owner) {
51057
51233
  } catch {
51058
51234
  return null;
51059
51235
  }
51236
+ const applyRecencyCutoff = !(sessionFloorMs > 0);
51060
51237
  const recencyCutoff = Date.now() - RECENT_WINDOW_MS;
51061
51238
  const candidates = [];
51062
51239
  for (const entry of entries) {
@@ -51067,7 +51244,7 @@ function pickUnboundConversationDb(convRoot, sessionFloorMs, owner) {
51067
51244
  if (isAntigravityConversationClaimedByOther(uuid, owner)) continue;
51068
51245
  const p = path34.join(convRoot, entry.name);
51069
51246
  const mtime = safeMtime(p);
51070
- if (mtime < recencyCutoff) continue;
51247
+ if (applyRecencyCutoff && mtime < recencyCutoff) continue;
51071
51248
  candidates.push({ path: p, uuid, mtime, birth: safeBirthtime(p) });
51072
51249
  }
51073
51250
  if (candidates.length === 0) return null;
@@ -68318,7 +68495,11 @@ var SessionRegistry = class {
68318
68495
  byInstanceKey = /* @__PURE__ */ new Map();
68319
68496
  byParentSessionId = /* @__PURE__ */ new Map();
68320
68497
  register(target) {
68498
+ const priorProviderSessionId = this.bySessionId.get(target.sessionId)?.providerSessionId;
68321
68499
  this.unregister(target.sessionId);
68500
+ if (priorProviderSessionId && !target.providerSessionId) {
68501
+ target = { ...target, providerSessionId: priorProviderSessionId };
68502
+ }
68322
68503
  this.bySessionId.set(target.sessionId, target);
68323
68504
  if (target.cdpManagerKey) this.addIndex(this.byManagerKey, target.cdpManagerKey, target.sessionId);
68324
68505
  if (target.instanceKey) this.addIndex(this.byInstanceKey, target.instanceKey, target.sessionId);
@@ -68328,6 +68509,22 @@ var SessionRegistry = class {
68328
68509
  if (!sessionId) return void 0;
68329
68510
  return this.bySessionId.get(sessionId);
68330
68511
  }
68512
+ /**
68513
+ * Record the authoritative provider-native conversation id for a session
68514
+ * (SSOT). Idempotent; a no-op when the session is unknown or the value is
68515
+ * empty or unchanged. Never overwrites a known binding with an empty one.
68516
+ * Returns whether the stored value changed.
68517
+ */
68518
+ setProviderSessionId(sessionId, providerSessionId) {
68519
+ const sid = typeof sessionId === "string" ? sessionId.trim() : "";
68520
+ const value = typeof providerSessionId === "string" ? providerSessionId.trim() : "";
68521
+ if (!sid || !value) return false;
68522
+ const target = this.bySessionId.get(sid);
68523
+ if (!target) return false;
68524
+ if (target.providerSessionId === value) return false;
68525
+ target.providerSessionId = value;
68526
+ return true;
68527
+ }
68331
68528
  unregister(sessionId) {
68332
68529
  if (!sessionId) return;
68333
68530
  const target = this.bySessionId.get(sessionId);