adhdev 0.9.82-rc.6 → 0.9.82-rc.8

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/cli/index.js CHANGED
@@ -46493,26 +46493,127 @@ function buildCachedInlineMeshGitStatus(node) {
46493
46493
  ...submodules ? { submodules } : {}
46494
46494
  };
46495
46495
  }
46496
+ function hasGitWorktreeChanges(git) {
46497
+ if (!git) return false;
46498
+ return Number(git.staged || 0) + Number(git.modified || 0) + Number(git.untracked || 0) + Number(git.deleted || 0) + Number(git.renamed || 0) > 0;
46499
+ }
46500
+ function getGitSubmoduleDriftState(git) {
46501
+ const submodules = Array.isArray(git?.submodules) ? git.submodules : [];
46502
+ let dirty = false;
46503
+ let outOfSync = false;
46504
+ for (const entry of submodules) {
46505
+ const submodule = readObjectRecord(entry);
46506
+ if (readBooleanValue(submodule.dirty) === true) dirty = true;
46507
+ if (readBooleanValue(submodule.outOfSync) === true || !!readStringValue(submodule.error)) outOfSync = true;
46508
+ }
46509
+ return { dirty, outOfSync };
46510
+ }
46511
+ function deriveMeshNodeHealthFromGit(git) {
46512
+ if (!git || readBooleanValue(git.isGitRepo) === false) return "degraded";
46513
+ const branch = readStringValue(git.branch);
46514
+ if (!branch) return "degraded";
46515
+ const submoduleDrift = getGitSubmoduleDriftState(git);
46516
+ if (submoduleDrift.outOfSync) return "degraded";
46517
+ if (submoduleDrift.dirty || hasGitWorktreeChanges(git)) return "dirty";
46518
+ return "online";
46519
+ }
46520
+ function readCachedInlineMeshActiveSessions(node) {
46521
+ const cachedStatus = readObjectRecord(node?.cachedStatus);
46522
+ const activeSession = readObjectRecord(cachedStatus.activeSession);
46523
+ const fallbackSession = Object.keys(activeSession).length ? activeSession : readObjectRecord(node?.activeSession ?? node?.active_session);
46524
+ const sessionId = readStringValue(fallbackSession.id, fallbackSession.sessionId, fallbackSession.session_id, node?.activeSessionId, node?.active_session_id, node?.sessionId, node?.session_id);
46525
+ return sessionId ? [sessionId] : [];
46526
+ }
46527
+ function readCachedInlineMeshActiveSessionDetails(node) {
46528
+ const cachedStatus = readObjectRecord(node?.cachedStatus);
46529
+ const activeSession = readObjectRecord(cachedStatus.activeSession);
46530
+ const fallbackSession = Object.keys(activeSession).length ? activeSession : readObjectRecord(node?.activeSession ?? node?.active_session);
46531
+ const sessionId = readStringValue(
46532
+ fallbackSession.id,
46533
+ fallbackSession.sessionId,
46534
+ fallbackSession.session_id,
46535
+ node?.activeSessionId,
46536
+ node?.active_session_id,
46537
+ node?.sessionId,
46538
+ node?.session_id
46539
+ );
46540
+ if (!sessionId) return [];
46541
+ return [{
46542
+ sessionId,
46543
+ providerType: readStringValue(
46544
+ fallbackSession.providerType,
46545
+ fallbackSession.provider_type,
46546
+ fallbackSession.cliType,
46547
+ fallbackSession.cli_type,
46548
+ fallbackSession.provider,
46549
+ node?.providerType,
46550
+ node?.provider_type
46551
+ ),
46552
+ state: readStringValue(fallbackSession.status, fallbackSession.state, fallbackSession.lifecycle),
46553
+ lifecycle: readStringValue(fallbackSession.lifecycle),
46554
+ title: readStringValue(fallbackSession.title, fallbackSession.displayName, fallbackSession.display_name) ?? null,
46555
+ workspace: readStringValue(fallbackSession.workspace, node?.workspace) ?? null,
46556
+ lastActivityAt: readStringValue(fallbackSession.lastActivityAt, fallbackSession.last_activity_at) ?? null,
46557
+ recoveryState: readStringValue(fallbackSession.recoveryState, fallbackSession.recovery_state) ?? null,
46558
+ isCached: true
46559
+ }];
46560
+ }
46561
+ function readLiveMeshSessionState(record2) {
46562
+ return readStringValue(
46563
+ record2?.meta?.sessionStatus,
46564
+ record2?.meta?.status,
46565
+ record2?.meta?.providerStatus,
46566
+ record2?.status,
46567
+ record2?.state,
46568
+ record2?.lifecycle
46569
+ );
46570
+ }
46571
+ function toIsoTimestamp(value) {
46572
+ if (typeof value === "number" && Number.isFinite(value)) return new Date(value).toISOString();
46573
+ const stringValue = readStringValue(value);
46574
+ return stringValue || null;
46575
+ }
46576
+ function summarizeMeshSessionRecord(record2) {
46577
+ return {
46578
+ sessionId: readStringValue(record2?.sessionId) || "unknown",
46579
+ providerType: readStringValue(record2?.providerType),
46580
+ state: readLiveMeshSessionState(record2),
46581
+ lifecycle: readStringValue(record2?.lifecycle),
46582
+ surfaceKind: getSessionHostSurfaceKind(record2),
46583
+ recoveryState: readStringValue(record2?.meta?.runtimeRecoveryState) ?? null,
46584
+ workspace: readStringValue(record2?.workspace) ?? null,
46585
+ title: readStringValue(record2?.displayName, record2?.workspaceLabel) ?? null,
46586
+ lastActivityAt: toIsoTimestamp(record2?.updatedAt ?? record2?.lastActivityAt ?? record2?.last_activity_at),
46587
+ isCached: false
46588
+ };
46589
+ }
46496
46590
  function applyCachedInlineMeshNodeStatus(status, node) {
46497
46591
  const cachedStatus = readObjectRecord(node?.cachedStatus);
46498
46592
  const git = buildCachedInlineMeshGitStatus(node);
46499
46593
  const error48 = readStringValue(cachedStatus.error, node?.error);
46500
46594
  const health = readStringValue(cachedStatus.health, node?.health);
46501
46595
  const machineStatus = readStringValue(cachedStatus.machineStatus, node?.machineStatus);
46502
- if (!git && !error48 && !health) return false;
46503
- if (!machineStatus && !git && !error48) return false;
46596
+ const lastSeenAt = toIsoTimestamp(cachedStatus.lastSeenAt ?? cachedStatus.last_seen_at ?? node?.lastSeenAt ?? node?.last_seen_at);
46597
+ const updatedAt = toIsoTimestamp(cachedStatus.updatedAt ?? cachedStatus.updated_at ?? node?.updatedAt ?? node?.updated_at);
46598
+ const activeSessions = readCachedInlineMeshActiveSessions(node);
46599
+ const activeSessionDetails = readCachedInlineMeshActiveSessionDetails(node);
46600
+ if (!git && !error48 && !health && !machineStatus && !lastSeenAt && !updatedAt && activeSessions.length === 0) return false;
46504
46601
  if (git) status.git = git;
46505
46602
  if (error48) status.error = error48;
46603
+ if (machineStatus) status.machineStatus = machineStatus;
46604
+ if (lastSeenAt) status.lastSeenAt = lastSeenAt;
46605
+ if (updatedAt) status.updatedAt = updatedAt;
46606
+ if (activeSessions.length > 0) status.activeSessions = activeSessions;
46607
+ if (activeSessionDetails.length > 0) status.activeSessionDetails = activeSessionDetails;
46506
46608
  if (health) {
46507
46609
  status.health = health;
46508
46610
  return true;
46509
46611
  }
46510
46612
  if (git) {
46511
- const dirty = Number(git.staged || 0) + Number(git.modified || 0) + Number(git.untracked || 0) + Number(git.deleted || 0) + Number(git.renamed || 0) > 0;
46512
- status.health = git.isGitRepo === false ? "degraded" : dirty ? "dirty" : "online";
46613
+ status.health = deriveMeshNodeHealthFromGit(git);
46513
46614
  return true;
46514
46615
  }
46515
- return false;
46616
+ return activeSessions.length > 0 || !!machineStatus || !!lastSeenAt || !!updatedAt;
46516
46617
  }
