@adhdev/daemon-core 0.9.82-rc.21 → 0.9.82-rc.23
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.js +125 -11
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +125 -11
- package/dist/index.mjs.map +1 -1
- package/package.json +1 -1
- package/src/commands/router.ts +158 -11
package/package.json
CHANGED
package/src/commands/router.ts
CHANGED
|
@@ -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;
|
|
@@ -328,6 +447,23 @@ function summarizeMeshSessionRecord(record: any): Record<string, unknown> {
|
|
|
328
447
|
};
|
|
329
448
|
}
|
|
330
449
|
|
|
450
|
+
function liveSessionRecordMatchesMeshNode(record: any, meshId: string, nodeId: string): boolean {
|
|
451
|
+
const recordNodeId = readStringValue(record?.meta?.meshNodeId);
|
|
452
|
+
if (!recordNodeId || recordNodeId !== nodeId) return false;
|
|
453
|
+
const recordMeshId = readStringValue(record?.meta?.meshNodeFor);
|
|
454
|
+
return !recordMeshId || recordMeshId === meshId;
|
|
455
|
+
}
|
|
456
|
+
|
|
457
|
+
function liveSessionRecordMatchesMeshWorkspace(record: any, meshId: string, workspace: string): boolean {
|
|
458
|
+
const recordWorkspace = readStringValue(record?.workspace);
|
|
459
|
+
if (!recordWorkspace || !workspace || recordWorkspace !== workspace) return false;
|
|
460
|
+
|
|
461
|
+
const recordMeshId = readStringValue(record?.meta?.meshNodeFor);
|
|
462
|
+
if (recordMeshId) return recordMeshId === meshId;
|
|
463
|
+
|
|
464
|
+
return record?.meta?.launchedByCoordinator === true || !!readStringValue(record?.meta?.meshNodeId);
|
|
465
|
+
}
|
|
466
|
+
|
|
331
467
|
function readLiveMeshNodeWorkspace(args: {
|
|
332
468
|
meshId: string;
|
|
333
469
|
nodeId: string;
|
|
@@ -335,7 +471,7 @@ function readLiveMeshNodeWorkspace(args: {
|
|
|
335
471
|
allowCoordinatorSession?: boolean;
|
|
336
472
|
}): string {
|
|
337
473
|
const directNodeWorkspace = args.liveSessionRecords.find((record) => (
|
|
338
|
-
|
|
474
|
+
liveSessionRecordMatchesMeshNode(record, args.meshId, args.nodeId)
|
|
339
475
|
&& readStringValue(record?.workspace)
|
|
340
476
|
));
|
|
341
477
|
if (directNodeWorkspace) {
|
|
@@ -363,10 +499,9 @@ function collectLiveMeshSessionRecords(args: {
|
|
|
363
499
|
allowCoordinatorSession?: boolean;
|
|
364
500
|
}): any[] {
|
|
365
501
|
const matches = args.liveSessionRecords.filter((record) => {
|
|
366
|
-
if (readStringValue(record?.meta?.meshNodeId) === args.nodeId) return true;
|
|
367
|
-
const recordWorkspace = readStringValue(record?.workspace);
|
|
368
502
|
const nodeWorkspace = readStringValue(args.node?.workspace);
|
|
369
|
-
|
|
503
|
+
if (liveSessionRecordMatchesMeshNode(record, args.meshId, args.nodeId)) return true;
|
|
504
|
+
return !!nodeWorkspace && liveSessionRecordMatchesMeshWorkspace(record, args.meshId, nodeWorkspace);
|
|
370
505
|
});
|
|
371
506
|
|
|
372
507
|
if (args.allowCoordinatorSession) {
|
|
@@ -960,10 +1095,15 @@ export class DaemonCommandRouter {
|
|
|
960
1095
|
|
|
961
1096
|
private warmInlineMeshCache(meshId: string, inlineMesh?: unknown): any | undefined {
|
|
962
1097
|
if (!inlineMesh || typeof inlineMesh !== 'object') return undefined;
|
|
1098
|
+
const sanitizedInlineMesh = sanitizeInlineMesh(inlineMesh as any);
|
|
963
1099
|
const cached = this.inlineMeshCache.get(meshId);
|
|
964
|
-
if (cached)
|
|
965
|
-
|
|
966
|
-
|
|
1100
|
+
if (cached) {
|
|
1101
|
+
const merged = reconcileInlineMeshCache(cached, sanitizedInlineMesh);
|
|
1102
|
+
this.inlineMeshCache.set(meshId, merged);
|
|
1103
|
+
return merged;
|
|
1104
|
+
}
|
|
1105
|
+
this.inlineMeshCache.set(meshId, sanitizedInlineMesh as any);
|
|
1106
|
+
return sanitizedInlineMesh as any;
|
|
967
1107
|
}
|
|
968
1108
|
|
|
969
1109
|
private async getMeshForCommand(
|
|
@@ -3203,10 +3343,17 @@ export class DaemonCommandRouter {
|
|
|
3203
3343
|
}
|
|
3204
3344
|
}
|
|
3205
3345
|
if (workspace) {
|
|
3206
|
-
if (!fs.existsSync(workspace)
|
|
3207
|
-
|
|
3208
|
-
|
|
3209
|
-
|
|
3346
|
+
if (!fs.existsSync(workspace)) {
|
|
3347
|
+
if (applyCachedInlineMeshNodeStatus(status, node)) {
|
|
3348
|
+
status.launchReady = !!daemonId && (readStringValue(status.machineStatus) === 'online' || isSelfNode);
|
|
3349
|
+
nodeStatuses.push(status);
|
|
3350
|
+
continue;
|
|
3351
|
+
}
|
|
3352
|
+
if (meshRecord?.source === 'inline_cache' && !isSelfNode) {
|
|
3353
|
+
status.launchReady = !!daemonId && (readStringValue(status.machineStatus) === 'online' || isSelfNode);
|
|
3354
|
+
nodeStatuses.push(status);
|
|
3355
|
+
continue;
|
|
3356
|
+
}
|
|
3210
3357
|
}
|
|
3211
3358
|
try {
|
|
3212
3359
|
const gitStatus = await getGitRepoStatus(workspace, { timeoutMs: 10_000, refreshUpstream: true });
|