@adhdev/daemon-core 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.
@@ -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
@@ -23926,26 +23926,127 @@ function buildCachedInlineMeshGitStatus(node) {
23926
23926
  ...submodules ? { submodules } : {}
23927
23927
  };
23928
23928
  }
23929
+ function hasGitWorktreeChanges(git) {
23930
+ if (!git) return false;
23931
+ return Number(git.staged || 0) + Number(git.modified || 0) + Number(git.untracked || 0) + Number(git.deleted || 0) + Number(git.renamed || 0) > 0;
23932
+ }
23933
+ function getGitSubmoduleDriftState(git) {
23934
+ const submodules = Array.isArray(git?.submodules) ? git.submodules : [];
23935
+ let dirty = false;
23936
+ let outOfSync = false;
23937
+ for (const entry of submodules) {
23938
+ const submodule = readObjectRecord(entry);
23939
+ if (readBooleanValue(submodule.dirty) === true) dirty = true;
23940
+ if (readBooleanValue(submodule.outOfSync) === true || !!readStringValue(submodule.error)) outOfSync = true;
23941
+ }
23942
+ return { dirty, outOfSync };
23943
+ }
23944
+ function deriveMeshNodeHealthFromGit(git) {
23945
+ if (!git || readBooleanValue(git.isGitRepo) === false) return "degraded";
23946
+ const branch = readStringValue(git.branch);
23947
+ if (!branch) return "degraded";
23948
+ const submoduleDrift = getGitSubmoduleDriftState(git);
23949
+ if (submoduleDrift.outOfSync) return "degraded";
23950
+ if (submoduleDrift.dirty || hasGitWorktreeChanges(git)) return "dirty";
23951
+ return "online";
23952
+ }
23953
+ function readCachedInlineMeshActiveSessions(node) {
23954
+ const cachedStatus = readObjectRecord(node?.cachedStatus);
23955
+ const activeSession = readObjectRecord(cachedStatus.activeSession);
23956
+ const fallbackSession = Object.keys(activeSession).length ? activeSession : readObjectRecord(node?.activeSession ?? node?.active_session);
23957
+ const sessionId = readStringValue(fallbackSession.id, fallbackSession.sessionId, fallbackSession.session_id, node?.activeSessionId, node?.active_session_id, node?.sessionId, node?.session_id);
23958
+ return sessionId ? [sessionId] : [];
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
+ }
23929
24023
  function applyCachedInlineMeshNodeStatus(status, node) {
23930
24024
  const cachedStatus = readObjectRecord(node?.cachedStatus);
23931
24025
  const git = buildCachedInlineMeshGitStatus(node);
23932
24026
  const error = readStringValue(cachedStatus.error, node?.error);
23933
24027
  const health = readStringValue(cachedStatus.health, node?.health);
23934
24028
  const machineStatus = readStringValue(cachedStatus.machineStatus, node?.machineStatus);
23935
- if (!git && !error && !health) return false;
23936
- if (!machineStatus && !git && !error) return false;
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);
24031
+ const activeSessions = readCachedInlineMeshActiveSessions(node);
24032
+ const activeSessionDetails = readCachedInlineMeshActiveSessionDetails(node);
24033
+ if (!git && !error && !health && !machineStatus && !lastSeenAt && !updatedAt && activeSessions.length === 0) return false;
23937
24034
  if (git) status.git = git;
23938
24035
  if (error) status.error = error;
24036
+ if (machineStatus) status.machineStatus = machineStatus;
24037
+ if (lastSeenAt) status.lastSeenAt = lastSeenAt;
24038
+ if (updatedAt) status.updatedAt = updatedAt;
24039
+ if (activeSessions.length > 0) status.activeSessions = activeSessions;
24040
+ if (activeSessionDetails.length > 0) status.activeSessionDetails = activeSessionDetails;
23939
24041
  if (health) {
23940
24042
  status.health = health;
23941
24043
  return true;
23942
24044
  }
23943
24045
  if (git) {
23944
- const dirty = Number(git.staged || 0) + Number(git.modified || 0) + Number(git.untracked || 0) + Number(git.deleted || 0) + Number(git.renamed || 0) > 0;
23945
- status.health = git.isGitRepo === false ? "degraded" : dirty ? "dirty" : "online";
24046
+ status.health = deriveMeshNodeHealthFromGit(git);
23946
24047
  return true;
23947
24048
  }
23948
- return false;
24049
+ return activeSessions.length > 0 || !!machineStatus || !!lastSeenAt || !!updatedAt;
23949
24050
  }