46517
46618
  async function resolveProviderTypeFromPriority(args) {
46518
46619
  if (!args.providerPriority.length) {
@@ -48789,23 +48890,81 @@ ${block}`);
48789
48890
  const { readLedgerEntries: readLedgerEntries2, getLedgerSummary: getLedgerSummary2 } = await Promise.resolve().then(() => (init_mesh_ledger(), mesh_ledger_exports));
48790
48891
  const ledgerEntries = readLedgerEntries2(meshId, { tail: 20 });
48791
48892
  const ledgerSummary = getLedgerSummary2(meshId);
48893
+ const sessionHostRecords = this.deps.sessionHostControl?.listSessions ? await this.deps.sessionHostControl.listSessions().catch(() => []) : [];
48894
+ const liveMeshSessions = partitionSessionHostRecords(Array.isArray(sessionHostRecords) ? sessionHostRecords : []).liveRuntimes;
48895
+ const localMachineId = loadConfig().machineId || "";
48896
+ const inlineCoordinatorNodeId = meshRecord?.inline && Array.isArray(mesh.nodes) ? readStringValue(mesh.nodes[0]?.id, mesh.nodes[0]?.nodeId) : void 0;
48897
+ const refreshedAt = (/* @__PURE__ */ new Date()).toISOString();
48792
48898
  const nodeStatuses = [];
48793
- for (const node of mesh.nodes || []) {
48899
+ for (const [nodeIndex, node] of (mesh.nodes || []).entries()) {
48900
+ const nodeId = String(node.id || node.nodeId || "");
48901
+ const daemonId = readStringValue(node.daemonId);
48902
+ const providerPriority = readProviderPriorityFromPolicy(node.policy);
48903
+ const isSelfNode = Boolean(
48904
+ nodeId && inlineCoordinatorNodeId && nodeId === inlineCoordinatorNodeId
48905
+ ) || Boolean(
48906
+ daemonId && (daemonId === localMachineId || daemonId === this.deps.statusInstanceId)
48907
+ ) || Boolean(meshRecord?.inline && nodeIndex === 0);
48794
48908
  const status = {
48795
- nodeId: node.id || node.nodeId,
48909
+ nodeId,
48796
48910
  machineLabel: node.machineLabel || node.id || node.nodeId,
48797
48911
  workspace: node.workspace,
48798
48912
  repoRoot: node.repoRoot,
48799
48913
  isLocalWorktree: node.isLocalWorktree,
48800
48914
  worktreeBranch: node.worktreeBranch,
48801
- daemonId: node.daemonId,
48915
+ daemonId,
48802
48916
  machineId: node.machineId,
48917
+ machineStatus: node.machineStatus,
48803
48918
  health: "unknown",
48804
48919
  providers: node.providers || [],
48805
- activeSessions: []
48920
+ providerPriority,
48921
+ activeSessions: [],
48922
+ activeSessionDetails: [],
48923
+ launchReady: false
48806
48924
  };
48925
+ if (isSelfNode) {
48926
+ status.connection = {
48927
+ perspective: "selected_coordinator",
48928
+ source: "mesh_peer_status",
48929
+ state: "self",
48930
+ transport: "local",
48931
+ reported: true,
48932
+ reason: "Selected coordinator daemon",
48933
+ lastStateChangeAt: refreshedAt
48934
+ };
48935
+ } else if (daemonId) {
48936
+ const connection = this.deps.getMeshPeerConnectionStatus?.(daemonId);
48937
+ status.connection = connection ?? {
48938
+ perspective: "selected_coordinator",
48939
+ source: "not_reported",
48940
+ state: "unknown",
48941
+ transport: "unknown",
48942
+ reported: false,
48943
+ reason: "No live mesh peer telemetry reported by the selected coordinator yet."
48944
+ };
48945
+ } else {
48946
+ status.connection = {
48947
+ perspective: "selected_coordinator",
48948
+ source: "not_reported",
48949
+ state: "unknown",
48950
+ transport: "unknown",
48951
+ reported: false,
48952
+ reason: "Node has no daemon id, so mesh transport cannot be reported from the selected coordinator."
48953
+ };
48954
+ }
48955
+ const matchedLiveSessionRecords = liveMeshSessions.filter((record2) => this.sessionMatchesMeshNode(record2, node, nodeId));
48956
+ if (matchedLiveSessionRecords.length > 0) {
48957
+ const sessionIds = matchedLiveSessionRecords.map((record2) => typeof record2?.sessionId === "string" ? record2.sessionId : "").filter(Boolean);
48958
+ const providerTypes = matchedLiveSessionRecords.map((record2) => readStringValue(record2?.providerType)).filter(Boolean);
48959
+ status.activeSessions = sessionIds;
48960
+ status.activeSessionDetails = matchedLiveSessionRecords.map(summarizeMeshSessionRecord);
48961
+ if (providerTypes.length > 0) {
48962
+ status.providers = Array.from(/* @__PURE__ */ new Set([...Array.isArray(status.providers) ? status.providers : [], ...providerTypes]));
48963
+ }
48964
+ }
48807
48965
  if (node.workspace && typeof node.workspace === "string") {
48808
48966
  if (!fs10.existsSync(node.workspace) && applyCachedInlineMeshNodeStatus(status, node)) {
48967
+ status.launchReady = !!daemonId && (readStringValue(status.machineStatus) === "online" || isSelfNode);
48809
48968
  nodeStatuses.push(status);
48810
48969
  continue;
48811
48970
  }
@@ -48813,8 +48972,7 @@ ${block}`);
48813
48972
  const gitStatus = await getGitRepoStatus(node.workspace, { timeoutMs: 1e4 });
48814
48973
  status.git = gitStatus;
48815
48974
  if (gitStatus.isGitRepo) {
48816
- const dirty = gitStatus.staged + gitStatus.modified + gitStatus.untracked + gitStatus.deleted + gitStatus.renamed > 0;
48817
- status.health = gitStatus.branch ? dirty ? "dirty" : "online" : "degraded";
48975
+ status.health = deriveMeshNodeHealthFromGit(gitStatus);
48818
48976
  } else {
48819
48977
  status.health = "degraded";
48820
48978
  if (gitStatus.error && !status.error) status.error = gitStatus.error;
@@ -48827,6 +48985,7 @@ ${block}`);
48827
48985
  } else {
48828
48986
  applyCachedInlineMeshNodeStatus(status, node);
48829
48987
  }
48988
+ status.launchReady = !!daemonId && (readStringValue(status.machineStatus) === "online" || isSelfNode);
48830
48989
  nodeStatuses.push(status);
48831
48990
  }
48832
48991
  return {
@@ -48835,6 +48994,7 @@ ${block}`);
48835
48994
  meshName: mesh.name,
48836
48995
  repoIdentity: mesh.repoIdentity,
48837
48996
  defaultBranch: mesh.defaultBranch,
48997
+ refreshedAt: (/* @__PURE__ */ new Date()).toISOString(),
48838
48998
  nodes: nodeStatuses,
48839
48999
  queue: { tasks: queue, summary: queueSummary },
48840
49000
  ledger: { entries: ledgerEntries, summary: ledgerSummary }
@@ -56913,6 +57073,7 @@ async function initDaemonComponents(config2) {
56913
57073
  sessionHostControl: config2.sessionHostControl,
56914
57074
  statusInstanceId: config2.statusInstanceId,
56915
57075
  statusVersion: config2.statusVersion,
57076
+ getMeshPeerConnectionStatus: config2.getMeshPeerConnectionStatus,
56916
57077
  getCdpLogFn: config2.getCdpLogFn || ((ideType) => LOG.forComponent(`CDP:${ideType}`).asLogFn())
56917
57078
  });
