@adhdev/daemon-core 0.9.82-rc.7 → 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.
@@ -59,6 +59,8 @@ export interface DaemonInitConfig {
59
59
  }) => void;
60
60
  /** Relays a command to a remote mesh node daemon */
61
61
  dispatchMeshCommand?: (daemonId: string, command: string, args: Record<string, unknown>) => Promise<any>;
62
+ /** Returns selected-coordinator mesh peer telemetry for a target daemon when available. */
63
+ getMeshPeerConnectionStatus?: (daemonId: string) => Record<string, unknown> | null;
62
64
  }
63
65
  export interface DaemonComponents {
64
66
  providerLoader: ProviderLoader;
@@ -72,6 +72,8 @@ export interface CommandRouterDeps {
72
72
  statusVersion?: string;
73
73
  /** Session host control plane */
74
74
  sessionHostControl?: SessionHostControlPlane | null;
75
+ /** Selected-coordinator mesh peer telemetry surface for target daemons, when supported by the runtime. */
76
+ getMeshPeerConnectionStatus?: (daemonId: string) => Record<string, unknown> | null;
75
77
  }
76
78
  export interface CommandRouterResult {
77
79
  success: boolean;
package/dist/index.d.ts CHANGED
@@ -5,7 +5,7 @@
5
5
  */
6
6
  export type { ChatBubbleState, ChatMessage, ExtensionInfo, CommandResult as CoreCommandResult, ProviderConfig, DaemonEvent, StatusResponse, SystemInfo, DetectedIde, ProviderInfo, AgentEntry, } from './types.js';
7
7
  export type { SessionEntry, CompactSessionEntry, CompactDaemonEntry, CloudDaemonSummaryEntry, DashboardBootstrapDaemonEntry, VersionUpdateReason, CloudStatusReportPayload, DaemonStatusEventPayload, DashboardStatusEventPayload, SessionTransport, SessionKind, SessionCapability, AgentSessionStream, ReadChatCursor, ReadChatSyncResult, TransportTopic, SessionChatTailSubscriptionParams, SessionRuntimeOutputSubscriptionParams, MachineRuntimeSubscriptionParams, SessionHostDiagnosticsSubscriptionParams, SessionModalSubscriptionParams, DaemonMetadataSubscriptionParams, WorkspaceGitSubscriptionParams, SessionChatTailUpdate, MachineRuntimeUpdate, SessionHostDiagnosticsUpdate, SessionModalUpdate, DaemonMetadataUpdate, TopicUpdateEnvelope, SubscribeRequest, UnsubscribeRequest, StandaloneWsStatusPayload, AvailableProviderInfo, AcpConfigOption, AcpMode, ProviderControlSchema, StatusReportPayload, MachineInfo, SessionHostDiagnosticsSnapshot, SessionHostRecord, SessionHostWriteOwner, SessionHostAttachedClient, SessionHostLogEntry, SessionHostRequestTrace, SessionHostRuntimeTransition, DetectedIdeInfo, WorkspaceEntry, ProviderSummaryItem, ProviderSummaryMetadata, ProviderState, ProviderStatus, ProviderErrorReason, SessionActiveChatData, ActiveChatData, IdeProviderState, CliProviderState, AcpProviderState, ExtensionProviderState, MessageInputSupport, InputMediaStrategyDescriptor, InputAttachmentStrategy, InputMediaType, } from './shared-types.js';
8
- export type { RepoMesh, RepoMeshNode, RepoMeshNodeHealth, RepoMeshPolicy, RepoMeshNodePolicy, RepoMeshRelatedRepo, RepoMeshNodeCapabilities, DetectedCommand, ProjectContextSnapshot, ProjectContextSource, RepoMeshCoordinatorConfig, LocalMeshConfig, LocalMeshEntry, LocalMeshNodeEntry, RepoMeshStatus, RepoMeshNodeStatus, } from './repo-mesh-types.js';
8
+ export type { RepoMesh, RepoMeshNode, RepoMeshNodeHealth, RepoMeshPolicy, RepoMeshNodePolicy, RepoMeshRelatedRepo, RepoMeshNodeCapabilities, DetectedCommand, ProjectContextSnapshot, ProjectContextSource, RepoMeshCoordinatorConfig, LocalMeshConfig, LocalMeshEntry, LocalMeshNodeEntry, RepoMeshStatus, RepoMeshNodeStatus, RepoMeshSessionStatus, RepoMeshQueueTask, RepoMeshQueueTaskStatus, RepoMeshQueueSummary, RepoMeshQueueStatus, RepoMeshLedgerEntryStatus, RepoMeshLedgerSummaryStatus, RepoMeshLedgerStatus, } from './repo-mesh-types.js';
9
9
  export { DEFAULT_MESH_POLICY } from './repo-mesh-types.js';
10
10
  export * from './git/index.js';
11
11
  import type { RuntimeWriteOwner as _RuntimeWriteOwner } from './shared-types-extra.js';
package/dist/index.js CHANGED
@@ -23957,17 +23957,87 @@ function readCachedInlineMeshActiveSessions(node) {
23957
23957
  const sessionId = readStringValue(fallbackSession.id, fallbackSession.sessionId, fallbackSession.session_id, node?.activeSessionId, node?.active_session_id, node?.sessionId, node?.session_id);
23958
23958
  return sessionId ? [sessionId] : [];
23959
23959
  }
23960
+ function readCachedInlineMeshActiveSessionDetails(node) {
23961
+ const cachedStatus = readObjectRecord(node?.cachedStatus);
23962
+ const activeSession = readObjectRecord(cachedStatus.activeSession);
23963
+ const fallbackSession = Object.keys(activeSession).length ? activeSession : readObjectRecord(node?.activeSession ?? node?.active_session);
23964
+ const sessionId = readStringValue(
23965
+ fallbackSession.id,
23966
+ fallbackSession.sessionId,
23967
+ fallbackSession.session_id,
23968
+ node?.activeSessionId,
23969
+ node?.active_session_id,
23970
+ node?.sessionId,
23971
+ node?.session_id
23972
+ );
23973
+ if (!sessionId) return [];
23974
+ return [{
23975
+ sessionId,
23976
+ providerType: readStringValue(
23977
+ fallbackSession.providerType,
23978
+ fallbackSession.provider_type,
23979
+ fallbackSession.cliType,
23980
+ fallbackSession.cli_type,
23981
+ fallbackSession.provider,
23982
+ node?.providerType,
23983
+ node?.provider_type
23984
+ ),
23985
+ state: readStringValue(fallbackSession.status, fallbackSession.state, fallbackSession.lifecycle),
23986
+ lifecycle: readStringValue(fallbackSession.lifecycle),
23987
+ title: readStringValue(fallbackSession.title, fallbackSession.displayName, fallbackSession.display_name) ?? null,
23988
+ workspace: readStringValue(fallbackSession.workspace, node?.workspace) ?? null,
23989
+ lastActivityAt: readStringValue(fallbackSession.lastActivityAt, fallbackSession.last_activity_at) ?? null,
23990
+ recoveryState: readStringValue(fallbackSession.recoveryState, fallbackSession.recovery_state) ?? null,
23991
+ isCached: true
23992
+ }];
23993
+ }
23994
+ function readLiveMeshSessionState(record) {
23995
+ return readStringValue(
23996
+ record?.meta?.sessionStatus,
23997
+ record?.meta?.status,
23998
+ record?.meta?.providerStatus,
23999
+ record?.status,
24000
+ record?.state,
24001
+ record?.lifecycle
24002
+ );
24003
+ }
24004
+ function toIsoTimestamp(value) {
24005
+ if (typeof value === "number" && Number.isFinite(value)) return new Date(value).toISOString();
24006
+ const stringValue = readStringValue(value);
24007
+ return stringValue || null;
24008
+ }
24009
+ function summarizeMeshSessionRecord(record) {
24010
+ return {
24011
+ sessionId: readStringValue(record?.sessionId) || "unknown",
24012
+ providerType: readStringValue(record?.providerType),
24013
+ state: readLiveMeshSessionState(record),
24014
+ lifecycle: readStringValue(record?.lifecycle),
24015
+ surfaceKind: getSessionHostSurfaceKind(record),
24016
+ recoveryState: readStringValue(record?.meta?.runtimeRecoveryState) ?? null,
24017
+ workspace: readStringValue(record?.workspace) ?? null,
24018
+ title: readStringValue(record?.displayName, record?.workspaceLabel) ?? null,
24019
+ lastActivityAt: toIsoTimestamp(record?.updatedAt ?? record?.lastActivityAt ?? record?.last_activity_at),
24020
+ isCached: false
24021
+ };
24022
+ }
23960
24023
  function applyCachedInlineMeshNodeStatus(status, node) {
23961
24024
  const cachedStatus = readObjectRecord(node?.cachedStatus);
23962
24025
  const git = buildCachedInlineMeshGitStatus(node);
23963
24026
  const error = readStringValue(cachedStatus.error, node?.error);
23964
24027
  const health = readStringValue(cachedStatus.health, node?.health);
23965
24028
  const machineStatus = readStringValue(cachedStatus.machineStatus, node?.machineStatus);
24029
+ const lastSeenAt = toIsoTimestamp(cachedStatus.lastSeenAt ?? cachedStatus.last_seen_at ?? node?.lastSeenAt ?? node?.last_seen_at);
24030
+ const updatedAt = toIsoTimestamp(cachedStatus.updatedAt ?? cachedStatus.updated_at ?? node?.updatedAt ?? node?.updated_at);
23966
24031
  const activeSessions = readCachedInlineMeshActiveSessions(node);
23967
- if (!git && !error && !health && !machineStatus && activeSessions.length === 0) return false;
24032
+ const activeSessionDetails = readCachedInlineMeshActiveSessionDetails(node);
24033
+ if (!git && !error && !health && !machineStatus && !lastSeenAt && !updatedAt && activeSessions.length === 0) return false;
23968
24034
  if (git) status.git = git;
23969
24035
  if (error) status.error = error;
24036
+ if (machineStatus) status.machineStatus = machineStatus;
24037
+ if (lastSeenAt) status.lastSeenAt = lastSeenAt;
24038
+ if (updatedAt) status.updatedAt = updatedAt;
23970
24039
  if (activeSessions.length > 0) status.activeSessions = activeSessions;
24040
+ if (activeSessionDetails.length > 0) status.activeSessionDetails = activeSessionDetails;
23971
24041
  if (health) {
23972
24042
  status.health = health;
23973
24043
  return true;
@@ -23976,7 +24046,7 @@ function applyCachedInlineMeshNodeStatus(status, node) {
23976
24046
  status.health = deriveMeshNodeHealthFromGit(git);
23977
24047
  return true;
23978
24048
  }
23979
- return activeSessions.length > 0 || !!machineStatus;
24049
+ return activeSessions.length > 0 || !!machineStatus || !!lastSeenAt || !!updatedAt;
23980
24050
  }
23981
24051
  async function resolveProviderTypeFromPriority(args) {
23982
24052
  if (!args.providerPriority.length) {
@@ -26218,28 +26288,79 @@ ${block}`);
26218
26288
  const ledgerSummary = getLedgerSummary2(meshId);
26219
26289
  const sessionHostRecords = this.deps.sessionHostControl?.listSessions ? await this.deps.sessionHostControl.listSessions().catch(() => []) : [];
26220
26290
  const liveMeshSessions = partitionSessionHostRecords(Array.isArray(sessionHostRecords) ? sessionHostRecords : []).liveRuntimes;
26291
+ const localMachineId = loadConfig().machineId || "";
26292
+ const inlineCoordinatorNodeId = meshRecord?.inline && Array.isArray(mesh.nodes) ? readStringValue(mesh.nodes[0]?.id, mesh.nodes[0]?.nodeId) : void 0;
26293
+ const refreshedAt = (/* @__PURE__ */ new Date()).toISOString();
26221
26294
  const nodeStatuses = [];
26222
- for (const node of mesh.nodes || []) {
26295
+ for (const [nodeIndex, node] of (mesh.nodes || []).entries()) {
26296
+ const nodeId = String(node.id || node.nodeId || "");
26297
+ const daemonId = readStringValue(node.daemonId);
26298
+ const providerPriority = readProviderPriorityFromPolicy(node.policy);
26299
+ const isSelfNode = Boolean(
26300
+ nodeId && inlineCoordinatorNodeId && nodeId === inlineCoordinatorNodeId
26301
+ ) || Boolean(
26302
+ daemonId && (daemonId === localMachineId || daemonId === this.deps.statusInstanceId)
26303
+ ) || Boolean(meshRecord?.inline && nodeIndex === 0);
26223
26304
  const status = {
26224
- nodeId: node.id || node.nodeId,
26305
+ nodeId,
26225
26306
  machineLabel: node.machineLabel || node.id || node.nodeId,
26226
26307
  workspace: node.workspace,
26227
26308
  repoRoot: node.repoRoot,
26228
26309
  isLocalWorktree: node.isLocalWorktree,
26229
26310
  worktreeBranch: node.worktreeBranch,
26230
- daemonId: node.daemonId,
26311
+ daemonId,
26231
26312
  machineId: node.machineId,
26313
+ machineStatus: node.machineStatus,
26232
26314
  health: "unknown",
26233
26315
  providers: node.providers || [],
26234
- activeSessions: []
26316
+ providerPriority,
26317
+ activeSessions: [],
26318
+ activeSessionDetails: [],
26319
+ launchReady: false
26235
26320
  };
26236
- const nodeId = String(node.id || node.nodeId || "");
26237
- const matchedLiveSessions = liveMeshSessions.filter((record) => this.sessionMatchesMeshNode(record, node, nodeId)).map((record) => typeof record?.sessionId === "string" ? record.sessionId : "").filter(Boolean);
26238
- if (matchedLiveSessions.length > 0) {
26239
- status.activeSessions = matchedLiveSessions;
26321
+ if (isSelfNode) {
26322
+ status.connection = {
26323
+ perspective: "selected_coordinator",
26324
+ source: "mesh_peer_status",
26325
+ state: "self",
26326
+ transport: "local",
26327
+ reported: true,
26328
+ reason: "Selected coordinator daemon",
26329
+ lastStateChangeAt: refreshedAt
26330
+ };
26331
+ } else if (daemonId) {
26332
+ const connection = this.deps.getMeshPeerConnectionStatus?.(daemonId);
26333
+ status.connection = connection ?? {
26334
+ perspective: "selected_coordinator",
26335
+ source: "not_reported",
26336
+ state: "unknown",
26337
+ transport: "unknown",
26338
+ reported: false,
26339
+ reason: "No live mesh peer telemetry reported by the selected coordinator yet."
26340
+ };
26341
+ } else {
26342
+ status.connection = {
26343
+ perspective: "selected_coordinator",
26344
+ source: "not_reported",
26345
+ state: "unknown",
26346
+ transport: "unknown",
26347
+ reported: false,
26348
+ reason: "Node has no daemon id, so mesh transport cannot be reported from the selected coordinator."
26349
+ };
26350
+ }
26351
+ const matchedLiveSessionRecords = liveMeshSessions.filter((record) => this.sessionMatchesMeshNode(record, node, nodeId));
26352
+ if (matchedLiveSessionRecords.length > 0) {
26353
+ const sessionIds = matchedLiveSessionRecords.map((record) => typeof record?.sessionId === "string" ? record.sessionId : "").filter(Boolean);
26354
+ const providerTypes = matchedLiveSessionRecords.map((record) => readStringValue(record?.providerType)).filter(Boolean);
26355
+ status.activeSessions = sessionIds;
26356
+ status.activeSessionDetails = matchedLiveSessionRecords.map(summarizeMeshSessionRecord);
26357
+ if (providerTypes.length > 0) {
26358
+ status.providers = Array.from(/* @__PURE__ */ new Set([...Array.isArray(status.providers) ? status.providers : [], ...providerTypes]));
26359
+ }
26240
26360
  }
26241
26361
  if (node.workspace && typeof node.workspace === "string") {
26242
26362
  if (!fs10.existsSync(node.workspace) && applyCachedInlineMeshNodeStatus(status, node)) {
26363
+ status.launchReady = !!daemonId && (readStringValue(status.machineStatus) === "online" || isSelfNode);
26243
26364
  nodeStatuses.push(status);
26244
26365
  continue;
26245
26366
  }
@@ -26260,6 +26381,7 @@ ${block}`);
26260
26381
  } else {
26261
26382
  applyCachedInlineMeshNodeStatus(status, node);
26262
26383
  }
26384
+ status.launchReady = !!daemonId && (readStringValue(status.machineStatus) === "online" || isSelfNode);
26263
26385
  nodeStatuses.push(status);
26264
26386
  }
26265
26387
  return {
@@ -26268,6 +26390,7 @@ ${block}`);
26268
26390
  meshName: mesh.name,
26269
26391
  repoIdentity: mesh.repoIdentity,
26270
26392
  defaultBranch: mesh.defaultBranch,
26393
+ refreshedAt: (/* @__PURE__ */ new Date()).toISOString(),
26271
26394
  nodes: nodeStatuses,
26272
26395
  queue: { tasks: queue, summary: queueSummary },
26273
26396
  ledger: { entries: ledgerEntries, summary: ledgerSummary }
@@ -34197,6 +34320,7 @@ async function initDaemonComponents(config) {
34197
34320
  sessionHostControl: config.sessionHostControl,
34198
34321
  statusInstanceId: config.statusInstanceId,
34199
34322
  statusVersion: config.statusVersion,
34323
+ getMeshPeerConnectionStatus: config.getMeshPeerConnectionStatus,
34200
34324
  getCdpLogFn: config.getCdpLogFn || ((ideType) => LOG.forComponent(`CDP:${ideType}`).asLogFn())
34201
34325
  });
34202
34326
  poller = new AgentStreamPoller({