@adhdev/daemon-core 0.9.82-rc.460 → 0.9.82-rc.461

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
@@ -409,10 +409,10 @@ function readInjected(value) {
409
409
  }
410
410
  function getDaemonBuildInfo() {
411
411
  if (cached) return cached;
412
- const commit = readInjected(true ? "f8ce1329d3bdef9564c4130a1e7f0b607738f3cd" : void 0) ?? "unknown";
413
- const commitShort = readInjected(true ? "f8ce1329" : void 0) ?? (commit !== "unknown" ? commit.slice(0, 7) : "unknown");
414
- const version = readInjected(true ? "0.9.82-rc.460" : void 0) ?? readInjected(typeof process !== "undefined" ? process.env?.ADHDEV_PKG_VERSION : void 0) ?? "unknown";
415
- const builtAt = readInjected(true ? "2026-07-04T14:24:11.778Z" : void 0);
412
+ const commit = readInjected(true ? "ed8842e811aa362a2b4cc530498bc1fc7e1a7e4a" : void 0) ?? "unknown";
413
+ const commitShort = readInjected(true ? "ed8842e8" : void 0) ?? (commit !== "unknown" ? commit.slice(0, 7) : "unknown");
414
+ const version = readInjected(true ? "0.9.82-rc.461" : void 0) ?? readInjected(typeof process !== "undefined" ? process.env?.ADHDEV_PKG_VERSION : void 0) ?? "unknown";
415
+ const builtAt = readInjected(true ? "2026-07-04T15:00:03.344Z" : void 0);
416
416
  cached = builtAt ? { commit, commitShort, version, builtAt } : { commit, commitShort, version };
417
417
  return cached;
418
418
  }
