@adhdev/daemon-core 0.9.82-rc.466 → 0.9.82-rc.468

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 ? "e0f04b7d54855e0f0d5ed4200078d95596ab9f6f" : void 0) ?? "unknown";
408
- const commitShort = readInjected(true ? "e0f04b7d" : void 0) ?? (commit !== "unknown" ? commit.slice(0, 7) : "unknown");
409
- const version = readInjected(true ? "0.9.82-rc.466" : void 0) ?? readInjected(typeof process !== "undefined" ? process.env?.ADHDEV_PKG_VERSION : void 0) ?? "unknown";
410
- const builtAt = readInjected(true ? "2026-07-05T08:18:54.364Z" : void 0);
407
+ const commit = readInjected(true ? "f05125bad26f9ee974d8bd31a8b9ab66bca9d4cd" : void 0) ?? "unknown";
408
+ const commitShort = readInjected(true ? "f05125ba" : void 0) ?? (commit !== "unknown" ? commit.slice(0, 7) : "unknown");
409
+ const version = readInjected(true ? "0.9.82-rc.468" : void 0) ?? readInjected(typeof process !== "undefined" ? process.env?.ADHDEV_PKG_VERSION : void 0) ?? "unknown";
410
+ const builtAt = readInjected(true ? "2026-07-05T10:08:41.050Z" : void 0);
411
411
  cached = builtAt ? { commit, commitShort, version, builtAt } : { commit, commitShort, version };
412
412
  return cached;
413
413
  }
@@ -6159,7 +6159,7 @@ var init_mesh_work_queue = __esm({
6159
6159
  });
6160
6160
 
6161
6161
  // src/mesh/mesh-runtime-store.ts
6162
- import { existsSync as existsSync8, mkdirSync as mkdirSync5, readFileSync as readFileSync6, renameSync as renameSync3, statSync as statSync5 } from "fs";
6162
+ import { existsSync as existsSync8, mkdirSync as mkdirSync5, readFileSync as readFileSync6, renameSync as renameSync3, statSync as statSync5, unlinkSync as unlinkSync2 } from "fs";
6163
6163
  import { dirname as dirname2, join as join9 } from "path";
