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

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@adhdev/daemon-core",
3
- "version": "0.9.82-rc.21",
3
+ "version": "0.9.82-rc.22",
4
4
  "description": "ADHDev daemon core — CDP, IDE detection, providers, command execution",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",
@@ -222,6 +222,125 @@ function buildCachedInlineMeshGitStatus(node: any): Record<string, unknown> | un
222
222
  };
223
223
  }
224
224
 
225
+ function shouldDiscardCachedInlineMeshStatus(node: any): boolean {
226
+ const cachedStatus = readObjectRecord(node?.cachedStatus);
227
+ if (!Object.keys(cachedStatus).length) return false;
228
+ const cachedGit = readObjectRecord(cachedStatus.git);
229
+ const workspaceError = readStringValue(cachedStatus.error, node?.error);
230
+ if (workspaceError && /workspace must be an existing directory/i.test(workspaceError)) return true;
231
+ const isGitRepo = readBooleanValue(cachedGit.isGitRepo);
232
+ const branch = readStringValue(cachedGit.branch);
233
+ const headCommit = readStringValue(cachedGit.headCommit);
234
+ return isGitRepo === false && !branch && !headCommit;
235
+ }
236
+
237
+ function stripInlineMeshTransientNodeState(node: any): any {
238
+ if (!node || typeof node !== 'object' || Array.isArray(node)) return node;
239
+ const {
240
+ cachedStatus,
241
+ lastGit: _lastGit,
242
+ last_git: _lastGitLegacy,
243
+ lastProbe: _lastProbe,
244
+ last_probe: _lastProbeLegacy,
245
+ error: _error,
246
+ health: _health,
247
+ machineStatus: _machineStatus,
248
+ lastSeenAt: _lastSeenAt,
249
+ last_seen_at: _lastSeenAtLegacy,
250
+ updatedAt: _updatedAt,
251
+ updated_at: _updatedAtLegacy,
252
+ activeSession: _activeSession,
253
+ active_session: _activeSessionLegacy,
254
+ activeSessionId: _activeSessionId,
255
+ active_session_id: _activeSessionIdLegacy,
256
+ sessionId: _sessionId,
257
+ session_id: _sessionIdLegacy,
258
+ providerType: _providerType,
259
+ provider_type: _providerTypeLegacy,
260
+ providers: _providers,
261
+ ...rest
262
+ } = node as Record<string, unknown>;
263
+ if (cachedStatus && !shouldDiscardCachedInlineMeshStatus(node)) {
264
+ return { ...rest, cachedStatus };
265
+ }
266
+ return rest;
267
+ }
268
+
269
+ function hasInlineMeshTransientNodeState(node: any): boolean {
270
+ if (!node || typeof node !== 'object' || Array.isArray(node)) return false;
271
+ return 'cachedStatus' in node
272
+ || 'lastGit' in node
273
+ || 'last_git' in node
274
+ || 'lastProbe' in node
275
+ || 'last_probe' in node
276
+ || 'error' in node
277
+ || 'health' in node
278
+ || 'machineStatus' in node
279
+ || 'lastSeenAt' in node
280
+ || 'last_seen_at' in node
281
+ || 'updatedAt' in node
282
+ || 'updated_at' in node
283
+ || 'activeSession' in node
284
+ || 'active_session' in node
285
+ || 'activeSessionId' in node
286
+ || 'active_session_id' in node
287
+ || 'sessionId' in node
288
+ || 'session_id' in node
289
+ || 'providerType' in node
290
+ || 'provider_type' in node
291
+ || 'providers' in node;
292
+ }
293
+
294
+ function readInlineMeshNodeId(node: any): string {
295
+ return readStringValue(node?.id, node?.nodeId) || '';
296
+ }
297
+
298
+ function sanitizeInlineMesh(inlineMesh: any): any {
299
+ if (!inlineMesh || typeof inlineMesh !== 'object' || Array.isArray(inlineMesh)) return inlineMesh;
300
+ if (!Array.isArray(inlineMesh.nodes)) return inlineMesh;
301
+ let changed = false;
302
+ const nodes = inlineMesh.nodes.map((node: any) => {
303
+ if (!hasInlineMeshTransientNodeState(node)) return node;
304
+ changed = true;
305
+ return stripInlineMeshTransientNodeState(node);
306
+ });
307
+ if (!changed) return inlineMesh;
308
+ return {
309
+ ...inlineMesh,
310
+ nodes,
311
+ };
312
+ }
313
+
314
+ function reconcileInlineMeshCache(cached: any, incoming: any): any {
315
+ if (!cached || typeof cached !== 'object' || Array.isArray(cached)) return incoming;
316
+ if (!incoming || typeof incoming !== 'object' || Array.isArray(incoming)) return cached;
317
+ const cachedNodes = Array.isArray(cached.nodes) ? cached.nodes : [];
318
+ const incomingNodes = Array.isArray(incoming.nodes) ? incoming.nodes : [];
319
+ if (!cachedNodes.length || !incomingNodes.length) return { ...cached, ...incoming };
320
+
321
+ const incomingById = new Map<string, any>();
322
+ for (const node of incomingNodes) {
323
+ const nodeId = readInlineMeshNodeId(node);
324
+ if (nodeId) incomingById.set(nodeId, node);
325
+ }
326
+
327
+ const nodes = cachedNodes.map((cachedNode: any) => {
328
+ const nodeId = readInlineMeshNodeId(cachedNode);
329
+ const incomingNode = nodeId ? incomingById.get(nodeId) : undefined;
330
+ if (!incomingNode) return cachedNode;
331
+ if (hasInlineMeshTransientNodeState(incomingNode)) {
332
+ return { ...cachedNode, ...incomingNode };
333
+ }
334
+ return { ...stripInlineMeshTransientNodeState(cachedNode), ...incomingNode };
335
+ });
336
+
337
+ return {
338
+ ...cached,
339
+ ...incoming,
340
+ nodes,
341
+ };
342
+ }
343
+
225
344
  function hasGitWorktreeChanges(git: Record<string, unknown> | null | undefined): boolean {
226
345
  if (!git) return false;
227
346
  return Number(git.staged || 0) + Number(git.modified || 0) + Number(git.untracked || 0) + Number(git.deleted || 0) + Number(git.renamed || 0) > 0;
@@ -960,10 +1079,15 @@ export class DaemonCommandRouter {
960
1079
 
961
1080
  private warmInlineMeshCache(meshId: string, inlineMesh?: unknown): any | undefined {
962
1081
  if (!inlineMesh || typeof inlineMesh !== 'object') return undefined;
1082
+ const sanitizedInlineMesh = sanitizeInlineMesh(inlineMesh as any);
963
1083
  const cached = this.inlineMeshCache.get(meshId);
964
- if (cached) return cached;
965
- this.inlineMeshCache.set(meshId, inlineMesh as any);
966
- return inlineMesh as any;
1084
+ if (cached) {
1085
+ const merged = reconcileInlineMeshCache(cached, sanitizedInlineMesh);
1086
+ this.inlineMeshCache.set(meshId, merged);
1087
+ return merged;
1088
+ }
1089
+ this.inlineMeshCache.set(meshId, sanitizedInlineMesh as any);
1090
+ return sanitizedInlineMesh as any;
967
1091
  }
968
1092
 
969
1093
  private async getMeshForCommand(
@@ -3203,10 +3327,17 @@ export class DaemonCommandRouter {
3203
3327
  }
3204
3328
  }
3205
3329
  if (workspace) {
3206
- if (!fs.existsSync(workspace) && applyCachedInlineMeshNodeStatus(status, node)) {
3207
- status.launchReady = !!daemonId && (readStringValue(status.machineStatus) === 'online' || isSelfNode);
3208
- nodeStatuses.push(status);
3209
- continue;
3330
+ if (!fs.existsSync(workspace)) {
3331
+ if (applyCachedInlineMeshNodeStatus(status, node)) {
3332
+ status.launchReady = !!daemonId && (readStringValue(status.machineStatus) === 'online' || isSelfNode);
3333
+ nodeStatuses.push(status);
3334
+ continue;
3335
+ }
3336
+ if (meshRecord?.source === 'inline_cache' && !isSelfNode) {
3337
+ status.launchReady = !!daemonId && (readStringValue(status.machineStatus) === 'online' || isSelfNode);
3338
+ nodeStatuses.push(status);
3339
+ continue;
3340
+ }
3210
3341
  }
3211
3342
  try {
3212
3343
  const gitStatus = await getGitRepoStatus(workspace, { timeoutMs: 10_000, refreshUpstream: true });