@adhdev/daemon-core 0.9.82-rc.2 → 0.9.82-rc.21

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.mjs CHANGED
@@ -1890,10 +1890,18 @@ __export(mesh_events_exports, {
1890
1890
  drainPendingMeshCoordinatorEvents: () => drainPendingMeshCoordinatorEvents,
1891
1891
  getPendingMeshCoordinatorEvents: () => getPendingMeshCoordinatorEvents,
1892
1892
  handleMeshForwardEvent: () => handleMeshForwardEvent,
1893
+ queuePendingMeshCoordinatorEvent: () => queuePendingMeshCoordinatorEvent,
1893
1894
  setupMeshEventForwarding: () => setupMeshEventForwarding,
1894
1895
  triggerMeshQueue: () => triggerMeshQueue,
1895
1896
  tryAssignQueueTask: () => tryAssignQueueTask
1896
1897
  });
1898
+ function queuePendingMeshCoordinatorEvent(event) {
1899
+ if (pendingMeshCoordinatorEvents.length >= MAX_PENDING_EVENTS) {
1900
+ return false;
1901
+ }
1902
+ pendingMeshCoordinatorEvents.push(event);
1903
+ return true;
1904
+ }
1897
1905
  function drainPendingMeshCoordinatorEvents() {
1898
1906
  return pendingMeshCoordinatorEvents.splice(0);
1899
1907
  }
@@ -2465,17 +2473,18 @@ function injectMeshSystemMessage(components, args) {
2465
2473
  return true;
2466
2474
  });