56918
57079
  poller = new AgentStreamPoller({
@@ -97190,11 +97351,30 @@ var init_daemon_mesh_manager = __esm({
97190
97351
  nodeDatachannel = null;
97191
97352
  peers = /* @__PURE__ */ new Map();
97192
97353
  // Map<targetDaemonId, PeerEntry>
97354
+ peerSnapshots = /* @__PURE__ */ new Map();
97193
97355
  pendingRequests = /* @__PURE__ */ new Map();
97194
97356
  commandCallback;
97195
97357
  p2pFailure(message, command, targetDaemonId) {
97196
97358
  return new P2pRelayFailureError(message, { command, targetDaemonId });
97197
97359
  }
97360
+ updatePeerSnapshot(targetDaemonId, state, patch = {}) {
97361
+ const previous = this.peerSnapshots.get(targetDaemonId);
97362
+ const now = (/* @__PURE__ */ new Date()).toISOString();
97363
+ this.peerSnapshots.set(targetDaemonId, {
97364
+ perspective: "selected_coordinator",
97365
+ source: "mesh_peer_status",
97366
+ reported: true,
97367
+ state,
97368
+ transport: patch.transport ?? previous?.transport ?? "unknown",
97369
+ reason: patch.reason ?? previous?.reason,
97370
+ lastStateChangeAt: now,
97371
+ lastConnectedAt: patch.lastConnectedAt ?? previous?.lastConnectedAt,
97372
+ lastCommandAt: patch.lastCommandAt ?? previous?.lastCommandAt
97373
+ });
97374
+ }
97375
+ getPeerConnectionStatus(targetDaemonId) {
97376
+ return this.peerSnapshots.get(targetDaemonId) ?? null;
97377
+ }
97198
97378
  invalidatePeer(targetDaemonId, reason, options = {}) {
97199
97379
  const peer = this.peers.get(targetDaemonId);
97200
97380
  if (peer?.commandQueue) {
@@ -97209,6 +97389,11 @@ var init_daemon_mesh_manager = __esm({
97209
97389
  pending.reject(this.p2pFailure(reason, pending.command, targetDaemonId));
97210
97390
  }
97211
97391
  }
97392
+ const snapshotState = peer?.state === "closed" ? "closed" : peer?.state === "disconnected" ? "disconnected" : "failed";
97393
+ this.updatePeerSnapshot(targetDaemonId, snapshotState, {
97394
+ reason,
97395
+ transport: peer?.isRelay === true ? "relay" : peer?.isRelay === false ? "direct" : "unknown"
97396
+ });
97212
97397
  if (options.closeResources !== false && peer) {
97213
97398
  try {
97214
97399
  peer.dataChannel?.close?.();
@@ -97328,6 +97513,20 @@ var init_daemon_mesh_manager = __esm({
97328
97513
  if (!peer) {
97329
97514
  throw this.p2pFailure("Failed to initiate P2P connection entry", command, targetDaemonId);
97330
97515
  }
97516
+ const lastCommandAt = (/* @__PURE__ */ new Date()).toISOString();
97517
+ if (peer.state === "connected") {
97518
+ this.updatePeerSnapshot(targetDaemonId, "connected", {
97519
+ transport: peer.isRelay === true ? "relay" : peer.isRelay === false ? "direct" : "unknown",
97520
+ lastConnectedAt: this.peerSnapshots.get(targetDaemonId)?.lastConnectedAt,
97521
+ lastCommandAt
97522
+ });
97523
+ } else {
97524
+ this.updatePeerSnapshot(targetDaemonId, "connecting", {
97525
+ transport: peer.isRelay === true ? "relay" : peer.isRelay === false ? "direct" : "unknown",
97526
+ reason: "Waiting for mesh DataChannel to open.",
97527
+ lastCommandAt
97528
+ });
97529
+ }
97331
97530
  return new Promise((resolve23, reject) => {
97332
97531
  const requestId = `req_${Date.now()}_${Math.random().toString(36).slice(2, 8)}`;
97333
97532
  const timer = setTimeout(() => {
@@ -97471,6 +97670,9 @@ var init_daemon_mesh_manager = __esm({
97471
97670
  remoteDescriptionSet: false
97472
97671
  };
97473
97672
  this.peers.set(targetDaemonId, entry);
97673
+ this.updatePeerSnapshot(targetDaemonId, "connecting", {
97674
+ reason: isInitiator ? "P2P mesh connection initiated by the selected coordinator." : "Waiting for the remote daemon to finish the mesh DataChannel handshake."
97675
+ });
97474
97676
  pc.onLocalDescription((sdp, type2) => {
97475
97677
  this.serverConn.sendMeshCommand(targetDaemonId, type2 === "offer" ? "mesh_p2p_offer" : "mesh_p2p_answer", { sdp, type: type2 });
97476
97678
  });
@@ -97481,7 +97683,26 @@ var init_daemon_mesh_manager = __esm({
97481
97683
  LOG.info("Mesh", `[Mesh] P2P state with ${targetDaemonId.slice(0, 12)}: ${state}`);
97482
97684
  if (state === "connected") {
97483
97685
  entry.state = "connected";
97686
+ let transport = "unknown";
97687
+ try {
97688
+ const pair = pc.getSelectedCandidatePair?.();
97689
+ if (pair) {
97690
+ const localType = pair.local?.type || "unknown";
97691
+ const remoteType = pair.remote?.type || "unknown";
97692
+ entry.isRelay = localType === "relay" || remoteType === "relay";
97693
+ transport = entry.isRelay ? "relay" : "direct";
97694
+ LOG.info("Mesh", `[Mesh] Candidate pair with ${targetDaemonId.slice(0, 12)}: local=${localType} remote=${remoteType} \u2192 ${transport}`);
97695
+ }
97696
+ } catch {
97697
+ transport = entry.isRelay === true ? "relay" : entry.isRelay === false ? "direct" : "unknown";
97698
+ }
97699
+ this.updatePeerSnapshot(targetDaemonId, "connected", {
97700
+ transport,
97701
+ reason: transport === "relay" ? "Connected over TURN relay." : transport === "direct" ? "Connected directly peer-to-peer." : "Connected, but selected candidate pair details are unavailable.",
97702
+ lastConnectedAt: (/* @__PURE__ */ new Date()).toISOString()
97703
+ });
97484
97704
  } else if (state === "failed" || state === "closed" || state === "disconnected") {
97705
+ entry.state = state;
97485
97706
  this.invalidatePeer(targetDaemonId, `P2P state changed to ${state}`, { rejectPending: true, closeResources: false });
97486
97707
  }
97487
97708
  });
@@ -97499,6 +97720,11 @@ var init_daemon_mesh_manager = __esm({
97499
97720
  dc.onOpen(() => {
97500
97721
  LOG.info("Mesh", `[Mesh] DataChannel OPEN with ${targetDaemonId.slice(0, 12)}`);
97501
97722
  entry.state = "connected";
97723
+ this.updatePeerSnapshot(targetDaemonId, "connected", {
97724
+ transport: entry.isRelay === true ? "relay" : entry.isRelay === false ? "direct" : "unknown",
97725
+ reason: entry.isRelay === true ? "Connected over TURN relay." : entry.isRelay === false ? "Connected directly peer-to-peer." : "DataChannel open; transport details not reported yet.",
97726
+ lastConnectedAt: (/* @__PURE__ */ new Date()).toISOString()
97727
+ });
97502
97728
  if (entry.commandQueue) {
97503
97729
  const queue = entry.commandQueue;
97504
97730
  entry.commandQueue = [];
@@ -97794,7 +98020,7 @@ var init_adhdev_daemon = __esm({
97794
98020
  init_version();
97795
98021
  init_src();
97796
98022
  init_runtime_defaults();
97797
- pkgVersion = resolvePackageVersion({ injectedVersion: "0.9.82-rc.6" });
98023
+ pkgVersion = resolvePackageVersion({ injectedVersion: "0.9.82-rc.8" });
97798
98024
  AdhdevDaemon = class _AdhdevDaemon {
97799
98025
  localHttpServer = null;
97800
98026
  localWss = null;
@@ -98318,6 +98544,7 @@ ${err?.stack || ""}`);
98318
98544
  if (!this.meshManager) throw new Error("Mesh manager not initialized");
98319
98545
  return this.meshManager.sendCommand(daemonId, command, args);
98320
98546
  },
98547
+ getMeshPeerConnectionStatus: (daemonId) => this.meshManager?.getPeerConnectionStatus(daemonId) ?? null,
98321
98548
  onStatusChange: () => {
98322
98549
  this.invalidateHotChatSnapshotCache();
98323
98550
  this.statusReporter?.onStatusChange();