@@ -3261,6 +3261,12 @@ function updateNode(meshId, nodeId, opts) {
3261
3261
  if (opts.reportedPlatform && opts.reportedPlatform.trim()) node.reportedPlatform = opts.reportedPlatform.trim();
3262
3262
  if (opts.reportedArch && opts.reportedArch.trim()) node.reportedArch = opts.reportedArch.trim();
3263
3263
  if (opts.reportedMachineNickname && opts.reportedMachineNickname.trim()) node.machineNickname = opts.reportedMachineNickname.trim();
3264
+ if (opts.reportedProviderVersions && Object.keys(opts.reportedProviderVersions).length > 0) {
3265
+ node.reportedProviderVersions = { ...opts.reportedProviderVersions };
3266
+ }
3267
+ if (opts.reportedDaemonBuildVersion && opts.reportedDaemonBuildVersion.trim()) {
3268
+ node.reportedDaemonBuildVersion = opts.reportedDaemonBuildVersion.trim();
3269
+ }
3264
3270
  if (opts.policy) node.policy = { ...node.policy, ...opts.policy };
3265
3271
  if (opts.worktreeBootstrap) node.worktreeBootstrap = opts.worktreeBootstrap;
3266
3272
  if (Object.prototype.hasOwnProperty.call(opts, "systemPrompt")) {
@@ -3604,9 +3610,16 @@ function buildNodeStatusSection(nodes) {
3604
3610
  const healthIcon = n.health === "online" ? "\u{1F7E2}" : n.health === "dirty" ? "\u{1F7E1}" : n.health === "offline" ? "\u26AB" : "\u{1F534}";
3605
3611
  const sessions = n.activeSessions.length > 0 ? `sessions: ${n.activeSessions.join(", ")}` : "no active sessions";
3606
3612
  const branch = n.git?.branch ? `branch: \`${n.git.branch}\`` : "";
3613
+ const providerVersions = n.providerVersions && typeof n.providerVersions === "object" ? n.providerVersions : void 0;
3614
+ const providersRendered = n.providers?.length ? n.providers.map((p) => {
3615
+ const version = providerVersions?.[p];
3616
+ return version ? `${p}@${version}` : p;
3617
+ }).join(", ") : "";
3618
+ const buildVersion = typeof n.daemonBuildVersion === "string" && n.daemonBuildVersion ? `build: ${n.daemonBuildVersion}` : "";
3607
3619
  const context = [
3608
3620
  n.daemonId ? `daemon: \`${n.daemonId}\`` : "",
3609
- n.providers?.length ? `providers: ${n.providers.join(", ")}` : ""
3621
+ providersRendered ? `providers: ${providersRendered}` : "",
3622
+ buildVersion
3610
3623
  ].filter(Boolean).join(" | ");
3611
3624
  lines.push(`- ${healthIcon} **${n.machineLabel}** (nodeId: \`${n.nodeId}\`)`);
3612
3625
  lines.push(` workspace: \`${n.workspace}\`${context ? ` | ${context}` : ""} | ${branch} | ${sessions}`);
@@ -4174,6 +4187,98 @@ var init_load_better_sqlite3 = __esm({
4174
4187
  });
4175
4188
 
4176
4189
  // src/mesh/contracts.ts
4190
+ function isSupportedMeshProtocolVersion(value) {
4191
+ return typeof value === "string" && SUPPORTED_MESH_PROTOCOL_VERSIONS.includes(value);
4192
+ }
4193
+ function coordinatorIdentityEquals(a, b) {
4194
+ return daemonIdsEquivalent(a.daemonId, b.daemonId) && a.coordinatorRunId === b.coordinatorRunId && (a.sessionId ?? "") === (b.sessionId ?? "");
4195
+ }
4196
+ function coordinatorIdentityKey(identity) {
4197
+ const daemonCore = machineCoreFromDaemonId(identity.daemonId) ?? identity.daemonId;
4198
+ return `${daemonCore}|${identity.coordinatorRunId}|${identity.sessionId ?? ""}`;
4199
+ }
4200
+ function isMeshEventScope(value) {
4201
+ return typeof value === "string" && MESH_EVENT_SCOPES.includes(value);
4202
+ }
4203
+ function isNonEmptyString(value) {
4204
+ return typeof value === "string" && value.length > 0;
4205
+ }
4206
+ function assertCoordinatorIdentity(raw, path44) {
4207
+ if (!raw || typeof raw !== "object" || Array.isArray(raw)) {
4208
+ throw new MeshContractViolationError(MESH_PROTOCOL_VERSION_V2, path44, "must be an object");
4209
+ }
4210
+ const obj = raw;
4211
+ if (!isNonEmptyString(obj.daemonId)) {
4212
+ throw new MeshContractViolationError(MESH_PROTOCOL_VERSION_V2, `${path44}.daemonId`, "must be a non-empty string");
4213
+ }
4214
+ if (!isNonEmptyString(obj.coordinatorRunId)) {
4215
+ throw new MeshContractViolationError(MESH_PROTOCOL_VERSION_V2, `${path44}.coordinatorRunId`, "must be a non-empty string");
4216
+ }
4217
+ const sessionId = obj.sessionId;
4218
+ if (sessionId !== void 0 && !isNonEmptyString(sessionId)) {
4219
+ throw new MeshContractViolationError(MESH_PROTOCOL_VERSION_V2, `${path44}.sessionId`, "must be a non-empty string when provided");
4220
+ }
4221
+ return sessionId !== void 0 ? { daemonId: obj.daemonId, coordinatorRunId: obj.coordinatorRunId, sessionId } : { daemonId: obj.daemonId, coordinatorRunId: obj.coordinatorRunId };
4222
+ }
4223
+ function assertPendingMeshCoordinatorEventV2(raw, path44 = "$") {
4224
+ if (!raw || typeof raw !== "object" || Array.isArray(raw)) {
4225
+ throw new MeshContractViolationError(MESH_PROTOCOL_VERSION_V2, path44, "must be an object");
4226
+ }
4227
+ const obj = raw;
4228
+ if (!isSupportedMeshProtocolVersion(obj.protocolVersion)) {
4229
+ throw new MeshContractViolationError(MESH_PROTOCOL_VERSION_V2, `${path44}.protocolVersion`, `must be one of ${SUPPORTED_MESH_PROTOCOL_VERSIONS.join(", ")}`);
4230
+ }
4231
+ if (!isNonEmptyString(obj.eventId)) {
4232
+ throw new MeshContractViolationError(MESH_PROTOCOL_VERSION_V2, `${path44}.eventId`, "must be a non-empty string");
4233
+ }
4234
+ if (!isMeshEventScope(obj.scope)) {
4235
+ throw new MeshContractViolationError(MESH_PROTOCOL_VERSION_V2, `${path44}.scope`, `must be one of ${MESH_EVENT_SCOPES.join(", ")}`);
4236
+ }
4237
+ if (!isNonEmptyString(obj.event)) {
4238
+ throw new MeshContractViolationError(MESH_PROTOCOL_VERSION_V2, `${path44}.event`, "must be a non-empty string");
4239
+ }
4240
+ if (!isNonEmptyString(obj.meshId)) {
4241
+ throw new MeshContractViolationError(MESH_PROTOCOL_VERSION_V2, `${path44}.meshId`, "must be a non-empty string");
4242
+ }
4243
+ const dispatchedBy = assertCoordinatorIdentity(obj.dispatchedBy, `${path44}.dispatchedBy`);
4244
+ if (obj.scope === "unicast") {
4245
+ if (!obj.intendedFor) {
4246
+ throw new MeshContractViolationError(MESH_PROTOCOL_VERSION_V2, `${path44}.intendedFor`, "unicast scope requires intendedFor");
4247
+ }
4248
+ } else if (obj.intendedFor !== void 0) {
4249
+ throw new MeshContractViolationError(MESH_PROTOCOL_VERSION_V2, `${path44}.intendedFor`, "only unicast scope may set intendedFor");
4250
+ }
4251
+ const intendedFor = obj.intendedFor ? assertCoordinatorIdentity(obj.intendedFor, `${path44}.intendedFor`) : void 0;
4252
+ const metadata = obj.metadataEvent && typeof obj.metadataEvent === "object" && !Array.isArray(obj.metadataEvent) ? obj.metadataEvent : null;
4253
+ if (!metadata) {
4254
+ throw new MeshContractViolationError(MESH_PROTOCOL_VERSION_V2, `${path44}.metadataEvent`, "must be an object");
4255
+ }
4256
+ const queuedAt = typeof obj.queuedAt === "number" && Number.isFinite(obj.queuedAt) ? obj.queuedAt : null;
4257
+ if (queuedAt === null) {
4258
+ throw new MeshContractViolationError(MESH_PROTOCOL_VERSION_V2, `${path44}.queuedAt`, "must be a finite number");
4259
+ }
4260
+ return {
4261
+ event: obj.event,
4262
+ meshId: obj.meshId,
4263
+ nodeLabel: isNonEmptyString(obj.nodeLabel) ? obj.nodeLabel : "",
4264
+ nodeId: typeof obj.nodeId === "string" ? obj.nodeId : void 0,
4265
+ workspace: typeof obj.workspace === "string" ? obj.workspace : void 0,
4266
+ metadataEvent: metadata,
4267
+ coordinatorMessage: typeof obj.coordinatorMessage === "string" ? obj.coordinatorMessage : void 0,
4268
+ queuedAt,
4269
+ protocolVersion: obj.protocolVersion,
4270
+ eventId: obj.eventId,
4271
+ scope: obj.scope,
4272
+ dispatchedBy,
4273
+ ...intendedFor ? { intendedFor } : {}
4274
+ };
4275
+ }
4276
+ function shouldDeliverPendingEventToCoordinator(event, drainer) {
4277
+ if (event.scope === "system") return false;
4278
+ if (event.scope === "broadcast") return true;
4279
+ if (!event.intendedFor) return false;
4280
+ return coordinatorIdentityEquals(event.intendedFor, drainer);
4281
+ }
4177
4282
  function defaultScopeForEvent(eventName) {
4178
4283
  if (SYSTEM_EVENTS.has(eventName)) return "system";
4179
4284
  if (TERMINAL_TASK_EVENTS.has(eventName)) return "unicast";
@@ -4202,12 +4307,28 @@ function buildPendingEventEmitStamp(opts) {
4202
4307
  ...intendedFor ? { intendedFor } : {}
4203
4308
  };
4204
4309
  }
4205
- var MESH_PROTOCOL_VERSION_V2, TERMINAL_TASK_EVENTS, SYSTEM_EVENTS;
4310
+ var MESH_PROTOCOL_VERSION_V1, MESH_PROTOCOL_VERSION_V2, SUPPORTED_MESH_PROTOCOL_VERSIONS, MESH_EVENT_SCOPES, MeshContractViolationError, TERMINAL_TASK_EVENTS, SYSTEM_EVENTS;
4206
4311
  var init_contracts = __esm({
4207
4312
  "src/mesh/contracts.ts"() {
4208
4313
  "use strict";
4209
4314
  init_dist();
4315
+ MESH_PROTOCOL_VERSION_V1 = "1.0";
4210
4316
  MESH_PROTOCOL_VERSION_V2 = "2.0";
4317
+ SUPPORTED_MESH_PROTOCOL_VERSIONS = [
4318
+ MESH_PROTOCOL_VERSION_V1,
4319
+ MESH_PROTOCOL_VERSION_V2
4320
+ ];
4321
+ MESH_EVENT_SCOPES = ["unicast", "broadcast", "system"];
4322
+ MeshContractViolationError = class extends Error {
4323
+ violationPath;
4324
+ protocolVersion;
4325
+ constructor(protocolVersion, violationPath, detail) {
4326
+ super(`mesh contract ${protocolVersion} violation at ${violationPath}: ${detail}`);
4327
+ this.name = "MeshContractViolationError";
4328
+ this.violationPath = violationPath;
4329
+ this.protocolVersion = protocolVersion;
4330
+ }
4331
+ };
4211
4332
  TERMINAL_TASK_EVENTS = /* @__PURE__ */ new Set([
4212
4333
  "agent:generating_completed",
4213
4334
  "agent:stopped",
@@ -7536,6 +7657,34 @@ var init_mesh_runtime_store = __esm({
7536
7657
  ).get(meshId, fingerprint);
7537
7658
  return row !== void 0;
7538
7659
  }
7660
+ /**
7661
+ * B3a — v2 eventId idempotency. Returns true when a row with this event_id has
7662
+ * ALREADY been drained (drained = 1) for the mesh. Drained rows are retained
7663
+ * (soft-marked, not deleted until mesh deletion), so this is a durable, restart-
7664
+ * surviving dedup: a v2 event whose eventId was already consumed is skipped on
7665
+ * re-delivery even when its content fingerprint differs. Scoped by mesh_id +
7666
+ * the partial event_id index (idx_mesh_pending_events_event_id).
7667
+ */
7668
+ hasDrainedEventId(meshId, eventId) {
7669
+ if (!eventId) return false;
7670
+ const row = this.db.prepare(
7671
+ "SELECT 1 FROM mesh_pending_events WHERE mesh_id = ? AND event_id = ? AND drained = 1 LIMIT 1"
7672
+ ).get(meshId, eventId);
7673
+ return row !== void 0;
7674
+ }
7675
+ /**
7676
+ * B3a — snapshot of the v2 event_ids ALREADY drained (drained = 1) for the mesh.
7677
+ * Taken BEFORE a drain call marks the current batch drained=1, so the resulting
7678
+ * set names only PRIOR drains — the re-delivery dedup baseline. (Reading it after
7679
+ * the drain would self-match the batch's own freshly-drained rows.) Non-v2 rows
7680
+ * have a NULL event_id and are excluded by the index/WHERE.
7681
+ */
7682
+ drainedEventIdsForMesh(meshId) {
7683
+ const rows = this.db.prepare(
7684
+ "SELECT DISTINCT event_id FROM mesh_pending_events WHERE mesh_id = ? AND drained = 1 AND event_id IS NOT NULL"
7685
+ ).all(meshId);
7686
+ return new Set(rows.map((r) => r.event_id));
7687
+ }
7539
7688
  // ── M3: Mission Records ─────────────────────────────────────────────────
7540
7689
  upsertMission(mission) {
7541
7690
  const now = (/* @__PURE__ */ new Date()).toISOString();
@@ -11330,6 +11479,95 @@ var init_mesh_events_utils = __esm({
11330
11479
  function normalizeCoordinatorDaemonIds(coordinatorDaemonId) {
11331
11480
  return expandDaemonIdForms(coordinatorDaemonId);
11332
11481
  }
11482
+ function warnV2Once(key2, message) {
11483
+ if (warnedV2Violations.has(key2)) return;
11484
+ warnedV2Violations.add(key2);
11485
+ if (warnedV2Violations.size > 2e3) {
11486
+ const first = warnedV2Violations.values().next().value;
11487
+ if (first !== void 0) warnedV2Violations.delete(first);
11488
+ }
11489
+ LOG.warn("MeshEventsV2", message);
11490
+ }
11491
+ function resolveDrainerIdentity(daemonIds, explicit) {
11492
+ if (explicit) return explicit;
11493
+ return coordinatorIdentityFromEmitFields({ daemonId: daemonIds[0] });
11494
+ }
11495
+ function isV2Event(event) {
11496
+ return event.protocolVersion === MESH_PROTOCOL_VERSION_V2;
11497
+ }
11498
+ function runIdIsDaemonFormFallback(identity) {
11499
+ return daemonIdsEquivalent(identity.coordinatorRunId, identity.daemonId);
11500
+ }
11501
+ function identityDeliversTo(intendedFor, drainer) {
11502
+ if (runIdIsDaemonFormFallback(intendedFor) && runIdIsDaemonFormFallback(drainer)) {
11503
+ if (!daemonIdsEquivalent(intendedFor.daemonId, drainer.daemonId)) return false;
11504
+ if (intendedFor.sessionId && drainer.sessionId) {
11505
+ return intendedFor.sessionId === drainer.sessionId;
11506
+ }
11507
+ return true;
11508
+ }
11509
+ return coordinatorIdentityEquals(intendedFor, drainer);
11510
+ }
11511
+ function routeV2EventsForDrainer(events, drainer, ctx) {
11512
+ if (!drainer) return events;
11513
+ const bump = (k) => {
11514
+ if (ctx.countMetrics) meshV2DrainCounters[k]++;
11515
+ };
11516
+ const kept = [];
11517
+ for (const event of events) {
11518
+ if (!isV2Event(event)) {
11519
+ bump("v1BroadcastAccepted");
11520
+ kept.push(event);
11521
+ continue;
11522
+ }
11523
+ let validated;
11524
+ try {
11525
+ validated = assertPendingMeshCoordinatorEventV2(event);
11526
+ } catch (e) {
11527
+ bump("v2ValidationFailedAccepted");
11528
+ warnV2Once(
11529
+ `${event.meshId}::${event.eventId ?? event.event}::invalid`,
11530
+ `v2 envelope validation failed for ${event.event} on mesh ${event.meshId} \u2014 PASSED THROUGH (accept mode): ${e?.message || e}`
11531
+ );
11532
+ kept.push(event);
11533
+ continue;
11534
+ }
11535
+ const eventId = validated.eventId;
11536
+ if (ctx.batchSeen.has(eventId) || ctx.alreadyDrained(eventId)) {
11537
+ bump("v2DedupSkipped");
11538
+ continue;
11539
+ }
11540
+ if (validated.scope !== "unicast") {
11541
+ if (shouldDeliverPendingEventToCoordinator(validated, drainer)) {
11542
+ ctx.batchSeen.add(eventId);
11543
+ bump("v2Delivered");
11544
+ kept.push(event);
11545
+ } else {
11546
+ bump("v2RoutedAway");
11547
+ }
11548
+ continue;
11549
+ }
11550
+ if (validated.intendedFor && identityDeliversTo(validated.intendedFor, drainer)) {
11551
+ ctx.batchSeen.add(eventId);
11552
+ bump("v2Delivered");
11553
+ kept.push(event);
11554
+ continue;
11555
+ }
11556
+ const realRunIdMismatch = !runIdIsDaemonFormFallback(validated.intendedFor) || !runIdIsDaemonFormFallback(drainer);
11557
+ if (validated.intendedFor && realRunIdMismatch && daemonIdsEquivalent(validated.intendedFor.daemonId, drainer.daemonId)) {
11558
+ ctx.batchSeen.add(eventId);
11559
+ bump("v2ReattributedToDrainer");
11560
+ warnV2Once(
11561
+ `${event.meshId}::${eventId}::reattributed`,
11562
+ `v2 unicast ${event.event} on mesh ${event.meshId} re-attributed to current coordinator ${coordinatorIdentityKey(drainer)} (originating coordinatorRunId no longer live)`
11563
+ );
11564
+ kept.push(event);
11565
+ continue;
11566
+ }
11567
+ bump("v2RoutedAway");
11568
+ }
11569
+ return kept;
11570
+ }
11333
11571
  function readRefineJobId2(event) {
11334
11572
  const metadata = readRecord5(event.metadataEvent) || event;
11335
11573
  const result = readRecord5(metadata.result);
@@ -11548,6 +11786,36 @@ function stampPendingEventV2(event, hint) {
11548
11786
  ...stamp.intendedFor ? { intendedFor: stamp.intendedFor } : {}
11549
11787
  };
11550
11788
  }
11789
+ function readCoordinatorIdentityFromWire(raw) {
11790
+ if (!raw || typeof raw !== "object" || Array.isArray(raw)) return void 0;
11791
+ const obj = raw;
11792
+ const daemonId = readNonEmptyString2(obj.daemonId);
11793
+ const coordinatorRunId = readNonEmptyString2(obj.coordinatorRunId);
11794
+ if (!daemonId || !coordinatorRunId) return void 0;
11795
+ const sessionId = readNonEmptyString2(obj.sessionId);
11796
+ return { daemonId, coordinatorRunId, ...sessionId ? { sessionId } : {} };
11797
+ }
11798
+ function serializeV2EnvelopeToWire(event) {
11799
+ const out = {};
11800
+ if (event.protocolVersion) out.protocolVersion = event.protocolVersion;
11801
+ if (readNonEmptyString2(event.eventId)) out.eventId = event.eventId;
11802
+ if (event.scope) out.scope = event.scope;
11803
+ if (event.dispatchedBy) out.dispatchedBy = event.dispatchedBy;
11804
+ if (event.intendedFor) out.intendedFor = event.intendedFor;
11805
+ return out;
11806
+ }
11807
+ function readV2EnvelopeFromWire(payload) {
11808
+ const out = {};
11809
+ if (payload.protocolVersion === MESH_PROTOCOL_VERSION_V2) out.protocolVersion = MESH_PROTOCOL_VERSION_V2;
11810
+ const eventId = readNonEmptyString2(payload.eventId);
11811
+ if (eventId) out.eventId = eventId;
11812
+ if (isMeshEventScope(payload.scope)) out.scope = payload.scope;
11813
+ const dispatchedBy = readCoordinatorIdentityFromWire(payload.dispatchedBy);
11814
+ if (dispatchedBy) out.dispatchedBy = dispatchedBy;
11815
+ const intendedFor = readCoordinatorIdentityFromWire(payload.intendedFor);
11816
+ if (intendedFor) out.intendedFor = intendedFor;
11817
+ return out;
11818
+ }
11551
11819
  function queuePendingMeshCoordinatorEvent(rawEvent, hint) {
11552
11820
  const event = stampPendingEventV2(rawEvent, hint);
11553
11821
  try {
@@ -11670,6 +11938,12 @@ function drainPendingMeshCoordinatorEvents(meshId, coordinatorDaemonId, opts) {
11670
11938
  if (!meshId) return [];
11671
11939
  const daemonIds = normalizeCoordinatorDaemonIds(coordinatorDaemonId);
11672
11940
  const primaryDaemonId = daemonIds[0];
11941
+ const drainer = resolveDrainerIdentity(daemonIds, opts?.drainerIdentity);
11942
+ let priorDrainedEventIds = /* @__PURE__ */ new Set();
11943
+ try {
11944
+ priorDrainedEventIds = MeshRuntimeStore.getInstance().drainedEventIdsForMesh(meshId);
11945
+ } catch {
11946
+ }
11673
11947
  const onlyEvents = opts?.onlyEvents;
11674
11948
  const matchesFilter = (eventName) => !onlyEvents || onlyEvents.has(eventName);
11675
11949
  const merged = [];
@@ -11716,7 +11990,12 @@ function drainPendingMeshCoordinatorEvents(meshId, coordinatorDaemonId, opts) {
11716
11990
  for (const event of filtered) pushUnique(event);
11717
11991
  }
11718
11992
  if (merged.length === 0) return [];
11719
- return reconcilePendingMeshCoordinatorEvents(meshId, merged);
11993
+ const routed = routeV2EventsForDrainer(merged, drainer, {
11994
+ alreadyDrained: (eventId) => priorDrainedEventIds.has(eventId),
11995
+ batchSeen: /* @__PURE__ */ new Set(),
11996
+ countMetrics: true
11997
+ });
11998
+ return reconcilePendingMeshCoordinatorEvents(meshId, routed);
11720
11999
  }
11721
12000
  function retractPendingDispatchBlockedEvent(meshId, taskId, coordinatorDaemonId) {
11722
12001
  if (!meshId || !taskId) return 0;
@@ -11747,9 +12026,15 @@ function retractPendingDispatchBlockedEvent(meshId, taskId, coordinatorDaemonId)
11747
12026
  }
11748
12027
  return removed;
11749
12028
  }
11750
- function getPendingMeshCoordinatorEvents(meshId, coordinatorDaemonId) {
12029
+ function getPendingMeshCoordinatorEvents(meshId, coordinatorDaemonId, opts) {
11751
12030
  if (!meshId) return [];
11752
12031
  const daemonIds = normalizeCoordinatorDaemonIds(coordinatorDaemonId);
12032
+ const drainer = resolveDrainerIdentity(daemonIds, opts?.drainerIdentity);
12033
+ let priorDrainedEventIds = /* @__PURE__ */ new Set();
12034
+ try {
12035
+ priorDrainedEventIds = MeshRuntimeStore.getInstance().drainedEventIdsForMesh(meshId);
12036
+ } catch {
12037
+ }
11753
12038
  const merged = [];
11754
12039
  const seenFingerprints = /* @__PURE__ */ new Set();
11755
12040
  const pushUnique = (event) => {
@@ -11773,7 +12058,12 @@ function getPendingMeshCoordinatorEvents(meshId, coordinatorDaemonId) {
11773
12058
  for (const event of readPendingMeshCoordinatorEventsFromDisk(meshId, daemonIds)) {
11774
12059
  pushUnique(event);
11775
12060
  }
11776
- return reconcilePendingMeshCoordinatorEvents(meshId, merged);
12061
+ const routed = routeV2EventsForDrainer(merged, drainer, {
12062
+ alreadyDrained: (eventId) => priorDrainedEventIds.has(eventId),
12063
+ batchSeen: /* @__PURE__ */ new Set(),
12064
+ countMetrics: false
12065
+ });
12066
+ return reconcilePendingMeshCoordinatorEvents(meshId, routed);
11777
12067
  }
11778
12068
  function clearPendingMeshCoordinatorEvents(meshId, coordinatorDaemonId) {
11779
12069
  if (!meshId) return;
@@ -11789,7 +12079,7 @@ function clearPendingMeshCoordinatorEvents(meshId, coordinatorDaemonId) {
11789
12079
  }
11790
12080
  }
11791
12081
  }
11792
- var import_fs11, import_path10, import_crypto8, REFINE_TERMINAL_EVENTS, TERMINAL_COMPLETION_EVENTS, MAX_PENDING_EVENTS_BYTES, MAX_PENDING_EVENTS_KEEP;
12082
+ var import_fs11, import_path10, import_crypto8, REFINE_TERMINAL_EVENTS, meshV2DrainCounters, warnedV2Violations, TERMINAL_COMPLETION_EVENTS, MAX_PENDING_EVENTS_BYTES, MAX_PENDING_EVENTS_KEEP;
11793
12083
  var init_mesh_events_pending = __esm({
11794
12084
  "src/mesh/mesh-events-pending.ts"() {
11795
12085
  "use strict";
@@ -11803,6 +12093,24 @@ var init_mesh_events_pending = __esm({
11803
12093
  init_dist();
11804
12094
  init_contracts();
11805
12095
  REFINE_TERMINAL_EVENTS = /* @__PURE__ */ new Set(["refine:completed", "refine:failed"]);
12096
+ meshV2DrainCounters = {
12097
+ /** v2 events that passed validation and unicast/broadcast routing → delivered. */
12098
+ v2Delivered: 0,
12099
+ /** v2 unicast events skipped because intendedFor addressed another coordinator. */
12100
+ v2RoutedAway: 0,
12101
+ /** v2 events skipped because their eventId was already drained (idempotency). */
12102
+ v2DedupSkipped: 0,
12103
+ /** v2 events that failed assertPendingMeshCoordinatorEventV2 but were PASSED
12104
+ * THROUGH (accept mode). Non-zero here is the rollout signal that a producer
12105
+ * emits a malformed envelope. */
12106
+ v2ValidationFailedAccepted: 0,
12107
+ /** unicast events re-attributed to the drainer via daemon-core match (a
12108
+ * coordinatorRunId change orphaned them). */
12109
+ v2ReattributedToDrainer: 0,
12110
+ /** v1 (unversioned) events passed through as broadcast (rollout baseline). */
12111
+ v1BroadcastAccepted: 0
12112
+ };
12113
+ warnedV2Violations = /* @__PURE__ */ new Set();
11806
12114
  TERMINAL_COMPLETION_EVENTS = /* @__PURE__ */ new Set(["agent:generating_completed", "agent:stopped"]);
11807
12115
  MAX_PENDING_EVENTS_BYTES = 100 * 1024;
11808
12116
  MAX_PENDING_EVENTS_KEEP = 50;
@@ -12853,7 +13161,38 @@ async function detectCLI(cliId, providerLoader, options) {
12853
13161
  const all = await detectCLIs(providerLoader, options);
12854
13162
  return all.find((c) => c.id === resolvedId && c.installed) || null;
12855
13163
  }
12856
- var import_child_process2, os6, path12, import_fs12;
13164
+ function buildProviderVersions(detected) {
13165
+ const out = {};
13166
+ for (const cli of detected) {
13167
+ if (!cli.installed) continue;
13168
+ const version = typeof cli.version === "string" ? cli.version.trim() : "";
13169
+ if (!version) continue;
13170
+ out[cli.id] = version;
13171
+ }
13172
+ return out;
13173
+ }
13174
+ function refreshProviderVersionsSnapshot(providerLoader) {
13175
+ if (providerVersionsRefreshInFlight) return providerVersionsRefreshInFlight;
13176
+ providerVersionsRefreshInFlight = (async () => {
13177
+ try {
13178
+ const detected = await detectCLIs(providerLoader, { includeVersion: true });
13179
+ cachedProviderVersions = buildProviderVersions(detected);
13180
+ cachedProviderVersionsAt = Date.now();
13181
+ } catch {
13182
+ } finally {
13183
+ providerVersionsRefreshInFlight = null;
13184
+ }
13185
+ })();
13186
+ return providerVersionsRefreshInFlight;
13187
+ }
13188
+ function getCachedProviderVersions(providerLoader) {
13189
+ const stale = Date.now() - cachedProviderVersionsAt > PROVIDER_VERSIONS_TTL_MS;
13190
+ if (stale) {
13191
+ void refreshProviderVersionsSnapshot(providerLoader);
13192
+ }
13193
+ return { ...cachedProviderVersions };
13194
+ }
13195
+ var import_child_process2, os6, path12, import_fs12, PROVIDER_VERSIONS_TTL_MS, cachedProviderVersions, cachedProviderVersionsAt, providerVersionsRefreshInFlight;
12857
13196
  var init_cli_detector = __esm({
12858
13197
  "src/detection/cli-detector.ts"() {
12859
13198
  "use strict";
@@ -12862,6 +13201,10 @@ var init_cli_detector = __esm({
12862
13201
  path12 = __toESM(require("path"));
12863
13202
  import_fs12 = require("fs");
12864
13203
  init_provider_cli_shared();
13204
+ PROVIDER_VERSIONS_TTL_MS = 5 * 60 * 1e3;
13205
+ cachedProviderVersions = {};
13206
+ cachedProviderVersionsAt = 0;
13207
+ providerVersionsRefreshInFlight = null;
12865
13208
  }
12866
13209
  });
12867
13210
 
@@ -17550,7 +17893,13 @@ function injectMeshSystemMessage(components, args) {
17550
17893
  ...workerCoordinatorDaemonId ? { targetCoordinatorDaemonId: workerCoordinatorDaemonId } : {},
17551
17894
  // Top-level session anchor for the local PHASE 2 strict-match on the coordinator
17552
17895
  // daemon. Absent → daemon-level broadcast (legacy / single-coordinator path).
17553
- ...workerCoordinatorSessionId ? { targetCoordinatorSessionId: workerCoordinatorSessionId } : {}
17896
+ ...workerCoordinatorSessionId ? { targetCoordinatorSessionId: workerCoordinatorSessionId } : {},
17897
+ // T4 (B3b): restore the v2 envelope from the remote relay so the re-queue keeps the
17898
+ // ORIGINAL eventId. Spread LAST so its authoritative eventId/scope/identity win over
17899
+ // any default. queuePendingMeshCoordinatorEvent → stampPendingEventV2 then no-ops
17900
+ // (already-stamped short-circuit) instead of minting a fresh eventId. Empty object
17901
+ // for a v1 relay → unchanged v1 emit-stamp path (version-skew safe).
17902
+ ...args.v2Envelope ?? {}
17554
17903
  };
17555
17904
  if (queuePendingMeshCoordinatorEvent(pendingEvent)) {
17556
17905
  LOG.info("MeshEvents", `Queued ${args.event} for coordinator (mesh ${args.meshId}${workerCoordinatorDaemonId ? `, coordinator daemon ${workerCoordinatorDaemonId}` : ""}${workerCoordinatorSessionId ? `, coordinator session ${workerCoordinatorSessionId}` : ""})`);
@@ -17663,7 +18012,12 @@ function handleMeshForwardEvent(components, payload) {
17663
18012
  nodeId,
17664
18013
  nodeLabel,
17665
18014
  event: eventName,
17666
- metadataEvent: buildRelayMetadataEvent(payload)
18015
+ metadataEvent: buildRelayMetadataEvent(payload),
18016
+ // T4 (B3b): restore the v2 envelope carried at the top level of the relayed flat
18017
+ // payload (buildForwardPayloadFromPending → serializeV2EnvelopeToWire) so the
18018
+ // re-queue preserves the original eventId (idempotency) and unicast routing rather
18019
+ // than re-stamping a fresh v1/broadcast event. Empty for a v1 relay (version-skew safe).
18020
+ v2Envelope: readV2EnvelopeFromWire(payload)
17667
18021
  });
17668
18022
  }
17669
18023
  function enqueueCoordinatorForwardPush(coordinatorDaemonId, run) {
@@ -19090,7 +19444,14 @@ function buildForwardPayloadFromPending(event) {
19090
19444
  ...(() => {
19091
19445
  const tid = readNonEmptyString2(metadata.taskId) || readNonEmptyString2(metadata.meshActiveTaskId);
19092
19446
  return tid ? { taskId: tid } : {};
19093
- })()
19447
+ })(),
19448
+ // T4 (B3b): carry the v2 envelope (protocolVersion/eventId/scope/dispatchedBy/
19449
+ // intendedFor) across the P2P relay boundary at the TOP LEVEL. These live on the
19450
+ // pending event itself, not inside metadataEvent, so without this the remote pull
19451
+ // re-queue would re-stamp a fresh eventId — breaking cross-machine idempotency and
19452
+ // downgrading the relayed completion to v1 broadcast routing. Spread LAST so the
19453
+ // authoritative envelope always wins over any stale key the metadata spread carried.
19454
+ ...serializeV2EnvelopeToWire(event)
19094
19455
  };
19095
19456
  }
19096
19457
  function setupMeshReconcileLoop(components) {
@@ -19164,9 +19525,11 @@ __export(mesh_events_exports, {
19164
19525
  isMeshCoordinatorEvent: () => isMeshCoordinatorEvent,
19165
19526
  isSessionActivelyGenerating: () => isSessionActivelyGenerating,
19166
19527
  queuePendingMeshCoordinatorEvent: () => queuePendingMeshCoordinatorEvent,
19528
+ readV2EnvelopeFromWire: () => readV2EnvelopeFromWire,
19167
19529
  reconcileDirectDispatchCompletionFromTranscript: () => reconcileDirectDispatchCompletionFromTranscript,
19168
19530
  resolveCoordinatorDrainDeliverability: () => resolveCoordinatorDrainDeliverability,
19169
19531
  runMeshReconcileTick: () => runMeshReconcileTick,
19532
+ serializeV2EnvelopeToWire: () => serializeV2EnvelopeToWire,
19170
19533
  setupMeshEventForwarding: () => setupMeshEventForwarding,
19171
19534
  setupMeshReconcileLoop: () => setupMeshReconcileLoop,
19172
19535
  shouldHoldPendingDrainForBusyLocalCoordinator: () => shouldHoldPendingDrainForBusyLocalCoordinator,
@@ -25109,6 +25472,7 @@ __export(index_exports, {
25109
25472
  readLedgerSliceFromStore: () => readLedgerSliceFromStore,
25110
25473
  readMeshCompletionSummary: () => readMeshCompletionSummary,
25111
25474
  readOperatingNotes: () => readOperatingNotes,
25475
+ readV2EnvelopeFromWire: () => readV2EnvelopeFromWire,
25112
25476
  reconcileDirectDispatchCompletionFromTranscript: () => reconcileDirectDispatchCompletionFromTranscript,
25113
25477
  recordCompletionConflict: () => recordCompletionConflict,
25114
25478
  recordDebugTrace: () => recordDebugTrace,
@@ -25149,6 +25513,7 @@ __export(index_exports, {
25149
25513
  runMeshWorktreeBootstrap: () => runMeshWorktreeBootstrap,
25150
25514
  saveConfig: () => saveConfig,
25151
25515
  saveState: () => saveState,
25516
+ serializeV2EnvelopeToWire: () => serializeV2EnvelopeToWire,
25152
25517
  setDebugRuntimeConfig: () => setDebugRuntimeConfig,
25153
25518
  setLogLevel: () => setLogLevel,
25154
25519
  setMagiKindPanel: () => setMagiKindPanel,
@@ -25917,7 +26282,7 @@ var defaultSnapshotStore = createGitSnapshotStore({
25917
26282
  getStatus: (workspace) => getGitRepoStatus(workspace),
25918
26283
  getDiffSummary: (workspace) => getGitDiffSummary(workspace)
25919
26284
  });
25920
- function createDefaultGitCommandServices() {
26285
+ function createDefaultGitCommandServices(overrides) {
25921
26286
  return {
25922
26287
  getStatus: ({ workspace, refreshUpstream }) => getGitRepoStatus(workspace, { refreshUpstream }),
25923
26288
  getDiffSummary: ({ workspace, base }) => getGitDiffSummary(workspace, base ? { baseRef: base } : {}),
@@ -25935,7 +26300,8 @@ function createDefaultGitCommandServices() {
25935
26300
  stashPop: async ({ workspace, stashRef }) => gitStashPop(workspace, stashRef),
25936
26301
  checkoutFiles: async ({ workspace, paths }) => gitCheckoutFiles(workspace, paths),
25937
26302
  getRemoteUrl: async ({ workspace, remote = "origin" }) => gitGetRemoteUrl(workspace, remote),
25938
- push: async ({ workspace, remote = "origin", branch, setUpstream = false }) => gitPush(workspace, remote, branch, setUpstream)
26303
+ push: async ({ workspace, remote = "origin", branch, setUpstream = false }) => gitPush(workspace, remote, branch, setUpstream),
26304
+ ...overrides?.getReporterProviderVersions ? { getReporterProviderVersions: overrides.getReporterProviderVersions } : {}
25939
26305
  };
25940
26306
  }
25941
26307
  var defaultGitCommandServices = createDefaultGitCommandServices();
@@ -26022,12 +26388,23 @@ async function handleGitCommand(command, args, services = defaultGitCommandServi
26022
26388
  return void 0;
26023
26389
  }
26024
26390
  })();
26391
+ const reporterVersions = (() => {
26392
+ try {
26393
+ return services.getReporterProviderVersions?.() ?? {};
26394
+ } catch {
26395
+ return {};
26396
+ }
26397
+ })();
26398
+ const reporterProviderVersions = reporterVersions.providerVersions && Object.keys(reporterVersions.providerVersions).length > 0 ? reporterVersions.providerVersions : void 0;
26399
+ const reporterDaemonBuildVersion = typeof reporterVersions.daemonBuildVersion === "string" && reporterVersions.daemonBuildVersion.trim() ? reporterVersions.daemonBuildVersion.trim() : void 0;
26025
26400
  return {
26026
26401
  success: true,
26027
26402
  status,
26028
26403
  reporterPlatform: process.platform,
26029
26404
  reporterArch: process.arch,
26030
- ...reporterMachineNickname ? { reporterMachineNickname } : {}
26405
+ ...reporterMachineNickname ? { reporterMachineNickname } : {},
26406
+ ...reporterProviderVersions ? { reporterProviderVersions } : {},
26407
+ ...reporterDaemonBuildVersion ? { reporterDaemonBuildVersion } : {}
26031
26408
  };
26032
26409
  }
26033
26410
  case "git_diff_summary": {
@@ -53900,6 +54277,12 @@ var meshStatusHandlers = {
53900
54277
  machineStatus: node.machineStatus,
53901
54278
  health: "unknown",
53902
54279
  providers: node.providers || [],
54280
+ // T7: surface self-healed provider versions + build version (from the
54281
+ // git_status envelope, persisted on the node) so the coordinator/UI can
54282
+ // spot a provider-version skew across nodes. Additive; omitted when a
54283
+ // node has never reported them.
54284
+ ...node.reportedProviderVersions && typeof node.reportedProviderVersions === "object" ? { providerVersions: node.reportedProviderVersions } : {},
54285
+ ...typeof node.reportedDaemonBuildVersion === "string" && node.reportedDaemonBuildVersion ? { daemonBuildVersion: node.reportedDaemonBuildVersion } : {},
53903
54286
  providerPriority,
53904
54287
  activeSessions: [],
53905
54288
  activeSessionDetails: [],
@@ -54673,7 +55056,13 @@ function buildLivePeerGitConnection(connection, timestamp = (/* @__PURE__ */ new
54673
55056
  }
54674
55057
  function recordInlineMeshDirectGitTruth(node, git, source) {
54675
55058
  if (!node || typeof node !== "object" || Array.isArray(node)) {
54676
- return { reporterPlatform: null, reporterArch: null, reporterMachineNickname: null };
55059
+ return {
55060
+ reporterPlatform: null,
55061
+ reporterArch: null,
55062
+ reporterMachineNickname: null,
55063
+ reporterProviderVersions: null,
55064
+ reporterDaemonBuildVersion: null
55065
+ };
54677
55066
  }
54678
55067
  const checkedAt = readNumberValue(git.lastCheckedAt) ?? Date.now();
54679
55068
  const updatedAt = new Date(checkedAt).toISOString();
@@ -54700,7 +55089,28 @@ function recordInlineMeshDirectGitTruth(node, git, source) {
54700
55089
  if (reporterArch) node.reportedArch = reporterArch;
54701
55090
  const reporterMachineNickname = readStringValue(git.reporterMachineNickname) ?? null;
54702
55091
  if (reporterMachineNickname) node.machineNickname = reporterMachineNickname;
54703
- return { reporterPlatform, reporterArch, reporterMachineNickname };
55092
+ const reporterProviderVersions = readProviderVersionsRecord(git.reporterProviderVersions);
55093
+ if (reporterProviderVersions) node.reportedProviderVersions = reporterProviderVersions;
55094
+ const reporterDaemonBuildVersion = readStringValue(git.reporterDaemonBuildVersion) ?? null;
55095
+ if (reporterDaemonBuildVersion) node.reportedDaemonBuildVersion = reporterDaemonBuildVersion;
55096
+ return {
55097
+ reporterPlatform,
55098
+ reporterArch,
55099
+ reporterMachineNickname,
55100
+ reporterProviderVersions,
55101
+ reporterDaemonBuildVersion
55102
+ };
55103
+ }
55104
+ function readProviderVersionsRecord(value) {
55105
+ if (!value || typeof value !== "object" || Array.isArray(value)) return null;
55106
+ const out = {};
55107
+ for (const [key2, raw] of Object.entries(value)) {
55108
+ if (typeof key2 !== "string" || !key2.trim()) continue;
55109
+ const version = typeof raw === "string" ? raw.trim() : "";
55110
+ if (!version) continue;
55111
+ out[key2] = version;
55112
+ }
55113
+ return Object.keys(out).length > 0 ? out : null;
54704
55114
  }
54705
55115
  function stampNodeReporterPlatform(node, platform10, arch2) {
54706
55116
  if (!node || typeof node !== "object" || Array.isArray(node)) return;
@@ -54724,8 +55134,18 @@ function persistNodeReporterPlatform(meshSource, mesh, nodeId, reporter) {
54724
55134
  const reportedPlatform = reporter.reporterPlatform ?? void 0;
54725
55135
  const reportedArch = reporter.reporterArch ?? void 0;
54726
55136
  const reportedMachineNickname = reporter.reporterMachineNickname ?? void 0;
54727
- if (!reportedPlatform && !reportedArch && !reportedMachineNickname) return;
54728
- void Promise.resolve().then(() => (init_mesh_config(), mesh_config_exports)).then(({ updateNode: updateNode2 }) => updateNode2(meshId, nodeId, { reportedPlatform, reportedArch, reportedMachineNickname })).catch(() => {
55137
+ const reportedProviderVersions = reporter.reporterProviderVersions ?? void 0;
55138
+ const reportedDaemonBuildVersion = reporter.reporterDaemonBuildVersion ?? void 0;
55139
+ if (!reportedPlatform && !reportedArch && !reportedMachineNickname && !reportedProviderVersions && !reportedDaemonBuildVersion) {
55140
+ return;
55141
+ }
55142
+ void Promise.resolve().then(() => (init_mesh_config(), mesh_config_exports)).then(({ updateNode: updateNode2 }) => updateNode2(meshId, nodeId, {
55143
+ reportedPlatform,
55144
+ reportedArch,
55145
+ reportedMachineNickname,
55146
+ reportedProviderVersions,
55147
+ reportedDaemonBuildVersion
55148
+ })).catch(() => {
54729
55149
  });
54730
55150
  }
54731
55151
  function buildCachedInlineMeshGitStatus(node) {
@@ -55382,6 +55802,10 @@ async function probeRemoteMeshGitStatus(args) {
55382
55802
  if (reporterPlatform) git.reporterPlatform = reporterPlatform;
55383
55803
  if (reporterArch) git.reporterArch = reporterArch;
55384
55804
  if (reporterMachineNickname) git.reporterMachineNickname = reporterMachineNickname;
55805
+ const reporterProviderVersions = readProviderVersionsRecord(remoteResult?.reporterProviderVersions);
55806
+ if (reporterProviderVersions) git.reporterProviderVersions = reporterProviderVersions;
55807
+ const reporterDaemonBuildVersion = readStringValue(remoteResult?.reporterDaemonBuildVersion);
55808
+ if (reporterDaemonBuildVersion) git.reporterDaemonBuildVersion = reporterDaemonBuildVersion;
55385
55809
  return git;
55386
55810
  }
55387
55811
  var MESH_DIRECT_PROBE_MAX_RETRIES = 2;
@@ -67313,6 +67737,7 @@ function launchIDE(ide, workspacePath) {
67313
67737
 
67314
67738
  // src/boot/daemon-lifecycle.ts
67315
67739
  init_cli_detector();
67740
+ init_build_info();
67316
67741
 
67317
67742
  // src/sessions/registry.ts
67318
67743
  var SessionRegistry = class {
@@ -67514,7 +67939,19 @@ async function initDaemonComponents(config) {
67514
67939
  providerLoader,
67515
67940
  instanceManager,
67516
67941
  sessionRegistry,
67517
- gitCommandServices: createDefaultGitCommandServices(),
67942
+ gitCommandServices: createDefaultGitCommandServices({
67943
+ // T7: fold this daemon's cached provider versions + build version onto the
67944
+ // git_status envelope so the mesh coordinator self-heals each node's
67945
+ // providerVersions. Non-blocking: reads a TTL cache, lazily refreshed.
67946
+ getReporterProviderVersions: () => {
67947
+ const providerVersions = getCachedProviderVersions(providerLoader);
67948
+ const daemonBuildVersion = getDaemonBuildInfo().version;
67949
+ return {
67950
+ ...Object.keys(providerVersions).length > 0 ? { providerVersions } : {},
67951
+ ...daemonBuildVersion && daemonBuildVersion !== "unknown" ? { daemonBuildVersion } : {}
67952
+ };
67953
+ }
67954
+ }),
67518
67955
  onProviderSettingChanged: async (providerType) => {
67519
67956
  await refreshProviderAvailability(providerType);
67520
67957
  config.onStatusChange?.();
@@ -68237,6 +68674,7 @@ var V1_CONTRACT_VERSION = "1.0.0";
68237
68674
  readLedgerSliceFromStore,
68238
68675
  readMeshCompletionSummary,
68239
68676
  readOperatingNotes,
68677
+ readV2EnvelopeFromWire,
68240
68678
  reconcileDirectDispatchCompletionFromTranscript,
68241
68679
  recordCompletionConflict,
68242
68680
  recordDebugTrace,
@@ -68277,6 +68715,7 @@ var V1_CONTRACT_VERSION = "1.0.0";
68277
68715
  runMeshWorktreeBootstrap,
68278
68716
  saveConfig,
68279
68717
  saveState,
68718
+ serializeV2EnvelopeToWire,
68280
68719
  setDebugRuntimeConfig,
68281
68720
  setLogLevel,
68282
68721
  setMagiKindPanel,