@adhdev/daemon-standalone 1.0.32-rc.3 → 1.0.32-rc.5
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 +79787 -79536
- package/dist/index.js.map +1 -1
- package/package.json +2 -2
- package/vendor/mcp-server/index.js +71 -10
- package/vendor/mcp-server/index.js.map +1 -1
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@adhdev/daemon-standalone",
|
|
3
|
-
"version": "1.0.32-rc.
|
|
3
|
+
"version": "1.0.32-rc.5",
|
|
4
4
|
"description": "ADHDev standalone daemon — embedded HTTP/WS server for local dashboard",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"bin": {
|
|
@@ -37,7 +37,7 @@
|
|
|
37
37
|
"license": "AGPL-3.0-or-later",
|
|
38
38
|
"dependencies": {
|
|
39
39
|
"@adhdev/ghostty-vt-node": "*",
|
|
40
|
-
"@adhdev/session-host-core": "1.0.32-rc.
|
|
40
|
+
"@adhdev/session-host-core": "1.0.32-rc.5",
|
|
41
41
|
"@xterm/addon-serialize": "^0.14.0",
|
|
42
42
|
"@xterm/xterm": "^6.0.0",
|
|
43
43
|
"chalk": "^5.3.0",
|
|
@@ -1883,7 +1883,23 @@ function summarizeCompactSubmodules(submodules) {
|
|
|
1883
1883
|
...outOfSync.length > 0 ? { outOfSyncPaths: outOfSync } : {}
|
|
1884
1884
|
};
|
|
1885
1885
|
}
|
|
1886
|
-
var MESH_COMPACT_PRESERVED_MARKER_FIELDS = ["dataFreshness"];
|
|
1886
|
+
var MESH_COMPACT_PRESERVED_MARKER_FIELDS = ["dataFreshness", "quota"];
|
|
1887
|
+
function summarizeNodeQuota(quota) {
|
|
1888
|
+
if (!quota || typeof quota !== "object" || Array.isArray(quota)) return void 0;
|
|
1889
|
+
const out = {};
|
|
1890
|
+
for (const [provider, snapshot] of Object.entries(quota)) {
|
|
1891
|
+
if (!snapshot || typeof snapshot !== "object") continue;
|
|
1892
|
+
const status = typeof snapshot.status === "string" ? snapshot.status : "unknown";
|
|
1893
|
+
if (status !== "ok") {
|
|
1894
|
+
const kind = typeof snapshot.metadata?.failureKind === "string" ? snapshot.metadata.failureKind : void 0;
|
|
1895
|
+
out[provider] = kind ? `${status}:${kind}` : status;
|
|
1896
|
+
continue;
|
|
1897
|
+
}
|
|
1898
|
+
const pct = (w) => w && Number.isFinite(w.usedPercent) ? `${Math.round(w.usedPercent)}%` : "\u2014";
|
|
1899
|
+
out[provider] = `${pct(snapshot.session)}/${pct(snapshot.weekly)}`;
|
|
1900
|
+
}
|
|
1901
|
+
return Object.keys(out).length > 0 ? out : void 0;
|
|
1902
|
+
}
|
|
1887
1903
|
function compactMeshStatusNode(entry) {
|
|
1888
1904
|
if (!entry || typeof entry !== "object") return entry;
|
|
1889
1905
|
const next = { ...entry };
|
|
@@ -1921,6 +1937,11 @@ function compactMeshStatusNode(entry) {
|
|
|
1921
1937
|
seeStaleDaemonBuilds: true
|
|
1922
1938
|
};
|
|
1923
1939
|
}
|
|
1940
|
+
if (next.quota !== void 0) {
|
|
1941
|
+
const summary = summarizeNodeQuota(next.quota);
|
|
1942
|
+
if (summary) next.quota = summary;
|
|
1943
|
+
else delete next.quota;
|
|
1944
|
+
}
|
|
1924
1945
|
delete next.capabilityTagsByProvider;
|
|
1925
1946
|
const elideSkip = /* @__PURE__ */ new Set(["git", "machine", "branchConvergence", "staleDaemonBuild", "sessions", ...MESH_COMPACT_PRESERVED_MARKER_FIELDS]);
|
|
1926
1947
|
for (const k of Object.keys(next)) {
|
|
@@ -2011,7 +2032,7 @@ var STALE_ASSIGNED_QUEUE_MS = 30 * 6e4;
|
|
|
2011
2032
|
var OLD_HISTORICAL_QUEUE_RECORD_MS = 7 * 24 * 60 * 6e4;
|
|
2012
2033
|
var ACTIVE_QUEUE_STATUSES = /* @__PURE__ */ new Set(["pending", "assigned"]);
|
|
2013
2034
|
var HISTORICAL_QUEUE_STATUSES = /* @__PURE__ */ new Set(["completed", "failed", "cancelled"]);
|
|
2014
|
-
function buildQueueLivenessIndex(mesh) {
|
|
2035
|
+
function buildQueueLivenessIndex(mesh, liveVerifiedNodes) {
|
|
2015
2036
|
const nodeIds = /* @__PURE__ */ new Set();
|
|
2016
2037
|
const nodeSessionIds = /* @__PURE__ */ new Map();
|
|
2017
2038
|
for (const node of Array.isArray(mesh?.nodes) ? mesh.nodes : []) {
|
|
@@ -2021,20 +2042,33 @@ function buildQueueLivenessIndex(mesh) {
|
|
|
2021
2042
|
const sessions = collectNodeSessionIds(node);
|
|
2022
2043
|
if (sessions.size > 0) nodeSessionIds.set(nodeId, sessions);
|
|
2023
2044
|
}
|
|
2024
|
-
|
|
2045
|
+
const verifiedLiveNodeIds = /* @__PURE__ */ new Set();
|
|
2046
|
+
for (const node of Array.isArray(liveVerifiedNodes) ? liveVerifiedNodes : []) {
|
|
2047
|
+
if (node?.__liveProbeVerified !== true) continue;
|
|
2048
|
+
const nodeId = readString(node.id) || readString(node.nodeId) || readString(node.node_id);
|
|
2049
|
+
if (!nodeId) continue;
|
|
2050
|
+
verifiedLiveNodeIds.add(nodeId);
|
|
2051
|
+
nodeSessionIds.set(nodeId, collectNodeSessionIds(node));
|
|
2052
|
+
}
|
|
2053
|
+
return { nodeIds, nodeSessionIds, verifiedLiveNodeIds };
|
|
2025
2054
|
}
|
|
2055
|
+
var SESSION_LIVENESS_STARTUP_GRACE_MS = 2 * 6e4;
|
|
2026
2056
|
function queueAssignmentStaleReason(task, liveness) {
|
|
2027
2057
|
if (task?.status !== "assigned") return void 0;
|
|
2028
2058
|
const nodeId = readString(task.assignedNodeId) || readString(task.nodeId) || readString(task.node_id) || readString(task.targetNodeId);
|
|
2029
2059
|
const sessionId = readString(task.assignedSessionId) || readString(task.sessionId) || readString(task.session_id) || readString(task.targetSessionId);
|
|
2060
|
+
const updatedAt = new Date(task.updatedAt).getTime();
|
|
2061
|
+
const ageMs = Number.isFinite(updatedAt) ? Date.now() - updatedAt : null;
|
|
2030
2062
|
if (nodeId && liveness.nodeIds.size > 0 && !liveness.nodeIds.has(nodeId)) {
|
|
2031
2063
|
return "assigned node is not present in the current mesh snapshot";
|
|
2032
2064
|
}
|
|
2033
2065
|
if (nodeId && sessionId && liveness.nodeSessionIds.has(nodeId) && !liveness.nodeSessionIds.get(nodeId).has(sessionId)) {
|
|
2034
|
-
|
|
2066
|
+
const verifiedByProbe = liveness.verifiedLiveNodeIds.size === 0 || liveness.verifiedLiveNodeIds.has(nodeId);
|
|
2067
|
+
const pastStartupGrace = ageMs === null || ageMs >= SESSION_LIVENESS_STARTUP_GRACE_MS;
|
|
2068
|
+
if (verifiedByProbe && pastStartupGrace) {
|
|
2069
|
+
return "assigned session is not live on the assigned node";
|
|
2070
|
+
}
|
|
2035
2071
|
}
|
|
2036
|
-
const updatedAt = new Date(task.updatedAt).getTime();
|
|
2037
|
-
const ageMs = Number.isFinite(updatedAt) ? Date.now() - updatedAt : null;
|
|
2038
2072
|
if (!nodeId && ageMs !== null && ageMs >= STALE_ASSIGNED_QUEUE_MS) {
|
|
2039
2073
|
return "assigned task has no assigned node metadata";
|
|
2040
2074
|
}
|
|
@@ -2210,8 +2244,8 @@ function compactActiveWorkRecords(records) {
|
|
|
2210
2244
|
const capped = records.slice(0, COMPACT_MAX_ACTIVE_WORK_ROWS).map(compactActiveWorkRecord);
|
|
2211
2245
|
return { records: capped, omitted: Math.max(0, records.length - capped.length) };
|
|
2212
2246
|
}
|
|
2213
|
-
function annotateQueueStaleness(queue, mesh) {
|
|
2214
|
-
const liveness = buildQueueLivenessIndex(mesh);
|
|
2247
|
+
function annotateQueueStaleness(queue, mesh, liveVerifiedNodes) {
|
|
2248
|
+
const liveness = buildQueueLivenessIndex(mesh, liveVerifiedNodes);
|
|
2215
2249
|
const now = Date.now();
|
|
2216
2250
|
return queue.map((task) => {
|
|
2217
2251
|
const taskStatus = typeof task?.status === "string" ? task.status : void 0;
|
|
@@ -2771,6 +2805,13 @@ function extractSubmodules(value, ignorePaths) {
|
|
|
2771
2805
|
const ignoreSet = new Set(ignorePaths);
|
|
2772
2806
|
return subs.filter((s) => s?.path && !ignoreSet.has(s.path));
|
|
2773
2807
|
}
|
|
2808
|
+
function extractReporterNodeFactsQuota(value) {
|
|
2809
|
+
const payload = unwrapCommandPayload(value);
|
|
2810
|
+
const facts = payload?.reporterNodeFacts ?? value?.reporterNodeFacts;
|
|
2811
|
+
const quota = facts?.quota;
|
|
2812
|
+
if (!quota || typeof quota !== "object" || Array.isArray(quota)) return void 0;
|
|
2813
|
+
return Object.keys(quota).length > 0 ? quota : void 0;
|
|
2814
|
+
}
|
|
2774
2815
|
function assignFullGitSnapshot(entry, status) {
|
|
2775
2816
|
if (!status || typeof status !== "object" || Array.isArray(status)) return;
|
|
2776
2817
|
entry.git = status;
|
|
@@ -3278,6 +3319,14 @@ async function collectLiveStatusSessions(ctx, node) {
|
|
|
3278
3319
|
return [];
|
|
3279
3320
|
}
|
|
3280
3321
|
}
|
|
3322
|
+
async function collectLiveStatusSessionsVerified(ctx, node) {
|
|
3323
|
+
try {
|
|
3324
|
+
const statusResult = await commandForNode(ctx, node, "get_status_metadata", {});
|
|
3325
|
+
return { sessions: extractStatusMetadataSessions(statusResult), verified: true };
|
|
3326
|
+
} catch {
|
|
3327
|
+
return { sessions: [], verified: false };
|
|
3328
|
+
}
|
|
3329
|
+
}
|
|
3281
3330
|
async function collectLiveStatusProbe(ctx, node) {
|
|
3282
3331
|
try {
|
|
3283
3332
|
const statusResult = await commandForNode(ctx, node, "get_status_metadata", {}, { statusProbe: true });
|
|
@@ -3309,6 +3358,16 @@ async function collectMeshViewQueueNodesWithLiveSessions(ctx) {
|
|
|
3309
3358
|
}));
|
|
3310
3359
|
return nodes;
|
|
3311
3360
|
}
|
|
3361
|
+
async function collectMeshViewQueueNodesWithLiveSessionsVerified(ctx) {
|
|
3362
|
+
const nodes = await Promise.all(ctx.mesh.nodes.map(async (node) => {
|
|
3363
|
+
const { sessions: liveSessions, verified } = await collectLiveStatusSessionsVerified(ctx, node);
|
|
3364
|
+
if (verified) {
|
|
3365
|
+
return { ...node, sessions: liveSessions, __liveProbeVerified: true };
|
|
3366
|
+
}
|
|
3367
|
+
return { ...node, __liveProbeVerified: false };
|
|
3368
|
+
}));
|
|
3369
|
+
return nodes;
|
|
3370
|
+
}
|
|
3312
3371
|
function buildBranchConvergence(mesh, node, status, dirty, uncommittedChanges) {
|
|
3313
3372
|
const defaultBranch = readString(mesh.defaultBranch) ?? "main";
|
|
3314
3373
|
const branch = readString(status?.branch) ?? readString(node.worktreeBranch) ?? null;
|
|
@@ -3742,6 +3801,8 @@ async function meshStatus(ctx, args = {}) {
|
|
|
3742
3801
|
if (status?.daemonBuildBehind && typeof status.daemonBuildBehind === "object") {
|
|
3743
3802
|
entry.staleDaemonBuild = status.daemonBuildBehind;
|
|
3744
3803
|
}
|
|
3804
|
+
const reportedQuota = extractReporterNodeFactsQuota(statusResult);
|
|
3805
|
+
if (reportedQuota) entry.quota = reportedQuota;
|
|
3745
3806
|
const submodules = extractSubmodules(statusResult, node.policy?.submoduleIgnorePaths || []);
|
|
3746
3807
|
if (submodules && submodules.some((s) => s?.outOfSync)) {
|
|
3747
3808
|
entry.submoduleWarning = "One or more submodules are out of sync with the parent repo. Run `git submodule update` or check deployment readiness.";
|
|
@@ -4440,12 +4501,12 @@ async function meshViewQueue(ctx, args) {
|
|
|
4440
4501
|
const depState = (0, import_daemon_core4.describeTaskDependencyState)(task, statusById);
|
|
4441
4502
|
return { ...task, ...depState };
|
|
4442
4503
|
});
|
|
4443
|
-
const
|
|
4504
|
+
const liveNodes = await collectMeshViewQueueNodesWithLiveSessionsVerified(ctx);
|
|
4505
|
+
const fullQueue = prioritizeActiveQueueRows(annotateQueueStaleness(withDependencies, ctx.mesh, liveNodes));
|
|
4444
4506
|
const queue = filterQueueForView(fullQueue, view, statusFilter);
|
|
4445
4507
|
const summary = buildQueueStatusSummary(fullQueue);
|
|
4446
4508
|
const visibleSummary = buildQueueStatusSummary(queue);
|
|
4447
4509
|
const maintenance = buildQueueMaintenanceReport(fullQueue);
|
|
4448
|
-
const liveNodes = await collectMeshViewQueueNodesWithLiveSessions(ctx);
|
|
4449
4510
|
let ledgerEntries = (0, import_daemon_core4.readLedgerEntries)(ctx.mesh.id, { tail: 200 });
|
|
4450
4511
|
let directDispatches = (0, import_daemon_core4.getActiveDirectDispatches)(ctx.mesh.id);
|
|
4451
4512
|
const directReconciliation = await reconcileDirectDispatchesFromTranscriptEvidence(ctx, liveNodes, directDispatches, ledgerEntries);
|