@adhdev/daemon-core 0.9.82-rc.58 → 0.9.82-rc.59
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.d.ts +6 -4
- package/dist/index.js +368 -66
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +361 -65
- package/dist/index.mjs.map +1 -1
- package/dist/mesh/mesh-active-work.d.ts +48 -0
- package/dist/mesh/mesh-ledger.d.ts +37 -0
- package/dist/mesh/mesh-work-queue.d.ts +12 -0
- package/package.json +1 -1
- package/src/commands/router.ts +7 -1
- package/src/index.ts +6 -4
- package/src/mesh/mesh-active-work.ts +205 -0
- package/src/mesh/mesh-events.ts +28 -8
- package/src/mesh/mesh-ledger.ts +135 -0
- package/src/mesh/mesh-work-queue.ts +54 -1
package/dist/index.mjs
CHANGED
|
@@ -1264,6 +1264,7 @@ __export(mesh_ledger_exports, {
|
|
|
1264
1264
|
getSessionRecoveryContext: () => getSessionRecoveryContext,
|
|
1265
1265
|
isIntentionalCleanupStopEntry: () => isIntentionalCleanupStopEntry,
|
|
1266
1266
|
meshLedgerEvents: () => meshLedgerEvents,
|
|
1267
|
+
normalizeMeshWorkerResult: () => normalizeMeshWorkerResult,
|
|
1267
1268
|
readLedgerEntries: () => readLedgerEntries,
|
|
1268
1269
|
readLedgerSlice: () => readLedgerSlice
|
|
1269
1270
|
});
|
|
@@ -1291,6 +1292,86 @@ function getRotatedPath(meshId, index) {
|
|
|
1291
1292
|
const safe = meshId.replace(/[^a-zA-Z0-9_-]/g, "_");
|
|
1292
1293
|
return join6(getLedgerDir(), `${safe}.${index}.jsonl`);
|
|
1293
1294
|
}
|
|
1295
|
+
function readNonEmptyString(value) {
|
|
1296
|
+
return typeof value === "string" && value.trim() ? value.trim() : void 0;
|
|
1297
|
+
}
|
|
1298
|
+
function readStringArray(value) {
|
|
1299
|
+
if (!Array.isArray(value)) return [];
|
|
1300
|
+
return value.map((item) => readNonEmptyString(item)).filter(Boolean);
|
|
1301
|
+
}
|
|
1302
|
+
function extractJsonObjectFromSummary(summary) {
|
|
1303
|
+
const text = readNonEmptyString(summary);
|
|
1304
|
+
if (!text) return void 0;
|
|
1305
|
+
const fenced = text.match(/```(?:json)?\s*([\s\S]*?)```/i);
|
|
1306
|
+
const candidates = [fenced?.[1], text].filter(Boolean);
|
|
1307
|
+
for (const candidate of candidates) {
|
|
1308
|
+
const trimmed = candidate.trim();
|
|
1309
|
+
if (!trimmed.startsWith("{") || !trimmed.endsWith("}")) continue;
|
|
1310
|
+
try {
|
|
1311
|
+
const parsed = JSON.parse(trimmed);
|
|
1312
|
+
if (parsed && typeof parsed === "object" && !Array.isArray(parsed)) return parsed;
|
|
1313
|
+
} catch {
|
|
1314
|
+
}
|
|
1315
|
+
}
|
|
1316
|
+
return void 0;
|
|
1317
|
+
}
|
|
1318
|
+
function normalizeValidationResults(value) {
|
|
1319
|
+
if (!Array.isArray(value)) return [];
|
|
1320
|
+
return value.filter((item) => item && typeof item === "object" && !Array.isArray(item)).map((item) => {
|
|
1321
|
+
const status = ["passed", "failed", "skipped", "unknown"].includes(item.status) ? item.status : "unknown";
|
|
1322
|
+
return {
|
|
1323
|
+
...readNonEmptyString(item.command) ? { command: readNonEmptyString(item.command) } : {},
|
|
1324
|
+
status,
|
|
1325
|
+
...Number.isFinite(Number(item.durationMs)) ? { durationMs: Number(item.durationMs) } : {},
|
|
1326
|
+
...readNonEmptyString(item.outputPath) ? { outputPath: readNonEmptyString(item.outputPath) } : {},
|
|
1327
|
+
...readNonEmptyString(item.summary) ? { summary: readNonEmptyString(item.summary) } : {}
|
|
1328
|
+
};
|
|
1329
|
+
});
|
|
1330
|
+
}
|
|
1331
|
+
function normalizeProcessArtifacts(value) {
|
|
1332
|
+
if (!Array.isArray(value)) return [];
|
|
1333
|
+
const kinds = /* @__PURE__ */ new Set(["process", "log", "port", "window", "session", "file", "url", "other"]);
|
|
1334
|
+
return value.filter((item) => item && typeof item === "object" && !Array.isArray(item)).map((item) => ({
|
|
1335
|
+
kind: kinds.has(item.kind) ? item.kind : "other",
|
|
1336
|
+
...readNonEmptyString(item.id) ? { id: readNonEmptyString(item.id) } : {},
|
|
1337
|
+
...readNonEmptyString(item.label) ? { label: readNonEmptyString(item.label) } : {},
|
|
1338
|
+
...readNonEmptyString(item.locator) ? { locator: readNonEmptyString(item.locator) } : {},
|
|
1339
|
+
...Number.isFinite(Number(item.pid)) ? { pid: Number(item.pid) } : {},
|
|
1340
|
+
...Number.isFinite(Number(item.port)) ? { port: Number(item.port) } : {},
|
|
1341
|
+
...readNonEmptyString(item.url) ? { url: readNonEmptyString(item.url) } : {},
|
|
1342
|
+
...readNonEmptyString(item.path) ? { path: readNonEmptyString(item.path) } : {},
|
|
1343
|
+
...readNonEmptyString(item.sessionId) ? { sessionId: readNonEmptyString(item.sessionId) } : {},
|
|
1344
|
+
...typeof item.keepRunning === "boolean" ? { keepRunning: item.keepRunning } : {},
|
|
1345
|
+
...item.metadata && typeof item.metadata === "object" && !Array.isArray(item.metadata) ? { metadata: item.metadata } : {}
|
|
1346
|
+
}));
|
|
1347
|
+
}
|
|
1348
|
+
function normalizeMeshWorkerResult(input, source = "explicit_metadata") {
|
|
1349
|
+
const raw = input && typeof input === "object" ? input : {};
|
|
1350
|
+
const status = ["completed", "failed", "blocked", "partial", "unknown"].includes(String(raw.status)) ? raw.status : "unknown";
|
|
1351
|
+
const gitStatus = raw.gitStatus && typeof raw.gitStatus === "object" && !Array.isArray(raw.gitStatus) ? raw.gitStatus : void 0;
|
|
1352
|
+
return {
|
|
1353
|
+
status,
|
|
1354
|
+
...readNonEmptyString(raw.classification) ? { classification: readNonEmptyString(raw.classification) } : {},
|
|
1355
|
+
changedFiles: readStringArray(raw.changedFiles),
|
|
1356
|
+
validationResults: normalizeValidationResults(raw.validationResults),
|
|
1357
|
+
...gitStatus ? { gitStatus } : {},
|
|
1358
|
+
processArtifacts: normalizeProcessArtifacts(raw.processArtifacts),
|
|
1359
|
+
errors: readStringArray(raw.errors),
|
|
1360
|
+
...readNonEmptyString(raw.nextAction) ? { nextAction: readNonEmptyString(raw.nextAction) } : {},
|
|
1361
|
+
requiresUserAction: raw.requiresUserAction === true,
|
|
1362
|
+
source
|
|
1363
|
+
};
|
|
1364
|
+
}
|
|
1365
|
+
function resolveWorkerResult(opts) {
|
|
1366
|
+
if (opts.workerResult && typeof opts.workerResult === "object") {
|
|
1367
|
+
return normalizeMeshWorkerResult(opts.workerResult, "explicit_metadata");
|
|
1368
|
+
}
|
|
1369
|
+
const parsed = extractJsonObjectFromSummary(opts.finalSummary);
|
|
1370
|
+
if (parsed) {
|
|
1371
|
+
return normalizeMeshWorkerResult(parsed, "final_summary_json");
|
|
1372
|
+
}
|
|
1373
|
+
return normalizeMeshWorkerResult(void 0, "default");
|
|
1374
|
+
}
|
|
1294
1375
|
function buildTaskCompletionEvidence(opts) {
|
|
1295
1376
|
const providerSessionId = opts.providerSessionId?.trim() || void 0;
|
|
1296
1377
|
const providerType = opts.providerType?.trim() || void 0;
|
|
@@ -1307,6 +1388,7 @@ function buildTaskCompletionEvidence(opts) {
|
|
|
1307
1388
|
providerSessionId,
|
|
1308
1389
|
finalSummaryAvailable: typeof opts.finalSummary === "string" && opts.finalSummary.trim().length > 0
|
|
1309
1390
|
},
|
|
1391
|
+
workerResult: resolveWorkerResult(opts),
|
|
1310
1392
|
git: {
|
|
1311
1393
|
status: "deferred",
|
|
1312
1394
|
reason: "ordinary_completion_git_status_not_checked"
|
|
@@ -1601,19 +1683,48 @@ var mesh_work_queue_exports = {};
|
|
|
1601
1683
|
__export(mesh_work_queue_exports, {
|
|
1602
1684
|
ACTIVE_MESH_QUEUE_STATUSES: () => ACTIVE_MESH_QUEUE_STATUSES,
|
|
1603
1685
|
HISTORICAL_MESH_QUEUE_STATUSES: () => HISTORICAL_MESH_QUEUE_STATUSES,
|
|
1686
|
+
MESH_TASK_MODES: () => MESH_TASK_MODES,
|
|
1604
1687
|
cancelTask: () => cancelTask,
|
|
1605
1688
|
claimNextTask: () => claimNextTask,
|
|
1606
1689
|
enqueueTask: () => enqueueTask,
|
|
1607
1690
|
getMeshQueueStats: () => getMeshQueueStats,
|
|
1608
1691
|
getQueue: () => getQueue,
|
|
1692
|
+
normalizeMeshTaskMode: () => normalizeMeshTaskMode,
|
|
1609
1693
|
recordTaskAutoLaunch: () => recordTaskAutoLaunch,
|
|
1610
1694
|
requeueTask: () => requeueTask,
|
|
1611
1695
|
updateSessionTaskStatus: () => updateSessionTaskStatus,
|
|
1612
|
-
updateTaskStatus: () => updateTaskStatus
|
|
1696
|
+
updateTaskStatus: () => updateTaskStatus,
|
|
1697
|
+
validateMeshTaskModeRequest: () => validateMeshTaskModeRequest
|
|
1613
1698
|
});
|
|
1614
1699
|
import { existsSync as existsSync7, writeFileSync as writeFileSync3, readFileSync as readFileSync5, openSync, closeSync, unlinkSync } from "fs";
|
|
1615
1700
|
import { join as join7 } from "path";
|
|
1616
1701
|
import { randomUUID as randomUUID5 } from "crypto";
|
|
1702
|
+
function normalizeMeshTaskMode(value) {
|
|
1703
|
+
if (typeof value !== "string") return void 0;
|
|
1704
|
+
const normalized = value.trim();
|
|
1705
|
+
return MESH_TASK_MODES.includes(normalized) ? normalized : void 0;
|
|
1706
|
+
}
|
|
1707
|
+
function validateMeshTaskModeRequest(mode, message) {
|
|
1708
|
+
const taskMode = normalizeMeshTaskMode(mode);
|
|
1709
|
+
if (!taskMode) {
|
|
1710
|
+
return { valid: true, violations: [] };
|
|
1711
|
+
}
|
|
1712
|
+
if (taskMode !== "live_debug_readonly") {
|
|
1713
|
+
return { valid: true, taskMode, violations: [] };
|
|
1714
|
+
}
|
|
1715
|
+
const violations = LIVE_DEBUG_READONLY_FORBIDDEN.filter((rule) => rule.pattern.test(message || "")).map((rule) => rule.label);
|
|
1716
|
+
return {
|
|
1717
|
+
valid: violations.length === 0,
|
|
1718
|
+
taskMode,
|
|
1719
|
+
violations,
|
|
1720
|
+
allowedOperations: [
|
|
1721
|
+
"process/log/window/port/session inspection",
|
|
1722
|
+
"read-only filesystem listing/reading",
|
|
1723
|
+
"status probes and keep-running handle reporting",
|
|
1724
|
+
"diagnostic summaries without source edits, commits, checkpoints, pushes, deploys, resets, rebases, or destructive cleanups"
|
|
1725
|
+
]
|
|
1726
|
+
};
|
|
1727
|
+
}
|
|
1617
1728
|
function getQueuePath(meshId) {
|
|
1618
1729
|
const safe = meshId.replace(/[^a-zA-Z0-9_-]/g, "_");
|
|
1619
1730
|
return join7(getLedgerDir(), `${safe}.queue.json`);
|
|
@@ -1664,6 +1775,10 @@ function writeQueue(meshId, queue) {
|
|
|
1664
1775
|
}
|
|
1665
1776
|
function enqueueTask(meshId, message, opts) {
|
|
1666
1777
|
requireMeshHostQueueOwner(opts);
|
|
1778
|
+
const modeValidation = validateMeshTaskModeRequest(opts?.taskMode, message);
|
|
1779
|
+
if (!modeValidation.valid) {
|
|
1780
|
+
throw new Error(`live_debug_readonly_guardrail_violation: forbidden operations (${modeValidation.violations.join(", ")})`);
|
|
1781
|
+
}
|
|
1667
1782
|
return withQueueLock(meshId, () => {
|
|
1668
1783
|
const queue = readQueue(meshId);
|
|
1669
1784
|
const entry = {
|
|
@@ -1671,6 +1786,7 @@ function enqueueTask(meshId, message, opts) {
|
|
|
1671
1786
|
meshId,
|
|
1672
1787
|
message,
|
|
1673
1788
|
status: "pending",
|
|
1789
|
+
taskMode: modeValidation.taskMode,
|
|
1674
1790
|
targetNodeId: opts?.targetNodeId,
|
|
1675
1791
|
targetSessionId: opts?.targetSessionId,
|
|
1676
1792
|
createdAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
@@ -1832,7 +1948,7 @@ function getMeshQueueStats(meshId) {
|
|
|
1832
1948
|
}))
|
|
1833
1949
|
};
|
|
1834
1950
|
}
|
|
1835
|
-
var ACTIVE_MESH_QUEUE_STATUSES, HISTORICAL_MESH_QUEUE_STATUSES;
|
|
1951
|
+
var ACTIVE_MESH_QUEUE_STATUSES, HISTORICAL_MESH_QUEUE_STATUSES, MESH_TASK_MODES, LIVE_DEBUG_READONLY_FORBIDDEN;
|
|
1836
1952
|
var init_mesh_work_queue = __esm({
|
|
1837
1953
|
"src/mesh/mesh-work-queue.ts"() {
|
|
1838
1954
|
"use strict";
|
|
@@ -1840,6 +1956,14 @@ var init_mesh_work_queue = __esm({
|
|
|
1840
1956
|
init_mesh_host_ownership();
|
|
1841
1957
|
ACTIVE_MESH_QUEUE_STATUSES = ["pending", "assigned"];
|
|
1842
1958
|
HISTORICAL_MESH_QUEUE_STATUSES = ["completed", "failed", "cancelled"];
|
|
1959
|
+
MESH_TASK_MODES = ["code_change", "validation", "live_debug_readonly", "launch_app", "convergence"];
|
|
1960
|
+
LIVE_DEBUG_READONLY_FORBIDDEN = [
|
|
1961
|
+
{ label: "source_edit", pattern: /\b(edit|modify|patch|apply\s+patch|write\s+(?:to\s+)?(?:file|source)|overwrite|delete\s+file|remove\s+file|create\s+file|touch\s+file)\b/i },
|
|
1962
|
+
{ label: "git_mutation", pattern: /\b(?:git\s+(?:add|commit|push|reset|rebase|clean|checkout|switch|merge|tag|restore|rm|mv)|push\b)/i },
|
|
1963
|
+
{ label: "checkpoint", pattern: /\b(checkpoint|mesh_checkpoint)\b/i },
|
|
1964
|
+
{ label: "deploy_or_version_bump", pattern: /\b(deploy|wrangler\s+deploy|version[-\s]?bump|npm\s+version|release)\b/i },
|
|
1965
|
+
{ label: "destructive_shell", pattern: /\b(rm\s+-rf|mv\s+\S+\s+\S+|truncate\s|tee\s+\S+|sed\s+-i)\b/i }
|
|
1966
|
+
];
|
|
1843
1967
|
}
|
|
1844
1968
|
});
|
|
1845
1969
|
|
|
@@ -2205,6 +2329,9 @@ __export(mesh_events_exports, {
|
|
|
2205
2329
|
});
|
|
2206
2330
|
import { appendFileSync as appendFileSync3, existsSync as existsSync10, readFileSync as readFileSync6, unlinkSync as unlinkSync3 } from "fs";
|
|
2207
2331
|
import { join as join10 } from "path";
|
|
2332
|
+
function readWorkerResultMetadata(event) {
|
|
2333
|
+
return readRecord(event.workerResult) || readRecord(event.meshWorkerResult) || readRecord(event.structuredResult);
|
|
2334
|
+
}
|
|
2208
2335
|
function sweepExpiredRemoteIdleSessions() {
|
|
2209
2336
|
const now = Date.now();
|
|
2210
2337
|
for (const [key, session] of remoteIdleSessions) {
|
|
@@ -2270,23 +2397,26 @@ function clearPendingMeshCoordinatorEvents(meshId) {
|
|
|
2270
2397
|
} catch {
|
|
2271
2398
|
}
|
|
2272
2399
|
}
|
|
2273
|
-
function
|
|
2400
|
+
function readNonEmptyString2(value) {
|
|
2274
2401
|
return typeof value === "string" && value.trim() ? value.trim() : "";
|
|
2275
2402
|
}
|
|
2403
|
+
function readRecord(value) {
|
|
2404
|
+
return value && typeof value === "object" && !Array.isArray(value) ? value : void 0;
|
|
2405
|
+
}
|
|
2276
2406
|
function resolveEventSessionId(event, fallback) {
|
|
2277
|
-
return
|
|
2407
|
+
return readNonEmptyString2(event.targetSessionId) || readNonEmptyString2(event.sessionId) || readNonEmptyString2(event.instanceId) || readNonEmptyString2(fallback);
|
|
2278
2408
|
}
|
|
2279
2409
|
function isMeshCoordinatorEvent(eventName) {
|
|
2280
2410
|
return typeof eventName === "string" && MESH_COORDINATOR_EVENTS.has(eventName);
|
|
2281
2411
|
}
|
|
2282
2412
|
function formatCompletionMetadata(event) {
|
|
2283
2413
|
const completionDiagnostic = event.completionDiagnostic && typeof event.completionDiagnostic === "object" ? event.completionDiagnostic : null;
|
|
2284
|
-
const diagnosticReason = completionDiagnostic ?
|
|
2414
|
+
const diagnosticReason = completionDiagnostic ? readNonEmptyString2(completionDiagnostic.blockReason) || "present" : "";
|
|
2285
2415
|
const finalAssistantPresent = typeof completionDiagnostic?.finalAssistantPresent === "boolean" ? String(completionDiagnostic.finalAssistantPresent) : "";
|
|
2286
2416
|
const parts = [
|
|
2287
|
-
|
|
2288
|
-
|
|
2289
|
-
|
|
2417
|
+
readNonEmptyString2(event.targetSessionId) ? `session_id=${readNonEmptyString2(event.targetSessionId)}` : "",
|
|
2418
|
+
readNonEmptyString2(event.providerType) ? `provider=${readNonEmptyString2(event.providerType)}` : "",
|
|
2419
|
+
readNonEmptyString2(event.providerSessionId) ? `provider_session_id=${readNonEmptyString2(event.providerSessionId)}` : "",
|
|
2290
2420
|
diagnosticReason ? `completion_diagnostic=${diagnosticReason}` : "",
|
|
2291
2421
|
finalAssistantPresent ? `final_assistant=${finalAssistantPresent}` : ""
|
|
2292
2422
|
].filter(Boolean);
|
|
@@ -2330,7 +2460,7 @@ function readEventTimestamp(value) {
|
|
|
2330
2460
|
return null;
|
|
2331
2461
|
}
|
|
2332
2462
|
function buildMeshCompletionFingerprint(args) {
|
|
2333
|
-
const timestampPart = Number.isFinite(args.timestamp) ? String(args.timestamp) :
|
|
2463
|
+
const timestampPart = Number.isFinite(args.timestamp) ? String(args.timestamp) : readNonEmptyString2(args.finalSummary).slice(0, 200);
|
|
2334
2464
|
return [
|
|
2335
2465
|
args.meshId,
|
|
2336
2466
|
args.event,
|
|
@@ -2408,7 +2538,7 @@ function isTerminalSessionStatus(status) {
|
|
|
2408
2538
|
return ["stopped", "failed", "terminated", "exited", "closed"].includes(status);
|
|
2409
2539
|
}
|
|
2410
2540
|
function isIdleSessionState(state) {
|
|
2411
|
-
const status =
|
|
2541
|
+
const status = readNonEmptyString2(state?.status).toLowerCase();
|
|
2412
2542
|
if (isTerminalSessionStatus(status)) return false;
|
|
2413
2543
|
return status === "idle" || state?.activeChat?.status === "waiting_input";
|
|
2414
2544
|
}
|
|
@@ -2417,15 +2547,15 @@ function isDirtyNode(node) {
|
|
|
2417
2547
|
}
|
|
2418
2548
|
function isLaunchableNode(node) {
|
|
2419
2549
|
if (!node || node.status === "disabled" || node.status === "removed") return false;
|
|
2420
|
-
const health =
|
|
2550
|
+
const health = readNonEmptyString2(node.health).toLowerCase();
|
|
2421
2551
|
if (!health) return true;
|
|
2422
2552
|
return health === "online" || health === "unknown";
|
|
2423
2553
|
}
|
|
2424
2554
|
function localAutoLaunchSkipReason(node) {
|
|
2425
|
-
const daemonId =
|
|
2426
|
-
const machineId =
|
|
2555
|
+
const daemonId = readNonEmptyString2(node?.daemonId);
|
|
2556
|
+
const machineId = readNonEmptyString2(node?.machineId);
|
|
2427
2557
|
const appConfig = loadConfig();
|
|
2428
|
-
const localMachineId =
|
|
2558
|
+
const localMachineId = readNonEmptyString2(appConfig.machineId) || readNonEmptyString2(appConfig.registeredMachineId);
|
|
2429
2559
|
const cloudDaemonId = localMachineId ? `daemon_${localMachineId}` : "";
|
|
2430
2560
|
const standaloneDaemonId = localMachineId ? `standalone_${localMachineId}` : "";
|
|
2431
2561
|
const daemonMatchesLocal = !daemonId || daemonId === cloudDaemonId || daemonId === standaloneDaemonId;
|
|
@@ -2448,10 +2578,10 @@ function liveSessionCountForNode(components, meshId, nodeId) {
|
|
|
2448
2578
|
return components.instanceManager.getByCategory("cli").filter((inst) => {
|
|
2449
2579
|
const state = inst.getState();
|
|
2450
2580
|
const settings = state.settings || {};
|
|
2451
|
-
if (
|
|
2452
|
-
const instNodeId =
|
|
2581
|
+
if (readNonEmptyString2(settings.meshNodeFor) !== meshId) return false;
|
|
2582
|
+
const instNodeId = readNonEmptyString2(settings.meshNodeId) || readNonEmptyString2(settings.nodeId);
|
|
2453
2583
|
if (instNodeId !== nodeId) return false;
|
|
2454
|
-
const status =
|
|
2584
|
+
const status = readNonEmptyString2(state.status).toLowerCase();
|
|
2455
2585
|
return !isTerminalSessionStatus(status);
|
|
2456
2586
|
}).length;
|
|
2457
2587
|
}
|
|
@@ -2543,7 +2673,7 @@ async function maybeAutoLaunchOneQueueSession(components, meshId, mesh) {
|
|
|
2543
2673
|
continue;
|
|
2544
2674
|
}
|
|
2545
2675
|
for (const node of candidateNodes) {
|
|
2546
|
-
const nodeId =
|
|
2676
|
+
const nodeId = readNonEmptyString2(node?.id);
|
|
2547
2677
|
if (!nodeId) continue;
|
|
2548
2678
|
const launchKey = `${meshId}:${nodeId}`;
|
|
2549
2679
|
const cooldownUntil = autoLaunchCooldownUntil.get(launchKey) || 0;
|
|
@@ -2602,7 +2732,7 @@ async function maybeAutoLaunchOneQueueSession(components, meshId, mesh) {
|
|
|
2602
2732
|
autoLaunchCooldownUntil.set(launchKey, Date.now() + AUTO_LAUNCH_COOLDOWN_MS);
|
|
2603
2733
|
return false;
|
|
2604
2734
|
}
|
|
2605
|
-
const sessionId =
|
|
2735
|
+
const sessionId = readNonEmptyString2(launchResult.sessionId) || readNonEmptyString2(launchResult.id) || readNonEmptyString2(launchResult.runtimeSessionId);
|
|
2606
2736
|
if (!sessionId) {
|
|
2607
2737
|
markAutoLaunch(meshId, task.id, { status: "failed", reason: "launch_missing_session_id", nodeId, providerType: resolved.providerType });
|
|
2608
2738
|
autoLaunchCooldownUntil.set(launchKey, Date.now() + AUTO_LAUNCH_COOLDOWN_MS);
|
|
@@ -2629,13 +2759,13 @@ async function triggerMeshQueue(components, meshId) {
|
|
|
2629
2759
|
for (const inst of cliInstances) {
|
|
2630
2760
|
const state = inst.getState();
|
|
2631
2761
|
const settings = state.settings || {};
|
|
2632
|
-
const instMeshId =
|
|
2762
|
+
const instMeshId = readNonEmptyString2(settings.meshNodeFor);
|
|
2633
2763
|
if (instMeshId !== meshId) continue;
|
|
2634
|
-
const nodeId =
|
|
2764
|
+
const nodeId = readNonEmptyString2(settings.meshNodeId) || readNonEmptyString2(settings.nodeId);
|
|
2635
2765
|
if (!nodeId) continue;
|
|
2636
2766
|
if (!isIdleSessionState(state)) continue;
|
|
2637
2767
|
const sessionId = state.instanceId;
|
|
2638
|
-
const providerType = state.type ||
|
|
2768
|
+
const providerType = state.type || readNonEmptyString2(settings.providerType);
|
|
2639
2769
|
if (providerType) {
|
|
2640
2770
|
tryAssignQueueTask(components, meshId, nodeId, sessionId, providerType);
|
|
2641
2771
|
}
|
|
@@ -2697,7 +2827,7 @@ Do NOT retry on this node. Consider reassigning to a different node or asking th
|
|
|
2697
2827
|
}
|
|
2698
2828
|
function injectMeshSystemMessage(components, args) {
|
|
2699
2829
|
const eventSessionId = resolveEventSessionId(args.metadataEvent, args.sourceInstanceId);
|
|
2700
|
-
const eventNodeId =
|
|
2830
|
+
const eventNodeId = readNonEmptyString2(args.nodeId) || readNonEmptyString2(args.metadataEvent.meshNodeId);
|
|
2701
2831
|
const intentionalCleanupStop = shouldSuppressIntentionalCleanupStop({
|
|
2702
2832
|
event: args.event,
|
|
2703
2833
|
meshId: args.meshId,
|
|
@@ -2718,10 +2848,10 @@ function injectMeshSystemMessage(components, args) {
|
|
|
2718
2848
|
meshId: args.meshId,
|
|
2719
2849
|
event: args.event,
|
|
2720
2850
|
sessionId: eventSessionId,
|
|
2721
|
-
providerType:
|
|
2722
|
-
providerSessionId:
|
|
2851
|
+
providerType: readNonEmptyString2(args.metadataEvent.providerType) || void 0,
|
|
2852
|
+
providerSessionId: readNonEmptyString2(args.metadataEvent.providerSessionId) || void 0,
|
|
2723
2853
|
timestamp: eventTimestamp,
|
|
2724
|
-
finalSummary:
|
|
2854
|
+
finalSummary: readNonEmptyString2(args.metadataEvent.finalSummary) || void 0
|
|
2725
2855
|
});
|
|
2726
2856
|
if (duplicateCompletion) {
|
|
2727
2857
|
LOG.info("MeshEvents", `Suppressed duplicate completion for mesh ${args.meshId} session ${eventSessionId}`);
|
|
@@ -2731,8 +2861,8 @@ function injectMeshSystemMessage(components, args) {
|
|
|
2731
2861
|
let completedTaskForLedger = null;
|
|
2732
2862
|
if (args.event === "agent:generating_completed") {
|
|
2733
2863
|
const sessionId = resolveEventSessionId(args.metadataEvent, args.sourceInstanceId);
|
|
2734
|
-
const nodeId =
|
|
2735
|
-
const providerType =
|
|
2864
|
+
const nodeId = readNonEmptyString2(args.nodeId) || readNonEmptyString2(args.metadataEvent.meshNodeId);
|
|
2865
|
+
const providerType = readNonEmptyString2(args.metadataEvent.providerType);
|
|
2736
2866
|
if (sessionId) {
|
|
2737
2867
|
const completedTask = updateSessionTaskStatus(args.meshId, sessionId, "completed", {
|
|
2738
2868
|
occurredAt: eventTimestamp !== null ? new Date(eventTimestamp).toISOString() : void 0
|
|
@@ -2746,8 +2876,11 @@ function injectMeshSystemMessage(components, args) {
|
|
|
2746
2876
|
}
|
|
2747
2877
|
} else if (args.event === "agent:ready") {
|
|
2748
2878
|
const sessionId = resolveEventSessionId(args.metadataEvent, args.sourceInstanceId);
|
|
2749
|
-
const nodeId =
|
|
2750
|
-
const providerType =
|
|
2879
|
+
const nodeId = readNonEmptyString2(args.nodeId) || readNonEmptyString2(args.metadataEvent.meshNodeId);
|
|
2880
|
+
const providerType = readNonEmptyString2(args.metadataEvent.providerType);
|
|
2881
|
+
const providerSessionId = readNonEmptyString2(args.metadataEvent.providerSessionId) || void 0;
|
|
2882
|
+
const finalSummary = readNonEmptyString2(args.metadataEvent.finalSummary) || void 0;
|
|
2883
|
+
const workerResult = readWorkerResultMetadata(args.metadataEvent);
|
|
2751
2884
|
const completedTask = sessionId ? updateSessionTaskStatus(args.meshId, sessionId, "completed") : null;
|
|
2752
2885
|
if (completedTask) {
|
|
2753
2886
|
completedTaskForLedger = { id: completedTask.id };
|
|
@@ -2762,15 +2895,17 @@ function injectMeshSystemMessage(components, args) {
|
|
|
2762
2895
|
nodeLabel: args.nodeLabel,
|
|
2763
2896
|
taskId: completedTask.id,
|
|
2764
2897
|
completedViaReady: true,
|
|
2765
|
-
providerSessionId
|
|
2766
|
-
finalSummary
|
|
2898
|
+
providerSessionId,
|
|
2899
|
+
finalSummary,
|
|
2900
|
+
workerResult,
|
|
2767
2901
|
evidence: buildTaskCompletionEvidence({
|
|
2768
2902
|
event: "agent:ready",
|
|
2769
2903
|
nodeId,
|
|
2770
2904
|
sessionId,
|
|
2771
2905
|
providerType: providerType || void 0,
|
|
2772
|
-
providerSessionId
|
|
2773
|
-
finalSummary
|
|
2906
|
+
providerSessionId,
|
|
2907
|
+
finalSummary,
|
|
2908
|
+
workerResult
|
|
2774
2909
|
})
|
|
2775
2910
|
}
|
|
2776
2911
|
});
|
|
@@ -2793,13 +2928,13 @@ function injectMeshSystemMessage(components, args) {
|
|
|
2793
2928
|
}
|
|
2794
2929
|
} else if (args.event === "agent:generating_started") {
|
|
2795
2930
|
const sessionId = resolveEventSessionId(args.metadataEvent, args.sourceInstanceId);
|
|
2796
|
-
const nodeId =
|
|
2931
|
+
const nodeId = readNonEmptyString2(args.nodeId) || readNonEmptyString2(args.metadataEvent.meshNodeId);
|
|
2797
2932
|
if (sessionId && nodeId) {
|
|
2798
2933
|
remoteIdleSessions.delete(`${nodeId}:${sessionId}`);
|
|
2799
2934
|
}
|
|
2800
2935
|
} else if (args.event === "agent:stopped") {
|
|
2801
2936
|
const sessionId = resolveEventSessionId(args.metadataEvent, args.sourceInstanceId);
|
|
2802
|
-
const nodeId =
|
|
2937
|
+
const nodeId = readNonEmptyString2(args.nodeId) || readNonEmptyString2(args.metadataEvent.meshNodeId);
|
|
2803
2938
|
if (sessionId && nodeId) {
|
|
2804
2939
|
remoteIdleSessions.delete(`${nodeId}:${sessionId}`);
|
|
2805
2940
|
}
|
|
@@ -2810,16 +2945,20 @@ function injectMeshSystemMessage(components, args) {
|
|
|
2810
2945
|
const ledgerKind = EVENT_TO_LEDGER_KIND[args.event];
|
|
2811
2946
|
if (ledgerKind) {
|
|
2812
2947
|
try {
|
|
2813
|
-
const ledgerNodeId =
|
|
2948
|
+
const ledgerNodeId = readNonEmptyString2(args.nodeId) || readNonEmptyString2(args.metadataEvent.meshNodeId) || void 0;
|
|
2814
2949
|
const ledgerSessionId = resolveEventSessionId(args.metadataEvent, args.sourceInstanceId) || void 0;
|
|
2815
|
-
const ledgerProviderType =
|
|
2950
|
+
const ledgerProviderType = readNonEmptyString2(args.metadataEvent.providerType) || void 0;
|
|
2951
|
+
const providerSessionId = readNonEmptyString2(args.metadataEvent.providerSessionId) || void 0;
|
|
2952
|
+
const finalSummary = readNonEmptyString2(args.metadataEvent.finalSummary) || void 0;
|
|
2953
|
+
const workerResult = readWorkerResultMetadata(args.metadataEvent);
|
|
2816
2954
|
const completionEvidence = ledgerKind === "task_completed" && ledgerNodeId && ledgerSessionId ? buildTaskCompletionEvidence({
|
|
2817
2955
|
event: "agent:generating_completed",
|
|
2818
2956
|
nodeId: ledgerNodeId,
|
|
2819
2957
|
sessionId: ledgerSessionId,
|
|
2820
2958
|
providerType: ledgerProviderType,
|
|
2821
|
-
providerSessionId
|
|
2822
|
-
finalSummary
|
|
2959
|
+
providerSessionId,
|
|
2960
|
+
finalSummary,
|
|
2961
|
+
workerResult
|
|
2823
2962
|
}) : void 0;
|
|
2824
2963
|
appendLedgerEntry(args.meshId, {
|
|
2825
2964
|
kind: ledgerKind,
|
|
@@ -2830,8 +2969,9 @@ function injectMeshSystemMessage(components, args) {
|
|
|
2830
2969
|
event: args.event,
|
|
2831
2970
|
nodeLabel: args.nodeLabel,
|
|
2832
2971
|
taskId: completedTaskForLedger?.id || void 0,
|
|
2833
|
-
providerSessionId
|
|
2834
|
-
finalSummary
|
|
2972
|
+
providerSessionId,
|
|
2973
|
+
finalSummary,
|
|
2974
|
+
workerResult,
|
|
2835
2975
|
completionDiagnostic: args.metadataEvent.completionDiagnostic && typeof args.metadataEvent.completionDiagnostic === "object" ? args.metadataEvent.completionDiagnostic : void 0,
|
|
2836
2976
|
evidence: completionEvidence
|
|
2837
2977
|
}
|
|
@@ -2847,10 +2987,10 @@ function injectMeshSystemMessage(components, args) {
|
|
|
2847
2987
|
const maxRetries = mesh?.policy?.maxTaskRetries ?? 1;
|
|
2848
2988
|
recoveryContext = getSessionRecoveryContext(args.meshId, {
|
|
2849
2989
|
sessionId: resolveEventSessionId(args.metadataEvent, args.sourceInstanceId) || void 0,
|
|
2850
|
-
nodeId:
|
|
2990
|
+
nodeId: readNonEmptyString2(args.nodeId) || readNonEmptyString2(args.metadataEvent.meshNodeId) || void 0,
|
|
2851
2991
|
maxRetries
|
|
2852
2992
|
});
|
|
2853
|
-
recoveryContext.failedProviderType =
|
|
2993
|
+
recoveryContext.failedProviderType = readNonEmptyString2(args.metadataEvent.providerType) || null;
|
|
2854
2994
|
if (recoveryContext.retryRecommended && recoveryContext.consecutiveNodeFailures > 0) {
|
|
2855
2995
|
appendLedgerEntry(args.meshId, {
|
|
2856
2996
|
kind: "recovery_attempted",
|
|
@@ -2906,7 +3046,7 @@ function injectMeshSystemMessage(components, args) {
|
|
|
2906
3046
|
meshId: args.meshId,
|
|
2907
3047
|
nodeLabel: args.nodeLabel,
|
|
2908
3048
|
nodeId: args.nodeId || void 0,
|
|
2909
|
-
workspace:
|
|
3049
|
+
workspace: readNonEmptyString2(args.metadataEvent.workspace),
|
|
2910
3050
|
metadataEvent: {
|
|
2911
3051
|
...args.metadataEvent,
|
|
2912
3052
|
...recoveryContext ? { recoveryContext } : {}
|
|
@@ -2932,14 +3072,14 @@ function injectMeshSystemMessage(components, args) {
|
|
|
2932
3072
|
return { success: true, forwarded: coordinatorInstances.length };
|
|
2933
3073
|
}
|
|
2934
3074
|
function handleMeshForwardEvent(components, payload) {
|
|
2935
|
-
const eventName =
|
|
3075
|
+
const eventName = readNonEmptyString2(payload.event);
|
|
2936
3076
|
if (!isMeshCoordinatorEvent(eventName)) {
|
|
2937
3077
|
return { success: false, error: "unsupported mesh event" };
|
|
2938
3078
|
}
|
|
2939
|
-
const meshId =
|
|
3079
|
+
const meshId = readNonEmptyString2(payload.meshId);
|
|
2940
3080
|
if (!meshId) return { success: false, error: "meshId required" };
|
|
2941
|
-
const nodeId =
|
|
2942
|
-
const workspace =
|
|
3081
|
+
const nodeId = readNonEmptyString2(payload.nodeId);
|
|
3082
|
+
const workspace = readNonEmptyString2(payload.workspace);
|
|
2943
3083
|
const nodeLabel = nodeId ? `Node '${nodeId}'` : workspace ? `Agent at ${workspace}` : "Remote agent";
|
|
2944
3084
|
return injectMeshSystemMessage(components, {
|
|
2945
3085
|
meshId,
|
|
@@ -2947,41 +3087,41 @@ function handleMeshForwardEvent(components, payload) {
|
|
|
2947
3087
|
nodeLabel,
|
|
2948
3088
|
event: eventName,
|
|
2949
3089
|
metadataEvent: {
|
|
2950
|
-
targetSessionId:
|
|
2951
|
-
providerType:
|
|
2952
|
-
providerSessionId:
|
|
2953
|
-
finalSummary:
|
|
3090
|
+
targetSessionId: readNonEmptyString2(payload.targetSessionId) || readNonEmptyString2(payload.sessionId) || readNonEmptyString2(payload.instanceId),
|
|
3091
|
+
providerType: readNonEmptyString2(payload.providerType),
|
|
3092
|
+
providerSessionId: readNonEmptyString2(payload.providerSessionId),
|
|
3093
|
+
finalSummary: readNonEmptyString2(payload.finalSummary) || readNonEmptyString2(payload.summary),
|
|
2954
3094
|
...payload.timestamp !== void 0 ? { timestamp: payload.timestamp } : {},
|
|
2955
3095
|
intentional: payload.intentional === true,
|
|
2956
3096
|
intentionalStop: payload.intentionalStop === true,
|
|
2957
3097
|
operatorCleanup: payload.operatorCleanup === true,
|
|
2958
|
-
reason:
|
|
2959
|
-
stopReason:
|
|
2960
|
-
cleanupReason:
|
|
2961
|
-
source:
|
|
3098
|
+
reason: readNonEmptyString2(payload.reason),
|
|
3099
|
+
stopReason: readNonEmptyString2(payload.stopReason),
|
|
3100
|
+
cleanupReason: readNonEmptyString2(payload.cleanupReason),
|
|
3101
|
+
source: readNonEmptyString2(payload.source)
|
|
2962
3102
|
}
|
|
2963
3103
|
});
|
|
2964
3104
|
}
|
|
2965
3105
|
function setupMeshEventForwarding(components) {
|
|
2966
3106
|
components.instanceManager.onEvent((event) => {
|
|
2967
3107
|
if (!isMeshCoordinatorEvent(event.event)) return;
|
|
2968
|
-
const instanceId =
|
|
3108
|
+
const instanceId = readNonEmptyString2(event.instanceId);
|
|
2969
3109
|
if (!instanceId) return;
|
|
2970
3110
|
const sourceInstance = components.instanceManager.getInstance(instanceId);
|
|
2971
3111
|
if (!sourceInstance || sourceInstance.category !== "cli") return;
|
|
2972
3112
|
const state = sourceInstance.getState();
|
|
2973
|
-
const workspace =
|
|
3113
|
+
const workspace = readNonEmptyString2(state.workspace);
|
|
2974
3114
|
if (!workspace) return;
|
|
2975
3115
|
const settings = state.settings && typeof state.settings === "object" ? state.settings : {};
|
|
2976
|
-
if (
|
|
2977
|
-
const meshIdFromRuntime =
|
|
3116
|
+
if (readNonEmptyString2(settings.meshCoordinatorFor)) return;
|
|
3117
|
+
const meshIdFromRuntime = readNonEmptyString2(settings.meshNodeFor);
|
|
2978
3118
|
const isMeshDelegate = Boolean(meshIdFromRuntime || settings.launchedByCoordinator);
|
|
2979
3119
|
if (!isMeshDelegate) return;
|
|
2980
3120
|
const mesh = meshIdFromRuntime ? getMeshWithCache(components, meshIdFromRuntime) : getMeshByRepo(workspace);
|
|
2981
|
-
const meshId = meshIdFromRuntime ||
|
|
3121
|
+
const meshId = meshIdFromRuntime || readNonEmptyString2(mesh?.id);
|
|
2982
3122
|
if (!meshId) return;
|
|
2983
3123
|
const targetNode = mesh?.nodes?.find((n) => n.workspace === workspace);
|
|
2984
|
-
const runtimeNodeId =
|
|
3124
|
+
const runtimeNodeId = readNonEmptyString2(settings.meshNodeId);
|
|
2985
3125
|
const resolvedNodeId = targetNode?.id || runtimeNodeId;
|
|
2986
3126
|
const nodeLabel = targetNode ? `Node '${targetNode.id}'` : runtimeNodeId ? `Node '${runtimeNodeId}'` : `Agent at ${workspace}`;
|
|
2987
3127
|
injectMeshSystemMessage(components, {
|
|
@@ -8535,6 +8675,152 @@ function buildMeshLedgerReconciliationEvidence(meshId, replicas) {
|
|
|
8535
8675
|
|
|
8536
8676
|
// src/index.ts
|
|
8537
8677
|
init_mesh_work_queue();
|
|
8678
|
+
|
|
8679
|
+
// src/mesh/mesh-active-work.ts
|
|
8680
|
+
var DIRECT_DISPATCH_VIA = /* @__PURE__ */ new Set(["p2p_direct", "local_direct", "mesh_send_task"]);
|
|
8681
|
+
var TERMINAL_LEDGER_KINDS = /* @__PURE__ */ new Set(["task_completed", "task_failed", "task_stalled"]);
|
|
8682
|
+
function readString2(value) {
|
|
8683
|
+
return typeof value === "string" && value.trim() ? value.trim() : void 0;
|
|
8684
|
+
}
|
|
8685
|
+
function summarizeMessage(message) {
|
|
8686
|
+
const oneLine = message.replace(/\s+/g, " ").trim();
|
|
8687
|
+
const title = oneLine.length > 96 ? `${oneLine.slice(0, 93)}...` : oneLine;
|
|
8688
|
+
return { title: title || "(untitled task)", summary: oneLine };
|
|
8689
|
+
}
|
|
8690
|
+
function elapsedSince(value, now) {
|
|
8691
|
+
const started = value ? new Date(value).getTime() : Number.NaN;
|
|
8692
|
+
return Number.isFinite(started) ? Math.max(0, now - started) : 0;
|
|
8693
|
+
}
|
|
8694
|
+
function sessionStatusFromNodes(nodes, nodeId, sessionId) {
|
|
8695
|
+
if (!nodeId || !sessionId || !Array.isArray(nodes)) return void 0;
|
|
8696
|
+
const node = nodes.find((item) => readString2(item?.id) === nodeId || readString2(item?.nodeId) === nodeId || readString2(item?.node_id) === nodeId);
|
|
8697
|
+
if (!node) return void 0;
|
|
8698
|
+
const candidates = [];
|
|
8699
|
+
for (const value of [node.sessions, node.activeSessions, node.active_sessions, node.lastProbe?.sessions, node.last_probe?.sessions, node.lastProbe?.status?.sessions, node.last_probe?.status?.sessions]) {
|
|
8700
|
+
if (Array.isArray(value)) candidates.push(...value);
|
|
8701
|
+
}
|
|
8702
|
+
for (const value of [node.activeSession, node.active_session, node.currentSession, node.current_session, node.runtimeSession, node.runtime_session, node.session]) {
|
|
8703
|
+
if (value && typeof value === "object") candidates.push(value);
|
|
8704
|
+
}
|
|
8705
|
+
const session = candidates.find((item) => {
|
|
8706
|
+
const id = readString2(item?.id) || readString2(item?.sessionId) || readString2(item?.session_id) || readString2(item?.runtimeSessionId) || readString2(item?.instanceId);
|
|
8707
|
+
return id === sessionId;
|
|
8708
|
+
});
|
|
8709
|
+
if (!session) return void 0;
|
|
8710
|
+
const raw = `${readString2(session.status) || ""} ${readString2(session.lifecycle) || ""} ${readString2(session.state) || ""} ${readString2(session.activeChat?.status) || ""}`.toLowerCase();
|
|
8711
|
+
if (raw.includes("approval")) return "awaiting_approval";
|
|
8712
|
+
if (raw.includes("generating") || raw.includes("running") || raw.includes("busy")) return "generating";
|
|
8713
|
+
if (raw.includes("failed") || raw.includes("stopped") || raw.includes("terminated") || raw.includes("exited")) return "failed";
|
|
8714
|
+
if (raw.includes("idle") || raw.includes("waiting_input") || raw.includes("ready")) return "idle";
|
|
8715
|
+
return void 0;
|
|
8716
|
+
}
|
|
8717
|
+
function isDirectDispatch(entry) {
|
|
8718
|
+
if (entry.kind !== "task_dispatched") return false;
|
|
8719
|
+
const payload = entry.payload || {};
|
|
8720
|
+
if (payload.source === "direct") return true;
|
|
8721
|
+
const via = readString2(payload.via);
|
|
8722
|
+
return Boolean(via && DIRECT_DISPATCH_VIA.has(via) && payload.source !== "queue");
|
|
8723
|
+
}
|
|
8724
|
+
function directDispatchTaskId(entry) {
|
|
8725
|
+
return readString2(entry.payload?.taskId) || entry.id;
|
|
8726
|
+
}
|
|
8727
|
+
function terminalMatchesDispatch(terminal, dispatch, taskId) {
|
|
8728
|
+
const terminalTaskId = readString2(terminal.payload?.taskId);
|
|
8729
|
+
if (terminalTaskId && terminalTaskId === taskId) return true;
|
|
8730
|
+
if (terminalTaskId && terminalTaskId !== taskId) return false;
|
|
8731
|
+
if (dispatch.sessionId && terminal.sessionId === dispatch.sessionId) return true;
|
|
8732
|
+
return Boolean(dispatch.nodeId && terminal.nodeId === dispatch.nodeId && !dispatch.sessionId);
|
|
8733
|
+
}
|
|
8734
|
+
function statusFromTerminal(entry) {
|
|
8735
|
+
if (entry.kind === "task_approval_needed") return "awaiting_approval";
|
|
8736
|
+
if (entry.kind === "task_completed") return "idle";
|
|
8737
|
+
return "failed";
|
|
8738
|
+
}
|
|
8739
|
+
function buildMeshActiveWorkSummary(activeWork) {
|
|
8740
|
+
const statusCounts = {
|
|
8741
|
+
pending: 0,
|
|
8742
|
+
assigned: 0,
|
|
8743
|
+
generating: 0,
|
|
8744
|
+
idle: 0,
|
|
8745
|
+
failed: 0,
|
|
8746
|
+
awaiting_approval: 0
|
|
8747
|
+
};
|
|
8748
|
+
const sourceCounts = { queue: 0, direct: 0 };
|
|
8749
|
+
for (const item of activeWork) {
|
|
8750
|
+
sourceCounts[item.source] += 1;
|
|
8751
|
+
statusCounts[item.status] += 1;
|
|
8752
|
+
}
|
|
8753
|
+
return {
|
|
8754
|
+
totalActiveCount: activeWork.length,
|
|
8755
|
+
queueActiveCount: sourceCounts.queue,
|
|
8756
|
+
directActiveCount: sourceCounts.direct,
|
|
8757
|
+
awaitingApprovalCount: statusCounts.awaiting_approval,
|
|
8758
|
+
generatingCount: statusCounts.generating,
|
|
8759
|
+
failedCount: statusCounts.failed,
|
|
8760
|
+
idleCount: statusCounts.idle,
|
|
8761
|
+
sourceCounts,
|
|
8762
|
+
statusCounts
|
|
8763
|
+
};
|
|
8764
|
+
}
|
|
8765
|
+
function buildMeshActiveWork(opts) {
|
|
8766
|
+
const now = opts.now ?? Date.now();
|
|
8767
|
+
const records = [];
|
|
8768
|
+
for (const task of opts.queue || []) {
|
|
8769
|
+
if (task.status !== "pending" && task.status !== "assigned") continue;
|
|
8770
|
+
const { title, summary } = summarizeMessage(task.message || "");
|
|
8771
|
+
records.push({
|
|
8772
|
+
taskId: task.id,
|
|
8773
|
+
source: "queue",
|
|
8774
|
+
status: task.status,
|
|
8775
|
+
nodeId: task.assignedNodeId || task.targetNodeId,
|
|
8776
|
+
sessionId: task.assignedSessionId || task.targetSessionId,
|
|
8777
|
+
taskTitle: title,
|
|
8778
|
+
taskSummary: summary,
|
|
8779
|
+
message: task.message,
|
|
8780
|
+
taskMode: task.taskMode,
|
|
8781
|
+
createdAt: task.createdAt,
|
|
8782
|
+
updatedAt: task.updatedAt,
|
|
8783
|
+
dispatchedAt: task.dispatchTimestamp,
|
|
8784
|
+
elapsedMs: elapsedSince(task.dispatchTimestamp || task.createdAt, now)
|
|
8785
|
+
});
|
|
8786
|
+
}
|
|
8787
|
+
const ledgerEntries = (opts.ledgerEntries || []).slice().sort((a, b) => new Date(a.timestamp).getTime() - new Date(b.timestamp).getTime());
|
|
8788
|
+
const terminals = ledgerEntries.filter((entry) => TERMINAL_LEDGER_KINDS.has(entry.kind) || entry.kind === "task_approval_needed");
|
|
8789
|
+
for (const dispatch of ledgerEntries.filter(isDirectDispatch)) {
|
|
8790
|
+
const taskId = directDispatchTaskId(dispatch);
|
|
8791
|
+
const terminal = terminals.filter((entry) => new Date(entry.timestamp).getTime() >= new Date(dispatch.timestamp).getTime()).find((entry) => terminalMatchesDispatch(entry, dispatch, taskId));
|
|
8792
|
+
const terminalStatus = terminal ? statusFromTerminal(terminal) : void 0;
|
|
8793
|
+
const liveStatus = sessionStatusFromNodes(opts.nodes, dispatch.nodeId, dispatch.sessionId);
|
|
8794
|
+
const status = terminalStatus || liveStatus || "assigned";
|
|
8795
|
+
const terminalRow = Boolean(terminal && terminal.kind !== "task_approval_needed");
|
|
8796
|
+
if (terminalRow && opts.includeTerminalDirect !== true) continue;
|
|
8797
|
+
const message = readString2(dispatch.payload?.message) || readString2(dispatch.payload?.summary) || "";
|
|
8798
|
+
const { title, summary } = summarizeMessage(message);
|
|
8799
|
+
records.push({
|
|
8800
|
+
taskId,
|
|
8801
|
+
source: "direct",
|
|
8802
|
+
status,
|
|
8803
|
+
nodeId: dispatch.nodeId,
|
|
8804
|
+
sessionId: dispatch.sessionId,
|
|
8805
|
+
providerType: dispatch.providerType || readString2(dispatch.payload?.providerType),
|
|
8806
|
+
taskTitle: readString2(dispatch.payload?.taskTitle) || title,
|
|
8807
|
+
taskSummary: readString2(dispatch.payload?.taskSummary) || summary,
|
|
8808
|
+
message,
|
|
8809
|
+
taskMode: readString2(dispatch.payload?.taskMode),
|
|
8810
|
+
createdAt: dispatch.timestamp,
|
|
8811
|
+
updatedAt: terminal?.timestamp || dispatch.timestamp,
|
|
8812
|
+
dispatchedAt: dispatch.timestamp,
|
|
8813
|
+
elapsedMs: elapsedSince(dispatch.timestamp, now),
|
|
8814
|
+
terminal: terminalRow,
|
|
8815
|
+
terminalKind: terminal?.kind,
|
|
8816
|
+
terminalAt: terminal?.timestamp
|
|
8817
|
+
});
|
|
8818
|
+
}
|
|
8819
|
+
records.sort((a, b) => new Date(a.createdAt).getTime() - new Date(b.createdAt).getTime());
|
|
8820
|
+
return { activeWork: records, summary: buildMeshActiveWorkSummary(records) };
|
|
8821
|
+
}
|
|
8822
|
+
|
|
8823
|
+
// src/index.ts
|
|
8538
8824
|
init_mesh_host_ownership();
|
|
8539
8825
|
init_mesh_events();
|
|
8540
8826
|
|
|
@@ -25031,6 +25317,9 @@ function reconcileInlineMeshCache(cached, incoming) {
|
|
|
25031
25317
|
const cachedNodes = Array.isArray(cached.nodes) ? cached.nodes : [];
|
|
25032
25318
|
const incomingNodes = Array.isArray(incoming.nodes) ? incoming.nodes : [];
|
|
25033
25319
|
if (!cachedNodes.length || !incomingNodes.length) return { ...cached, ...incoming };
|
|
25320
|
+
const cachedUpdatedAt = Date.parse(readStringValue(cached.updatedAt, cached.updated_at) || "");
|
|
25321
|
+
const incomingUpdatedAt = Date.parse(readStringValue(incoming.updatedAt, incoming.updated_at) || "");
|
|
25322
|
+
const preserveCachedMembership = Number.isFinite(cachedUpdatedAt) && (!Number.isFinite(incomingUpdatedAt) || cachedUpdatedAt > incomingUpdatedAt);
|
|
25034
25323
|
const cachedById = /* @__PURE__ */ new Map();
|
|
25035
25324
|
for (const node of cachedNodes) {
|
|
25036
25325
|
const nodeId = readInlineMeshNodeId(node);
|
|
@@ -25039,12 +25328,13 @@ function reconcileInlineMeshCache(cached, incoming) {
|
|
|
25039
25328
|
const nodes = incomingNodes.map((incomingNode) => {
|
|
25040
25329
|
const nodeId = readInlineMeshNodeId(incomingNode);
|
|
25041
25330
|
const cachedNode = nodeId ? cachedById.get(nodeId) : void 0;
|
|
25331
|
+
if (!cachedNode && preserveCachedMembership) return null;
|
|
25042
25332
|
if (!cachedNode) return incomingNode;
|
|
25043
25333
|
if (hasInlineMeshTransientNodeState(incomingNode)) {
|
|
25044
25334
|
return { ...cachedNode, ...incomingNode };
|
|
25045
25335
|
}
|
|
25046
25336
|
return { ...stripInlineMeshTransientNodeState(cachedNode), ...incomingNode };
|
|
25047
|
-
});
|
|
25337
|
+
}).filter(Boolean);
|
|
25048
25338
|
return {
|
|
25049
25339
|
...cached,
|
|
25050
25340
|
...incoming,
|
|
@@ -36547,6 +36837,8 @@ export {
|
|
|
36547
36837
|
buildChatTailDeliverySignature,
|
|
36548
36838
|
buildCoordinatorSystemPrompt,
|
|
36549
36839
|
buildMachineInfo,
|
|
36840
|
+
buildMeshActiveWork,
|
|
36841
|
+
buildMeshActiveWorkSummary,
|
|
36550
36842
|
buildMeshHostRequiredFailure,
|
|
36551
36843
|
buildMeshLedgerReconciliationEvidence,
|
|
36552
36844
|
buildMeshLedgerReplicaEvidence,
|
|
@@ -36557,6 +36849,7 @@ export {
|
|
|
36557
36849
|
buildSessionModalDeliverySignature,
|
|
36558
36850
|
buildStatusSnapshot,
|
|
36559
36851
|
buildSystemChatMessage,
|
|
36852
|
+
buildTaskCompletionEvidence,
|
|
36560
36853
|
buildTerminalChatMessage,
|
|
36561
36854
|
buildThoughtChatMessage,
|
|
36562
36855
|
buildToolChatMessage,
|
|
@@ -36667,6 +36960,8 @@ export {
|
|
|
36667
36960
|
normalizeInputEnvelope,
|
|
36668
36961
|
normalizeManagedStatus,
|
|
36669
36962
|
normalizeMeshDaemonRole,
|
|
36963
|
+
normalizeMeshTaskMode,
|
|
36964
|
+
normalizeMeshWorkerResult,
|
|
36670
36965
|
normalizeMessageParts,
|
|
36671
36966
|
normalizeRepoIdentity,
|
|
36672
36967
|
normalizeSessionModalFields,
|
|
@@ -36722,6 +37017,7 @@ export {
|
|
|
36722
37017
|
updateSessionTaskStatus,
|
|
36723
37018
|
updateTaskStatus,
|
|
36724
37019
|
upsertSavedProviderSession,
|
|
36725
|
-
validateMeshRefineConfig
|
|
37020
|
+
validateMeshRefineConfig,
|
|
37021
|
+
validateMeshTaskModeRequest
|
|
36726
37022
|
};
|
|
36727
37023
|
//# sourceMappingURL=index.mjs.map
|