2467
2475
  if (coordinatorInstances.length === 0) {
2468
- if (pendingMeshCoordinatorEvents.length < MAX_PENDING_EVENTS) {
2469
- pendingMeshCoordinatorEvents.push({
2470
- event: args.event,
2471
- meshId: args.meshId,
2472
- nodeLabel: args.nodeLabel,
2473
- metadataEvent: {
2474
- ...args.metadataEvent,
2475
- ...recoveryContext ? { recoveryContext } : {}
2476
- },
2477
- queuedAt: Date.now()
2478
- });
2476
+ if (queuePendingMeshCoordinatorEvent({
2477
+ event: args.event,
2478
+ meshId: args.meshId,
2479
+ nodeLabel: args.nodeLabel,
2480
+ nodeId: args.nodeId || void 0,
2481
+ workspace: readNonEmptyString(args.metadataEvent.workspace),
2482
+ metadataEvent: {
2483
+ ...args.metadataEvent,
2484
+ ...recoveryContext ? { recoveryContext } : {}
2485
+ },
2486
+ queuedAt: Date.now()
2487
+ })) {
2479
2488
  LOG.info("MeshEvents", `Queued ${args.event} for MCP coordinator (mesh ${args.meshId})`);
2480
2489
  }
2481
2490
  return { success: true, forwarded: 0 };
@@ -5676,8 +5685,14 @@ async function getGitRepoStatus(workspace, options = {}) {
5676
5685
  const includeSubmodules = options.includeSubmodules !== false;
5677
5686
  try {
5678
5687
  const repo = await resolveGitRepository(workspace, options);
5679
- const statusOutput = await runGit(repo, ["status", "--porcelain=v2", "--branch"], options);
5680
- const parsed = parsePorcelainV2Status(statusOutput.stdout);
5688
+ let parsed = await readPorcelainStatus(repo, options);
5689
+ let upstreamProbe = getInitialUpstreamProbe(parsed);
5690
+ if (options.refreshUpstream) {
5691
+ upstreamProbe = await refreshTrackedUpstream(repo, parsed, options);
5692
+ if (upstreamProbe.upstreamStatus === "fresh") {
5693
+ parsed = await readPorcelainStatus(repo, options);
5694
+ }
5695
+ }
5681
5696
  const head = await readHead(repo, options);
5682
5697
  const stashCount = await readStashCount(repo, options);
5683
5698
  let submodules;
@@ -5692,6 +5707,9 @@ async function getGitRepoStatus(workspace, options = {}) {
5692
5707
  headCommit: head.commit,
5693
5708
  headMessage: head.message,
5694
5709
  upstream: parsed.upstream,
5710
+ upstreamStatus: parsed.upstream ? upstreamProbe.upstreamStatus : "no_upstream",
5711
+ upstreamFetchedAt: upstreamProbe.upstreamFetchedAt,
5712
+ upstreamFetchError: upstreamProbe.upstreamFetchError,
5695
5713
  ahead: parsed.ahead,
5696
5714
  behind: parsed.behind,
5697
5715
  staged: parsed.staged,
@@ -5716,6 +5734,60 @@ async function getGitRepoStatus(workspace, options = {}) {
5716
5734
  );
5717
5735
  }
5718
5736
  }
5737
+ async function readPorcelainStatus(repo, options) {
5738
+ const statusOutput = await runGit(repo, ["status", "--porcelain=v2", "--branch"], options);
5739
+ return parsePorcelainV2Status(statusOutput.stdout);
5740
+ }
5741
+ function getInitialUpstreamProbe(parsed) {
5742
+ return {
5743
+ upstreamStatus: parsed.upstream ? "unchecked" : "no_upstream"
5744
+ };
5745
+ }
5746
+ async function refreshTrackedUpstream(repo, parsed, options) {
5747
+ if (!parsed.upstream || !parsed.branch) {
5748
+ return { upstreamStatus: "no_upstream" };
5749
+ }
5750
+ const remoteName = await readBranchRemote(repo, parsed.branch, options) ?? inferRemoteName(parsed.upstream);
5751
+ if (!remoteName) {
5752
+ return {
5753
+ upstreamStatus: "stale",
5754
+ upstreamFetchError: `Unable to resolve remote for upstream '${parsed.upstream}'`
5755
+ };
5756
+ }
5757
+ try {
5758
+ await runGit(repo, ["fetch", "--quiet", "--prune", "--no-tags", remoteName], options);
5759
+ return {
5760
+ upstreamStatus: "fresh",
5761
+ upstreamFetchedAt: Date.now()
5762
+ };
5763
+ } catch (error) {
5764
+ return {
5765
+ upstreamStatus: "stale",
5766
+ upstreamFetchError: formatGitError(error)
5767
+ };
5768
+ }
5769
+ }
5770
+ async function readBranchRemote(repo, branch, options) {
5771
+ try {
5772
+ const result = await runGit(repo, ["config", "--get", `branch.${branch}.remote`], options);
5773
+ return result.stdout.trim() || null;
5774
+ } catch {
5775
+ return null;
5776
+ }
5777
+ }
5778
+ function inferRemoteName(upstream) {
5779
+ const [remoteName] = upstream.split("/");
5780
+ return remoteName?.trim() || null;
5781
+ }
5782
+ function formatGitError(error) {
5783
+ if (error instanceof GitCommandError) {
5784
+ return error.stderr || error.message;
5785
+ }
5786
+ if (error instanceof Error) {
5787
+ return error.message;
5788
+ }
5789
+ return String(error);
5790
+ }
5719
5791
  function parsePorcelainV2Status(output) {
5720
5792
  const parsed = {
5721
5793
  branch: null,
@@ -5810,6 +5882,7 @@ function emptyStatus(workspace, lastCheckedAt, error) {
5810
5882
  headCommit: null,
5811
5883
  headMessage: null,
5812
5884
  upstream: null,
5885
+ upstreamStatus: "unavailable",
5813
5886
  ahead: 0,
5814
5887
  behind: 0,
5815
5888
  staged: 0,
@@ -6090,6 +6163,9 @@ function createGitCompactSummary(status, diffSummary) {
6090
6163
  isGitRepo: status.isGitRepo,
6091
6164
  repoRoot: status.repoRoot,
6092
6165
  branch: status.branch,
6166
+ upstreamStatus: status.upstreamStatus,
6167
+ upstreamFetchedAt: status.upstreamFetchedAt,
6168
+ upstreamFetchError: status.upstreamFetchError,
6093
6169
  dirty: status.staged > 0 || status.modified > 0 || status.untracked > 0 || status.deleted > 0 || status.renamed > 0 || conflictCount > 0 || changedFiles > 0,
6094
6170
  changedFiles,
6095
6171
  ahead: status.ahead,
@@ -6434,7 +6510,7 @@ var defaultSnapshotStore = createGitSnapshotStore({
6434
6510
  });
6435
6511
  function createDefaultGitCommandServices() {
6436
6512
  return {
6437
- getStatus: ({ workspace }) => getGitRepoStatus(workspace),
6513
+ getStatus: ({ workspace, refreshUpstream }) => getGitRepoStatus(workspace, { refreshUpstream }),
6438
6514
  getDiffSummary: ({ workspace }) => getGitDiffSummary(workspace),
6439
6515
  getDiffFile: ({ workspace, path: filePath }) => getGitFileDiff(workspace, filePath),
6440
6516
  createSnapshot: ({ workspace, reason, sessionId, turnId }) => defaultSnapshotStore.create({
@@ -6520,7 +6596,7 @@ async function handleGitCommand(command, args, services = defaultGitCommandServi
6520
6596
  switch (command) {
6521
6597
  case "git_status": {
6522
6598
  if (!services.getStatus) return serviceNotImplemented(command);
6523
- const status = await runService(() => services.getStatus({ workspace }));
6599
+ const status = await runService(() => services.getStatus({ workspace, refreshUpstream: optionalBoolean(args?.refreshUpstream) }));
6524
6600
  return "success" in status ? status : { success: true, status };
6525
6601
  }
6526
6602
  case "git_diff_summary": {
@@ -9606,7 +9682,8 @@ var StatusMonitor = class {
9606
9682
  };
9607
9683
 
9608
9684
  // src/providers/chat-message-normalization.ts
9609
- function extractFinalSummaryFromMessages(messages, maxChars = 500) {
9685
+ var DEFAULT_FINAL_SUMMARY_MAX_CHARS = 4e3;
9686
+ function extractFinalSummaryFromMessages(messages, maxChars = DEFAULT_FINAL_SUMMARY_MAX_CHARS) {
9610
9687
  if (!Array.isArray(messages) || messages.length === 0) return "";
9611
9688
  for (let i = messages.length - 1; i >= 0; i--) {
9612
9689
  const msg = messages[i];
@@ -23603,6 +23680,26 @@ function readBooleanValue(...values) {
23603
23680
  }
23604
23681
  return void 0;
23605
23682
  }
23683
+ function readGitSubmodules(value) {
23684
+ if (!Array.isArray(value)) return void 0;
23685
+ const submodules = value.map((entry) => {
23686
+ const submodule = readObjectRecord(entry);
23687
+ const path28 = readStringValue(submodule.path);
23688
+ const commit = readStringValue(submodule.commit);
23689
+ const repoPath = readStringValue(submodule.repoPath, submodule.repo_root);
23690
+ if (!path28 || !commit || !repoPath) return null;
23691
+ return {
23692
+ path: path28,
23693
+ commit,
23694
+ repoPath,
23695
+ dirty: readBooleanValue(submodule.dirty) ?? false,
23696
+ outOfSync: readBooleanValue(submodule.outOfSync, submodule.out_of_sync) ?? false,
23697
+ lastCheckedAt: readNumberValue(submodule.lastCheckedAt, submodule.last_checked_at) ?? Date.now(),
23698
+ ...readStringValue(submodule.error) ? { error: readStringValue(submodule.error) } : {}
23699
+ };
23700
+ }).filter((entry) => entry !== null);
23701
+ return submodules.length > 0 ? submodules : void 0;
23702
+ }
23606
23703
  function buildCachedInlineMeshGitStatus(node) {
23607
23704
  const cachedStatus = readObjectRecord(node?.cachedStatus);
23608
23705
  const cachedGit = readObjectRecord(cachedStatus.git);
@@ -23612,6 +23709,7 @@ function buildCachedInlineMeshGitStatus(node) {
23612
23709
  const hasConflicts2 = readBooleanValue(cachedGit.hasConflicts) ?? conflictCount2 > 0;
23613
23710
  const isGitRepo2 = readBooleanValue(cachedGit.isGitRepo);
23614
23711
  if (isGitRepo2 !== void 0) {
23712
+ const submodules2 = readGitSubmodules(cachedGit.submodules);
23615
23713
  return {
23616
23714
  workspace: readStringValue(cachedGit.workspace, node?.workspace) || "",
23617
23715
  repoRoot: readStringValue(cachedGit.repoRoot, node?.repoRoot, node?.workspace) || null,
@@ -23630,7 +23728,8 @@ function buildCachedInlineMeshGitStatus(node) {
23630
23728
  hasConflicts: hasConflicts2,
23631
23729
  conflictFiles: conflictFiles2,
23632
23730
  stashCount: readNumberValue(cachedGit.stashCount) ?? 0,
23633
- lastCheckedAt: readNumberValue(cachedGit.lastCheckedAt) ?? Date.now()
23731
+ lastCheckedAt: readNumberValue(cachedGit.lastCheckedAt) ?? Date.now(),
23732
+ ...submodules2 ? { submodules: submodules2 } : {}
23634
23733
  };
23635
23734
  }
23636
23735
  }
@@ -23649,6 +23748,7 @@ function buildCachedInlineMeshGitStatus(node) {
23649
23748
  const conflictFiles = Array.isArray(status.conflictFiles) ? status.conflictFiles.filter((value) => typeof value === "string") : [];
23650
23749
  const conflictCount = readNumberValue(status.conflicts) ?? conflictFiles.length;
23651
23750
  const hasConflicts = readBooleanValue(status.hasConflicts) ?? conflictCount > 0;
23751
+ const submodules = readGitSubmodules(status.submodules);
23652
23752
  return {
23653
23753
  workspace: readStringValue(status.workspace, node?.workspace) || "",
23654
23754
  repoRoot: readStringValue(status.repoRoot, node?.repoRoot, node?.workspace) || null,
@@ -23667,29 +23767,161 @@ function buildCachedInlineMeshGitStatus(node) {
23667
23767
  hasConflicts,
23668
23768
  conflictFiles,
23669
23769
  stashCount: readNumberValue(status.stashCount) ?? 0,
23670
- lastCheckedAt: Date.now()
23770
+ lastCheckedAt: Date.now(),
23771
+ ...submodules ? { submodules } : {}
23772
+ };
23773
+ }
23774
+ function hasGitWorktreeChanges(git) {
23775
+ if (!git) return false;
23776
+ return Number(git.staged || 0) + Number(git.modified || 0) + Number(git.untracked || 0) + Number(git.deleted || 0) + Number(git.renamed || 0) > 0;
23777
+ }
23778
+ function getGitSubmoduleDriftState(git) {
23779
+ const submodules = Array.isArray(git?.submodules) ? git.submodules : [];
23780
+ let dirty = false;
23781
+ let outOfSync = false;
23782
+ for (const entry of submodules) {
23783
+ const submodule = readObjectRecord(entry);
23784
+ if (readBooleanValue(submodule.dirty) === true) dirty = true;
23785
+ if (readBooleanValue(submodule.outOfSync) === true || !!readStringValue(submodule.error)) outOfSync = true;
23786
+ }
23787
+ return { dirty, outOfSync };
23788
+ }
23789
+ function deriveMeshNodeHealthFromGit(git) {
23790
+ if (!git || readBooleanValue(git.isGitRepo) === false) return "degraded";
23791
+ const branch = readStringValue(git.branch);
23792
+ if (!branch) return "degraded";
23793
+ const submoduleDrift = getGitSubmoduleDriftState(git);
23794
+ if (submoduleDrift.outOfSync) return "degraded";
23795
+ if (submoduleDrift.dirty || hasGitWorktreeChanges(git)) return "dirty";
23796
+ return "online";
23797
+ }
23798
+ function readCachedInlineMeshActiveSessions(node) {
23799
+ const cachedStatus = readObjectRecord(node?.cachedStatus);
23800
+ const activeSession = readObjectRecord(cachedStatus.activeSession);
23801
+ const fallbackSession = Object.keys(activeSession).length ? activeSession : readObjectRecord(node?.activeSession ?? node?.active_session);
23802
+ const sessionId = readStringValue(fallbackSession.id, fallbackSession.sessionId, fallbackSession.session_id, node?.activeSessionId, node?.active_session_id, node?.sessionId, node?.session_id);
23803
+ return sessionId ? [sessionId] : [];
23804
+ }
23805
+ function readCachedInlineMeshActiveSessionDetails(node) {
23806
+ const cachedStatus = readObjectRecord(node?.cachedStatus);
23807
+ const activeSession = readObjectRecord(cachedStatus.activeSession);
23808
+ const fallbackSession = Object.keys(activeSession).length ? activeSession : readObjectRecord(node?.activeSession ?? node?.active_session);
23809
+ const sessionId = readStringValue(
23810
+ fallbackSession.id,
23811
+ fallbackSession.sessionId,
23812
+ fallbackSession.session_id,
23813
+ node?.activeSessionId,
23814
+ node?.active_session_id,
23815
+ node?.sessionId,
23816
+ node?.session_id
23817
+ );
23818
+ if (!sessionId) return [];
23819
+ return [{
23820
+ sessionId,
23821
+ providerType: readStringValue(
23822
+ fallbackSession.providerType,
23823
+ fallbackSession.provider_type,
23824
+ fallbackSession.cliType,
23825
+ fallbackSession.cli_type,
23826
+ fallbackSession.provider,
23827
+ node?.providerType,
23828
+ node?.provider_type
23829
+ ),
23830
+ state: readStringValue(fallbackSession.status, fallbackSession.state, fallbackSession.lifecycle),
23831
+ lifecycle: readStringValue(fallbackSession.lifecycle),
23832
+ title: readStringValue(fallbackSession.title, fallbackSession.displayName, fallbackSession.display_name) ?? null,
23833
+ workspace: readStringValue(fallbackSession.workspace, node?.workspace) ?? null,
23834
+ lastActivityAt: readStringValue(fallbackSession.lastActivityAt, fallbackSession.last_activity_at) ?? null,
23835
+ recoveryState: readStringValue(fallbackSession.recoveryState, fallbackSession.recovery_state) ?? null,
23836
+ isCached: true
23837
+ }];
23838
+ }
23839
+ function readLiveMeshSessionState(record) {
23840
+ return readStringValue(
23841
+ record?.meta?.sessionStatus,
23842
+ record?.meta?.status,
23843
+ record?.meta?.providerStatus,
23844
+ record?.status,
23845
+ record?.state,
23846
+ record?.lifecycle
23847
+ );
23848
+ }
23849
+ function toIsoTimestamp(value) {
23850
+ if (typeof value === "number" && Number.isFinite(value)) return new Date(value).toISOString();
23851
+ const stringValue = readStringValue(value);
23852
+ return stringValue || null;
23853
+ }
23854
+ function summarizeMeshSessionRecord(record) {
23855
+ return {
23856
+ sessionId: readStringValue(record?.sessionId) || "unknown",
23857
+ providerType: readStringValue(record?.providerType),
23858
+ state: readLiveMeshSessionState(record),
23859
+ lifecycle: readStringValue(record?.lifecycle),
23860
+ surfaceKind: getSessionHostSurfaceKind(record),
23861
+ recoveryState: readStringValue(record?.meta?.runtimeRecoveryState) ?? null,
23862
+ workspace: readStringValue(record?.workspace) ?? null,
23863
+ title: readStringValue(record?.displayName, record?.workspaceLabel) ?? null,
23864
+ lastActivityAt: toIsoTimestamp(record?.updatedAt ?? record?.lastActivityAt ?? record?.last_activity_at),
23865
+ isCached: false
23671
23866
  };
23672
23867
  }
23868
+ function readLiveMeshNodeWorkspace(args) {
23869
+ const directNodeWorkspace = args.liveSessionRecords.find((record) => readStringValue(record?.meta?.meshNodeId) === args.nodeId && readStringValue(record?.workspace));
23870
+ if (directNodeWorkspace) {
23871
+ return readStringValue(directNodeWorkspace.workspace) || "";
23872
+ }
23873
+ if (args.allowCoordinatorSession) {
23874
+ const coordinatorWorkspace = args.liveSessionRecords.find((record) => readStringValue(record?.meta?.meshCoordinatorFor) === args.meshId && readStringValue(record?.workspace));
23875
+ if (coordinatorWorkspace) {
23876
+ return readStringValue(coordinatorWorkspace.workspace) || "";
23877
+ }
23878
+ }
23879
+ return "";
23880
+ }
23881
+ function collectLiveMeshSessionRecords(args) {
23882
+ const matches = args.liveSessionRecords.filter((record) => {
23883
+ if (readStringValue(record?.meta?.meshNodeId) === args.nodeId) return true;
23884
+ const recordWorkspace = readStringValue(record?.workspace);
23885
+ const nodeWorkspace = readStringValue(args.node?.workspace);
23886
+ return !!recordWorkspace && !!nodeWorkspace && recordWorkspace === nodeWorkspace;
23887
+ });
23888
+ if (args.allowCoordinatorSession) {
23889
+ for (const record of args.liveSessionRecords) {
23890
+ if (readStringValue(record?.meta?.meshCoordinatorFor) !== args.meshId) continue;
23891
+ const sessionId = readStringValue(record?.sessionId);
23892
+ if (sessionId && matches.some((entry) => readStringValue(entry?.sessionId) === sessionId)) continue;
23893
+ matches.push(record);
23894
+ }
23895
+ }
23896
+ return matches;
23897
+ }
23673
23898
  function applyCachedInlineMeshNodeStatus(status, node) {
23674
23899
  const cachedStatus = readObjectRecord(node?.cachedStatus);
23675
23900
  const git = buildCachedInlineMeshGitStatus(node);
23676
23901
  const error = readStringValue(cachedStatus.error, node?.error);
23677
23902
  const health = readStringValue(cachedStatus.health, node?.health);
23678
23903
  const machineStatus = readStringValue(cachedStatus.machineStatus, node?.machineStatus);
23679
- if (!git && !error && !health) return false;
23680
- if (!machineStatus && !git && !error) return false;
23904
+ const lastSeenAt = toIsoTimestamp(cachedStatus.lastSeenAt ?? cachedStatus.last_seen_at ?? node?.lastSeenAt ?? node?.last_seen_at);
23905
+ const updatedAt = toIsoTimestamp(cachedStatus.updatedAt ?? cachedStatus.updated_at ?? node?.updatedAt ?? node?.updated_at);
23906
+ const activeSessions = readCachedInlineMeshActiveSessions(node);
23907
+ const activeSessionDetails = readCachedInlineMeshActiveSessionDetails(node);
23908
+ if (!git && !error && !health && !machineStatus && !lastSeenAt && !updatedAt && activeSessions.length === 0) return false;
23681
23909
  if (git) status.git = git;
23682
23910
  if (error) status.error = error;
23911
+ if (machineStatus) status.machineStatus = machineStatus;
23912
+ if (lastSeenAt) status.lastSeenAt = lastSeenAt;
23913
+ if (updatedAt) status.updatedAt = updatedAt;
23914
+ if (activeSessions.length > 0) status.activeSessions = activeSessions;
23915
+ if (activeSessionDetails.length > 0) status.activeSessionDetails = activeSessionDetails;
23683
23916
  if (health) {
23684
23917
  status.health = health;
23685
23918
  return true;
23686
23919
  }
23687
23920
  if (git) {
23688
- const dirty = Number(git.staged || 0) + Number(git.modified || 0) + Number(git.untracked || 0) + Number(git.deleted || 0) + Number(git.renamed || 0) > 0;
23689
- status.health = git.isGitRepo === false ? "degraded" : dirty ? "dirty" : "online";
23921
+ status.health = deriveMeshNodeHealthFromGit(git);
23690
23922
  return true;
23691
23923
  }
23692
- return false;
23924
+ return activeSessions.length > 0 || !!machineStatus || !!lastSeenAt || !!updatedAt;
23693
23925
  }
23694
23926
  async function resolveProviderTypeFromPriority(args) {
23695
23927
  if (!args.providerPriority.length) {
@@ -24087,25 +24319,35 @@ var DaemonCommandRouter = class {
24087
24319
  }
24088
24320
  getCachedInlineMesh(meshId, inlineMesh) {
24089
24321
  if (inlineMesh && typeof inlineMesh === "object") {
24090
- this.inlineMeshCache.set(meshId, inlineMesh);
24091
- return inlineMesh;
24322
+ return this.warmInlineMeshCache(meshId, inlineMesh);
24092
24323
  }
24093
24324
  return this.inlineMeshCache.get(meshId);
24094
24325
  }
24326
+ warmInlineMeshCache(meshId, inlineMesh) {
24327
+ if (!inlineMesh || typeof inlineMesh !== "object") return void 0;
24328
+ const cached = this.inlineMeshCache.get(meshId);
24329
+ if (cached) return cached;
24330
+ this.inlineMeshCache.set(meshId, inlineMesh);
24331
+ return inlineMesh;
24332
+ }
24095
24333
  async getMeshForCommand(meshId, inlineMesh, options) {
24096
24334
  const preferInline = options?.preferInline === true;
24097
24335
  if (preferInline) {
24098
- const cached2 = this.getCachedInlineMesh(meshId, inlineMesh);
24099
- if (cached2) return { mesh: cached2, inline: true };
24336
+ const cached2 = this.getCachedInlineMesh(meshId);
24337
+ if (cached2) return { mesh: cached2, inline: true, source: "inline_cache" };
24338
+ const warmedInline2 = this.warmInlineMeshCache(meshId, inlineMesh);
24339
+ if (warmedInline2) return { mesh: warmedInline2, inline: true, source: "inline_bootstrap" };
24100
24340
  }
24101
24341
  try {
24102
24342
  const { getMesh: getMesh3 } = await Promise.resolve().then(() => (init_mesh_config(), mesh_config_exports));
24103
24343
  const mesh = getMesh3(meshId);
24104
- if (mesh) return { mesh, inline: false };
24344
+ if (mesh) return { mesh, inline: false, source: "local_config" };
24105
24345
  } catch {
24106
24346
  }
24107
- const cached = this.getCachedInlineMesh(meshId, inlineMesh);
24108
- return cached ? { mesh: cached, inline: true } : null;
24347
+ const cached = this.getCachedInlineMesh(meshId);
24348
+ if (cached) return { mesh: cached, inline: true, source: "inline_cache" };
24349
+ const warmedInline = this.warmInlineMeshCache(meshId, inlineMesh);
24350
+ return warmedInline ? { mesh: warmedInline, inline: true, source: "inline_bootstrap" } : null;
24109
24351
  }
24110
24352
  updateInlineMeshNode(meshId, mesh, node) {
24111
24353
  if (!mesh || !Array.isArray(mesh.nodes) || !node?.id) return;
@@ -24334,6 +24576,7 @@ var DaemonCommandRouter = class {
24334
24576
  const deletedSessionIds = [];
24335
24577
  const skippedSessionIds = [];
24336
24578
  const skippedLiveSessionIds = [];
24579
+ const skippedCoordinatorSessionIds = [];
24337
24580
  const deleteUnsupportedSessionIds = [];
24338
24581
  const recordsRemainSessionIds = [];
24339
24582
  const errors = [];
@@ -24366,6 +24609,12 @@ var DaemonCommandRouter = class {
24366
24609
  const completed = this.isCompletedHostedSession(record);
24367
24610
  const surfaceKind = getSessionHostSurfaceKind(record);
24368
24611
  const liveRuntime = surfaceKind === "live_runtime";
24612
+ const coordinatorSession = readStringValue(record?.meta?.meshCoordinatorFor) === args.meshId;
24613
+ if (!hasExplicitSessionIds && coordinatorSession) {
24614
+ skippedSessionIds.push(sessionId);
24615
+ skippedCoordinatorSessionIds.push(sessionId);
24616
+ continue;
24617
+ }
24369
24618
  if (!hasExplicitSessionIds && liveRuntime) {
24370
24619
  skippedSessionIds.push(sessionId);
24371
24620
  skippedLiveSessionIds.push(sessionId);
@@ -24431,6 +24680,7 @@ var DaemonCommandRouter = class {
24431
24680
  deletedSessionIds,
24432
24681
  skippedSessionIds,
24433
24682
  skippedLiveSessionIds,
24683
+ skippedCoordinatorSessionIds,
24434
24684
  ...deleteUnsupported ? {
24435
24685
  deleteUnsupported: true,
24436
24686
  effectiveCleanup: args.mode === "stop_and_delete" ? "stopped_only_records_remain" : "delete_unsupported_records_remain",
@@ -25092,14 +25342,8 @@ var DaemonCommandRouter = class {
25092
25342
  case "get_mesh": {
25093
25343
  const meshId = typeof args?.meshId === "string" ? args.meshId.trim() : "";
25094
25344
  if (!meshId) return { success: false, error: "meshId required" };
25095
- try {
25096
- const { getMesh: getMesh3 } = await Promise.resolve().then(() => (init_mesh_config(), mesh_config_exports));
25097
- const mesh = getMesh3(meshId);
25098
- if (mesh) return { success: true, mesh };
25099
- } catch {
25100
- }
25101
- const cached = this.inlineMeshCache.get(meshId);
25102
- if (cached) return { success: true, mesh: cached };
25345
+ const meshRecord = await this.getMeshForCommand(meshId, args?.inlineMesh, { preferInline: true });
25346
+ if (meshRecord?.mesh) return { success: true, mesh: meshRecord.mesh };
25103
25347
  return { success: false, error: "Mesh not found" };
25104
25348
  }
25105
25349
  case "create_mesh": {
@@ -25621,7 +25865,14 @@ var DaemonCommandRouter = class {
25621
25865
  cliType
25622
25866
  };
25623
25867
  }
25624
- const workspace = typeof coordinatorNode.workspace === "string" ? coordinatorNode.workspace.trim() : "";
25868
+ const sessionHostRecords = this.deps.sessionHostControl?.listSessions ? await this.deps.sessionHostControl.listSessions().catch(() => []) : [];
25869
+ const liveMeshSessions = partitionSessionHostRecords(Array.isArray(sessionHostRecords) ? sessionHostRecords : []).liveRuntimes;
25870
+ const workspace = readLiveMeshNodeWorkspace({
25871
+ meshId,
25872
+ nodeId: String(coordinatorNode.id || coordinatorNode.nodeId || preferredCoordinatorNodeId || ""),
25873
+ liveSessionRecords: liveMeshSessions,
25874
+ allowCoordinatorSession: true
25875
+ }) || (typeof coordinatorNode.workspace === "string" ? coordinatorNode.workspace.trim() : "");
25625
25876
  if (!workspace) return { success: false, error: "Coordinator node workspace required", meshId, cliType };
25626
25877
  if (!cliType) {
25627
25878
  const resolved = await resolveProviderTypeFromPriority({
@@ -25929,84 +26180,111 @@ ${block}`);
25929
26180
  const { readLedgerEntries: readLedgerEntries2, getLedgerSummary: getLedgerSummary2 } = await Promise.resolve().then(() => (init_mesh_ledger(), mesh_ledger_exports));
25930
26181
  const ledgerEntries = readLedgerEntries2(meshId, { tail: 20 });
25931
26182
  const ledgerSummary = getLedgerSummary2(meshId);
26183
+ const sessionHostRecords = this.deps.sessionHostControl?.listSessions ? await this.deps.sessionHostControl.listSessions().catch(() => []) : [];
26184
+ const liveMeshSessions = partitionSessionHostRecords(Array.isArray(sessionHostRecords) ? sessionHostRecords : []).liveRuntimes;
26185
+ const localMachineId = loadConfig().machineId || "";
26186
+ const selectedCoordinatorNodeId = readStringValue(
26187
+ mesh.coordinator?.preferredNodeId,
26188
+ mesh.nodes?.[0]?.id,
26189
+ mesh.nodes?.[0]?.nodeId
26190
+ );
26191
+ const inlineCoordinatorNodeId = meshRecord?.inline && Array.isArray(mesh.nodes) ? selectedCoordinatorNodeId : void 0;
26192
+ const refreshedAt = (/* @__PURE__ */ new Date()).toISOString();
25932
26193
  const nodeStatuses = [];
25933
- for (const node of mesh.nodes || []) {
26194
+ for (const [nodeIndex, node] of (mesh.nodes || []).entries()) {
26195
+ const nodeId = String(node.id || node.nodeId || "");
26196
+ const daemonId = readStringValue(node.daemonId);
26197
+ const providerPriority = readProviderPriorityFromPolicy(node.policy);
26198
+ const isSelfNode = Boolean(
26199
+ nodeId && inlineCoordinatorNodeId && nodeId === inlineCoordinatorNodeId
26200
+ ) || Boolean(
26201
+ daemonId && (daemonId === localMachineId || daemonId === this.deps.statusInstanceId)
26202
+ ) || Boolean(meshRecord?.inline && nodeIndex === 0);
25934
26203
  const status = {
25935
- nodeId: node.id || node.nodeId,
26204
+ nodeId,
25936
26205
  machineLabel: node.machineLabel || node.id || node.nodeId,
25937
26206
  workspace: node.workspace,
25938
26207
  repoRoot: node.repoRoot,
25939
26208
  isLocalWorktree: node.isLocalWorktree,
25940
26209
  worktreeBranch: node.worktreeBranch,
25941
- daemonId: node.daemonId,
26210
+ daemonId,
25942
26211
  machineId: node.machineId,
26212
+ machineStatus: node.machineStatus,
25943
26213
  health: "unknown",
25944
26214
  providers: node.providers || [],
25945
- activeSessions: []
26215
+ providerPriority,
26216
+ activeSessions: [],
26217
+ activeSessionDetails: [],
26218
+ launchReady: false
25946
26219
  };
25947
- if (node.workspace && typeof node.workspace === "string") {
25948
- if (!fs10.existsSync(node.workspace) && applyCachedInlineMeshNodeStatus(status, node)) {
26220
+ if (isSelfNode) {
26221
+ status.connection = {
26222
+ perspective: "selected_coordinator",
26223
+ source: "mesh_peer_status",
26224
+ state: "self",
26225
+ transport: "local",
26226
+ reported: true,
26227
+ reason: "Selected coordinator daemon",
26228
+ lastStateChangeAt: refreshedAt
26229
+ };
26230
+ } else if (daemonId) {
26231
+ const connection = this.deps.getMeshPeerConnectionStatus?.(daemonId);
26232
+ status.connection = connection ?? {
26233
+ perspective: "selected_coordinator",
26234
+ source: "not_reported",
26235
+ state: "unknown",
26236
+ transport: "unknown",
26237
+ reported: false,
26238
+ reason: "No live mesh peer telemetry reported by the selected coordinator yet."
26239
+ };
26240
+ } else {
26241
+ status.connection = {
26242
+ perspective: "selected_coordinator",
26243
+ source: "not_reported",
26244
+ state: "unknown",
26245
+ transport: "unknown",
26246
+ reported: false,
26247
+ reason: "Node has no daemon id, so mesh transport cannot be reported from the selected coordinator."
26248
+ };
26249
+ }
26250
+ const matchedLiveSessionRecords = collectLiveMeshSessionRecords({
26251
+ meshId,
26252
+ node,
26253
+ nodeId,
26254
+ liveSessionRecords: liveMeshSessions,
26255
+ allowCoordinatorSession: nodeId === selectedCoordinatorNodeId
26256
+ });
26257
+ const workspace = readLiveMeshNodeWorkspace({
26258
+ meshId,
26259
+ nodeId,
26260
+ liveSessionRecords: matchedLiveSessionRecords,
26261
+ allowCoordinatorSession: nodeId === selectedCoordinatorNodeId
26262
+ }) || (typeof node.workspace === "string" ? node.workspace : "");
26263
+ status.workspace = workspace || node.workspace;
26264
+ if (matchedLiveSessionRecords.length > 0) {
26265
+ const sessionIds = matchedLiveSessionRecords.map((record) => typeof record?.sessionId === "string" ? record.sessionId : "").filter(Boolean);
26266
+ const providerTypes = matchedLiveSessionRecords.map((record) => readStringValue(record?.providerType)).filter(Boolean);
26267
+ status.activeSessions = sessionIds;
26268
+ status.activeSessionDetails = matchedLiveSessionRecords.map(summarizeMeshSessionRecord);
26269
+ if (providerTypes.length > 0) {
26270
+ status.providers = Array.from(/* @__PURE__ */ new Set([...Array.isArray(status.providers) ? status.providers : [], ...providerTypes]));
26271
+ }
26272
+ }
26273
+ if (workspace) {
26274
+ if (!fs10.existsSync(workspace) && applyCachedInlineMeshNodeStatus(status, node)) {
26275
+ status.launchReady = !!daemonId && (readStringValue(status.machineStatus) === "online" || isSelfNode);
25949
26276
  nodeStatuses.push(status);
25950
26277
  continue;
25951
26278
  }
25952
26279
  try {
25953
- const { execFile: execFile3 } = await import("child_process");
25954
- const { promisify: promisify3 } = await import("util");
25955
- const execFileAsync3 = promisify3(execFile3);
25956
- const runGit2 = async (args2) => {
25957
- const result = await execFileAsync3("git", ["-C", node.workspace, ...args2], {
25958
- encoding: "utf8",
25959
- timeout: 1e4
25960
- });
25961
- return result.stdout.trim();
25962
- };
25963
- const branch = await runGit2(["branch", "--show-current"]).catch(() => "");
25964
- const porc = await runGit2(["status", "--porcelain"]).catch(() => "");
25965
- const headCommit = await runGit2(["rev-parse", "--short", "HEAD"]).catch(() => null);
25966
- const headMessage = await runGit2(["log", "-1", "--format=%s"]).catch(() => null);
25967
- const upstream = await runGit2(["rev-parse", "--abbrev-ref", "@{upstream}"]).catch(() => null);
25968
- const aheadBehind = await runGit2(["rev-list", "--left-right", "--count", "@{upstream}...HEAD"]).catch(() => "");
25969
- const stashCount = await runGit2(["stash", "list"]).catch(() => "");
25970
- let ahead = 0, behind = 0;
25971
- if (aheadBehind) {
25972
- const parts = aheadBehind.split(/\s+/);
25973
- if (parts.length >= 2) {
25974
- behind = parseInt(parts[0], 10) || 0;
25975
- ahead = parseInt(parts[1], 10) || 0;
25976
- }
25977
- }
25978
- const dirty = porc.length > 0;
25979
- const lines = porc ? porc.split("\n").filter(Boolean) : [];
25980
- let staged = 0, modified = 0, untracked = 0, deleted = 0, renamed = 0;
25981
- for (const line of lines) {
25982
- const xy = line.slice(0, 2);
25983
- if (xy[0] !== " " && xy[0] !== "?") staged++;
25984
- if (xy[1] === "M") modified++;
25985
- if (xy[1] === "D") deleted++;
25986
- if (xy[0] === "R" || xy[1] === "R") renamed++;
25987
- if (xy === "??") untracked++;
26280
+ const gitStatus = await getGitRepoStatus(workspace, { timeoutMs: 1e4, refreshUpstream: true });
26281
+ status.git = gitStatus;
26282
+ if (gitStatus.isGitRepo) {
26283
+ status.health = deriveMeshNodeHealthFromGit(gitStatus);
26284
+ } else {
26285
+ status.health = "degraded";
26286
+ if (gitStatus.error && !status.error) status.error = gitStatus.error;
25988
26287
  }
25989
- status.git = {
25990
- workspace: node.workspace,
25991
- repoRoot: node.workspace,
25992
- isGitRepo: true,
25993
- branch: branch || null,
25994
- headCommit,
25995
- headMessage,
25996
- upstream,
25997
- ahead,
25998
- behind,
25999
- staged,
26000
- modified,
26001
- untracked,
26002
- deleted,
26003
- renamed,
26004
- hasConflicts: false,
26005
- conflictFiles: [],
26006
- stashCount: stashCount ? stashCount.split("\n").filter(Boolean).length : 0,
26007
- lastCheckedAt: Date.now()
26008
- };
26009
- status.health = branch ? dirty ? "dirty" : "online" : "degraded";
26010
26288
  } catch {
26011
26289
  if (!applyCachedInlineMeshNodeStatus(status, node)) {
26012
26290
  status.health = "degraded";
@@ -26015,6 +26293,7 @@ ${block}`);
26015
26293
  } else {
26016
26294
  applyCachedInlineMeshNodeStatus(status, node);
26017
26295
  }
26296
+ status.launchReady = !!daemonId && (readStringValue(status.machineStatus) === "online" || isSelfNode);
26018
26297
  nodeStatuses.push(status);
26019
26298
  }
26020
26299
  return {
@@ -26023,6 +26302,12 @@ ${block}`);
26023
26302
  meshName: mesh.name,
26024
26303
  repoIdentity: mesh.repoIdentity,
26025
26304
  defaultBranch: mesh.defaultBranch,
26305
+ refreshedAt: (/* @__PURE__ */ new Date()).toISOString(),
26306
+ sourceOfTruth: {
26307
+ membership: meshRecord?.source === "inline_cache" ? "coordinator_inline_mesh_cache" : meshRecord?.source === "local_config" ? "local_mesh_config" : "inline_bootstrap_snapshot",
26308
+ coordinatorOwnsLiveTruth: meshRecord?.source !== "inline_bootstrap",
26309
+ historicalEvidenceOnly: ["recoveryHints", "ledger.summary", "queue.summary"]
26310
+ },
26026
26311
  nodes: nodeStatuses,
26027
26312
  queue: { tasks: queue, summary: queueSummary },
26028
26313
  ledger: { entries: ledgerEntries, summary: ledgerSummary }
@@ -33957,6 +34242,7 @@ async function initDaemonComponents(config) {
33957
34242
  sessionHostControl: config.sessionHostControl,
33958
34243
  statusInstanceId: config.statusInstanceId,
33959
34244
  statusVersion: config.statusVersion,
34245
+ getMeshPeerConnectionStatus: config.getMeshPeerConnectionStatus,
33960
34246
  getCdpLogFn: config.getCdpLogFn || ((ideType) => LOG.forComponent(`CDP:${ideType}`).asLogFn())
33961
34247
  });
33962
34248
  poller = new AgentStreamPoller({
@@ -34231,6 +34517,7 @@ export {
34231
34517
  prepareSessionChatTailUpdate,
34232
34518
  prepareSessionModalUpdate,
34233
34519
  probeCdpPort,
34520
+ queuePendingMeshCoordinatorEvent,
34234
34521
  readChatHistory,
34235
34522
  readLedgerEntries,
34236
34523
  readLedgerSlice,