6164
6164
  function loadDatabaseCtor() {
6165
6165
  if (DatabaseCtor) return DatabaseCtor;
@@ -6172,9 +6172,28 @@ function safeMeshId(meshId) {
6172
6172
  function legacyQueuePath(meshId) {
6173
6173
  return join9(getLedgerDir(), `${safeMeshId(meshId)}.queue.json`);
6174
6174
  }
6175
+ function cleanupStrayRootRuntimeDb(canonicalPath) {
6176
+ try {
6177
+ const strayPath = join9(getConfigDir(), "mesh-runtime.db");
6178
+ if (strayPath === canonicalPath) return;
6179
+ if (!existsSync8(strayPath)) return;
6180
+ if (statSync5(strayPath).size !== 0) return;
6181
+ unlinkSync2(strayPath);
6182
+ if (!loggedStrayCleanup) {
6183
+ loggedStrayCleanup = true;
6184
+ LOG.info("MeshRuntimeStore", `Removed stray 0-byte root mesh-runtime.db at ${strayPath}`);
6185
+ }
6186
+ } catch (err) {
6187
+ if (!loggedStrayCleanup) {
6188
+ loggedStrayCleanup = true;
6189
+ LOG.warn("MeshRuntimeStore", `Stray root mesh-runtime.db cleanup failed (ignored): ${err?.message || err}`);
6190
+ }
6191
+ }
6192
+ }
6175
6193
  function meshRuntimeStorePath() {
6176
6194
  const dir = getLedgerDir();
6177
6195
  const nextPath = join9(dir, "mesh-runtime.db");
6196
+ cleanupStrayRootRuntimeDb(nextPath);
6178
6197
  if (existsSync8(nextPath)) return nextPath;
6179
6198
  const legacyPath = join9(dir, "beads.db");
6180
6199
  if (!existsSync8(legacyPath)) return nextPath;
@@ -6198,16 +6217,18 @@ function meshRuntimeStorePath() {
6198
6217
  }
6199
6218
  return nextPath;
6200
6219
  }
6201
- var DatabaseCtor, loggedMigrationFailure, MeshRuntimeStore;
6220
+ var DatabaseCtor, loggedMigrationFailure, loggedStrayCleanup, MeshRuntimeStore;
6202
6221
  var init_mesh_runtime_store = __esm({
6203
6222
  "src/mesh/mesh-runtime-store.ts"() {
6204
6223
  "use strict";
6205
6224
  init_logger();
6206
6225
  init_load_better_sqlite3();
6226
+ init_config();
6207
6227
  init_mesh_ledger();
6208
6228
  init_mesh_work_queue();
6209
6229
  init_dist();
6210
6230
  loggedMigrationFailure = false;
6231
+ loggedStrayCleanup = false;
6211
6232
  MeshRuntimeStore = class _MeshRuntimeStore {
6212
6233
  static instance;
6213
6234
  db;
@@ -6550,6 +6571,7 @@ var init_mesh_runtime_store = __esm({
6550
6571
  ON mesh_pending_events(mesh_id, event_id)
6551
6572
  WHERE event_id IS NOT NULL
6552
6573
  `);
6574
+ this.db.exec(`DROP TABLE IF EXISTS mesh_direct_delivered_events`);
6553
6575
  } catch (err) {
6554
6576
  if (!loggedMigrationFailure) {
6555
6577
  loggedMigrationFailure = true;
@@ -11510,7 +11532,7 @@ var init_mesh_events_utils = __esm({
11510
11532
  });
11511
11533
 
11512
11534
  // src/mesh/mesh-events-pending.ts
11513
- import { appendFileSync as appendFileSync2, existsSync as existsSync15, readFileSync as readFileSync12, renameSync as renameSync4, statSync as statSync6, unlinkSync as unlinkSync2, writeFileSync as writeFileSync6 } from "fs";
11535
+ import { appendFileSync as appendFileSync2, existsSync as existsSync15, readFileSync as readFileSync12, renameSync as renameSync4, statSync as statSync6, unlinkSync as unlinkSync3, writeFileSync as writeFileSync6 } from "fs";
11514
11536
  import { join as join16 } from "path";
11515
11537
  import { randomUUID as randomUUID8 } from "crypto";
11516
11538
  function normalizeCoordinatorDaemonIds(coordinatorDaemonId) {
@@ -11986,13 +12008,13 @@ function atomicDrainFile(path45) {
11986
12008
  try {
11987
12009
  const content = readFileSync12(tmpPath, "utf-8");
11988
12010
  try {
11989
- unlinkSync2(tmpPath);
12011
+ unlinkSync3(tmpPath);
11990
12012
  } catch {
11991
12013
  }
11992
12014
  return content;
11993
12015
  } catch {
11994
12016
  try {
11995
- unlinkSync2(tmpPath);
12017
+ unlinkSync3(tmpPath);
11996
12018
  } catch {
11997
12019
  }
11998
12020
  return null;
@@ -12010,7 +12032,7 @@ function selectiveDrainFile(path45, predicate) {
12010
12032
  content = readFileSync12(tmpPath, "utf-8");
12011
12033
  } catch {
12012
12034
  try {
12013
- unlinkSync2(tmpPath);
12035
+ unlinkSync3(tmpPath);
12014
12036
  } catch {
12015
12037
  }
12016
12038
  return [];
@@ -12035,7 +12057,7 @@ function selectiveDrainFile(path45, predicate) {
12035
12057
  if (keptLines.length > 0) {
12036
12058
  writeFileSync6(path45, keptLines.join("\n") + "\n", "utf-8");
12037
12059
  }
12038
- unlinkSync2(tmpPath);
12060
+ unlinkSync3(tmpPath);
12039
12061
  } catch {
12040
12062
  try {
12041
12063
  if (existsSync15(tmpPath) && !existsSync15(path45)) renameSync4(tmpPath, path45);
@@ -12185,7 +12207,7 @@ function clearPendingMeshCoordinatorEvents(meshId, coordinatorDaemonId) {
12185
12207
  const paths = coordinatorDaemonId ? [getPendingEventsPath(meshId, coordinatorDaemonId), getPendingEventsPath(meshId)] : [getPendingEventsPath(meshId)];
12186
12208
  for (const path45 of paths) {
12187
12209
  if (existsSync15(path45)) try {
12188
- unlinkSync2(path45);
12210
+ unlinkSync3(path45);
12189
12211
  } catch {
12190
12212
  }
12191
12213
  }
@@ -19309,11 +19331,13 @@ async function pullRemoteNodeQueues(components, mesh, localDaemonId, candidateDa
19309
19331
  if (!dispatchMeshCommand) return;
19310
19332
  const meshId = mesh.id;
19311
19333
  const pulls = candidateDaemonIds.length > 0 ? candidateDaemonIds.map((id) => ({ meshId, coordinatorDaemonId: id })) : [{ meshId }];
19312
- for (const node of mesh.nodes) {
19334
+ await Promise.allSettled(mesh.nodes.map(async (node) => {
19313
19335
  const nodeDaemonId = readNonEmptyString2(node.daemonId);
19314
- if (!nodeDaemonId) continue;
19315
- if (daemonIdsEquivalent(nodeDaemonId, localDaemonId)) continue;
19316
- if (daemonIdListIncludes(candidateDaemonIds, nodeDaemonId)) continue;
19336
+ if (!nodeDaemonId) return;
19337
+ if (daemonIdsEquivalent(nodeDaemonId, localDaemonId)) return;
19338
+ if (daemonIdListIncludes(candidateDaemonIds, nodeDaemonId)) return;
19339
+ const peerSnapshot = components.getMeshPeerConnectionStatus?.(nodeDaemonId);
19340
+ if (peerSnapshot && String(peerSnapshot.state) !== "connected") return;
19317
19341
  for (const pendingEventArgs of pulls) {
19318
19342
  let events;
19319
19343
  try {
@@ -19331,7 +19355,7 @@ async function pullRemoteNodeQueues(components, mesh, localDaemonId, candidateDa
19331
19355
  }
19332
19356
  }
19333
19357
  }
19334
- }
19358
+ }));
19335
19359
  }
19336
19360
  function unwrapReadChatPayload(raw) {
19337
19361
  let cursor = raw;
@@ -19567,6 +19591,10 @@ async function collectLiveNodesWithSessions(components, mesh, selfIds, localDaem
19567
19591
  return Promise.all(mesh.nodes.map(async (node) => {
19568
19592
  const nodeDaemonId = readNonEmptyString2(node.daemonId);
19569
19593
  const isLocalNode = !nodeDaemonId || daemonIdListIncludes(selfIds, nodeDaemonId) || daemonIdsEquivalent(nodeDaemonId, localDaemonId);
19594
+ if (!isLocalNode) {
19595
+ const peerSnapshot = components.getMeshPeerConnectionStatus?.(nodeDaemonId);
19596
+ if (peerSnapshot && String(peerSnapshot.state) !== "connected") return node;
19597
+ }
19570
19598
  let statusResult;
19571
19599
  try {
19572
19600
  if (isLocalNode) {
@@ -42306,7 +42334,7 @@ async function waitForCliAdapterReady(adapter, options) {
42306
42334
  throw new Error(`CLI runtime did not become ready within ${timeoutMs}ms`);
42307
42335
  }
42308
42336
 
42309
- // src/providers/cli-provider-instance.ts
42337
+ // src/providers/cli-provider-instance-types.ts
42310
42338
  var STATUS_HYDRATION_TAIL_LIMIT = 200;
42311
42339
  var COMPLETED_FINALIZATION_RETRY_MS = 1e3;
42312
42340
  var COMPLETED_FINALIZATION_MAX_WAIT_MS = 3e4;
@@ -42318,6 +42346,123 @@ var TERMINAL_MESH_EVENTS = /* @__PURE__ */ new Set([
42318
42346
  "agent:stopped",
42319
42347
  "agent:ready"
42320
42348
  ]);
42349
+
42350
+ // src/providers/cli-provider-transcript-merge.ts
42351
+ init_contracts2();
42352
+ init_chat_message_normalization();
42353
+ function mergeConversationMessages(runtimeMessages, parsedMessages) {
42354
+ if (runtimeMessages.length === 0) return normalizeChatMessages(parsedMessages);
42355
+ const parsedEntries = parsedMessages.map((message, index) => ({
42356
+ message,
42357
+ index,
42358
+ source: "parsed"
42359
+ }));
42360
+ const getRole = (message) => typeof message.role === "string" ? message.role.trim().toLowerCase() : "";
42361
+ const runtimeEntries = runtimeMessages.map((entry, index) => ({
42362
+ message: entry.message,
42363
+ index: parsedMessages.length + index,
42364
+ source: "runtime",
42365
+ runtimeKey: entry.key
42366
+ })).filter((entry) => {
42367
+ const meta = entry.message.meta && typeof entry.message.meta === "object" && !Array.isArray(entry.message.meta) ? entry.message.meta : {};
42368
+ if (meta.runtimeInputAck !== true) return true;
42369
+ const runtimeText = flattenContent(entry.message.content).replace(/\s+/g, " ").trim();
42370
+ if (!runtimeText) return false;
42371
+ return !parsedEntries.some((parsedEntry) => {
42372
+ const parsedRole = getRole(parsedEntry.message);
42373
+ if (parsedRole !== "user" && parsedRole !== "human") return false;
42374
+ const parsedText = flattenContent(parsedEntry.message.content).replace(/\s+/g, " ").trim();
42375
+ return parsedText === runtimeText;
42376
+ });
42377
+ });
42378
+ const getTime = (message) => {
42379
+ const value = typeof message.receivedAt === "number" ? message.receivedAt : typeof message.timestamp === "number" ? message.timestamp : 0;
42380
+ return Number.isFinite(value) && value > 0 ? value : 0;
42381
+ };
42382
+ const isRuntimeOverlay = (entry) => {
42383
+ if (entry.source !== "runtime") return false;
42384
+ const key2 = typeof entry.runtimeKey === "string" ? entry.runtimeKey.trim().toLowerCase() : "";
42385
+ if (key2.startsWith("auto_approval:")) return true;
42386
+ return !isUserFacingChatMessage(entry.message);
42387
+ };
42388
+ const shouldKeepParsedBeforeUntimedRuntime = (message) => {
42389
+ const role = getRole(message);
42390
+ return role === "user" || role === "human";
42391
+ };
42392
+ const shouldKeepParsedAfterUntimedRuntime = (message) => {
42393
+ const role = getRole(message);
42394
+ if (role !== "assistant") return false;
42395
+ const kind = resolveChatMessageKind(message);
42396
+ return kind === "standard" || kind === "terminal";
42397
+ };
42398
+ return normalizeChatMessages([...parsedEntries, ...runtimeEntries].sort((a, b) => {
42399
+ const aTime = getTime(a.message);
42400
+ const bTime = getTime(b.message);
42401
+ if (aTime && bTime && aTime !== bTime) return aTime - bTime;
42402
+ if (a.source !== b.source && aTime !== bTime) {
42403
+ const parsedEntry = a.source === "parsed" ? a : b.source === "parsed" ? b : null;
42404
+ const runtimeEntry = a.source === "runtime" ? a : b.source === "runtime" ? b : null;
42405
+ if (parsedEntry && runtimeEntry && isRuntimeOverlay(runtimeEntry) && getTime(parsedEntry.message) === 0 && getTime(runtimeEntry.message) > 0) {
42406
+ if (shouldKeepParsedBeforeUntimedRuntime(parsedEntry.message)) {
42407
+ return a.source === "parsed" ? -1 : 1;
42408
+ }
42409
+ if (shouldKeepParsedAfterUntimedRuntime(parsedEntry.message)) {
42410
+ return a.source === "parsed" ? 1 : -1;
42411
+ }
42412
+ }
42413
+ }
42414
+ return a.index - b.index;
42415
+ }).map((entry) => entry.message));
42416
+ }
42417
+ function buildExternalTranscriptProbe(messages, sourcePath, sourceMtimeMs) {
42418
+ const visibleMessages = messages.filter((message) => isUserFacingChatMessage(message));
42419
+ const lastVisible = visibleMessages[visibleMessages.length - 1];
42420
+ const readAt = Date.now();
42421
+ const mtimeMs = Number(sourceMtimeMs) || 0;
42422
+ return {
42423
+ readAt,
42424
+ msgCount: messages.length,
42425
+ lastRole: typeof lastVisible?.role === "string" ? lastVisible.role.trim().toLowerCase() : null,
42426
+ lastKind: typeof lastVisible?.kind === "string" ? lastVisible.kind : null,
42427
+ contentLen: lastVisible ? flattenContent(lastVisible.content).trim().length : 0,
42428
+ sourcePath: typeof sourcePath === "string" && sourcePath ? sourcePath : null,
42429
+ sourceMtimeMs: mtimeMs || null,
42430
+ mtimeAgeMs: mtimeMs ? Math.max(0, readAt - mtimeMs) : null
42431
+ };
42432
+ }
42433
+
42434
+ // src/providers/cli-provider-effect-format.ts
42435
+ function getEffectDedupKey(effect) {
42436
+ if (effect.id) return `provider_effect:${effect.id}`;
42437
+ if (effect.type === "message") {
42438
+ const content = typeof effect.message?.content === "string" ? effect.message.content : JSON.stringify(effect.message?.content || "");
42439
+ return `provider_effect:message:${content}`;
42440
+ }
42441
+ if (effect.type === "notification") {
42442
+ return `provider_effect:notification:${effect.notification?.title || ""}:${effect.notification?.body || ""}`;
42443
+ }
42444
+ return `provider_effect:toast:${effect.toast?.message || ""}`;
42445
+ }
42446
+ function formatApprovalRequestMessage(modalMessage, buttons) {
42447
+ const lines = ["Approval requested"];
42448
+ const cleanMessage = String(modalMessage || "").trim();
42449
+ if (cleanMessage) lines.push(cleanMessage);
42450
+ const labels = (buttons || []).map((button) => String(button || "").trim()).filter(Boolean);
42451
+ if (labels.length > 0) {
42452
+ lines.push(labels.map((label) => `[${label}]`).join(" "));
42453
+ }
42454
+ return lines.join("\n");
42455
+ }
42456
+ function formatMarkerTimestamp(timestamp) {
42457
+ const date = new Date(timestamp);
42458
+ const pad = (value) => String(value).padStart(2, "0");
42459
+ return `${date.getFullYear()}-${pad(date.getMonth() + 1)}-${pad(date.getDate())} ${pad(date.getHours())}:${pad(date.getMinutes())}:${pad(date.getSeconds())}`;
42460
+ }
42461
+
42462
+ // src/providers/cli-provider-instance.ts
42463
+ function approvalModalSignature(message, affirmativeAnchor) {
42464
+ return [typeof message === "string" ? message.trim() : "", affirmativeAnchor].join("::");
42465
+ }
42321
42466
  var CliProviderInstance = class _CliProviderInstance {
42322
42467
  constructor(provider, workingDir, cliArgs = [], instanceId, transportFactory, options) {
42323
42468
  this.provider = provider;
@@ -42565,7 +42710,7 @@ var CliProviderInstance = class _CliProviderInstance {
42565
42710
  const resumedAt = Date.now();
42566
42711
  this.historyWriter.appendSystemMarker(
42567
42712
  this.type,
42568
- `Resumed saved session at ${this.formatMarkerTimestamp(resumedAt)}`,
42713
+ `Resumed saved session at ${formatMarkerTimestamp(resumedAt)}`,
42569
42714
  {
42570
42715
  instanceId: this.instanceId,
42571
42716
  historySessionId: this.providerSessionId,
@@ -42677,7 +42822,7 @@ var CliProviderInstance = class _CliProviderInstance {
42677
42822
  if (historyMessageCount !== null) {
42678
42823
  parsedMessages = historyMessageCount > 0 ? parsedMessages.slice(-historyMessageCount) : [];
42679
42824
  }
42680
- const mergedMessages = this.mergeConversationMessages(parsedMessages);
42825
+ const mergedMessages = mergeConversationMessages(this.runtimeMessages, parsedMessages);
42681
42826
  const canonicalBackedHistory = this.shouldHydrateExistingProviderHistory() ? this.syncCanonicalSavedHistoryIfNeeded() : false;
42682
42827
  const statusMessages = canonicalBackedHistory && this.lastPersistedHistoryMessages.length > 0 ? this.lastPersistedHistoryMessages.map((message) => ({
42683
42828
  role: message.role,
@@ -43142,22 +43287,6 @@ var CliProviderInstance = class _CliProviderInstance {
43142
43287
  }
43143
43288
  return true;
43144
43289
  }
43145
- buildExternalTranscriptProbe(messages, sourcePath, sourceMtimeMs) {
43146
- const visibleMessages = messages.filter((message) => isUserFacingChatMessage(message));
43147
- const lastVisible = visibleMessages[visibleMessages.length - 1];
43148
- const readAt = Date.now();
43149
- const mtimeMs = Number(sourceMtimeMs) || 0;
43150
- return {
43151
- readAt,
43152
- msgCount: messages.length,
43153
- lastRole: typeof lastVisible?.role === "string" ? lastVisible.role.trim().toLowerCase() : null,
43154
- lastKind: typeof lastVisible?.kind === "string" ? lastVisible.kind : null,
43155
- contentLen: lastVisible ? flattenContent(lastVisible.content).trim().length : 0,
43156
- sourcePath: typeof sourcePath === "string" && sourcePath ? sourcePath : null,
43157
- sourceMtimeMs: mtimeMs || null,
43158
- mtimeAgeMs: mtimeMs ? Math.max(0, readAt - mtimeMs) : null
43159
- };
43160
- }
43161
43290
  recordPendingTranscriptProbe(pending) {
43162
43291
  const probe = this.lastExternalCompletionProbe;
43163
43292
  if (!probe) return null;
@@ -43209,7 +43338,7 @@ var CliProviderInstance = class _CliProviderInstance {
43209
43338
  this.lastExternalCompletionProbe = null;
43210
43339
  return null;
43211
43340
  }
43212
- this.lastExternalCompletionProbe = this.buildExternalTranscriptProbe(
43341
+ this.lastExternalCompletionProbe = buildExternalTranscriptProbe(
43213
43342
  restoredHistory.messages,
43214
43343
  restoredHistory.sourcePath,
43215
43344
  restoredHistory.sourceMtimeMs
@@ -43457,6 +43586,27 @@ var CliProviderInstance = class _CliProviderInstance {
43457
43586
  autoApproveContinuityWindowMs() {
43458
43587
  return this.autoApproveMaskSince > 0 && this.isMeshWorkerSession() ? _CliProviderInstance.AUTO_APPROVE_FLAP_CONTINUITY_MS : _CliProviderInstance.AUTO_APPROVE_GATE_HYSTERESIS_MS;
43459
43588
  }
43589
+ /**
43590
+ * The settle-gate identity signature for a raw activeModal, or null when the
43591
+ * modal is NOT a concrete auto-approvable consent prompt (no captured buttons,
43592
+ * a picker/confirm kind, or no reliable affirmative+decline anchor). Mirrors the
43593
+ * gates the auto-approve fire path applies before computing modalSignature, so
43594
+ * the mask-stall nudge can ask the SAME question the settle gate is tracking —
43595
+ * "is THIS frame's modal the identity the settle clock is accruing against?" —
43596
+ * without duplicating the button-pick logic. The signature is message +
43597
+ * normalized affirmative label only (no volatile counters/button set), matching
43598
+ * the fire path exactly (AUTOAPPROVE-SETTLE-FLAP).
43599
+ */
43600
+ approvableModalSignature(modal) {
43601
+ const buttons = Array.isArray(modal?.buttons) ? modal.buttons.map((b) => String(b || "").trim()).filter(Boolean) : [];
43602
+ if (!modal || buttons.length === 0) return null;
43603
+ const modalKind = typeof modal?.kind === "string" ? modal.kind : "approval";
43604
+ if (modalKind !== "approval") return null;
43605
+ const { index: buttonIndex, label: buttonLabel } = pickApprovalButton(buttons, this.provider);
43606
+ const hasReliableConsentAnchor = hasNegativeApprovalOption(buttons) || hasReliableApprovalAffirmative(buttons);
43607
+ if (buttonIndex < 0 || !hasReliableConsentAnchor) return null;
43608
+ return approvalModalSignature(modal?.message, normalizeApprovalLabel(buttonLabel));
43609
+ }
43460
43610
  // FALSE-IDLE (self-coordinator settle): an autonomously-progressing mesh session
43461
43611
  // is either a delegated worker (isMeshWorkerSession) OR the coordinator's OWN
43462
43612
  // claude-cli session (meshCoordinatorFor). Both run auto-approved tool turns whose
@@ -43760,10 +43910,7 @@ var CliProviderInstance = class _CliProviderInstance {
43760
43910
  return autoApproveActive;
43761
43911
  }
43762
43912
  const affirmativeAnchor = normalizeApprovalLabel(buttonLabel);
43763
- const modalSignature = [
43764
- typeof modal?.message === "string" ? modal.message.trim() : "",
43765
- affirmativeAnchor
43766
- ].join("::");
43913
+ const modalSignature = approvalModalSignature(modal?.message, affirmativeAnchor);
43767
43914
  const approvalEntrySeq = typeof adapterStatus?.approvalEntrySeq === "number" ? adapterStatus.approvalEntrySeq : 0;
43768
43915
  const busySignature = `${approvalEntrySeq}::${modalSignature}`;
43769
43916
  if (this.autoApproveBusy && busySignature === this.lastAutoApprovalSignature) {
@@ -43996,7 +44143,7 @@ var CliProviderInstance = class _CliProviderInstance {
43996
44143
  if (approvalFingerprint !== this.lastApprovalEventFingerprint) {
43997
44144
  this.lastApprovalEventFingerprint = approvalFingerprint;
43998
44145
  this.appendRuntimeSystemMessage(
43999
- this.formatApprovalRequestMessage(modal?.message, modal?.buttons),
44146
+ formatApprovalRequestMessage(modal?.message, modal?.buttons),
44000
44147
  `approval_request:${now}`,
44001
44148
  now
44002
44149
  );
@@ -44297,7 +44444,7 @@ var CliProviderInstance = class _CliProviderInstance {
44297
44444
  const effectWhen = effect.when || "immediate";
44298
44445
  if (effectWhen === "turn_completed" && options.phase !== "turn_completed") continue;
44299
44446
  if (effectWhen === "immediate" && options.phase === "turn_completed") continue;
44300
- const effectKey = this.getEffectDedupKey(effect);
44447
+ const effectKey = getEffectDedupKey(effect);
44301
44448
  if (this.appliedEffectKeys.has(effectKey)) continue;
44302
44449
  this.appliedEffectKeys.add(effectKey);
44303
44450
  if (effect.persist !== false) {
@@ -44340,34 +44487,6 @@ var CliProviderInstance = class _CliProviderInstance {
44340
44487
  this.appliedEffectKeys = new Set(Array.from(this.appliedEffectKeys).slice(-100));
44341
44488
  }
44342
44489
  }
44343
- getEffectDedupKey(effect) {
44344
- if (effect.id) return `provider_effect:${effect.id}`;
44345
- if (effect.type === "message") {
44346
- const content = typeof effect.message?.content === "string" ? effect.message.content : JSON.stringify(effect.message?.content || "");
44347
- return `provider_effect:message:${content}`;
44348
- }
44349
- if (effect.type === "notification") {
44350
- return `provider_effect:notification:${effect.notification?.title || ""}:${effect.notification?.body || ""}`;
44351
- }
44352
- return `provider_effect:toast:${effect.toast?.message || ""}`;
44353
- }
44354
- getPersistedEffectContent(effect) {
44355
- if (effect.type === "message") {
44356
- return typeof effect.message?.content === "string" ? effect.message.content : JSON.stringify(effect.message?.content || "");
44357
- }
44358
- if (effect.type === "toast") {
44359
- return effect.toast?.message || null;
44360
- }
44361
- if (effect.type === "notification") {
44362
- if (typeof effect.notification?.bubbleContent === "string") return effect.notification.bubbleContent;
44363
- if (typeof effect.notification?.title === "string" && effect.notification.title.trim()) {
44364
- return `${effect.notification.title}
44365
- ${effect.notification.body || ""}`.trim();
44366
- }
44367
- return effect.notification?.body || null;
44368
- }
44369
- return null;
44370
- }
44371
44490
  // ─── Adapter access (backward compat) ──────────────────
44372
44491
  getAdapter() {
44373
44492
  return this.adapter;
@@ -44439,15 +44558,16 @@ ${effect.notification.body || ""}`.trim();
44439
44558
  if (!this.isMeshWorkerSession()) return;
44440
44559
  if (adapterStatus?.status !== "waiting_approval") return;
44441
44560
  if (!this.autoApproveMaskStalled(now)) return;
44442
- const modalButtons = Array.isArray(adapterStatus.activeModal?.buttons) ? adapterStatus.activeModal.buttons.map((b) => String(b || "").trim()).filter(Boolean) : [];
44443
- if (this.pendingAutoApprovalSince && modalButtons.length > 0) return;
44561
+ const currentSignature = this.approvableModalSignature(adapterStatus.activeModal);
44562
+ const settleProgressing = !!currentSignature && this.pendingAutoApprovalSince > 0 && currentSignature === this.pendingAutoApprovalSignature;
44563
+ if (settleProgressing) return;
44444
44564
  if (this.stalledApprovalNudgeEpisode === this.autoApproveMaskSince) return;
44445
44565
  this.stalledApprovalNudgeEpisode = this.autoApproveMaskSince;
44446
44566
  const modal = adapterStatus.activeModal;
44447
44567
  const dirName = workingDirBasename(this.workingDir);
44448
44568
  const chatTitle = `${this.provider.name} \xB7 ${dirName}`;
44449
44569
  this.appendRuntimeSystemMessage(
44450
- this.formatApprovalRequestMessage(modal?.message, modal?.buttons),
44570
+ formatApprovalRequestMessage(modal?.message, modal?.buttons),
44451
44571
  `approval_request:${now}`,
44452
44572
  now
44453
44573
  );
@@ -44477,11 +44597,6 @@ ${effect.notification.body || ""}`.trim();
44477
44597
  now
44478
44598
  );
44479
44599
  }
44480
- formatMarkerTimestamp(timestamp) {
44481
- const date = new Date(timestamp);
44482
- const pad = (value) => String(value).padStart(2, "0");
44483
- return `${date.getFullYear()}-${pad(date.getMonth() + 1)}-${pad(date.getDate())} ${pad(date.getHours())}:${pad(date.getMinutes())}:${pad(date.getSeconds())}`;
44484
- }
44485
44600
  maybeAppendRuntimeRecoveryMessage(runtime) {
44486
44601
  if (!runtime?.restoredFromStorage || !runtime.runtimeId) return;
44487
44602
  const recoveryState = String(runtime.recoveryState || "").trim();
@@ -44542,81 +44657,7 @@ ${effect.notification.body || ""}`.trim();
44542
44657
  }
44543
44658
  }
44544
44659
  mergeRuntimeChatMessages(parsedMessages) {
44545
- return this.mergeConversationMessages(parsedMessages);
44546
- }
44547
- mergeConversationMessages(parsedMessages) {
44548
- if (this.runtimeMessages.length === 0) return normalizeChatMessages(parsedMessages);
44549
- const parsedEntries = parsedMessages.map((message, index) => ({
44550
- message,
44551
- index,
44552
- source: "parsed"
44553
- }));
44554
- const getRole = (message) => typeof message.role === "string" ? message.role.trim().toLowerCase() : "";
44555
- const runtimeEntries = this.runtimeMessages.map((entry, index) => ({
44556
- message: entry.message,
44557
- index: parsedMessages.length + index,
44558
- source: "runtime",
44559
- runtimeKey: entry.key
44560
- })).filter((entry) => {
44561
- const meta = entry.message.meta && typeof entry.message.meta === "object" && !Array.isArray(entry.message.meta) ? entry.message.meta : {};
44562
- if (meta.runtimeInputAck !== true) return true;
44563
- const runtimeText = flattenContent(entry.message.content).replace(/\s+/g, " ").trim();
44564
- if (!runtimeText) return false;
44565
- return !parsedEntries.some((parsedEntry) => {
44566
- const parsedRole = getRole(parsedEntry.message);
44567
- if (parsedRole !== "user" && parsedRole !== "human") return false;
44568
- const parsedText = flattenContent(parsedEntry.message.content).replace(/\s+/g, " ").trim();
44569
- return parsedText === runtimeText;
44570
- });
44571
- });
44572
- const getTime = (message) => {
44573
- const value = typeof message.receivedAt === "number" ? message.receivedAt : typeof message.timestamp === "number" ? message.timestamp : 0;
44574
- return Number.isFinite(value) && value > 0 ? value : 0;
44575
- };
44576
- const isRuntimeOverlay = (entry) => {
44577
- if (entry.source !== "runtime") return false;
44578
- const key2 = typeof entry.runtimeKey === "string" ? entry.runtimeKey.trim().toLowerCase() : "";
44579
- if (key2.startsWith("auto_approval:")) return true;
44580
- return !isUserFacingChatMessage(entry.message);
44581
- };
44582
- const shouldKeepParsedBeforeUntimedRuntime = (message) => {
44583
- const role = getRole(message);
44584
- return role === "user" || role === "human";
44585
- };
44586
- const shouldKeepParsedAfterUntimedRuntime = (message) => {
44587
- const role = getRole(message);
44588
- if (role !== "assistant") return false;
44589
- const kind = resolveChatMessageKind(message);
44590
- return kind === "standard" || kind === "terminal";
44591
- };
44592
- return normalizeChatMessages([...parsedEntries, ...runtimeEntries].sort((a, b) => {
44593
- const aTime = getTime(a.message);
44594
- const bTime = getTime(b.message);
44595
- if (aTime && bTime && aTime !== bTime) return aTime - bTime;
44596
- if (a.source !== b.source && aTime !== bTime) {
44597
- const parsedEntry = a.source === "parsed" ? a : b.source === "parsed" ? b : null;
44598
- const runtimeEntry = a.source === "runtime" ? a : b.source === "runtime" ? b : null;
44599
- if (parsedEntry && runtimeEntry && isRuntimeOverlay(runtimeEntry) && getTime(parsedEntry.message) === 0 && getTime(runtimeEntry.message) > 0) {
44600
- if (shouldKeepParsedBeforeUntimedRuntime(parsedEntry.message)) {
44601
- return a.source === "parsed" ? -1 : 1;
44602
- }
44603
- if (shouldKeepParsedAfterUntimedRuntime(parsedEntry.message)) {
44604
- return a.source === "parsed" ? 1 : -1;
44605
- }
44606
- }
44607
- }
44608
- return a.index - b.index;
44609
- }).map((entry) => entry.message));
44610
- }
44611
- formatApprovalRequestMessage(modalMessage, buttons) {
44612
- const lines = ["Approval requested"];
44613
- const cleanMessage = String(modalMessage || "").trim();
44614
- if (cleanMessage) lines.push(cleanMessage);
44615
- const labels = (buttons || []).map((button) => String(button || "").trim()).filter(Boolean);
44616
- if (labels.length > 0) {
44617
- lines.push(labels.map((label) => `[${label}]`).join(" "));
44618
- }
44619
- return lines.join("\n");
44660
+ return mergeConversationMessages(this.runtimeMessages, parsedMessages);
44620
44661
  }
44621
44662
  promoteProviderSessionId(sessionId, opts = {}) {
44622
44663
  const nextSessionId = String(sessionId || "").trim();