23950
24051
  async function resolveProviderTypeFromPriority(args) {
23951
24052
  if (!args.providerPriority.length) {
@@ -26185,23 +26286,81 @@ ${block}`);
26185
26286
  const { readLedgerEntries: readLedgerEntries2, getLedgerSummary: getLedgerSummary2 } = await Promise.resolve().then(() => (init_mesh_ledger(), mesh_ledger_exports));
26186
26287
  const ledgerEntries = readLedgerEntries2(meshId, { tail: 20 });
26187
26288
  const ledgerSummary = getLedgerSummary2(meshId);
26289
+ const sessionHostRecords = this.deps.sessionHostControl?.listSessions ? await this.deps.sessionHostControl.listSessions().catch(() => []) : [];
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();
26188
26294
  const nodeStatuses = [];
26189
- 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);
26190
26304
  const status = {
26191
- nodeId: node.id || node.nodeId,
26305
+ nodeId,
26192
26306
  machineLabel: node.machineLabel || node.id || node.nodeId,
26193
26307
  workspace: node.workspace,
26194
26308
  repoRoot: node.repoRoot,
26195
26309
  isLocalWorktree: node.isLocalWorktree,
26196
26310
  worktreeBranch: node.worktreeBranch,
26197
- daemonId: node.daemonId,
26311
+ daemonId,
26198
26312
  machineId: node.machineId,
26313
+ machineStatus: node.machineStatus,
26199
26314
  health: "unknown",
26200
26315
  providers: node.providers || [],
26201
- activeSessions: []
26316
+ providerPriority,
26317
+ activeSessions: [],
26318
+ activeSessionDetails: [],
26319
+ launchReady: false
26202
26320
  };
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
+ }
26360
+ }
26203
26361
  if (node.workspace && typeof node.workspace === "string") {
26204
26362
  if (!fs10.existsSync(node.workspace) && applyCachedInlineMeshNodeStatus(status, node)) {
26363
+ status.launchReady = !!daemonId && (readStringValue(status.machineStatus) === "online" || isSelfNode);
26205
26364
  nodeStatuses.push(status);
26206
26365
  continue;
26207
26366
  }
@@ -26209,8 +26368,7 @@ ${block}`);
26209
26368
  const gitStatus = await getGitRepoStatus(node.workspace, { timeoutMs: 1e4 });
26210
26369
  status.git = gitStatus;
26211
26370
  if (gitStatus.isGitRepo) {
26212
- const dirty = gitStatus.staged + gitStatus.modified + gitStatus.untracked + gitStatus.deleted + gitStatus.renamed > 0;
26213
- status.health = gitStatus.branch ? dirty ? "dirty" : "online" : "degraded";
26371
+ status.health = deriveMeshNodeHealthFromGit(gitStatus);
26214
26372
  } else {
26215
26373
  status.health = "degraded";
26216
26374
  if (gitStatus.error && !status.error) status.error = gitStatus.error;
@@ -26223,6 +26381,7 @@ ${block}`);
26223
26381
  } else {
26224
26382
  applyCachedInlineMeshNodeStatus(status, node);
26225
26383
  }
26384
+ status.launchReady = !!daemonId && (readStringValue(status.machineStatus) === "online" || isSelfNode);
26226
26385
  nodeStatuses.push(status);
26227
26386
  }
26228
26387
  return {
@@ -26231,6 +26390,7 @@ ${block}`);
26231
26390
  meshName: mesh.name,
26232
26391
  repoIdentity: mesh.repoIdentity,
26233
26392
  defaultBranch: mesh.defaultBranch,
26393
+ refreshedAt: (/* @__PURE__ */ new Date()).toISOString(),
26234
26394
  nodes: nodeStatuses,
26235
26395
  queue: { tasks: queue, summary: queueSummary },
26236
26396
  ledger: { entries: ledgerEntries, summary: ledgerSummary }
@@ -34160,6 +34320,7 @@ async function initDaemonComponents(config) {
34160
34320
  sessionHostControl: config.sessionHostControl,
34161
34321
  statusInstanceId: config.statusInstanceId,
34162
34322
  statusVersion: config.statusVersion,
34323
+ getMeshPeerConnectionStatus: config.getMeshPeerConnectionStatus,
34163
34324
  getCdpLogFn: config.getCdpLogFn || ((ideType) => LOG.forComponent(`CDP:${ideType}`).asLogFn())
34164
34325
  });
34165
34326
  poller = new AgentStreamPoller({