adhdev 0.9.82-rc.3 → 0.9.82-rc.31

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
@@ -264,8 +264,14 @@ async function getGitRepoStatus(workspace, options = {}) {
264
264
  const includeSubmodules = options.includeSubmodules !== false;
265
265
  try {
266
266
  const repo = await resolveGitRepository(workspace, options);
267
- const statusOutput = await runGit(repo, ["status", "--porcelain=v2", "--branch"], options);
268
- const parsed = parsePorcelainV2Status(statusOutput.stdout);
267
+ let parsed = await readPorcelainStatus(repo, options);
268
+ let upstreamProbe = getInitialUpstreamProbe(parsed);
269
+ if (options.refreshUpstream) {
270
+ upstreamProbe = await refreshTrackedUpstream(repo, parsed, options);
271
+ if (upstreamProbe.upstreamStatus === "fresh") {
272
+ parsed = await readPorcelainStatus(repo, options);
273
+ }
274
+ }
269
275
  const head = await readHead(repo, options);
270
276
  const stashCount = await readStashCount(repo, options);
271
277
  let submodules;
@@ -280,6 +286,9 @@ async function getGitRepoStatus(workspace, options = {}) {
280
286
  headCommit: head.commit,
281
287
  headMessage: head.message,
282
288
  upstream: parsed.upstream,
289
+ upstreamStatus: parsed.upstream ? upstreamProbe.upstreamStatus : "no_upstream",
290
+ upstreamFetchedAt: upstreamProbe.upstreamFetchedAt,
291
+ upstreamFetchError: upstreamProbe.upstreamFetchError,
283
292
  ahead: parsed.ahead,
284
293
  behind: parsed.behind,
285
294
  staged: parsed.staged,
@@ -304,6 +313,60 @@ async function getGitRepoStatus(workspace, options = {}) {
304
313
  );
305
314
  }
306
315
  }
316
+ async function readPorcelainStatus(repo, options) {
317
+ const statusOutput = await runGit(repo, ["status", "--porcelain=v2", "--branch"], options);
318
+ return parsePorcelainV2Status(statusOutput.stdout);
319
+ }
320
+ function getInitialUpstreamProbe(parsed) {
321
+ return {
322
+ upstreamStatus: parsed.upstream ? "unchecked" : "no_upstream"
323
+ };
324
+ }
325
+ async function refreshTrackedUpstream(repo, parsed, options) {
326
+ if (!parsed.upstream || !parsed.branch) {
327
+ return { upstreamStatus: "no_upstream" };
328
+ }
329
+ const remoteName = await readBranchRemote(repo, parsed.branch, options) ?? inferRemoteName(parsed.upstream);
330
+ if (!remoteName) {
331
+ return {
332
+ upstreamStatus: "stale",
333
+ upstreamFetchError: `Unable to resolve remote for upstream '${parsed.upstream}'`
334
+ };
335
+ }
336
+ try {
337
+ await runGit(repo, ["fetch", "--quiet", "--prune", "--no-tags", remoteName], options);
338
+ return {
339
+ upstreamStatus: "fresh",
340
+ upstreamFetchedAt: Date.now()
341
+ };
342
+ } catch (error48) {
343
+ return {
344
+ upstreamStatus: "stale",
345
+ upstreamFetchError: formatGitError(error48)
346
+ };
347
+ }
348
+ }
349
+ async function readBranchRemote(repo, branch, options) {
350
+ try {
351
+ const result = await runGit(repo, ["config", "--get", `branch.${branch}.remote`], options);
352
+ return result.stdout.trim() || null;
353
+ } catch {
354
+ return null;
355
+ }
356
+ }
357
+ function inferRemoteName(upstream) {
358
+ const [remoteName] = upstream.split("/");
359
+ return remoteName?.trim() || null;
360
+ }
361
+ function formatGitError(error48) {
362
+ if (error48 instanceof GitCommandError) {
363
+ return error48.stderr || error48.message;
364
+ }
365
+ if (error48 instanceof Error) {
366
+ return error48.message;
367
+ }
368
+ return String(error48);
369
+ }
307
370
  function parsePorcelainV2Status(output) {
308
371
  const parsed = {
309
372
  branch: null,
@@ -398,6 +461,7 @@ function emptyStatus(workspace, lastCheckedAt, error48) {
398
461
  headCommit: null,
399
462
  headMessage: null,
400
463
  upstream: null,
464
+ upstreamStatus: "unavailable",
401
465
  ahead: 0,
402
466
  behind: 0,
403
467
  staged: 0,
@@ -690,6 +754,9 @@ function createGitCompactSummary(status, diffSummary) {
690
754
  isGitRepo: status.isGitRepo,
691
755
  repoRoot: status.repoRoot,
692
756
  branch: status.branch,
757
+ upstreamStatus: status.upstreamStatus,
758
+ upstreamFetchedAt: status.upstreamFetchedAt,
759
+ upstreamFetchError: status.upstreamFetchError,
693
760
  dirty: status.staged > 0 || status.modified > 0 || status.untracked > 0 || status.deleted > 0 || status.renamed > 0 || conflictCount > 0 || changedFiles > 0,
694
761
  changedFiles,
695
762
  ahead: status.ahead,
@@ -1017,7 +1084,7 @@ function serviceNotImplemented(command) {
1017
1084
  }
1018
1085
  function createDefaultGitCommandServices() {
1019
1086
  return {
1020
- getStatus: ({ workspace }) => getGitRepoStatus(workspace),
1087
+ getStatus: ({ workspace, refreshUpstream }) => getGitRepoStatus(workspace, { refreshUpstream }),
1021
1088
  getDiffSummary: ({ workspace }) => getGitDiffSummary(workspace),
1022
1089
  getDiffFile: ({ workspace, path: filePath }) => getGitFileDiff(workspace, filePath),
1023
1090
  createSnapshot: ({ workspace, reason, sessionId, turnId }) => defaultSnapshotStore.create({
@@ -1102,7 +1169,7 @@ async function handleGitCommand(command, args, services = defaultGitCommandServi
1102
1169
  switch (command) {
1103
1170
  case "git_status": {
1104
1171
  if (!services.getStatus) return serviceNotImplemented(command);
1105
- const status = await runService(() => services.getStatus({ workspace }));
1172
+ const status = await runService(() => services.getStatus({ workspace, refreshUpstream: optionalBoolean(args?.refreshUpstream) }));
1106
1173
  return "success" in status ? status : { success: true, status };
1107
1174
  }
1108
1175
  case "git_diff_summary": {
@@ -3223,6 +3290,36 @@ function getQueuePath(meshId) {
3223
3290
  const safe = meshId.replace(/[^a-zA-Z0-9_-]/g, "_");
3224
3291
  return (0, import_path4.join)(getLedgerDir(), `${safe}.queue.json`);
3225
3292
  }
3293
+ function getLockPath(meshId) {
3294
+ const safe = meshId.replace(/[^a-zA-Z0-9_-]/g, "_");
3295
+ return (0, import_path4.join)(getLedgerDir(), `${safe}.queue.lock`);
3296
+ }
3297
+ function withQueueLock(meshId, fn) {
3298
+ const lockPath = getLockPath(meshId);
3299
+ let fd = -1;
3300
+ for (let i = 0; i < 10; i++) {
3301
+ try {
3302
+ fd = (0, import_fs4.openSync)(lockPath, "wx");
3303
+ break;
3304
+ } catch {
3305
+ const deadline = Date.now() + 30;
3306
+ while (Date.now() < deadline) {
3307
+ }
3308
+ }
3309
+ }
3310
+ try {
3311
+ return fn();
3312
+ } finally {
3313
+ if (fd !== -1) try {
3314
+ (0, import_fs4.closeSync)(fd);
3315
+ } catch {
3316
+ }
3317
+ try {
3318
+ (0, import_fs4.unlinkSync)(lockPath);
3319
+ } catch {
3320
+ }
3321
+ }
3322
+ }
3226
3323
  function readQueue(meshId) {
3227
3324
  const path35 = getQueuePath(meshId);
3228
3325
  if (!(0, import_fs4.existsSync)(path35)) return [];
@@ -3238,20 +3335,22 @@ function writeQueue(meshId, queue) {
3238
3335
  (0, import_fs4.writeFileSync)(path35, JSON.stringify(queue, null, 2), "utf-8");
3239
3336
  }
3240
3337
  function enqueueTask(meshId, message, opts) {
3241
- const queue = readQueue(meshId);
3242
- const entry = {
3243
- id: (0, import_crypto5.randomUUID)(),
3244
- meshId,
3245
- message,
3246
- status: "pending",
3247
- targetNodeId: opts?.targetNodeId,
3248
- targetSessionId: opts?.targetSessionId,
3249
- createdAt: (/* @__PURE__ */ new Date()).toISOString(),
3250
- updatedAt: (/* @__PURE__ */ new Date()).toISOString()
3251
- };
3252
- queue.push(entry);
3253
- writeQueue(meshId, queue);
3254
- return entry;
3338
+ return withQueueLock(meshId, () => {
3339
+ const queue = readQueue(meshId);
3340
+ const entry = {
3341
+ id: (0, import_crypto5.randomUUID)(),
3342
+ meshId,
3343
+ message,
3344
+ status: "pending",
3345
+ targetNodeId: opts?.targetNodeId,
3346
+ targetSessionId: opts?.targetSessionId,
3347
+ createdAt: (/* @__PURE__ */ new Date()).toISOString(),
3348
+ updatedAt: (/* @__PURE__ */ new Date()).toISOString()
3349
+ };
3350
+ queue.push(entry);
3351
+ writeQueue(meshId, queue);
3352
+ return entry;
3353
+ });
3255
3354
  }
3256
3355
  function getQueue(meshId, opts) {
3257
3356
  let queue = readQueue(meshId);
@@ -3262,100 +3361,111 @@ function getQueue(meshId, opts) {
3262
3361
  return queue;
3263
3362
  }
3264
3363
  function claimNextTask(meshId, nodeId, sessionId) {
3265
- const queue = readQueue(meshId);
3266
- const hasActiveAssignment = queue.some((q) => q.status === "assigned" && (q.assignedSessionId === sessionId || q.assignedNodeId === nodeId));
3267
- if (hasActiveAssignment) return null;
3268
- let targetIdx = queue.findIndex((q) => q.status === "pending" && q.targetSessionId === sessionId);
3269
- if (targetIdx === -1) {
3270
- targetIdx = queue.findIndex((q) => q.status === "pending" && q.targetNodeId === nodeId && !q.targetSessionId);
3271
- }
3272
- if (targetIdx === -1) {
3273
- targetIdx = queue.findIndex((q) => q.status === "pending" && !q.targetNodeId && !q.targetSessionId);
3274
- }
3275
- if (targetIdx === -1) return null;
3276
- const entry = queue[targetIdx];
3277
- entry.status = "assigned";
3278
- entry.assignedNodeId = nodeId;
3279
- entry.assignedSessionId = sessionId;
3280
- entry.dispatchTimestamp = (/* @__PURE__ */ new Date()).toISOString();
3281
- entry.updatedAt = (/* @__PURE__ */ new Date()).toISOString();
3282
- writeQueue(meshId, queue);
3283
- return entry;
3364
+ return withQueueLock(meshId, () => {
3365
+ const queue = readQueue(meshId);
3366
+ const hasActiveAssignment = queue.some((q) => q.status === "assigned" && (q.assignedSessionId === sessionId || q.assignedNodeId === nodeId));
3367
+ if (hasActiveAssignment) return null;
3368
+ let targetIdx = queue.findIndex((q) => q.status === "pending" && q.targetSessionId === sessionId);
3369
+ if (targetIdx === -1) {
3370
+ targetIdx = queue.findIndex((q) => q.status === "pending" && q.targetNodeId === nodeId && !q.targetSessionId);
3371
+ }
3372
+ if (targetIdx === -1) {
3373
+ targetIdx = queue.findIndex((q) => q.status === "pending" && !q.targetNodeId && !q.targetSessionId);
3374
+ }
3375
+ if (targetIdx === -1) return null;
3376
+ const entry = queue[targetIdx];
3377
+ entry.status = "assigned";
3378
+ entry.assignedNodeId = nodeId;
3379
+ entry.assignedSessionId = sessionId;
3380
+ entry.dispatchTimestamp = (/* @__PURE__ */ new Date()).toISOString();
3381
+ entry.updatedAt = (/* @__PURE__ */ new Date()).toISOString();
3382
+ writeQueue(meshId, queue);
3383
+ return entry;
3384
+ });
3284
3385
  }
3285
3386
  function updateTaskStatus(meshId, taskId, status) {
3286
- const queue = readQueue(meshId);
3287
- const idx = queue.findIndex((q) => q.id === taskId);
3288
- if (idx === -1) return null;
3289
- queue[idx].status = status;
3290
- queue[idx].updatedAt = (/* @__PURE__ */ new Date()).toISOString();
3291
- writeQueue(meshId, queue);
3292
- return queue[idx];
3387
+ return withQueueLock(meshId, () => {
3388
+ const queue = readQueue(meshId);
3389
+ const idx = queue.findIndex((q) => q.id === taskId);
3390
+ if (idx === -1) return null;
3391
+ queue[idx].status = status;
3392
+ queue[idx].updatedAt = (/* @__PURE__ */ new Date()).toISOString();
3393
+ writeQueue(meshId, queue);
3394
+ return queue[idx];
3395
+ });
3293
3396
  }
3294
3397
  function recordTaskAutoLaunch(meshId, taskId, autoLaunch) {
3295
- const queue = readQueue(meshId);
3296
- const idx = queue.findIndex((q) => q.id === taskId);
3297
- if (idx === -1) return null;
3298
- const now = (/* @__PURE__ */ new Date()).toISOString();
3299
- queue[idx].autoLaunch = {
3300
- ...autoLaunch,
3301
- updatedAt: now
3302
- };
3303
- queue[idx].updatedAt = now;
3304
- writeQueue(meshId, queue);
3305
- return queue[idx];
3398
+ return withQueueLock(meshId, () => {
3399
+ const queue = readQueue(meshId);
3400
+ const idx = queue.findIndex((q) => q.id === taskId);
3401
+ if (idx === -1) return null;
3402
+ const now = (/* @__PURE__ */ new Date()).toISOString();
3403
+ queue[idx].autoLaunch = { ...autoLaunch, updatedAt: now };
3404
+ queue[idx].updatedAt = now;
3405
+ writeQueue(meshId, queue);
3406
+ return queue[idx];
3407
+ });
3306
3408
  }
3307
3409
  function cancelTask(meshId, taskId, opts) {
3308
- const queue = readQueue(meshId);
3309
- const idx = queue.findIndex((q) => q.id === taskId);
3310
- if (idx === -1) return null;
3311
- const now = (/* @__PURE__ */ new Date()).toISOString();
3312
- queue[idx].status = "cancelled";
3313
- queue[idx].updatedAt = now;
3314
- queue[idx].cancelledAt = now;
3315
- if (opts?.reason) queue[idx].cancelReason = opts.reason;
3316
- writeQueue(meshId, queue);
3317
- return queue[idx];
3410
+ return withQueueLock(meshId, () => {
3411
+ const queue = readQueue(meshId);
3412
+ const idx = queue.findIndex((q) => q.id === taskId);
3413
+ if (idx === -1) return null;
3414
+ const now = (/* @__PURE__ */ new Date()).toISOString();
3415
+ queue[idx].status = "cancelled";
3416
+ queue[idx].updatedAt = now;
3417
+ queue[idx].cancelledAt = now;
3418
+ if (opts?.reason) queue[idx].cancelReason = opts.reason;
3419
+ writeQueue(meshId, queue);
3420
+ return queue[idx];
3421
+ });
3318
3422
  }
3319
3423
  function requeueTask(meshId, taskId, opts) {
3320
- const queue = readQueue(meshId);
3321
- const idx = queue.findIndex((q) => q.id === taskId);
3322
- if (idx === -1) return null;
3323
- const entry = queue[idx];
3324
- const now = (/* @__PURE__ */ new Date()).toISOString();
3325
- entry.status = "pending";
3326
- delete entry.assignedNodeId;
3327
- delete entry.assignedSessionId;
3328
- delete entry.cancelledAt;
3329
- delete entry.cancelReason;
3330
- if (opts?.clearTargetNode) delete entry.targetNodeId;
3331
- if (typeof opts?.targetNodeId === "string") entry.targetNodeId = opts.targetNodeId;
3332
- if (opts?.clearTargetSession !== false) delete entry.targetSessionId;
3333
- if (typeof opts?.targetSessionId === "string") entry.targetSessionId = opts.targetSessionId;
3334
- entry.updatedAt = now;
3335
- entry.requeuedAt = now;
3336
- entry.requeueCount = (entry.requeueCount || 0) + 1;
3337
- if (opts?.reason) entry.requeueReason = opts.reason;
3338
- writeQueue(meshId, queue);
3339
- return entry;
3340
- }
3341
- function updateSessionTaskStatus(meshId, sessionId, status) {
3342
- const queue = readQueue(meshId);
3343
- let bestIdx = -1;
3344
- let bestTime = 0;
3345
- for (let i = queue.length - 1; i >= 0; i--) {
3346
- if (queue[i].assignedSessionId === sessionId && queue[i].status === "assigned") {
3424
+ return withQueueLock(meshId, () => {
3425
+ const queue = readQueue(meshId);
3426
+ const idx = queue.findIndex((q) => q.id === taskId);
3427
+ if (idx === -1) return null;
3428
+ const entry = queue[idx];
3429
+ const now = (/* @__PURE__ */ new Date()).toISOString();
3430
+ entry.status = "pending";
3431
+ delete entry.assignedNodeId;
3432
+ delete entry.assignedSessionId;
3433
+ delete entry.cancelledAt;
3434
+ delete entry.cancelReason;
3435
+ if (opts?.clearTargetNode) delete entry.targetNodeId;
3436
+ if (typeof opts?.targetNodeId === "string") entry.targetNodeId = opts.targetNodeId;
3437
+ if (opts?.clearTargetSession !== false) delete entry.targetSessionId;
3438
+ if (typeof opts?.targetSessionId === "string") entry.targetSessionId = opts.targetSessionId;
3439
+ entry.updatedAt = now;
3440
+ entry.requeuedAt = now;
3441
+ entry.requeueCount = (entry.requeueCount || 0) + 1;
3442
+ if (opts?.reason) entry.requeueReason = opts.reason;
3443
+ writeQueue(meshId, queue);
3444
+ return entry;
3445
+ });
3446
+ }
3447
+ function updateSessionTaskStatus(meshId, sessionId, status, opts) {
3448
+ return withQueueLock(meshId, () => {
3449
+ const queue = readQueue(meshId);
3450
+ const occurredAtTime = opts?.occurredAt ? new Date(opts.occurredAt).getTime() : Number.NaN;
3451
+ const hasOccurredAt = Number.isFinite(occurredAtTime);
3452
+ let bestIdx = -1;
3453
+ let bestTime = 0;
3454
+ for (let i = queue.length - 1; i >= 0; i--) {
3455
+ if (queue[i].assignedSessionId !== sessionId || queue[i].status !== "assigned") continue;
3347
3456
  const time3 = new Date(queue[i].dispatchTimestamp || queue[i].updatedAt).getTime();
3457
+ if (hasOccurredAt && Number.isFinite(time3) && time3 > occurredAtTime) continue;
3348
3458
  if (time3 > bestTime) {
3349
3459
  bestTime = time3;
3350
3460
  bestIdx = i;
3351
3461
  }
3352
3462
  }
3353
- }
3354
- if (bestIdx === -1) return null;
3355
- queue[bestIdx].status = status;
3356
- queue[bestIdx].updatedAt = (/* @__PURE__ */ new Date()).toISOString();
3357
- writeQueue(meshId, queue);
3358
- return queue[bestIdx];
3463
+ if (bestIdx === -1) return null;
3464
+ queue[bestIdx].status = status;
3465
+ queue[bestIdx].updatedAt = (/* @__PURE__ */ new Date()).toISOString();
3466
+ writeQueue(meshId, queue);
3467
+ return queue[bestIdx];
3468
+ });
3359
3469
  }
3360
3470
  function getMeshQueueStats(meshId) {
3361
3471
  const queue = readQueue(meshId);
@@ -3759,18 +3869,75 @@ __export(mesh_events_exports, {
3759
3869
  drainPendingMeshCoordinatorEvents: () => drainPendingMeshCoordinatorEvents,
3760
3870
  getPendingMeshCoordinatorEvents: () => getPendingMeshCoordinatorEvents,
3761
3871
  handleMeshForwardEvent: () => handleMeshForwardEvent,
3872
+ queuePendingMeshCoordinatorEvent: () => queuePendingMeshCoordinatorEvent,
3762
3873
  setupMeshEventForwarding: () => setupMeshEventForwarding,
3763
3874
  triggerMeshQueue: () => triggerMeshQueue,
3764
3875
  tryAssignQueueTask: () => tryAssignQueueTask
3765
3876
  });
3766
- function drainPendingMeshCoordinatorEvents() {
3767
- return pendingMeshCoordinatorEvents.splice(0);
3877
+ function sweepExpiredRemoteIdleSessions() {
3878
+ const now = Date.now();
3879
+ for (const [key, session] of remoteIdleSessions) {
3880
+ if (session.expiresAt <= now) remoteIdleSessions.delete(key);
3881
+ }
3882
+ }
3883
+ function getPendingEventsPath(meshId) {
3884
+ const safe = meshId.replace(/[^a-zA-Z0-9_-]/g, "_");
3885
+ return (0, import_path5.join)(getLedgerDir(), `${safe}.pending-events.jsonl`);
3886
+ }
3887
+ function queuePendingMeshCoordinatorEvent(event) {
3888
+ try {
3889
+ (0, import_fs6.appendFileSync)(getPendingEventsPath(event.meshId), JSON.stringify(event) + "\n", "utf-8");
3890
+ return true;
3891
+ } catch (e) {
3892
+ LOG.warn("MeshEvents", `Failed to persist pending coordinator event: ${e?.message || e}`);
3893
+ return false;
3894
+ }
3768
3895
  }
3769
- function getPendingMeshCoordinatorEvents() {
3770
- return pendingMeshCoordinatorEvents.slice();
3896
+ function drainPendingMeshCoordinatorEvents(meshId) {
3897
+ if (!meshId) return [];
3898
+ const path35 = getPendingEventsPath(meshId);
3899
+ if (!(0, import_fs6.existsSync)(path35)) return [];
3900
+ try {
3901
+ const raw = (0, import_fs6.readFileSync)(path35, "utf-8");
3902
+ try {
3903
+ (0, import_fs6.unlinkSync)(path35);
3904
+ } catch {
3905
+ }
3906
+ return raw.split("\n").filter(Boolean).flatMap((line) => {
3907
+ try {
3908
+ return [JSON.parse(line)];
3909
+ } catch {
3910
+ return [];
3911
+ }
3912
+ });
3913
+ } catch {
3914
+ return [];
3915
+ }
3771
3916
  }
3772
- function clearPendingMeshCoordinatorEvents() {
3773
- pendingMeshCoordinatorEvents.splice(0);
3917
+ function getPendingMeshCoordinatorEvents(meshId) {
3918
+ if (!meshId) return [];
3919
+ const path35 = getPendingEventsPath(meshId);
3920
+ if (!(0, import_fs6.existsSync)(path35)) return [];
3921
+ try {
3922
+ const raw = (0, import_fs6.readFileSync)(path35, "utf-8");
3923
+ return raw.split("\n").filter(Boolean).flatMap((line) => {
3924
+ try {
3925
+ return [JSON.parse(line)];
3926
+ } catch {
3927
+ return [];
3928
+ }
3929
+ });
3930
+ } catch {
3931
+ return [];
3932
+ }
3933
+ }
3934
+ function clearPendingMeshCoordinatorEvents(meshId) {
3935
+ if (!meshId) return;
3936
+ const path35 = getPendingEventsPath(meshId);
3937
+ if ((0, import_fs6.existsSync)(path35)) try {
3938
+ (0, import_fs6.unlinkSync)(path35);
3939
+ } catch {
3940
+ }
3774
3941
  }
3775
3942
  function readNonEmptyString(value) {
3776
3943
  return typeof value === "string" && value.trim() ? value.trim() : "";
@@ -3816,6 +3983,38 @@ function shouldSuppressIntentionalCleanupStop(args) {
3816
3983
  if (isIntentionalCleanupStopMetadata(args.metadataEvent)) return true;
3817
3984
  return hasRecentIntentionalCleanupStop(args.meshId, args.sessionId, args.nodeId);
3818
3985
  }
3986
+ function readEventTimestamp(value) {
3987
+ if (typeof value === "number" && Number.isFinite(value)) return value;
3988
+ if (typeof value === "string" && value.trim()) {
3989
+ const numeric = Number(value);
3990
+ if (Number.isFinite(numeric)) return numeric;
3991
+ const parsed = Date.parse(value);
3992
+ if (Number.isFinite(parsed)) return parsed;
3993
+ }
3994
+ return null;
3995
+ }
3996
+ function buildMeshCompletionFingerprint(args) {
3997
+ const timestampPart = Number.isFinite(args.timestamp) ? String(args.timestamp) : readNonEmptyString(args.finalSummary).slice(0, 200);
3998
+ return [
3999
+ args.meshId,
4000
+ args.event,
4001
+ args.sessionId,
4002
+ args.providerType || "",
4003
+ args.providerSessionId || "",
4004
+ timestampPart
4005
+ ].join("::");
4006
+ }
4007
+ function isDuplicateMeshCompletionEvent(args) {
4008
+ const fingerprint = buildMeshCompletionFingerprint(args);
4009
+ if (!fingerprint) return false;
4010
+ const now = Date.now();
4011
+ for (const [key, seenAt] of recentCompletionFingerprints.entries()) {
4012
+ if (now - seenAt > RECENT_COMPLETION_FINGERPRINT_TTL_MS) recentCompletionFingerprints.delete(key);
4013
+ }
4014
+ if (recentCompletionFingerprints.has(fingerprint)) return true;
4015
+ recentCompletionFingerprints.set(fingerprint, now);
4016
+ return false;
4017
+ }
3819
4018
  function tryAssignQueueTask(components, meshId, nodeId, sessionId, providerType) {
3820
4019
  const task = claimNextTask(meshId, nodeId, sessionId);
3821
4020
  if (!task) {
@@ -3834,7 +4033,16 @@ function tryAssignQueueTask(components, meshId, nodeId, sessionId, providerType)
3834
4033
  message: task.message
3835
4034
  }).catch((e) => {
3836
4035
  LOG.error("MeshQueue", `Failed to dispatch task via P2P to remote node ${nodeId}: ${e?.message}`);
3837
- updateTaskStatus(meshId, task.id, "failed");
4036
+ updateTaskStatus(meshId, task.id, "pending");
4037
+ try {
4038
+ appendLedgerEntry(meshId, {
4039
+ kind: "dispatch_failed",
4040
+ nodeId,
4041
+ sessionId,
4042
+ payload: { taskId: task.id, error: e?.message, retryable: true }
4043
+ });
4044
+ } catch {
4045
+ }
3838
4046
  });
3839
4047
  return true;
3840
4048
  }
@@ -4168,18 +4376,36 @@ function injectMeshSystemMessage(components, args) {
4168
4376
  LOG.info("MeshEvents", `Suppressed ${args.event} for intentionally cleanup-stopped session ${eventSessionId || "(unknown session)"}`);
4169
4377
  return { success: true, forwarded: 0, suppressed: true, intentionalCleanupStop: true };
4170
4378
  }
4379
+ const eventTimestamp = readEventTimestamp(args.metadataEvent.timestamp);
4380
+ if (args.event === "agent:generating_completed" && eventSessionId) {
4381
+ const duplicateCompletion = isDuplicateMeshCompletionEvent({
4382
+ meshId: args.meshId,
4383
+ event: args.event,
4384
+ sessionId: eventSessionId,
4385
+ providerType: readNonEmptyString(args.metadataEvent.providerType) || void 0,
4386
+ providerSessionId: readNonEmptyString(args.metadataEvent.providerSessionId) || void 0,
4387
+ timestamp: eventTimestamp,
4388
+ finalSummary: readNonEmptyString(args.metadataEvent.finalSummary) || void 0
4389
+ });
4390
+ if (duplicateCompletion) {
4391
+ LOG.info("MeshEvents", `Suppressed duplicate completion for mesh ${args.meshId} session ${eventSessionId}`);
4392
+ return { success: true, forwarded: 0, suppressed: true, duplicateCompletion: true };
4393
+ }
4394
+ }
4171
4395
  let completedTaskForLedger = null;
4172
4396
  if (args.event === "agent:generating_completed") {
4173
4397
  const sessionId = resolveEventSessionId(args.metadataEvent, args.sourceInstanceId);
4174
4398
  const nodeId = readNonEmptyString(args.nodeId) || readNonEmptyString(args.metadataEvent.meshNodeId);
4175
4399
  const providerType = readNonEmptyString(args.metadataEvent.providerType);
4176
4400
  if (sessionId) {
4177
- const completedTask = updateSessionTaskStatus(args.meshId, sessionId, "completed");
4401
+ const completedTask = updateSessionTaskStatus(args.meshId, sessionId, "completed", {
4402
+ occurredAt: eventTimestamp !== null ? new Date(eventTimestamp).toISOString() : void 0
4403
+ });
4178
4404
  completedTaskForLedger = completedTask ? { id: completedTask.id } : null;
4179
4405
  if (nodeId && providerType) {
4180
- setTimeout(() => {
4406
+ setImmediate(() => {
4181
4407
  tryAssignQueueTask(components, args.meshId, nodeId, sessionId, providerType);
4182
- }, 500);
4408
+ });
4183
4409
  }
4184
4410
  }
4185
4411
  } else if (args.event === "agent:ready") {
@@ -4217,13 +4443,17 @@ function injectMeshSystemMessage(components, args) {
4217
4443
  }
4218
4444
  }
4219
4445
  if (sessionId && nodeId && providerType) {
4220
- remoteIdleSessions.set(`${nodeId}:${sessionId}`, { nodeId, sessionId, providerType });
4221
- setTimeout(() => {
4446
+ sweepExpiredRemoteIdleSessions();
4447
+ remoteIdleSessions.set(`${nodeId}:${sessionId}`, {
4448
+ nodeId,
4449
+ sessionId,
4450
+ providerType,
4451
+ expiresAt: Date.now() + REMOTE_IDLE_SESSION_TTL_MS
4452
+ });
4453
+ setImmediate(() => {
4222
4454
  const assigned = tryAssignQueueTask(components, args.meshId, nodeId, sessionId, providerType);
4223
- if (assigned) {
4224
- remoteIdleSessions.delete(`${nodeId}:${sessionId}`);
4225
- }
4226
- }, 500);
4455
+ if (assigned) remoteIdleSessions.delete(`${nodeId}:${sessionId}`);
4456
+ });
4227
4457
  }
4228
4458
  } else if (args.event === "agent:generating_started") {
4229
4459
  const sessionId = resolveEventSessionId(args.metadataEvent, args.sourceInstanceId);
@@ -4334,17 +4564,18 @@ function injectMeshSystemMessage(components, args) {
4334
4564
  return true;
4335
4565
  });
4336
4566
  if (coordinatorInstances.length === 0) {
4337
- if (pendingMeshCoordinatorEvents.length < MAX_PENDING_EVENTS) {
4338
- pendingMeshCoordinatorEvents.push({
4339
- event: args.event,
4340
- meshId: args.meshId,
4341
- nodeLabel: args.nodeLabel,
4342
- metadataEvent: {
4343
- ...args.metadataEvent,
4344
- ...recoveryContext ? { recoveryContext } : {}
4345
- },
4346
- queuedAt: Date.now()
4347
- });
4567
+ if (queuePendingMeshCoordinatorEvent({
4568
+ event: args.event,
4569
+ meshId: args.meshId,
4570
+ nodeLabel: args.nodeLabel,
4571
+ nodeId: args.nodeId || void 0,
4572
+ workspace: readNonEmptyString(args.metadataEvent.workspace),
4573
+ metadataEvent: {
4574
+ ...args.metadataEvent,
4575
+ ...recoveryContext ? { recoveryContext } : {}
4576
+ },
4577
+ queuedAt: Date.now()
4578
+ })) {
4348
4579
  LOG.info("MeshEvents", `Queued ${args.event} for MCP coordinator (mesh ${args.meshId})`);
4349
4580
  }
4350
4581
  return { success: true, forwarded: 0 };
@@ -4383,6 +4614,7 @@ function handleMeshForwardEvent(components, payload) {
4383
4614
  providerType: readNonEmptyString(payload.providerType),
4384
4615
  providerSessionId: readNonEmptyString(payload.providerSessionId),
4385
4616
  finalSummary: readNonEmptyString(payload.finalSummary) || readNonEmptyString(payload.summary),
4617
+ ...payload.timestamp !== void 0 ? { timestamp: payload.timestamp } : {},
4386
4618
  intentional: payload.intentional === true,
4387
4619
  intentionalStop: payload.intentionalStop === true,
4388
4620
  operatorCleanup: payload.operatorCleanup === true,
@@ -4425,19 +4657,20 @@ function setupMeshEventForwarding(components) {
4425
4657
  });
4426
4658
  });
4427
4659
  }
4428
- var remoteIdleSessions, MAX_PENDING_EVENTS, pendingMeshCoordinatorEvents, MESH_COORDINATOR_EVENTS, EVENT_TO_LEDGER_KIND, INTENTIONAL_CLEANUP_STOP_SUPPRESSION_MS, autoLaunchInProgress, autoLaunchCooldownUntil, AUTO_LAUNCH_COOLDOWN_MS;
4660
+ var import_fs6, import_path5, REMOTE_IDLE_SESSION_TTL_MS, remoteIdleSessions, MESH_COORDINATOR_EVENTS, EVENT_TO_LEDGER_KIND, INTENTIONAL_CLEANUP_STOP_SUPPRESSION_MS, RECENT_COMPLETION_FINGERPRINT_TTL_MS, recentCompletionFingerprints, autoLaunchInProgress, autoLaunchCooldownUntil, AUTO_LAUNCH_COOLDOWN_MS;
4429
4661
  var init_mesh_events = __esm({
4430
4662
  "../../oss/packages/daemon-core/src/mesh/mesh-events.ts"() {
4431
4663
  "use strict";
4664
+ import_fs6 = require("fs");
4665
+ import_path5 = require("path");
4432
4666
  init_config();
4433
4667
  init_mesh_config();
4434
4668
  init_cli_detector();
4435
4669
  init_logger();
4436
4670
  init_mesh_ledger();
4437
4671
  init_mesh_work_queue();
4672
+ REMOTE_IDLE_SESSION_TTL_MS = 5 * 60 * 1e3;
4438
4673
  remoteIdleSessions = /* @__PURE__ */ new Map();
4439
- MAX_PENDING_EVENTS = 50;
4440
- pendingMeshCoordinatorEvents = [];
4441
4674
  MESH_COORDINATOR_EVENTS = /* @__PURE__ */ new Set([
4442
4675
  "agent:generating_started",
4443
4676
  "agent:generating_completed",
@@ -4453,6 +4686,8 @@ var init_mesh_events = __esm({
4453
4686
  "monitor:long_generating": "task_stalled"
4454
4687
  };
4455
4688
  INTENTIONAL_CLEANUP_STOP_SUPPRESSION_MS = 30 * 60 * 1e3;
4689
+ RECENT_COMPLETION_FINGERPRINT_TTL_MS = 10 * 60 * 1e3;
4690
+ recentCompletionFingerprints = /* @__PURE__ */ new Map();
4456
4691
  autoLaunchInProgress = /* @__PURE__ */ new Set();
4457
4692
  autoLaunchCooldownUntil = /* @__PURE__ */ new Map();
4458
4693
  AUTO_LAUNCH_COOLDOWN_MS = 5e3;
@@ -4580,7 +4815,7 @@ function isPlainObject2(value) {
4580
4815
  return !!value && typeof value === "object" && !Array.isArray(value);
4581
4816
  }
4582
4817
  function getStatePath() {
4583
- return (0, import_path5.join)(getConfigDir(), "state.json");
4818
+ return (0, import_path6.join)(getConfigDir(), "state.json");
4584
4819
  }
4585
4820
  function normalizeState(raw) {
4586
4821
  const parsed = isPlainObject2(raw) ? raw : {};
@@ -4616,11 +4851,11 @@ function normalizeState(raw) {
4616
4851
  }
4617
4852
  function loadState() {
4618
4853
  const statePath = getStatePath();
4619
- if (!(0, import_fs6.existsSync)(statePath)) {
4854
+ if (!(0, import_fs7.existsSync)(statePath)) {
4620
4855
  return { ...DEFAULT_STATE };
4621
4856
  }
4622
4857
  try {
4623
- const raw = (0, import_fs6.readFileSync)(statePath, "utf-8");
4858
+ const raw = (0, import_fs7.readFileSync)(statePath, "utf-8");
4624
4859
  return normalizeState(JSON.parse(raw));
4625
4860
  } catch {
4626
4861
  return { ...DEFAULT_STATE };
@@ -4629,17 +4864,17 @@ function loadState() {
4629
4864
  function saveState(state) {
4630
4865
  const statePath = getStatePath();
4631
4866
  const normalized = normalizeState(state);
4632
- (0, import_fs6.writeFileSync)(statePath, JSON.stringify(normalized, null, 2), { encoding: "utf-8", mode: 384 });
4867
+ (0, import_fs7.writeFileSync)(statePath, JSON.stringify(normalized, null, 2), { encoding: "utf-8", mode: 384 });
4633
4868
  }
4634
4869
  function resetState() {
4635
4870
  saveState({ ...DEFAULT_STATE });
4636
4871
  }
4637
- var import_fs6, import_path5, DEFAULT_STATE;
4872
+ var import_fs7, import_path6, DEFAULT_STATE;
4638
4873
  var init_state_store = __esm({
4639
4874
  "../../oss/packages/daemon-core/src/config/state-store.ts"() {
4640
4875
  "use strict";
4641
- import_fs6 = require("fs");
4642
- import_path5 = require("path");
4876
+ import_fs7 = require("fs");
4877
+ import_path6 = require("path");
4643
4878
  init_config();
4644
4879
  DEFAULT_STATE = {
4645
4880
  recentActivity: [],
@@ -4672,7 +4907,7 @@ function findCliCommand(command) {
4672
4907
  if (path10.isAbsolute(trimmed) || trimmed.includes("/") || trimmed.includes("\\") || trimmed.startsWith("~")) {
4673
4908
  const candidate = trimmed.startsWith("~") ? path10.join((0, import_os2.homedir)(), trimmed.slice(1)) : trimmed;
4674
4909
  const resolved = path10.isAbsolute(candidate) ? candidate : path10.resolve(candidate);
4675
- return (0, import_fs7.existsSync)(resolved) ? resolved : null;
4910
+ return (0, import_fs8.existsSync)(resolved) ? resolved : null;
4676
4911
  }
4677
4912
  try {
4678
4913
  const result = (0, import_child_process2.execSync)(
@@ -4703,9 +4938,9 @@ function checkPathExists(paths) {
4703
4938
  if (normalized.includes("*")) {
4704
4939
  const username = home.split(/[\\/]/).pop() || "";
4705
4940
  const resolved = normalized.replace("*", username);
4706
- if ((0, import_fs7.existsSync)(resolved)) return resolved;
4941
+ if ((0, import_fs8.existsSync)(resolved)) return resolved;
4707
4942
  } else {
4708
- if ((0, import_fs7.existsSync)(normalized)) return normalized;
4943
+ if ((0, import_fs8.existsSync)(normalized)) return normalized;
4709
4944
  }
4710
4945
  }
4711
4946
  return null;
@@ -4719,7 +4954,7 @@ async function detectIDEs(providerLoader) {
4719
4954
  let resolvedCli = cliPath;
4720
4955
  if (!resolvedCli && appPath && os30 === "darwin") {
4721
4956
  const bundledCli = `${appPath}/Contents/Resources/app/bin/${def.cli}`;
4722
- if ((0, import_fs7.existsSync)(bundledCli)) resolvedCli = bundledCli;
4957
+ if ((0, import_fs8.existsSync)(bundledCli)) resolvedCli = bundledCli;
4723
4958
  }
4724
4959
  if (!resolvedCli && appPath && os30 === "win32") {
4725
4960
  const { dirname: dirname12 } = await import("path");
@@ -4732,7 +4967,7 @@ async function detectIDEs(providerLoader) {
4732
4967
  `${appDir}\\\\resources\\\\app\\\\bin\\\\${def.cli}.cmd`
4733
4968
  ];
4734
4969
  for (const c of candidates) {
4735
- if ((0, import_fs7.existsSync)(c)) {
4970
+ if ((0, import_fs8.existsSync)(c)) {
4736
4971
  resolvedCli = c;
4737
4972
  break;
4738
4973
  }
@@ -4753,12 +4988,12 @@ async function detectIDEs(providerLoader) {
4753
4988
  }
4754
4989
  return results;
4755
4990
  }
4756
- var import_child_process2, import_fs7, import_os2, path10, BUILTIN_IDE_DEFINITIONS, registeredIDEs;
4991
+ var import_child_process2, import_fs8, import_os2, path10, BUILTIN_IDE_DEFINITIONS, registeredIDEs;
4757
4992
  var init_ide_detector = __esm({
4758
4993
  "../../oss/packages/daemon-core/src/detection/ide-detector.ts"() {
4759
4994
  "use strict";
4760
4995
  import_child_process2 = require("child_process");
4761
- import_fs7 = require("fs");
4996
+ import_fs8 = require("fs");
4762
4997
  import_os2 = require("os");
4763
4998
  path10 = __toESM(require("path"));
4764
4999
  BUILTIN_IDE_DEFINITIONS = [];
@@ -6679,7 +6914,7 @@ var init_status_monitor = __esm({
6679
6914
  });
6680
6915
 
6681
6916
  // ../../oss/packages/daemon-core/src/providers/chat-message-normalization.ts
6682
- function extractFinalSummaryFromMessages(messages, maxChars = 500) {
6917
+ function extractFinalSummaryFromMessages(messages, maxChars = DEFAULT_FINAL_SUMMARY_MAX_CHARS) {
6683
6918
  if (!Array.isArray(messages) || messages.length === 0) return "";
6684
6919
  for (let i = messages.length - 1; i >= 0; i--) {
6685
6920
  const msg = messages[i];
@@ -6981,11 +7216,12 @@ function filterInternalChatMessages(messages) {
6981
7216
  function filterChatMessagesByVisibility(messages, surface) {
6982
7217
  return (Array.isArray(messages) ? messages : []).filter((message) => classifyChatMessageVisibility(message).surface === surface);
6983
7218
  }
6984
- var BUILTIN_CHAT_MESSAGE_KINDS, CHAT_MESSAGE_VISIBILITIES, CHAT_MESSAGE_TRANSCRIPT_VISIBILITIES, CHAT_MESSAGE_AUDIENCES, CHAT_MESSAGE_SOURCES, CHAT_MESSAGE_ACTIVITY_SOURCES, CHAT_MESSAGE_INTERNAL_SOURCES, KNOWN_CHAT_MESSAGE_KINDS, CHAT_MESSAGE_KIND_ALIASES, EXPLICIT_HIDDEN_VISIBILITIES, EXPLICIT_VISIBLE_VISIBILITIES, HIDDEN_AUDIENCES, ACTIVITY_SOURCE_SET, INTERNAL_SOURCE_SET;
7219
+ var DEFAULT_FINAL_SUMMARY_MAX_CHARS, BUILTIN_CHAT_MESSAGE_KINDS, CHAT_MESSAGE_VISIBILITIES, CHAT_MESSAGE_TRANSCRIPT_VISIBILITIES, CHAT_MESSAGE_AUDIENCES, CHAT_MESSAGE_SOURCES, CHAT_MESSAGE_ACTIVITY_SOURCES, CHAT_MESSAGE_INTERNAL_SOURCES, KNOWN_CHAT_MESSAGE_KINDS, CHAT_MESSAGE_KIND_ALIASES, EXPLICIT_HIDDEN_VISIBILITIES, EXPLICIT_VISIBLE_VISIBILITIES, HIDDEN_AUDIENCES, ACTIVITY_SOURCE_SET, INTERNAL_SOURCE_SET;
6985
7220
  var init_chat_message_normalization = __esm({
6986
7221
  "../../oss/packages/daemon-core/src/providers/chat-message-normalization.ts"() {
6987
7222
  "use strict";
6988
7223
  init_contracts();
7224
+ DEFAULT_FINAL_SUMMARY_MAX_CHARS = 4e3;
6989
7225
  BUILTIN_CHAT_MESSAGE_KINDS = ["standard", "thought", "tool", "terminal", "system"];
6990
7226
  CHAT_MESSAGE_VISIBILITIES = ["user", "debug", "internal", "hidden"];
6991
7227
  CHAT_MESSAGE_TRANSCRIPT_VISIBILITIES = ["visible", "chat", "user", "debug", "internal", "hidden"];
@@ -36737,7 +36973,7 @@ function commandExists(command) {
36737
36973
  const trimmed = command.trim();
36738
36974
  if (!trimmed) return false;
36739
36975
  if (isExplicitCommand(trimmed)) {
36740
- return (0, import_fs8.existsSync)(expandExecutable(trimmed));
36976
+ return (0, import_fs9.existsSync)(expandExecutable(trimmed));
36741
36977
  }
36742
36978
  try {
36743
36979
  (0, import_child_process6.execFileSync)(process.platform === "win32" ? "where" : "which", [trimmed], {
@@ -36758,10 +36994,10 @@ function hasCliArg(args, flag) {
36758
36994
  }
36759
36995
  function ensureEmptyDelegatedMcpConfig(workspace) {
36760
36996
  const baseDir = path18.join(os15.tmpdir(), "adhdev-delegated-agent-empty-mcp");
36761
- (0, import_fs8.mkdirSync)(baseDir, { recursive: true });
36997
+ (0, import_fs9.mkdirSync)(baseDir, { recursive: true });
36762
36998
  const workspaceHash = crypto4.createHash("sha256").update(path18.resolve(workspace || os15.tmpdir())).digest("hex").slice(0, 16);
36763
36999
  const filePath = path18.join(baseDir, `${workspaceHash}.json`);
36764
- (0, import_fs8.writeFileSync)(filePath, JSON.stringify({ mcpServers: {} }, null, 2), "utf-8");
37000
+ (0, import_fs9.writeFileSync)(filePath, JSON.stringify({ mcpServers: {} }, null, 2), "utf-8");
36765
37001
  return filePath;
36766
37002
  }
36767
37003
  function buildCoordinatorDelegatedCliLaunchOptions(input) {
@@ -36888,14 +37124,14 @@ function resolveCliSessionBinding(provider, normalizedType, cliArgs, requestedRe
36888
37124
  launchMode: "new"
36889
37125
  };
36890
37126
  }
36891
- var os15, path18, crypto4, import_fs8, import_child_process6, chalkModule, chalkApi, COORDINATOR_DELEGATED_ENV_UNSETS, DaemonCliManager;
37127
+ var os15, path18, crypto4, import_fs9, import_child_process6, chalkModule, chalkApi, COORDINATOR_DELEGATED_ENV_UNSETS, DaemonCliManager;
36892
37128
  var init_cli_manager = __esm({
36893
37129
  "../../oss/packages/daemon-core/src/commands/cli-manager.ts"() {
36894
37130
  "use strict";
36895
37131
  os15 = __toESM(require("os"));
36896
37132
  path18 = __toESM(require("path"));
36897
37133
  crypto4 = __toESM(require("crypto"));
36898
- import_fs8 = require("fs");
37134
+ import_fs9 = require("fs");
36899
37135
  import_child_process6 = require("child_process");
36900
37136
  init_source();
36901
37137
  init_provider_cli_adapter();
@@ -37809,7 +38045,7 @@ function createFsWatchInstance(path35, options, listener, errHandler, emitRaw) {
37809
38045
  }
37810
38046
  };
37811
38047
  try {
37812
- return (0, import_fs9.watch)(path35, {
38048
+ return (0, import_fs10.watch)(path35, {
37813
38049
  persistent: options.persistent
37814
38050
  }, handleEvent);
37815
38051
  } catch (error48) {
@@ -37817,11 +38053,11 @@ function createFsWatchInstance(path35, options, listener, errHandler, emitRaw) {
37817
38053
  return void 0;
37818
38054
  }
37819
38055
  }
37820
- var import_fs9, import_promises5, sysPath, import_os3, STR_DATA, STR_END, STR_CLOSE, EMPTY_FN, pl, isWindows, isMacos, isLinux, isFreeBSD, isIBMi, EVENTS, EV, THROTTLE_MODE_WATCH, statMethods, KEY_LISTENERS, KEY_ERR, KEY_RAW, HANDLER_KEYS, binaryExtensions, isBinaryPath, foreach, addAndConvert, clearItem, delFromSet, isEmptySet, FsWatchInstances, fsWatchBroadcast, setFsWatchListener, FsWatchFileInstances, setFsWatchFileListener, NodeFsHandler;
38056
+ var import_fs10, import_promises5, sysPath, import_os3, STR_DATA, STR_END, STR_CLOSE, EMPTY_FN, pl, isWindows, isMacos, isLinux, isFreeBSD, isIBMi, EVENTS, EV, THROTTLE_MODE_WATCH, statMethods, KEY_LISTENERS, KEY_ERR, KEY_RAW, HANDLER_KEYS, binaryExtensions, isBinaryPath, foreach, addAndConvert, clearItem, delFromSet, isEmptySet, FsWatchInstances, fsWatchBroadcast, setFsWatchListener, FsWatchFileInstances, setFsWatchFileListener, NodeFsHandler;
37821
38057
  var init_handler2 = __esm({
37822
38058
  "../../oss/node_modules/chokidar/esm/handler.js"() {
37823
38059
  "use strict";
37824
- import_fs9 = require("fs");
38060
+ import_fs10 = require("fs");
37825
38061
  import_promises5 = require("fs/promises");
37826
38062
  sysPath = __toESM(require("path"), 1);
37827
38063
  import_os3 = require("os");
@@ -38225,7 +38461,7 @@ var init_handler2 = __esm({
38225
38461
  let cont = FsWatchFileInstances.get(fullPath);
38226
38462
  const copts = cont && cont.options;
38227
38463
  if (copts && (copts.persistent < options.persistent || copts.interval > options.interval)) {
38228
- (0, import_fs9.unwatchFile)(fullPath);
38464
+ (0, import_fs10.unwatchFile)(fullPath);
38229
38465
  cont = void 0;
38230
38466
  }
38231
38467
  if (cont) {
@@ -38236,7 +38472,7 @@ var init_handler2 = __esm({
38236
38472
  listeners: listener,
38237
38473
  rawEmitters: rawEmitter,
38238
38474
  options,
38239
- watcher: (0, import_fs9.watchFile)(fullPath, options, (curr, prev) => {
38475
+ watcher: (0, import_fs10.watchFile)(fullPath, options, (curr, prev) => {
38240
38476
  foreach(cont.rawEmitters, (rawEmitter2) => {
38241
38477
  rawEmitter2(EV.CHANGE, fullPath, { curr, prev });
38242
38478
  });
@@ -38253,7 +38489,7 @@ var init_handler2 = __esm({
38253
38489
  delFromSet(cont, KEY_RAW, rawEmitter);
38254
38490
  if (isEmptySet(cont.listeners)) {
38255
38491
  FsWatchFileInstances.delete(fullPath);
38256
- (0, import_fs9.unwatchFile)(fullPath);
38492
+ (0, import_fs10.unwatchFile)(fullPath);
38257
38493
  cont.options = cont.watcher = void 0;
38258
38494
  Object.freeze(cont);
38259
38495
  }
@@ -38631,11 +38867,11 @@ function watch(paths, options = {}) {
38631
38867
  watcher.add(paths);
38632
38868
  return watcher;
38633
38869
  }
38634
- var import_fs10, import_promises6, import_events2, sysPath2, SLASH, SLASH_SLASH, ONE_DOT, TWO_DOTS, STRING_TYPE, BACK_SLASH_RE, DOUBLE_SLASH_RE, DOT_RE, REPLACER_RE, isMatcherObject, unifyPaths, toUnix, normalizePathToUnix, normalizeIgnored, getAbsolutePath, EMPTY_SET, DirEntry, STAT_METHOD_F, STAT_METHOD_L, WatchHelper, FSWatcher;
38870
+ var import_fs11, import_promises6, import_events2, sysPath2, SLASH, SLASH_SLASH, ONE_DOT, TWO_DOTS, STRING_TYPE, BACK_SLASH_RE, DOUBLE_SLASH_RE, DOT_RE, REPLACER_RE, isMatcherObject, unifyPaths, toUnix, normalizePathToUnix, normalizeIgnored, getAbsolutePath, EMPTY_SET, DirEntry, STAT_METHOD_F, STAT_METHOD_L, WatchHelper, FSWatcher;
38635
38871
  var init_esm2 = __esm({
38636
38872
  "../../oss/node_modules/chokidar/esm/index.js"() {
38637
38873
  "use strict";
38638
- import_fs10 = require("fs");
38874
+ import_fs11 = require("fs");
38639
38875
  import_promises6 = require("fs/promises");
38640
38876
  import_events2 = require("events");
38641
38877
  sysPath2 = __toESM(require("path"), 1);
@@ -39113,7 +39349,7 @@ var init_esm2 = __esm({
39113
39349
  const now = /* @__PURE__ */ new Date();
39114
39350
  const writes = this._pendingWrites;
39115
39351
  function awaitWriteFinishFn(prevStat) {
39116
- (0, import_fs10.stat)(fullPath, (err, curStat) => {
39352
+ (0, import_fs11.stat)(fullPath, (err, curStat) => {
39117
39353
  if (err || !writes.has(path35)) {
39118
39354
  if (err && err.code !== "ENOENT")
39119
39355
  awfEmit(err);
@@ -45414,55 +45650,45 @@ function readBooleanValue(...values) {
45414
45650
  }
45415
45651
  return void 0;
45416
45652
  }
45417
- function buildCachedInlineMeshGitStatus(node) {
45418
- const cachedStatus = readObjectRecord(node?.cachedStatus);
45419
- const cachedGit = readObjectRecord(cachedStatus.git);
45420
- if (Object.keys(cachedGit).length) {
45421
- const conflictFiles2 = Array.isArray(cachedGit.conflictFiles) ? cachedGit.conflictFiles.filter((value) => typeof value === "string") : [];
45422
- const conflictCount2 = readNumberValue(cachedGit.conflicts) ?? conflictFiles2.length;
45423
- const hasConflicts2 = readBooleanValue(cachedGit.hasConflicts) ?? conflictCount2 > 0;
45424
- const isGitRepo2 = readBooleanValue(cachedGit.isGitRepo);
45425
- if (isGitRepo2 !== void 0) {
45426
- return {
45427
- workspace: readStringValue(cachedGit.workspace, node?.workspace) || "",
45428
- repoRoot: readStringValue(cachedGit.repoRoot, node?.repoRoot, node?.workspace) || null,
45429
- isGitRepo: isGitRepo2,
45430
- branch: readStringValue(cachedGit.branch) ?? null,
45431
- headCommit: readStringValue(cachedGit.headCommit) ?? null,
45432
- headMessage: readStringValue(cachedGit.headMessage) ?? null,
45433
- upstream: readStringValue(cachedGit.upstream) ?? null,
45434
- ahead: readNumberValue(cachedGit.ahead) ?? 0,
45435
- behind: readNumberValue(cachedGit.behind) ?? 0,
45436
- staged: readNumberValue(cachedGit.staged) ?? 0,
45437
- modified: readNumberValue(cachedGit.modified) ?? 0,
45438
- untracked: readNumberValue(cachedGit.untracked) ?? 0,
45439
- deleted: readNumberValue(cachedGit.deleted) ?? 0,
45440
- renamed: readNumberValue(cachedGit.renamed) ?? 0,
45441
- hasConflicts: hasConflicts2,
45442
- conflictFiles: conflictFiles2,
45443
- stashCount: readNumberValue(cachedGit.stashCount) ?? 0,
45444
- lastCheckedAt: readNumberValue(cachedGit.lastCheckedAt) ?? Date.now()
45445
- };
45446
- }
45447
- }
45448
- const rawGit = readObjectRecord(node?.lastGit ?? node?.last_git);
45449
- const gitResult = readObjectRecord(rawGit.result);
45450
- const directStatus = readObjectRecord(rawGit.status);
45451
- const nestedStatus = readObjectRecord(gitResult.status);
45452
- const rawProbe = readObjectRecord(node?.lastProbe ?? node?.last_probe);
45453
- const probeGit = readObjectRecord(rawProbe.git);
45454
- const probeGitResult = readObjectRecord(probeGit.result);
45455
- const probeDirectStatus = readObjectRecord(probeGit.status);
45456
- const probeNestedStatus = readObjectRecord(probeGitResult.status);
45457
- const status = Object.keys(directStatus).length ? directStatus : Object.keys(nestedStatus).length ? nestedStatus : Object.keys(probeDirectStatus).length ? probeDirectStatus : Object.keys(probeNestedStatus).length ? probeNestedStatus : {};
45653
+ function joinRepoPath(root, relativePath) {
45654
+ const normalizedRoot = typeof root === "string" ? root.trim().replace(/[\\/]+$/, "") : "";
45655
+ const normalizedPath = typeof relativePath === "string" ? relativePath.trim() : "";
45656
+ if (!normalizedPath) return void 0;
45657
+ if (/^(?:[A-Za-z]:[\\/]|\/)/.test(normalizedPath)) return normalizedPath;
45658
+ if (!normalizedRoot) return void 0;
45659
+ return `${normalizedRoot}/${normalizedPath.replace(/^[\\/]+/, "")}`;
45660
+ }
45661
+ function readGitSubmodules(value, parentRepoRoot) {
45662
+ if (!Array.isArray(value)) return void 0;
45663
+ const submodules = value.map((entry) => {
45664
+ const submodule = readObjectRecord(entry);
45665
+ const path35 = readStringValue(submodule.path);
45666
+ const commit = readStringValue(submodule.commit);
45667
+ const repoPath = readStringValue(submodule.repoPath, submodule.repo_root) ?? joinRepoPath(parentRepoRoot, path35);
45668
+ if (!path35 || !commit || !repoPath) return null;
45669
+ return {
45670
+ path: path35,
45671
+ commit,
45672
+ repoPath,
45673
+ dirty: readBooleanValue(submodule.dirty) ?? false,
45674
+ outOfSync: readBooleanValue(submodule.outOfSync, submodule.out_of_sync) ?? false,
45675
+ lastCheckedAt: readNumberValue(submodule.lastCheckedAt, submodule.last_checked_at) ?? Date.now(),
45676
+ ...readStringValue(submodule.error) ? { error: readStringValue(submodule.error) } : {}
45677
+ };
45678
+ }).filter((entry) => entry !== null);
45679
+ return submodules.length > 0 ? submodules : void 0;
45680
+ }
45681
+ function normalizeInlineMeshGitStatus(status, node, options) {
45458
45682
  const isGitRepo = readBooleanValue(status.isGitRepo);
45459
45683
  if (!Object.keys(status).length || isGitRepo === void 0) return void 0;
45460
45684
  const conflictFiles = Array.isArray(status.conflictFiles) ? status.conflictFiles.filter((value) => typeof value === "string") : [];
45461
45685
  const conflictCount = readNumberValue(status.conflicts) ?? conflictFiles.length;
45462
45686
  const hasConflicts = readBooleanValue(status.hasConflicts) ?? conflictCount > 0;
45687
+ const repoRoot = readStringValue(status.repoRoot, status.repo_root, node?.repoRoot, node?.repo_root, status.workspace, node?.workspace) || void 0;
45688
+ const submodules = readGitSubmodules(status.submodules, repoRoot);
45463
45689
  return {
45464
45690
  workspace: readStringValue(status.workspace, node?.workspace) || "",
45465
- repoRoot: readStringValue(status.repoRoot, node?.repoRoot, node?.workspace) || null,
45691
+ repoRoot: repoRoot ?? null,
45466
45692
  isGitRepo,
45467
45693
  branch: readStringValue(status.branch) ?? null,
45468
45694
  headCommit: readStringValue(status.headCommit) ?? null,
@@ -45478,29 +45704,407 @@ function buildCachedInlineMeshGitStatus(node) {
45478
45704
  hasConflicts,
45479
45705
  conflictFiles,
45480
45706
  stashCount: readNumberValue(status.stashCount) ?? 0,
45481
- lastCheckedAt: Date.now()
45707
+ lastCheckedAt: options?.lastCheckedAt ?? readNumberValue(status.lastCheckedAt) ?? Date.now(),
45708
+ ...submodules ? { submodules } : {}
45709
+ };
45710
+ }
45711
+ function buildInlineMeshTransitGitStatus(node) {
45712
+ const rawGit = readObjectRecord(node?.lastGit ?? node?.last_git);
45713
+ const gitResult = readObjectRecord(rawGit.result);
45714
+ const directStatus = readObjectRecord(rawGit.status);
45715
+ const nestedStatus = readObjectRecord(gitResult.status);
45716
+ const rawProbe = readObjectRecord(node?.lastProbe ?? node?.last_probe);
45717
+ const probeGit = readObjectRecord(rawProbe.git);
45718
+ const probeGitResult = readObjectRecord(probeGit.result);
45719
+ const probeDirectStatus = readObjectRecord(probeGit.status);
45720
+ const probeNestedStatus = readObjectRecord(probeGitResult.status);
45721
+ const status = Object.keys(directStatus).length ? directStatus : Object.keys(nestedStatus).length ? nestedStatus : Object.keys(probeDirectStatus).length ? probeDirectStatus : Object.keys(probeNestedStatus).length ? probeNestedStatus : {};
45722
+ return normalizeInlineMeshGitStatus(status, node, { lastCheckedAt: Date.now() });
45723
+ }
45724
+ function recordInlineMeshDirectGitTruth(node, git, source) {
45725
+ if (!node || typeof node !== "object" || Array.isArray(node)) return;
45726
+ const checkedAt = readNumberValue(git.lastCheckedAt) ?? Date.now();
45727
+ const updatedAt = new Date(checkedAt).toISOString();
45728
+ const nextGit = {
45729
+ ...git,
45730
+ lastCheckedAt: checkedAt
45731
+ };
45732
+ node.lastGit = {
45733
+ source,
45734
+ checkedAt,
45735
+ status: nextGit
45736
+ };
45737
+ node.last_git = node.lastGit;
45738
+ node.machineStatus = "online";
45739
+ node.updatedAt = updatedAt;
45740
+ node.lastSeenAt = updatedAt;
45741
+ const repoRoot = readStringValue(nextGit.repoRoot);
45742
+ if (repoRoot && !readStringValue(node.repoRoot)) node.repoRoot = repoRoot;
45743
+ }
45744
+ function buildCachedInlineMeshGitStatus(node) {
45745
+ const liveGit = buildInlineMeshTransitGitStatus(node);
45746
+ if (liveGit) return liveGit;
45747
+ const cachedStatus = readObjectRecord(node?.cachedStatus);
45748
+ const cachedGit = readObjectRecord(cachedStatus.git);
45749
+ if (!Object.keys(cachedGit).length) return void 0;
45750
+ return normalizeInlineMeshGitStatus(cachedGit, node);
45751
+ }
45752
+ function shouldDiscardCachedInlineMeshStatus(node) {
45753
+ const cachedStatus = readObjectRecord(node?.cachedStatus);
45754
+ if (!Object.keys(cachedStatus).length) return false;
45755
+ const cachedGit = readObjectRecord(cachedStatus.git);
45756
+ const workspaceError = readStringValue(cachedStatus.error, node?.error);
45757
+ if (workspaceError && /workspace must be an existing directory/i.test(workspaceError)) return true;
45758
+ const isGitRepo = readBooleanValue(cachedGit.isGitRepo);
45759
+ const branch = readStringValue(cachedGit.branch);
45760
+ const headCommit = readStringValue(cachedGit.headCommit);
45761
+ return isGitRepo === false && !branch && !headCommit;
45762
+ }
45763
+ function stripInlineMeshTransientNodeState(node) {
45764
+ if (!node || typeof node !== "object" || Array.isArray(node)) return node;
45765
+ const {
45766
+ cachedStatus,
45767
+ lastGit: _lastGit,
45768
+ last_git: _lastGitLegacy,
45769
+ lastProbe: _lastProbe,
45770
+ last_probe: _lastProbeLegacy,
45771
+ error: _error,
45772
+ health: _health,
45773
+ machineStatus: _machineStatus,
45774
+ lastSeenAt: _lastSeenAt,
45775
+ last_seen_at: _lastSeenAtLegacy,
45776
+ updatedAt: _updatedAt,
45777
+ updated_at: _updatedAtLegacy,
45778
+ activeSession: _activeSession,
45779
+ active_session: _activeSessionLegacy,
45780
+ activeSessionId: _activeSessionId,
45781
+ active_session_id: _activeSessionIdLegacy,
45782
+ sessionId: _sessionId,
45783
+ session_id: _sessionIdLegacy,
45784
+ providerType: _providerType,
45785
+ provider_type: _providerTypeLegacy,
45786
+ ...rest
45787
+ } = node;
45788
+ if (cachedStatus && !shouldDiscardCachedInlineMeshStatus(node)) {
45789
+ return { ...rest, cachedStatus };
45790
+ }
45791
+ return rest;
45792
+ }
45793
+ function hasInlineMeshTransientNodeState(node) {
45794
+ if (!node || typeof node !== "object" || Array.isArray(node)) return false;
45795
+ return "cachedStatus" in node || "lastGit" in node || "last_git" in node || "lastProbe" in node || "last_probe" in node || "error" in node || "health" in node || "machineStatus" in node || "lastSeenAt" in node || "last_seen_at" in node || "updatedAt" in node || "updated_at" in node || "activeSession" in node || "active_session" in node || "activeSessionId" in node || "active_session_id" in node || "sessionId" in node || "session_id" in node || "providerType" in node || "provider_type" in node;
45796
+ }
45797
+ function readInlineMeshNodeId(node) {
45798
+ return readStringValue(node?.id, node?.nodeId) || "";
45799
+ }
45800
+ function sanitizeInlineMesh(inlineMesh) {
45801
+ if (!inlineMesh || typeof inlineMesh !== "object" || Array.isArray(inlineMesh)) return inlineMesh;
45802
+ if (!Array.isArray(inlineMesh.nodes)) return inlineMesh;
45803
+ let changed = false;
45804
+ const nodes = inlineMesh.nodes.map((node) => {
45805
+ if (!hasInlineMeshTransientNodeState(node)) return node;
45806
+ changed = true;
45807
+ return stripInlineMeshTransientNodeState(node);
45808
+ });
45809
+ if (!changed) return inlineMesh;
45810
+ return {
45811
+ ...inlineMesh,
45812
+ nodes
45813
+ };
45814
+ }
45815
+ function reconcileInlineMeshCache(cached2, incoming) {
45816
+ if (!cached2 || typeof cached2 !== "object" || Array.isArray(cached2)) return incoming;
45817
+ if (!incoming || typeof incoming !== "object" || Array.isArray(incoming)) return cached2;
45818
+ const cachedNodes = Array.isArray(cached2.nodes) ? cached2.nodes : [];
45819
+ const incomingNodes = Array.isArray(incoming.nodes) ? incoming.nodes : [];
45820
+ if (!cachedNodes.length || !incomingNodes.length) return { ...cached2, ...incoming };
45821
+ const incomingById = /* @__PURE__ */ new Map();
45822
+ for (const node of incomingNodes) {
45823
+ const nodeId = readInlineMeshNodeId(node);
45824
+ if (nodeId) incomingById.set(nodeId, node);
45825
+ }
45826
+ const nodes = cachedNodes.map((cachedNode) => {
45827
+ const nodeId = readInlineMeshNodeId(cachedNode);
45828
+ const incomingNode = nodeId ? incomingById.get(nodeId) : void 0;
45829
+ if (!incomingNode) return cachedNode;
45830
+ if (hasInlineMeshTransientNodeState(incomingNode)) {
45831
+ return { ...cachedNode, ...incomingNode };
45832
+ }
45833
+ return { ...stripInlineMeshTransientNodeState(cachedNode), ...incomingNode };
45834
+ });
45835
+ return {
45836
+ ...cached2,
45837
+ ...incoming,
45838
+ nodes
45839
+ };
45840
+ }
45841
+ function hasGitWorktreeChanges(git) {
45842
+ if (!git) return false;
45843
+ return Number(git.staged || 0) + Number(git.modified || 0) + Number(git.untracked || 0) + Number(git.deleted || 0) + Number(git.renamed || 0) > 0;
45844
+ }
45845
+ function getGitSubmoduleDriftState(git) {
45846
+ const submodules = Array.isArray(git?.submodules) ? git.submodules : [];
45847
+ let dirty = false;
45848
+ let outOfSync = false;
45849
+ for (const entry of submodules) {
45850
+ const submodule = readObjectRecord(entry);
45851
+ if (readBooleanValue(submodule.dirty) === true) dirty = true;
45852
+ if (readBooleanValue(submodule.outOfSync) === true || !!readStringValue(submodule.error)) outOfSync = true;
45853
+ }
45854
+ return { dirty, outOfSync };
45855
+ }
45856
+ function deriveMeshNodeHealthFromGit(git) {
45857
+ if (!git || readBooleanValue(git.isGitRepo) === false) return "degraded";
45858
+ const branch = readStringValue(git.branch);
45859
+ if (!branch) return "degraded";
45860
+ const submoduleDrift = getGitSubmoduleDriftState(git);
45861
+ if (submoduleDrift.outOfSync) return "degraded";
45862
+ if (submoduleDrift.dirty || hasGitWorktreeChanges(git)) return "dirty";
45863
+ return "online";
45864
+ }
45865
+ function readCachedInlineMeshActiveSessions(node) {
45866
+ const cachedStatus = readObjectRecord(node?.cachedStatus);
45867
+ const activeSession = readObjectRecord(cachedStatus.activeSession);
45868
+ const fallbackSession = Object.keys(activeSession).length ? activeSession : readObjectRecord(node?.activeSession ?? node?.active_session);
45869
+ const sessionId = readStringValue(fallbackSession.id, fallbackSession.sessionId, fallbackSession.session_id, node?.activeSessionId, node?.active_session_id, node?.sessionId, node?.session_id);
45870
+ return sessionId ? [sessionId] : [];
45871
+ }
45872
+ function readCachedInlineMeshActiveSessionDetails(node) {
45873
+ const cachedStatus = readObjectRecord(node?.cachedStatus);
45874
+ const activeSession = readObjectRecord(cachedStatus.activeSession);
45875
+ const fallbackSession = Object.keys(activeSession).length ? activeSession : readObjectRecord(node?.activeSession ?? node?.active_session);
45876
+ const sessionId = readStringValue(
45877
+ fallbackSession.id,
45878
+ fallbackSession.sessionId,
45879
+ fallbackSession.session_id,
45880
+ node?.activeSessionId,
45881
+ node?.active_session_id,
45882
+ node?.sessionId,
45883
+ node?.session_id
45884
+ );
45885
+ if (!sessionId) return [];
45886
+ return [{
45887
+ sessionId,
45888
+ providerType: readStringValue(
45889
+ fallbackSession.providerType,
45890
+ fallbackSession.provider_type,
45891
+ fallbackSession.cliType,
45892
+ fallbackSession.cli_type,
45893
+ fallbackSession.provider,
45894
+ node?.providerType,
45895
+ node?.provider_type
45896
+ ),
45897
+ state: readStringValue(fallbackSession.status, fallbackSession.state, fallbackSession.lifecycle),
45898
+ lifecycle: readStringValue(fallbackSession.lifecycle),
45899
+ title: readStringValue(fallbackSession.title, fallbackSession.displayName, fallbackSession.display_name) ?? null,
45900
+ workspace: readStringValue(fallbackSession.workspace, node?.workspace) ?? null,
45901
+ lastActivityAt: readStringValue(fallbackSession.lastActivityAt, fallbackSession.last_activity_at) ?? null,
45902
+ recoveryState: readStringValue(fallbackSession.recoveryState, fallbackSession.recovery_state) ?? null,
45903
+ isCached: true
45904
+ }];
45905
+ }
45906
+ function readLiveMeshSessionState(record2) {
45907
+ return readStringValue(
45908
+ record2?.meta?.sessionStatus,
45909
+ record2?.meta?.status,
45910
+ record2?.meta?.providerStatus,
45911
+ record2?.status,
45912
+ record2?.state,
45913
+ record2?.lifecycle
45914
+ );
45915
+ }
45916
+ function toIsoTimestamp(value) {
45917
+ if (typeof value === "number" && Number.isFinite(value)) return new Date(value).toISOString();
45918
+ const stringValue = readStringValue(value);
45919
+ return stringValue || null;
45920
+ }
45921
+ function synthesizeMeshNodeFreshnessFromConnection(status) {
45922
+ const connection = readObjectRecord(status.connection);
45923
+ const connectionFreshAt = toIsoTimestamp(connection.lastCommandAt ?? connection.lastConnectedAt ?? connection.lastStateChangeAt);
45924
+ const git = readObjectRecord(status.git);
45925
+ const gitCheckedAt = toIsoTimestamp(git.lastCheckedAt);
45926
+ if (!status.lastSeenAt && connectionFreshAt) status.lastSeenAt = connectionFreshAt;
45927
+ if (!status.updatedAt && (gitCheckedAt || connectionFreshAt)) {
45928
+ status.updatedAt = gitCheckedAt ?? connectionFreshAt;
45929
+ }
45930
+ }
45931
+ function finalizeMeshNodeStatus(args) {
45932
+ const { status, node, daemonId, isSelfNode } = args;
45933
+ if (!readStringValue(status.machineStatus)) {
45934
+ const cachedStatus = readObjectRecord(node?.cachedStatus);
45935
+ const machineStatus = readStringValue(cachedStatus.machineStatus, cachedStatus.machine_status, node?.machineStatus);
45936
+ if (machineStatus) status.machineStatus = machineStatus;
45937
+ }
45938
+ synthesizeMeshNodeFreshnessFromConnection(status);
45939
+ const connectionState = readStringValue(readObjectRecord(status.connection).state);
45940
+ status.launchReady = !!daemonId && (readStringValue(status.machineStatus) === "online" || connectionState === "connected" || isSelfNode);
45941
+ }
45942
+ async function probeRemoteMeshGitStatus(args) {
45943
+ if (!args.dispatchMeshCommand) return null;
45944
+ const remoteResult = await Promise.race([
45945
+ args.dispatchMeshCommand(args.daemonId, "git_status", { workspace: args.workspace }),
45946
+ new Promise((_2, reject) => setTimeout(() => reject(new Error("timeout")), args.timeoutMs))
45947
+ ]);
45948
+ const remoteGit = remoteResult?.status ?? remoteResult?.git ?? remoteResult;
45949
+ return remoteGit && typeof remoteGit === "object" && typeof remoteGit.isGitRepo === "boolean" ? remoteGit : null;
45950
+ }
45951
+ async function hydrateInlineMeshDirectTruth(args) {
45952
+ const nodes = Array.isArray(args.mesh?.nodes) ? args.mesh.nodes : [];
45953
+ if (!nodes.length) {
45954
+ return {
45955
+ directEvidenceCount: 0,
45956
+ localConfirmedCount: 0,
45957
+ peerAttemptedCount: 0,
45958
+ peerConfirmedCount: 0,
45959
+ unavailableNodeIds: []
45960
+ };
45961
+ }
45962
+ const selectedCoordinatorNodeId = readStringValue(
45963
+ args.mesh?.coordinator?.preferredNodeId,
45964
+ nodes[0]?.id,
45965
+ nodes[0]?.nodeId
45966
+ );
45967
+ let localConfirmedCount = 0;
45968
+ let peerAttemptedCount = 0;
45969
+ let peerConfirmedCount = 0;
45970
+ const unavailableNodeIds = [];
45971
+ for (const [nodeIndex, node] of nodes.entries()) {
45972
+ const nodeId = readStringValue(node?.id, node?.nodeId) || `node_${nodeIndex}`;
45973
+ const workspace = readStringValue(node?.workspace);
45974
+ const daemonId = readStringValue(node?.daemonId);
45975
+ const isSelfNode = Boolean(
45976
+ nodeId && selectedCoordinatorNodeId && nodeId === selectedCoordinatorNodeId
45977
+ ) || Boolean(
45978
+ daemonId && (daemonId === args.localMachineId || daemonId === args.statusInstanceId)
45979
+ ) || Boolean(args.meshSource !== "local_config" && nodeIndex === 0);
45980
+ if (!workspace) {
45981
+ if (!isSelfNode && daemonId) unavailableNodeIds.push(nodeId);
45982
+ continue;
45983
+ }
45984
+ if (isSelfNode && fs10.existsSync(workspace)) {
45985
+ try {
45986
+ const localGit = await getGitRepoStatus(workspace, { timeoutMs: 1e4, refreshUpstream: true });
45987
+ if (localGit?.isGitRepo) {
45988
+ recordInlineMeshDirectGitTruth(node, localGit, "selected_coordinator_local_git");
45989
+ localConfirmedCount += 1;
45990
+ continue;
45991
+ }
45992
+ } catch {
45993
+ }
45994
+ }
45995
+ if (!daemonId || !args.dispatchMeshCommand) {
45996
+ if (!isSelfNode) unavailableNodeIds.push(nodeId);
45997
+ continue;
45998
+ }
45999
+ peerAttemptedCount += 1;
46000
+ try {
46001
+ const remoteGit = await probeRemoteMeshGitStatus({
46002
+ dispatchMeshCommand: args.dispatchMeshCommand,
46003
+ daemonId,
46004
+ workspace,
46005
+ timeoutMs: 8e3
46006
+ });
46007
+ if (remoteGit) {
46008
+ recordInlineMeshDirectGitTruth(node, remoteGit, "selected_coordinator_mesh_p2p_git");
46009
+ peerConfirmedCount += 1;
46010
+ continue;
46011
+ }
46012
+ } catch {
46013
+ }
46014
+ unavailableNodeIds.push(nodeId);
46015
+ }
46016
+ return {
46017
+ directEvidenceCount: localConfirmedCount + peerConfirmedCount,
46018
+ localConfirmedCount,
46019
+ peerAttemptedCount,
46020
+ peerConfirmedCount,
46021
+ unavailableNodeIds
46022
+ };
46023
+ }
46024
+ function summarizeMeshSessionRecord(record2) {
46025
+ return {
46026
+ sessionId: readStringValue(record2?.sessionId) || "unknown",
46027
+ providerType: readStringValue(record2?.providerType),
46028
+ state: readLiveMeshSessionState(record2),
46029
+ lifecycle: readStringValue(record2?.lifecycle),
46030
+ surfaceKind: getSessionHostSurfaceKind(record2),
46031
+ recoveryState: readStringValue(record2?.meta?.runtimeRecoveryState) ?? null,
46032
+ workspace: readStringValue(record2?.workspace) ?? null,
46033
+ title: readStringValue(record2?.displayName, record2?.workspaceLabel) ?? null,
46034
+ lastActivityAt: toIsoTimestamp(record2?.updatedAt ?? record2?.lastActivityAt ?? record2?.last_activity_at),
46035
+ isCached: false
45482
46036
  };
45483
46037
  }
45484
- function applyCachedInlineMeshNodeStatus(status, node) {
46038
+ function liveSessionRecordMatchesMeshNode(record2, meshId, nodeId) {
46039
+ const recordNodeId = readStringValue(record2?.meta?.meshNodeId);
46040
+ if (!recordNodeId || recordNodeId !== nodeId) return false;
46041
+ const recordMeshId = readStringValue(record2?.meta?.meshNodeFor);
46042
+ return !recordMeshId || recordMeshId === meshId;
46043
+ }
46044
+ function liveSessionRecordMatchesMeshWorkspace(record2, meshId, workspace) {
46045
+ const recordWorkspace = readStringValue(record2?.workspace);
46046
+ if (!recordWorkspace || !workspace || recordWorkspace !== workspace) return false;
46047
+ const recordMeshId = readStringValue(record2?.meta?.meshNodeFor);
46048
+ if (recordMeshId) return recordMeshId === meshId;
46049
+ return record2?.meta?.launchedByCoordinator === true || !!readStringValue(record2?.meta?.meshNodeId);
46050
+ }
46051
+ function readLiveMeshNodeWorkspace(args) {
46052
+ const directNodeWorkspace = args.liveSessionRecords.find((record2) => liveSessionRecordMatchesMeshNode(record2, args.meshId, args.nodeId) && readStringValue(record2?.workspace));
46053
+ if (directNodeWorkspace) {
46054
+ return readStringValue(directNodeWorkspace.workspace) || "";
46055
+ }
46056
+ if (args.allowCoordinatorSession) {
46057
+ const coordinatorWorkspace = args.liveSessionRecords.find((record2) => readStringValue(record2?.meta?.meshCoordinatorFor) === args.meshId && readStringValue(record2?.workspace));
46058
+ if (coordinatorWorkspace) {
46059
+ return readStringValue(coordinatorWorkspace.workspace) || "";
46060
+ }
46061
+ }
46062
+ return "";
46063
+ }
46064
+ function collectLiveMeshSessionRecords(args) {
46065
+ const matches = args.liveSessionRecords.filter((record2) => {
46066
+ const nodeWorkspace = readStringValue(args.node?.workspace);
46067
+ if (liveSessionRecordMatchesMeshNode(record2, args.meshId, args.nodeId)) return true;
46068
+ return !!nodeWorkspace && liveSessionRecordMatchesMeshWorkspace(record2, args.meshId, nodeWorkspace);
46069
+ });
46070
+ if (args.allowCoordinatorSession) {
46071
+ for (const record2 of args.liveSessionRecords) {
46072
+ if (readStringValue(record2?.meta?.meshCoordinatorFor) !== args.meshId) continue;
46073
+ const sessionId = readStringValue(record2?.sessionId);
46074
+ if (sessionId && matches.some((entry) => readStringValue(entry?.sessionId) === sessionId)) continue;
46075
+ matches.push(record2);
46076
+ }
46077
+ }
46078
+ return matches;
46079
+ }
46080
+ function applyCachedInlineMeshNodeStatus(status, node, options) {
45485
46081
  const cachedStatus = readObjectRecord(node?.cachedStatus);
45486
- const git = buildCachedInlineMeshGitStatus(node);
45487
- const error48 = readStringValue(cachedStatus.error, node?.error);
45488
- const health = readStringValue(cachedStatus.health, node?.health);
46082
+ const liveGit = buildInlineMeshTransitGitStatus(node);
46083
+ const git = options?.skipGit ? void 0 : liveGit ?? buildCachedInlineMeshGitStatus(node);
46084
+ const error48 = options?.skipError ? void 0 : liveGit ? void 0 : readStringValue(cachedStatus.error, node?.error);
46085
+ const health = options?.skipHealth ? void 0 : liveGit ? void 0 : readStringValue(cachedStatus.health, node?.health);
45489
46086
  const machineStatus = readStringValue(cachedStatus.machineStatus, node?.machineStatus);
45490
- if (!git && !error48 && !health) return false;
45491
- if (!machineStatus && !git && !error48) return false;
46087
+ const lastSeenAt = toIsoTimestamp(cachedStatus.lastSeenAt ?? cachedStatus.last_seen_at ?? node?.lastSeenAt ?? node?.last_seen_at);
46088
+ const updatedAt = toIsoTimestamp(cachedStatus.updatedAt ?? cachedStatus.updated_at ?? node?.updatedAt ?? node?.updated_at);
46089
+ const activeSessions = readCachedInlineMeshActiveSessions(node);
46090
+ const activeSessionDetails = readCachedInlineMeshActiveSessionDetails(node);
46091
+ if (!git && !error48 && !health && !machineStatus && !lastSeenAt && !updatedAt && activeSessions.length === 0) return false;
45492
46092
  if (git) status.git = git;
45493
46093
  if (error48) status.error = error48;
46094
+ if (machineStatus) status.machineStatus = machineStatus;
46095
+ if (lastSeenAt) status.lastSeenAt = lastSeenAt;
46096
+ if (updatedAt) status.updatedAt = updatedAt;
46097
+ if (activeSessions.length > 0) status.activeSessions = activeSessions;
46098
+ if (activeSessionDetails.length > 0) status.activeSessionDetails = activeSessionDetails;
45494
46099
  if (health) {
45495
46100
  status.health = health;
45496
46101
  return true;
45497
46102
  }
45498
46103
  if (git) {
45499
- const dirty = Number(git.staged || 0) + Number(git.modified || 0) + Number(git.untracked || 0) + Number(git.deleted || 0) + Number(git.renamed || 0) > 0;
45500
- status.health = git.isGitRepo === false ? "degraded" : dirty ? "dirty" : "online";
46104
+ status.health = deriveMeshNodeHealthFromGit(git);
45501
46105
  return true;
45502
46106
  }
45503
- return false;
46107
+ return activeSessions.length > 0 || !!machineStatus || !!lastSeenAt || !!updatedAt;
45504
46108
  }
45505
46109
  async function resolveProviderTypeFromPriority(args) {
45506
46110
  if (!args.providerPriority.length) {
@@ -45533,7 +46137,7 @@ function truncateValidationOutput(value) {
45533
46137
  }
45534
46138
  function readPackageScripts(workspace) {
45535
46139
  try {
45536
- const packageJsonPath = (0, import_path6.join)(workspace, "package.json");
46140
+ const packageJsonPath = (0, import_path7.join)(workspace, "package.json");
45537
46141
  const parsed = JSON.parse(fs10.readFileSync(packageJsonPath, "utf-8"));
45538
46142
  return parsed?.scripts && typeof parsed.scripts === "object" && !Array.isArray(parsed.scripts) ? parsed.scripts : {};
45539
46143
  } catch {
@@ -45741,13 +46345,13 @@ function serializeMeshCoordinatorMcpConfig(config2, format) {
45741
46345
  }
45742
46346
  function resolveHermesUserHome() {
45743
46347
  const explicitHome = process.env.HERMES_HOME?.trim();
45744
- return explicitHome || (0, import_path6.join)((0, import_os4.homedir)(), ".hermes");
46348
+ return explicitHome || (0, import_path7.join)((0, import_os4.homedir)(), ".hermes");
45745
46349
  }
45746
46350
  function loadHermesCoordinatorBaseConfig(targetConfigPath) {
45747
46351
  const sourceHome = resolveHermesUserHome();
45748
- const sourceConfigPath = (0, import_path6.join)(sourceHome, "config.yaml");
46352
+ const sourceConfigPath = (0, import_path7.join)(sourceHome, "config.yaml");
45749
46353
  if (!fs10.existsSync(sourceConfigPath)) return { config: {}, sourceHome, sourceConfigPath };
45750
- if ((0, import_path6.resolve)(sourceConfigPath) === (0, import_path6.resolve)(targetConfigPath)) return { config: {}, sourceHome, sourceConfigPath };
46354
+ if ((0, import_path7.resolve)(sourceConfigPath) === (0, import_path7.resolve)(targetConfigPath)) return { config: {}, sourceHome, sourceConfigPath };
45751
46355
  const parsed = parseMeshCoordinatorMcpConfig(fs10.readFileSync(sourceConfigPath, "utf-8"), "hermes_config_yaml");
45752
46356
  const { mcp_servers: _mcpServers, ...baseConfig } = parsed;
45753
46357
  return { config: baseConfig, sourceHome, sourceConfigPath };
@@ -45781,10 +46385,10 @@ function stripHermesCoordinatorTempModelProviderOverrides(config2) {
45781
46385
  return sanitized;
45782
46386
  }
45783
46387
  function copyHermesCoordinatorCredentialFiles(sourceHome, targetHome) {
45784
- if ((0, import_path6.resolve)(sourceHome) === (0, import_path6.resolve)(targetHome)) return;
46388
+ if ((0, import_path7.resolve)(sourceHome) === (0, import_path7.resolve)(targetHome)) return;
45785
46389
  for (const fileName of [".env", "auth.json"]) {
45786
- const sourcePath = (0, import_path6.join)(sourceHome, fileName);
45787
- const targetPath = (0, import_path6.join)(targetHome, fileName);
46390
+ const sourcePath = (0, import_path7.join)(sourceHome, fileName);
46391
+ const targetPath = (0, import_path7.join)(targetHome, fileName);
45788
46392
  if (!fs10.existsSync(sourcePath)) continue;
45789
46393
  try {
45790
46394
  fs10.copyFileSync(sourcePath, targetPath);
@@ -45874,7 +46478,7 @@ function summarizeSessionHostPruneResult(result) {
45874
46478
  keptCount: Array.isArray(value.keptSessionIds) ? value.keptSessionIds.length : void 0
45875
46479
  };
45876
46480
  }
45877
- var import_os4, import_path6, fs10, CHANNEL_NPM_TAG, CHANNEL_SERVER_URL, REFINE_VALIDATION_CATEGORIES, REFINE_VALIDATION_TIMEOUT_MS, REFINE_VALIDATION_OUTPUT_LIMIT_BYTES, REFINE_VALIDATION_SUMMARY_CHARS, REFINE_VALIDATION_MAX_COMMANDS, CHAT_COMMANDS, READ_DEBUG_ENABLED2, DaemonCommandRouter;
46481
+ var import_os4, import_path7, fs10, CHANNEL_NPM_TAG, CHANNEL_SERVER_URL, REFINE_VALIDATION_CATEGORIES, REFINE_VALIDATION_TIMEOUT_MS, REFINE_VALIDATION_OUTPUT_LIMIT_BYTES, REFINE_VALIDATION_SUMMARY_CHARS, REFINE_VALIDATION_MAX_COMMANDS, CHAT_COMMANDS, READ_DEBUG_ENABLED2, DaemonCommandRouter;
45878
46482
  var init_router = __esm({
45879
46483
  "../../oss/packages/daemon-core/src/commands/router.ts"() {
45880
46484
  "use strict";
@@ -45890,6 +46494,7 @@ var init_router = __esm({
45890
46494
  init_chat_history();
45891
46495
  init_ide_detector();
45892
46496
  init_cli_detector();
46497
+ init_git_status();
45893
46498
  init_logger();
45894
46499
  init_command_log();
45895
46500
  init_js_yaml();
@@ -45903,7 +46508,7 @@ var init_router = __esm({
45903
46508
  init_snapshot();
45904
46509
  init_upgrade_helper();
45905
46510
  import_os4 = require("os");
45906
- import_path6 = require("path");
46511
+ import_path7 = require("path");
45907
46512
  fs10 = __toESM(require("fs"));
45908
46513
  CHANNEL_NPM_TAG = { stable: "latest", preview: "next" };
45909
46514
  CHANNEL_SERVER_URL = {
@@ -45934,25 +46539,40 @@ var init_router = __esm({
45934
46539
  }
45935
46540
  getCachedInlineMesh(meshId, inlineMesh) {
45936
46541
  if (inlineMesh && typeof inlineMesh === "object") {
45937
- this.inlineMeshCache.set(meshId, inlineMesh);
45938
- return inlineMesh;
46542
+ return this.warmInlineMeshCache(meshId, inlineMesh);
45939
46543
  }
45940
46544
  return this.inlineMeshCache.get(meshId);
45941
46545
  }
46546
+ warmInlineMeshCache(meshId, inlineMesh) {
46547
+ if (!inlineMesh || typeof inlineMesh !== "object") return void 0;
46548
+ const sanitizedInlineMesh = sanitizeInlineMesh(inlineMesh);
46549
+ const cached2 = this.inlineMeshCache.get(meshId);
46550
+ if (cached2) {
46551
+ const merged = reconcileInlineMeshCache(cached2, sanitizedInlineMesh);
46552
+ this.inlineMeshCache.set(meshId, merged);
46553
+ return merged;
46554
+ }
46555
+ this.inlineMeshCache.set(meshId, sanitizedInlineMesh);
46556
+ return sanitizedInlineMesh;
46557
+ }
45942
46558
  async getMeshForCommand(meshId, inlineMesh, options) {
45943
46559
  const preferInline = options?.preferInline === true;
45944
46560
  if (preferInline) {
45945
- const cached3 = this.getCachedInlineMesh(meshId, inlineMesh);
45946
- if (cached3) return { mesh: cached3, inline: true };
46561
+ const cached3 = this.getCachedInlineMesh(meshId);
46562
+ if (cached3) return { mesh: cached3, inline: true, source: "inline_cache" };
46563
+ const warmedInline2 = this.warmInlineMeshCache(meshId, inlineMesh);
46564
+ if (warmedInline2) return { mesh: warmedInline2, inline: true, source: "inline_bootstrap" };
45947
46565
  }
45948
46566
  try {
45949
46567
  const { getMesh: getMesh3 } = await Promise.resolve().then(() => (init_mesh_config(), mesh_config_exports));
45950
46568
  const mesh = getMesh3(meshId);
45951
- if (mesh) return { mesh, inline: false };
46569
+ if (mesh) return { mesh, inline: false, source: "local_config" };
45952
46570
  } catch {
45953
46571
  }
45954
- const cached2 = this.getCachedInlineMesh(meshId, inlineMesh);
45955
- return cached2 ? { mesh: cached2, inline: true } : null;
46572
+ const cached2 = this.getCachedInlineMesh(meshId);
46573
+ if (cached2) return { mesh: cached2, inline: true, source: "inline_cache" };
46574
+ const warmedInline = this.warmInlineMeshCache(meshId, inlineMesh);
46575
+ return warmedInline ? { mesh: warmedInline, inline: true, source: "inline_bootstrap" } : null;
45956
46576
  }
45957
46577
  updateInlineMeshNode(meshId, mesh, node) {
45958
46578
  if (!mesh || !Array.isArray(mesh.nodes) || !node?.id) return;
@@ -46017,7 +46637,7 @@ var init_router = __esm({
46017
46637
  }
46018
46638
  const { resolveWorktreePath: resolveWorktreePath2, listWorktrees: listWorktrees2, removeWorktree: removeWorktree2 } = await Promise.resolve().then(() => (init_git_worktree(), git_worktree_exports));
46019
46639
  const normalizePath2 = (value) => {
46020
- const resolved = (0, import_path6.resolve)(value);
46640
+ const resolved = (0, import_path7.resolve)(value);
46021
46641
  try {
46022
46642
  return fs10.realpathSync(resolved);
46023
46643
  } catch {
@@ -46181,6 +46801,7 @@ var init_router = __esm({
46181
46801
  const deletedSessionIds = [];
46182
46802
  const skippedSessionIds = [];
46183
46803
  const skippedLiveSessionIds = [];
46804
+ const skippedCoordinatorSessionIds = [];
46184
46805
  const deleteUnsupportedSessionIds = [];
46185
46806
  const recordsRemainSessionIds = [];
46186
46807
  const errors = [];
@@ -46213,6 +46834,12 @@ var init_router = __esm({
46213
46834
  const completed = this.isCompletedHostedSession(record2);
46214
46835
  const surfaceKind = getSessionHostSurfaceKind(record2);
46215
46836
  const liveRuntime = surfaceKind === "live_runtime";
46837
+ const coordinatorSession = readStringValue(record2?.meta?.meshCoordinatorFor) === args.meshId;
46838
+ if (!hasExplicitSessionIds && coordinatorSession) {
46839
+ skippedSessionIds.push(sessionId);
46840
+ skippedCoordinatorSessionIds.push(sessionId);
46841
+ continue;
46842
+ }
46216
46843
  if (!hasExplicitSessionIds && liveRuntime) {
46217
46844
  skippedSessionIds.push(sessionId);
46218
46845
  skippedLiveSessionIds.push(sessionId);
@@ -46278,6 +46905,7 @@ var init_router = __esm({
46278
46905
  deletedSessionIds,
46279
46906
  skippedSessionIds,
46280
46907
  skippedLiveSessionIds,
46908
+ skippedCoordinatorSessionIds,
46281
46909
  ...deleteUnsupported ? {
46282
46910
  deleteUnsupported: true,
46283
46911
  effectiveCleanup: args.mode === "stop_and_delete" ? "stopped_only_records_remain" : "delete_unsupported_records_remain",
@@ -46410,7 +47038,8 @@ var init_router = __esm({
46410
47038
  return handleMeshForwardEvent({ instanceManager: this.deps.instanceManager }, args);
46411
47039
  }
46412
47040
  case "get_pending_mesh_events": {
46413
- const events = drainPendingMeshCoordinatorEvents();
47041
+ const meshId = typeof args?.meshId === "string" ? args.meshId.trim() : "";
47042
+ const events = drainPendingMeshCoordinatorEvents(meshId || void 0);
46414
47043
  return { success: true, events };
46415
47044
  }
46416
47045
  case "launch_cli":
@@ -46939,15 +47568,39 @@ var init_router = __esm({
46939
47568
  case "get_mesh": {
46940
47569
  const meshId = typeof args?.meshId === "string" ? args.meshId.trim() : "";
46941
47570
  if (!meshId) return { success: false, error: "meshId required" };
46942
- try {
46943
- const { getMesh: getMesh3 } = await Promise.resolve().then(() => (init_mesh_config(), mesh_config_exports));
46944
- const mesh = getMesh3(meshId);
46945
- if (mesh) return { success: true, mesh };
46946
- } catch {
47571
+ const meshRecord = await this.getMeshForCommand(meshId, args?.inlineMesh, { preferInline: true });
47572
+ if (!meshRecord?.mesh) return { success: false, error: "Mesh not found" };
47573
+ const requireDirectPeerTruth = args?.requireDirectPeerTruth === true;
47574
+ const directTruth = await hydrateInlineMeshDirectTruth({
47575
+ mesh: meshRecord.mesh,
47576
+ meshSource: meshRecord.source,
47577
+ dispatchMeshCommand: this.deps.dispatchMeshCommand,
47578
+ statusInstanceId: this.deps.statusInstanceId,
47579
+ localMachineId: loadConfig().machineId || ""
47580
+ });
47581
+ const directTruthSatisfied = meshRecord.source !== "inline_bootstrap" || directTruth.directEvidenceCount > 0;
47582
+ const sourceOfTruth = {
47583
+ membership: meshRecord.source === "inline_cache" ? "coordinator_inline_mesh_cache" : meshRecord.source === "local_config" ? "local_mesh_config" : "inline_bootstrap_snapshot",
47584
+ coordinatorOwnsLiveTruth: directTruthSatisfied,
47585
+ directPeerTruth: {
47586
+ required: requireDirectPeerTruth,
47587
+ satisfied: directTruthSatisfied,
47588
+ directEvidenceCount: directTruth.directEvidenceCount,
47589
+ localConfirmedCount: directTruth.localConfirmedCount,
47590
+ peerAttemptedCount: directTruth.peerAttemptedCount,
47591
+ peerConfirmedCount: directTruth.peerConfirmedCount,
47592
+ unavailableNodeIds: directTruth.unavailableNodeIds
47593
+ }
47594
+ };
47595
+ if (requireDirectPeerTruth && !directTruthSatisfied) {
47596
+ return {
47597
+ success: false,
47598
+ code: "mesh_direct_peer_truth_unavailable",
47599
+ error: "Selected coordinator could not confirm direct mesh truth yet. Bootstrap inventory stays unavailable until direct get_mesh probes succeed.",
47600
+ sourceOfTruth
47601
+ };
46947
47602
  }
46948
- const cached2 = this.inlineMeshCache.get(meshId);
46949
- if (cached2) return { success: true, mesh: cached2 };
46950
- return { success: false, error: "Mesh not found" };
47603
+ return { success: true, mesh: meshRecord.mesh, sourceOfTruth };
46951
47604
  }
46952
47605
  case "create_mesh": {
46953
47606
  const name = typeof args?.name === "string" ? args.name.trim() : "";
@@ -47468,7 +48121,14 @@ var init_router = __esm({
47468
48121
  cliType
47469
48122
  };
47470
48123
  }
47471
- const workspace = typeof coordinatorNode.workspace === "string" ? coordinatorNode.workspace.trim() : "";
48124
+ const sessionHostRecords = this.deps.sessionHostControl?.listSessions ? await this.deps.sessionHostControl.listSessions().catch(() => []) : [];
48125
+ const liveMeshSessions = partitionSessionHostRecords(Array.isArray(sessionHostRecords) ? sessionHostRecords : []).liveRuntimes;
48126
+ const workspace = readLiveMeshNodeWorkspace({
48127
+ meshId,
48128
+ nodeId: String(coordinatorNode.id || coordinatorNode.nodeId || preferredCoordinatorNodeId || ""),
48129
+ liveSessionRecords: liveMeshSessions,
48130
+ allowCoordinatorSession: true
48131
+ }) || (typeof coordinatorNode.workspace === "string" ? coordinatorNode.workspace.trim() : "");
47472
48132
  if (!workspace) return { success: false, error: "Coordinator node workspace required", meshId, cliType };
47473
48133
  if (!cliType) {
47474
48134
  const resolved = await resolveProviderTypeFromPriority({
@@ -47630,7 +48290,7 @@ ${block}`);
47630
48290
  workspace
47631
48291
  };
47632
48292
  }
47633
- const { existsSync: existsSync29, readFileSync: readFileSync22, writeFileSync: writeFileSync17, copyFileSync: copyFileSync5, mkdirSync: mkdirSync21 } = await import("fs");
48293
+ const { existsSync: existsSync30, readFileSync: readFileSync23, writeFileSync: writeFileSync17, copyFileSync: copyFileSync5, mkdirSync: mkdirSync21 } = await import("fs");
47634
48294
  const { dirname: dirname12 } = await import("path");
47635
48295
  const mcpConfigPath = coordinatorSetup.configPath;
47636
48296
  const hermesManualFallback = cliType === "hermes-cli" && configFormat === "hermes_config_yaml" ? createHermesManualMeshCoordinatorSetup(meshId, workspace) : null;
@@ -47673,14 +48333,14 @@ ${block}`);
47673
48333
  if (hermesManualFallback) return returnManualFallback(message);
47674
48334
  return { success: false, code: "mesh_coordinator_config_write_failed", error: message, meshId, cliType, workspace };
47675
48335
  }
47676
- const hadExistingMcpConfig = existsSync29(mcpConfigPath);
48336
+ const hadExistingMcpConfig = existsSync30(mcpConfigPath);
47677
48337
  let existingMcpConfig = hermesBaseConfig?.config || {};
47678
48338
  if (hermesBaseConfig) {
47679
48339
  copyHermesCoordinatorCredentialFiles(hermesBaseConfig.sourceHome, dirname12(mcpConfigPath));
47680
48340
  }
47681
48341
  if (hadExistingMcpConfig) {
47682
48342
  try {
47683
- const parsedExistingMcpConfig = parseMeshCoordinatorMcpConfig(readFileSync22(mcpConfigPath, "utf-8"), configFormat);
48343
+ const parsedExistingMcpConfig = parseMeshCoordinatorMcpConfig(readFileSync23(mcpConfigPath, "utf-8"), configFormat);
47684
48344
  const existingCoordinatorConfig = hermesManualFallback ? stripHermesCoordinatorTempModelProviderOverrides(parsedExistingMcpConfig) : parsedExistingMcpConfig;
47685
48345
  existingMcpConfig = { ...existingMcpConfig, ...existingCoordinatorConfig };
47686
48346
  copyFileSync5(mcpConfigPath, mcpConfigPath + ".backup");
@@ -47776,92 +48436,184 @@ ${block}`);
47776
48436
  const { readLedgerEntries: readLedgerEntries2, getLedgerSummary: getLedgerSummary2 } = await Promise.resolve().then(() => (init_mesh_ledger(), mesh_ledger_exports));
47777
48437
  const ledgerEntries = readLedgerEntries2(meshId, { tail: 20 });
47778
48438
  const ledgerSummary = getLedgerSummary2(meshId);
48439
+ const sessionHostRecords = this.deps.sessionHostControl?.listSessions ? await this.deps.sessionHostControl.listSessions().catch(() => []) : [];
48440
+ const liveMeshSessions = partitionSessionHostRecords(Array.isArray(sessionHostRecords) ? sessionHostRecords : []).liveRuntimes;
48441
+ const localMachineId = loadConfig().machineId || "";
48442
+ const selectedCoordinatorNodeId = readStringValue(
48443
+ mesh.coordinator?.preferredNodeId,
48444
+ mesh.nodes?.[0]?.id,
48445
+ mesh.nodes?.[0]?.nodeId
48446
+ );
48447
+ const inlineCoordinatorNodeId = meshRecord?.inline && Array.isArray(mesh.nodes) ? selectedCoordinatorNodeId : void 0;
48448
+ const refreshedAt = (/* @__PURE__ */ new Date()).toISOString();
47779
48449
  const nodeStatuses = [];
47780
- for (const node of mesh.nodes || []) {
48450
+ for (const [nodeIndex, node] of (mesh.nodes || []).entries()) {
48451
+ const nodeId = String(node.id || node.nodeId || "");
48452
+ const daemonId = readStringValue(node.daemonId);
48453
+ const providerPriority = readProviderPriorityFromPolicy(node.policy);
48454
+ const isSelfNode = Boolean(
48455
+ nodeId && inlineCoordinatorNodeId && nodeId === inlineCoordinatorNodeId
48456
+ ) || Boolean(
48457
+ daemonId && (daemonId === localMachineId || daemonId === this.deps.statusInstanceId)
48458
+ ) || Boolean(meshRecord?.inline && nodeIndex === 0);
47781
48459
  const status = {
47782
- nodeId: node.id || node.nodeId,
48460
+ nodeId,
47783
48461
  machineLabel: node.machineLabel || node.id || node.nodeId,
47784
48462
  workspace: node.workspace,
47785
48463
  repoRoot: node.repoRoot,
47786
48464
  isLocalWorktree: node.isLocalWorktree,
47787
48465
  worktreeBranch: node.worktreeBranch,
47788
- daemonId: node.daemonId,
48466
+ daemonId,
47789
48467
  machineId: node.machineId,
48468
+ machineStatus: node.machineStatus,
47790
48469
  health: "unknown",
47791
48470
  providers: node.providers || [],
47792
- activeSessions: []
48471
+ providerPriority,
48472
+ activeSessions: [],
48473
+ activeSessionDetails: [],
48474
+ launchReady: false
47793
48475
  };
47794
- if (node.workspace && typeof node.workspace === "string") {
47795
- if (!fs10.existsSync(node.workspace) && applyCachedInlineMeshNodeStatus(status, node)) {
47796
- nodeStatuses.push(status);
47797
- continue;
48476
+ if (isSelfNode) {
48477
+ status.connection = {
48478
+ perspective: "selected_coordinator",
48479
+ source: "mesh_peer_status",
48480
+ state: "self",
48481
+ transport: "local",
48482
+ reported: true,
48483
+ reason: "Selected coordinator daemon",
48484
+ lastStateChangeAt: refreshedAt
48485
+ };
48486
+ } else if (daemonId) {
48487
+ const connection = this.deps.getMeshPeerConnectionStatus?.(daemonId);
48488
+ status.connection = connection ?? {
48489
+ perspective: "selected_coordinator",
48490
+ source: "not_reported",
48491
+ state: "unknown",
48492
+ transport: "unknown",
48493
+ reported: false,
48494
+ reason: "No live mesh peer telemetry reported by the selected coordinator yet."
48495
+ };
48496
+ } else {
48497
+ status.connection = {
48498
+ perspective: "selected_coordinator",
48499
+ source: "not_reported",
48500
+ state: "unknown",
48501
+ transport: "unknown",
48502
+ reported: false,
48503
+ reason: "Node has no daemon id, so mesh transport cannot be reported from the selected coordinator."
48504
+ };
48505
+ }
48506
+ const matchedLiveSessionRecords = collectLiveMeshSessionRecords({
48507
+ meshId,
48508
+ node,
48509
+ nodeId,
48510
+ liveSessionRecords: liveMeshSessions,
48511
+ allowCoordinatorSession: nodeId === selectedCoordinatorNodeId
48512
+ });
48513
+ const workspace = readLiveMeshNodeWorkspace({
48514
+ meshId,
48515
+ nodeId,
48516
+ liveSessionRecords: matchedLiveSessionRecords,
48517
+ allowCoordinatorSession: nodeId === selectedCoordinatorNodeId
48518
+ }) || (typeof node.workspace === "string" ? node.workspace : "");
48519
+ status.workspace = workspace || node.workspace;
48520
+ if (matchedLiveSessionRecords.length > 0) {
48521
+ const sessionIds = matchedLiveSessionRecords.map((record2) => typeof record2?.sessionId === "string" ? record2.sessionId : "").filter(Boolean);
48522
+ const providerTypes = matchedLiveSessionRecords.map((record2) => readStringValue(record2?.providerType)).filter(Boolean);
48523
+ status.activeSessions = sessionIds;
48524
+ status.activeSessionDetails = matchedLiveSessionRecords.map(summarizeMeshSessionRecord);
48525
+ if (providerTypes.length > 0) {
48526
+ status.providers = Array.from(/* @__PURE__ */ new Set([...Array.isArray(status.providers) ? status.providers : [], ...providerTypes]));
47798
48527
  }
47799
- try {
47800
- const { execFile: execFile3 } = await import("child_process");
47801
- const { promisify: promisify3 } = await import("util");
47802
- const execFileAsync3 = promisify3(execFile3);
47803
- const runGit2 = async (args2) => {
47804
- const result = await execFileAsync3("git", ["-C", node.workspace, ...args2], {
47805
- encoding: "utf8",
47806
- timeout: 1e4
47807
- });
47808
- return result.stdout.trim();
47809
- };
47810
- const branch = await runGit2(["branch", "--show-current"]).catch(() => "");
47811
- const porc = await runGit2(["status", "--porcelain"]).catch(() => "");
47812
- const headCommit = await runGit2(["rev-parse", "--short", "HEAD"]).catch(() => null);
47813
- const headMessage = await runGit2(["log", "-1", "--format=%s"]).catch(() => null);
47814
- const upstream = await runGit2(["rev-parse", "--abbrev-ref", "@{upstream}"]).catch(() => null);
47815
- const aheadBehind = await runGit2(["rev-list", "--left-right", "--count", "@{upstream}...HEAD"]).catch(() => "");
47816
- const stashCount = await runGit2(["stash", "list"]).catch(() => "");
47817
- let ahead = 0, behind = 0;
47818
- if (aheadBehind) {
47819
- const parts = aheadBehind.split(/\s+/);
47820
- if (parts.length >= 2) {
47821
- behind = parseInt(parts[0], 10) || 0;
47822
- ahead = parseInt(parts[1], 10) || 0;
48528
+ }
48529
+ if (workspace) {
48530
+ if (!fs10.existsSync(workspace)) {
48531
+ const inlineTransitGit = buildInlineMeshTransitGitStatus(node);
48532
+ let remoteProbeApplied = false;
48533
+ if (inlineTransitGit) {
48534
+ status.git = inlineTransitGit;
48535
+ status.health = inlineTransitGit.isGitRepo ? deriveMeshNodeHealthFromGit(inlineTransitGit) : "degraded";
48536
+ remoteProbeApplied = true;
48537
+ } else if (!isSelfNode && daemonId && this.deps.dispatchMeshCommand) {
48538
+ try {
48539
+ const remoteGit = await probeRemoteMeshGitStatus({
48540
+ dispatchMeshCommand: this.deps.dispatchMeshCommand,
48541
+ daemonId,
48542
+ workspace,
48543
+ timeoutMs: 8e3
48544
+ });
48545
+ if (remoteGit) {
48546
+ status.git = remoteGit;
48547
+ status.health = remoteGit.isGitRepo ? deriveMeshNodeHealthFromGit(remoteGit) : "degraded";
48548
+ recordInlineMeshDirectGitTruth(node, remoteGit, "selected_coordinator_mesh_p2p_git");
48549
+ remoteProbeApplied = true;
48550
+ }
48551
+ } catch {
48552
+ const refreshedConnection = this.deps.getMeshPeerConnectionStatus?.(daemonId);
48553
+ const refreshedConnectionState = readStringValue(refreshedConnection?.state);
48554
+ if (refreshedConnection && refreshedConnectionState === "connected") {
48555
+ status.connection = refreshedConnection;
48556
+ try {
48557
+ const remoteGit = await probeRemoteMeshGitStatus({
48558
+ dispatchMeshCommand: this.deps.dispatchMeshCommand,
48559
+ daemonId,
48560
+ workspace,
48561
+ timeoutMs: 12e3
48562
+ });
48563
+ if (remoteGit) {
48564
+ status.git = remoteGit;
48565
+ status.health = remoteGit.isGitRepo ? deriveMeshNodeHealthFromGit(remoteGit) : "degraded";
48566
+ recordInlineMeshDirectGitTruth(node, remoteGit, "selected_coordinator_mesh_p2p_git");
48567
+ remoteProbeApplied = true;
48568
+ }
48569
+ } catch {
48570
+ }
48571
+ }
47823
48572
  }
47824
48573
  }
47825
- const dirty = porc.length > 0;
47826
- const lines = porc ? porc.split("\n").filter(Boolean) : [];
47827
- let staged = 0, modified = 0, untracked = 0, deleted = 0, renamed2 = 0;
47828
- for (const line of lines) {
47829
- const xy = line.slice(0, 2);
47830
- if (xy[0] !== " " && xy[0] !== "?") staged++;
47831
- if (xy[1] === "M") modified++;
47832
- if (xy[1] === "D") deleted++;
47833
- if (xy[0] === "R" || xy[1] === "R") renamed2++;
47834
- if (xy === "??") untracked++;
48574
+ if (!remoteProbeApplied) {
48575
+ const connectionState = readStringValue(status.connection?.state);
48576
+ const pendingPeerGitProbe = !inlineTransitGit && !isSelfNode && !!daemonId && (readStringValue(status.machineStatus) === "online" || readStringValue(status.health) === "online" || connectionState === "connecting" || connectionState === "connected" || connectionState === "unknown");
48577
+ if (pendingPeerGitProbe) {
48578
+ status.gitProbePending = true;
48579
+ status.health = "unknown";
48580
+ }
48581
+ if (applyCachedInlineMeshNodeStatus(
48582
+ status,
48583
+ node,
48584
+ pendingPeerGitProbe ? { skipGit: true, skipError: true, skipHealth: true } : void 0
48585
+ )) {
48586
+ finalizeMeshNodeStatus({ status, node, daemonId, isSelfNode });
48587
+ nodeStatuses.push(status);
48588
+ continue;
48589
+ }
48590
+ if (meshRecord?.source === "inline_cache" && !isSelfNode) {
48591
+ finalizeMeshNodeStatus({ status, node, daemonId, isSelfNode });
48592
+ nodeStatuses.push(status);
48593
+ continue;
48594
+ }
47835
48595
  }
47836
- status.git = {
47837
- workspace: node.workspace,
47838
- repoRoot: node.workspace,
47839
- isGitRepo: true,
47840
- branch: branch || null,
47841
- headCommit,
47842
- headMessage,
47843
- upstream,
47844
- ahead,
47845
- behind,
47846
- staged,
47847
- modified,
47848
- untracked,
47849
- deleted,
47850
- renamed: renamed2,
47851
- hasConflicts: false,
47852
- conflictFiles: [],
47853
- stashCount: stashCount ? stashCount.split("\n").filter(Boolean).length : 0,
47854
- lastCheckedAt: Date.now()
47855
- };
47856
- status.health = branch ? dirty ? "dirty" : "online" : "degraded";
47857
- } catch {
47858
- if (!applyCachedInlineMeshNodeStatus(status, node)) {
47859
- status.health = "degraded";
48596
+ } else {
48597
+ try {
48598
+ const gitStatus = await getGitRepoStatus(workspace, { timeoutMs: 1e4, refreshUpstream: true });
48599
+ status.git = gitStatus;
48600
+ recordInlineMeshDirectGitTruth(node, gitStatus, "selected_coordinator_local_git");
48601
+ if (gitStatus.isGitRepo) {
48602
+ status.health = deriveMeshNodeHealthFromGit(gitStatus);
48603
+ } else {
48604
+ status.health = "degraded";
48605
+ if (gitStatus.error && !status.error) status.error = gitStatus.error;
48606
+ }
48607
+ } catch {
48608
+ if (!applyCachedInlineMeshNodeStatus(status, node)) {
48609
+ status.health = "degraded";
48610
+ }
47860
48611
  }
47861
48612
  }
47862
48613
  } else {
47863
48614
  applyCachedInlineMeshNodeStatus(status, node);
47864
48615
  }
48616
+ finalizeMeshNodeStatus({ status, node, daemonId, isSelfNode });
47865
48617
  nodeStatuses.push(status);
47866
48618
  }
47867
48619
  return {
@@ -47870,6 +48622,12 @@ ${block}`);
47870
48622
  meshName: mesh.name,
47871
48623
  repoIdentity: mesh.repoIdentity,
47872
48624
  defaultBranch: mesh.defaultBranch,
48625
+ refreshedAt: (/* @__PURE__ */ new Date()).toISOString(),
48626
+ sourceOfTruth: {
48627
+ membership: meshRecord?.source === "inline_cache" ? "coordinator_inline_mesh_cache" : meshRecord?.source === "local_config" ? "local_mesh_config" : "inline_bootstrap_snapshot",
48628
+ coordinatorOwnsLiveTruth: meshRecord?.source !== "inline_bootstrap",
48629
+ historicalEvidenceOnly: ["recoveryHints", "ledger.summary", "queue.summary"]
48630
+ },
47873
48631
  nodes: nodeStatuses,
47874
48632
  queue: { tasks: queue, summary: queueSummary },
47875
48633
  ledger: { entries: ledgerEntries, summary: ledgerSummary }
@@ -55948,6 +56706,7 @@ async function initDaemonComponents(config2) {
55948
56706
  sessionHostControl: config2.sessionHostControl,
55949
56707
  statusInstanceId: config2.statusInstanceId,
55950
56708
  statusVersion: config2.statusVersion,
56709
+ getMeshPeerConnectionStatus: config2.getMeshPeerConnectionStatus,
55951
56710
  getCdpLogFn: config2.getCdpLogFn || ((ideType) => LOG.forComponent(`CDP:${ideType}`).asLogFn())
55952
56711
  });
55953
56712
  poller = new AgentStreamPoller({
@@ -56249,6 +57008,7 @@ __export(src_exports, {
56249
57008
  prepareSessionChatTailUpdate: () => prepareSessionChatTailUpdate,
56250
57009
  prepareSessionModalUpdate: () => prepareSessionModalUpdate,
56251
57010
  probeCdpPort: () => probeCdpPort,
57011
+ queuePendingMeshCoordinatorEvent: () => queuePendingMeshCoordinatorEvent,
56252
57012
  readChatHistory: () => readChatHistory,
56253
57013
  readLedgerEntries: () => readLedgerEntries,
56254
57014
  readLedgerSlice: () => readLedgerSlice,
@@ -58292,7 +59052,7 @@ var require_filesystem = __commonJS({
58292
59052
  var LDD_PATH = "/usr/bin/ldd";
58293
59053
  var SELF_PATH = "/proc/self/exe";
58294
59054
  var MAX_LENGTH = 2048;
58295
- var readFileSync22 = (path35) => {
59055
+ var readFileSync23 = (path35) => {
58296
59056
  const fd = fs20.openSync(path35, "r");
58297
59057
  const buffer = Buffer.alloc(MAX_LENGTH);
58298
59058
  const bytesRead = fs20.readSync(fd, buffer, 0, MAX_LENGTH, 0);
@@ -58317,7 +59077,7 @@ var require_filesystem = __commonJS({
58317
59077
  module2.exports = {
58318
59078
  LDD_PATH,
58319
59079
  SELF_PATH,
58320
- readFileSync: readFileSync22,
59080
+ readFileSync: readFileSync23,
58321
59081
  readFile: readFile2
58322
59082
  };
58323
59083
  }
@@ -58366,7 +59126,7 @@ var require_detect_libc = __commonJS({
58366
59126
  "use strict";
58367
59127
  var childProcess = require("child_process");
58368
59128
  var { isLinux: isLinux2, getReport } = require_process();
58369
- var { LDD_PATH, SELF_PATH, readFile: readFile2, readFileSync: readFileSync22 } = require_filesystem();
59129
+ var { LDD_PATH, SELF_PATH, readFile: readFile2, readFileSync: readFileSync23 } = require_filesystem();
58370
59130
  var { interpreterPath } = require_elf();
58371
59131
  var cachedFamilyInterpreter;
58372
59132
  var cachedFamilyFilesystem;
@@ -58458,7 +59218,7 @@ var require_detect_libc = __commonJS({
58458
59218
  }
58459
59219
  cachedFamilyFilesystem = null;
58460
59220
  try {
58461
- const lddContent = readFileSync22(LDD_PATH);
59221
+ const lddContent = readFileSync23(LDD_PATH);
58462
59222
  cachedFamilyFilesystem = getFamilyFromLddContent(lddContent);
58463
59223
  } catch (e) {
58464
59224
  }
@@ -58483,7 +59243,7 @@ var require_detect_libc = __commonJS({
58483
59243
  }
58484
59244
  cachedFamilyInterpreter = null;
58485
59245
  try {
58486
- const selfContent = readFileSync22(SELF_PATH);
59246
+ const selfContent = readFileSync23(SELF_PATH);
58487
59247
  const path35 = interpreterPath(selfContent);
58488
59248
  cachedFamilyInterpreter = familyFromInterpreterPath(path35);
58489
59249
  } catch (e) {
@@ -58547,7 +59307,7 @@ var require_detect_libc = __commonJS({
58547
59307
  }
58548
59308
  cachedVersionFilesystem = null;
58549
59309
  try {
58550
- const lddContent = readFileSync22(LDD_PATH);
59310
+ const lddContent = readFileSync23(LDD_PATH);
58551
59311
  const versionMatch = lddContent.match(RE_GLIBC_VERSION);
58552
59312
  if (versionMatch) {
58553
59313
  cachedVersionFilesystem = versionMatch[1];
@@ -65989,25 +66749,25 @@ function resolvePackageVersion(options) {
65989
66749
  const injectedVersion = options?.injectedVersion || "unknown";
65990
66750
  const dir = options?.dirname || __dirname;
65991
66751
  const possiblePaths = [
65992
- (0, import_path7.join)(dir, "..", "..", "package.json"),
65993
- (0, import_path7.join)(dir, "..", "package.json"),
65994
- (0, import_path7.join)(dir, "package.json")
66752
+ (0, import_path8.join)(dir, "..", "..", "package.json"),
66753
+ (0, import_path8.join)(dir, "..", "package.json"),
66754
+ (0, import_path8.join)(dir, "package.json")
65995
66755
  ];
65996
66756
  for (const p of possiblePaths) {
65997
66757
  try {
65998
- const data = JSON.parse((0, import_fs11.readFileSync)(p, "utf-8"));
66758
+ const data = JSON.parse((0, import_fs12.readFileSync)(p, "utf-8"));
65999
66759
  if (data.version) return data.version;
66000
66760
  } catch {
66001
66761
  }
66002
66762
  }
66003
66763
  return injectedVersion;
66004
66764
  }
66005
- var import_fs11, import_path7;
66765
+ var import_fs12, import_path8;
66006
66766
  var init_version = __esm({
66007
66767
  "src/version.ts"() {
66008
66768
  "use strict";
66009
- import_fs11 = require("fs");
66010
- import_path7 = require("path");
66769
+ import_fs12 = require("fs");
66770
+ import_path8 = require("path");
66011
66771
  }
66012
66772
  });
66013
66773
 
@@ -66040,11 +66800,30 @@ var init_daemon_mesh_manager = __esm({
66040
66800
  nodeDatachannel = null;
66041
66801
  peers = /* @__PURE__ */ new Map();
66042
66802
  // Map<targetDaemonId, PeerEntry>
66803
+ peerSnapshots = /* @__PURE__ */ new Map();
66043
66804
  pendingRequests = /* @__PURE__ */ new Map();
66044
66805
  commandCallback;
66045
66806
  p2pFailure(message, command, targetDaemonId) {
66046
66807
  return new P2pRelayFailureError(message, { command, targetDaemonId });
66047
66808
  }
66809
+ updatePeerSnapshot(targetDaemonId, state, patch = {}) {
66810
+ const previous = this.peerSnapshots.get(targetDaemonId);
66811
+ const now = (/* @__PURE__ */ new Date()).toISOString();
66812
+ this.peerSnapshots.set(targetDaemonId, {
66813
+ perspective: "selected_coordinator",
66814
+ source: "mesh_peer_status",
66815
+ reported: true,
66816
+ state,
66817
+ transport: patch.transport ?? previous?.transport ?? "unknown",
66818
+ reason: patch.reason ?? previous?.reason,
66819
+ lastStateChangeAt: now,
66820
+ lastConnectedAt: patch.lastConnectedAt ?? previous?.lastConnectedAt,
66821
+ lastCommandAt: patch.lastCommandAt ?? previous?.lastCommandAt
66822
+ });
66823
+ }
66824
+ getPeerConnectionStatus(targetDaemonId) {
66825
+ return this.peerSnapshots.get(targetDaemonId) ?? null;
66826
+ }
66048
66827
  invalidatePeer(targetDaemonId, reason, options = {}) {
66049
66828
  const peer = this.peers.get(targetDaemonId);
66050
66829
  if (peer?.commandQueue) {
@@ -66059,6 +66838,11 @@ var init_daemon_mesh_manager = __esm({
66059
66838
  pending.reject(this.p2pFailure(reason, pending.command, targetDaemonId));
66060
66839
  }
66061
66840
  }
66841
+ const snapshotState = peer?.state === "closed" ? "closed" : peer?.state === "disconnected" ? "disconnected" : "failed";
66842
+ this.updatePeerSnapshot(targetDaemonId, snapshotState, {
66843
+ reason,
66844
+ transport: peer?.isRelay === true ? "relay" : peer?.isRelay === false ? "direct" : "unknown"
66845
+ });
66062
66846
  if (options.closeResources !== false && peer) {
66063
66847
  try {
66064
66848
  peer.dataChannel?.close?.();
@@ -66091,6 +66875,7 @@ var init_daemon_mesh_manager = __esm({
66091
66875
  "send_chat",
66092
66876
  "read_chat",
66093
66877
  "get_chat_debug_bundle",
66878
+ "get_pending_mesh_events",
66094
66879
  "git_status",
66095
66880
  "git_diff_summary",
66096
66881
  "launch_cli",
@@ -66178,6 +66963,20 @@ var init_daemon_mesh_manager = __esm({
66178
66963
  if (!peer) {
66179
66964
  throw this.p2pFailure("Failed to initiate P2P connection entry", command, targetDaemonId);
66180
66965
  }
66966
+ const lastCommandAt = (/* @__PURE__ */ new Date()).toISOString();
66967
+ if (peer.state === "connected") {
66968
+ this.updatePeerSnapshot(targetDaemonId, "connected", {
66969
+ transport: peer.isRelay === true ? "relay" : peer.isRelay === false ? "direct" : "unknown",
66970
+ lastConnectedAt: this.peerSnapshots.get(targetDaemonId)?.lastConnectedAt,
66971
+ lastCommandAt
66972
+ });
66973
+ } else {
66974
+ this.updatePeerSnapshot(targetDaemonId, "connecting", {
66975
+ transport: peer.isRelay === true ? "relay" : peer.isRelay === false ? "direct" : "unknown",
66976
+ reason: "Waiting for mesh DataChannel to open.",
66977
+ lastCommandAt
66978
+ });
66979
+ }
66181
66980
  return new Promise((resolve20, reject) => {
66182
66981
  const requestId = `req_${Date.now()}_${Math.random().toString(36).slice(2, 8)}`;
66183
66982
  const timer = setTimeout(() => {
@@ -66321,6 +67120,9 @@ var init_daemon_mesh_manager = __esm({
66321
67120
  remoteDescriptionSet: false
66322
67121
  };
66323
67122
  this.peers.set(targetDaemonId, entry);
67123
+ this.updatePeerSnapshot(targetDaemonId, "connecting", {
67124
+ reason: isInitiator ? "P2P mesh connection initiated by the selected coordinator." : "Waiting for the remote daemon to finish the mesh DataChannel handshake."
67125
+ });
66324
67126
  pc.onLocalDescription((sdp, type2) => {
66325
67127
  this.serverConn.sendMeshCommand(targetDaemonId, type2 === "offer" ? "mesh_p2p_offer" : "mesh_p2p_answer", { sdp, type: type2 });
66326
67128
  });
@@ -66331,7 +67133,26 @@ var init_daemon_mesh_manager = __esm({
66331
67133
  LOG.info("Mesh", `[Mesh] P2P state with ${targetDaemonId.slice(0, 12)}: ${state}`);
66332
67134
  if (state === "connected") {
66333
67135
  entry.state = "connected";
67136
+ let transport = "unknown";
67137
+ try {
67138
+ const pair = pc.getSelectedCandidatePair?.();
67139
+ if (pair) {
67140
+ const localType = pair.local?.type || "unknown";
67141
+ const remoteType = pair.remote?.type || "unknown";
67142
+ entry.isRelay = localType === "relay" || remoteType === "relay";
67143
+ transport = entry.isRelay ? "relay" : "direct";
67144
+ LOG.info("Mesh", `[Mesh] Candidate pair with ${targetDaemonId.slice(0, 12)}: local=${localType} remote=${remoteType} \u2192 ${transport}`);
67145
+ }
67146
+ } catch {
67147
+ transport = entry.isRelay === true ? "relay" : entry.isRelay === false ? "direct" : "unknown";
67148
+ }
67149
+ this.updatePeerSnapshot(targetDaemonId, "connected", {
67150
+ transport,
67151
+ reason: transport === "relay" ? "Connected over TURN relay." : transport === "direct" ? "Connected directly peer-to-peer." : "Connected, but selected candidate pair details are unavailable.",
67152
+ lastConnectedAt: (/* @__PURE__ */ new Date()).toISOString()
67153
+ });
66334
67154
  } else if (state === "failed" || state === "closed" || state === "disconnected") {
67155
+ entry.state = state;
66335
67156
  this.invalidatePeer(targetDaemonId, `P2P state changed to ${state}`, { rejectPending: true, closeResources: false });
66336
67157
  }
66337
67158
  });
@@ -66349,6 +67170,11 @@ var init_daemon_mesh_manager = __esm({
66349
67170
  dc.onOpen(() => {
66350
67171
  LOG.info("Mesh", `[Mesh] DataChannel OPEN with ${targetDaemonId.slice(0, 12)}`);
66351
67172
  entry.state = "connected";
67173
+ this.updatePeerSnapshot(targetDaemonId, "connected", {
67174
+ transport: entry.isRelay === true ? "relay" : entry.isRelay === false ? "direct" : "unknown",
67175
+ reason: entry.isRelay === true ? "Connected over TURN relay." : entry.isRelay === false ? "Connected directly peer-to-peer." : "DataChannel open; transport details not reported yet.",
67176
+ lastConnectedAt: (/* @__PURE__ */ new Date()).toISOString()
67177
+ });
66352
67178
  if (entry.commandQueue) {
66353
67179
  const queue = entry.commandQueue;
66354
67180
  entry.commandQueue = [];
@@ -66628,6 +67454,7 @@ var init_adhdev_daemon = __esm({
66628
67454
  "use strict";
66629
67455
  init_server_connection();
66630
67456
  init_src();
67457
+ init_mesh_events();
66631
67458
  init_daemon_p2p2();
66632
67459
  init_screenshot_controller();
66633
67460
  init_session_host();
@@ -66644,7 +67471,7 @@ var init_adhdev_daemon = __esm({
66644
67471
  init_version();
66645
67472
  init_src();
66646
67473
  init_runtime_defaults();
66647
- pkgVersion = resolvePackageVersion({ injectedVersion: "0.9.82-rc.3" });
67474
+ pkgVersion = resolvePackageVersion({ injectedVersion: "0.9.82-rc.31" });
66648
67475
  AdhdevDaemon = class _AdhdevDaemon {
66649
67476
  localHttpServer = null;
66650
67477
  localWss = null;
@@ -67168,6 +67995,7 @@ ${err?.stack || ""}`);
67168
67995
  if (!this.meshManager) throw new Error("Mesh manager not initialized");
67169
67996
  return this.meshManager.sendCommand(daemonId, command, args);
67170
67997
  },
67998
+ getMeshPeerConnectionStatus: (daemonId) => this.meshManager?.getPeerConnectionStatus(daemonId) ?? null,
67171
67999
  onStatusChange: () => {
67172
68000
  this.invalidateHotChatSnapshotCache();
67173
68001
  this.statusReporter?.onStatusChange();
@@ -67537,6 +68365,7 @@ ${err?.stack || ""}`);
67537
68365
  const meshId = this.readMeshString(settings.meshNodeFor);
67538
68366
  const coordinatorDaemonId = this.readMeshString(settings.meshCoordinatorDaemonId);
67539
68367
  if (!meshId || !coordinatorDaemonId) return;
68368
+ const relayTimestamp = typeof event.timestamp === "number" && Number.isFinite(event.timestamp) ? event.timestamp : this.readMeshString(event.timestamp) || void 0;
67540
68369
  const payload = {
67541
68370
  event: this.readMeshString(event.event),
67542
68371
  meshId,
@@ -67545,7 +68374,8 @@ ${err?.stack || ""}`);
67545
68374
  targetSessionId: this.readMeshString(event.targetSessionId) || instanceId,
67546
68375
  providerType: this.readMeshString(event.providerType),
67547
68376
  providerSessionId: this.readMeshString(event.providerSessionId),
67548
- finalSummary: this.readMeshString(event.finalSummary) || this.readMeshString(event.summary)
68377
+ finalSummary: this.readMeshString(event.finalSummary) || this.readMeshString(event.summary),
68378
+ ...relayTimestamp !== void 0 ? { timestamp: relayTimestamp } : {}
67549
68379
  };
67550
68380
  if (coordinatorDaemonId === localDaemonId) {
67551
68381
  try {
@@ -67560,6 +68390,22 @@ ${err?.stack || ""}`);
67560
68390
  await this.meshManager.sendCommand(coordinatorDaemonId, "mesh_forward_event", payload);
67561
68391
  LOG.info("MeshEvents", `Relayed ${payload.event} for mesh ${meshId} to coordinator daemon ${coordinatorDaemonId.slice(0, 12)}\u2026`);
67562
68392
  } catch (error48) {
68393
+ queuePendingMeshCoordinatorEvent({
68394
+ event: payload.event,
68395
+ meshId,
68396
+ nodeLabel: payload.nodeId ? `Node '${payload.nodeId}'` : payload.workspace ? `Agent at ${payload.workspace}` : "Remote agent",
68397
+ nodeId: payload.nodeId || void 0,
68398
+ workspace: payload.workspace || void 0,
68399
+ metadataEvent: {
68400
+ targetSessionId: payload.targetSessionId,
68401
+ providerType: payload.providerType,
68402
+ providerSessionId: payload.providerSessionId,
68403
+ finalSummary: payload.finalSummary,
68404
+ workspace: payload.workspace,
68405
+ ...payload.timestamp !== void 0 ? { timestamp: payload.timestamp } : {}
68406
+ },
68407
+ queuedAt: Date.now()
68408
+ });
67563
68409
  LOG.warn("MeshEvents", `Failed to relay ${payload.event} for mesh ${meshId}: ${error48?.message || error48}`);
67564
68410
  }
67565
68411
  }
@@ -82608,7 +83454,7 @@ var require_buffer_list = __commonJS({
82608
83454
  }
82609
83455
  }, {
82610
83456
  key: "join",
82611
- value: function join36(s) {
83457
+ value: function join37(s) {
82612
83458
  if (this.length === 0) return "";
82613
83459
  var p = this.head;
82614
83460
  var ret = "" + p.data;
@@ -96667,13 +97513,13 @@ function splitStringBySpace(str2) {
96667
97513
  }
96668
97514
  return pieces;
96669
97515
  }
96670
- var import_chardet, import_child_process14, import_fs12, import_node_path3, import_node_os3, import_node_crypto3, import_iconv_lite, ExternalEditor;
97516
+ var import_chardet, import_child_process14, import_fs13, import_node_path3, import_node_os3, import_node_crypto3, import_iconv_lite, ExternalEditor;
96671
97517
  var init_esm4 = __esm({
96672
97518
  "../../node_modules/@inquirer/external-editor/dist/esm/index.js"() {
96673
97519
  "use strict";
96674
97520
  import_chardet = __toESM(require_lib2(), 1);
96675
97521
  import_child_process14 = require("child_process");
96676
- import_fs12 = require("fs");
97522
+ import_fs13 = require("fs");
96677
97523
  import_node_path3 = __toESM(require("path"), 1);
96678
97524
  import_node_os3 = __toESM(require("os"), 1);
96679
97525
  import_node_crypto3 = require("crypto");
@@ -96749,14 +97595,14 @@ var init_esm4 = __esm({
96749
97595
  if (Object.prototype.hasOwnProperty.call(this.fileOptions, "mode")) {
96750
97596
  opt.mode = this.fileOptions.mode;
96751
97597
  }
96752
- (0, import_fs12.writeFileSync)(this.tempFile, this.text, opt);
97598
+ (0, import_fs13.writeFileSync)(this.tempFile, this.text, opt);
96753
97599
  } catch (createFileError) {
96754
97600
  throw new CreateFileError(createFileError);
96755
97601
  }
96756
97602
  }
96757
97603
  readTemporaryFile() {
96758
97604
  try {
96759
- const tempFileBuffer = (0, import_fs12.readFileSync)(this.tempFile);
97605
+ const tempFileBuffer = (0, import_fs13.readFileSync)(this.tempFile);
96760
97606
  if (tempFileBuffer.length === 0) {
96761
97607
  this.text = "";
96762
97608
  } else {
@@ -96772,7 +97618,7 @@ var init_esm4 = __esm({
96772
97618
  }
96773
97619
  removeTemporaryFile() {
96774
97620
  try {
96775
- (0, import_fs12.unlinkSync)(this.tempFile);
97621
+ (0, import_fs13.unlinkSync)(this.tempFile);
96776
97622
  } catch (removeFileError) {
96777
97623
  throw new RemoveFileError(removeFileError);
96778
97624
  }