@adhdev/daemon-core 0.9.81 → 0.9.82-rc.10
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/boot/daemon-lifecycle.d.ts +2 -0
- package/dist/commands/router.d.ts +2 -0
- package/dist/git/git-commands.d.ts +1 -0
- package/dist/git/git-status.d.ts +5 -0
- package/dist/git/git-types.d.ts +10 -0
- package/dist/index.d.ts +2 -2
- package/dist/index.js +415 -78
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +414 -78
- package/dist/index.mjs.map +1 -1
- package/dist/mesh/mesh-events.d.ts +3 -0
- package/dist/repo-mesh-types.d.ts +121 -0
- package/package.json +1 -1
- package/src/boot/daemon-lifecycle.ts +3 -0
- package/src/commands/router.ts +373 -67
- package/src/git/git-commands.ts +3 -3
- package/src/git/git-status.ts +97 -6
- package/src/git/git-summary.ts +3 -0
- package/src/git/git-types.ts +11 -0
- package/src/index.ts +9 -1
- package/src/mesh/mesh-events.ts +14 -3
- package/src/repo-mesh-types.ts +131 -0
package/dist/index.mjs
CHANGED
|
@@ -1890,10 +1890,18 @@ __export(mesh_events_exports, {
|
|
|
1890
1890
|
drainPendingMeshCoordinatorEvents: () => drainPendingMeshCoordinatorEvents,
|
|
1891
1891
|
getPendingMeshCoordinatorEvents: () => getPendingMeshCoordinatorEvents,
|
|
1892
1892
|
handleMeshForwardEvent: () => handleMeshForwardEvent,
|
|
1893
|
+
queuePendingMeshCoordinatorEvent: () => queuePendingMeshCoordinatorEvent,
|
|
1893
1894
|
setupMeshEventForwarding: () => setupMeshEventForwarding,
|
|
1894
1895
|
triggerMeshQueue: () => triggerMeshQueue,
|
|
1895
1896
|
tryAssignQueueTask: () => tryAssignQueueTask
|
|
1896
1897
|
});
|
|
1898
|
+
function queuePendingMeshCoordinatorEvent(event) {
|
|
1899
|
+
if (pendingMeshCoordinatorEvents.length >= MAX_PENDING_EVENTS) {
|
|
1900
|
+
return false;
|
|
1901
|
+
}
|
|
1902
|
+
pendingMeshCoordinatorEvents.push(event);
|
|
1903
|
+
return true;
|
|
1904
|
+
}
|
|
1897
1905
|
function drainPendingMeshCoordinatorEvents() {
|
|
1898
1906
|
return pendingMeshCoordinatorEvents.splice(0);
|
|
1899
1907
|
}
|
|
@@ -2465,17 +2473,18 @@ function injectMeshSystemMessage(components, args) {
|
|
|
2465
2473
|
return true;
|
|
2466
2474
|
});
|
|
2467
2475
|
if (coordinatorInstances.length === 0) {
|
|
2468
|
-
if (
|
|
2469
|
-
|
|
2470
|
-
|
|
2471
|
-
|
|
2472
|
-
|
|
2473
|
-
|
|
2474
|
-
|
|
2475
|
-
|
|
2476
|
-
}
|
|
2477
|
-
|
|
2478
|
-
|
|
2476
|
+
if (queuePendingMeshCoordinatorEvent({
|
|
2477
|
+
event: args.event,
|
|
2478
|
+
meshId: args.meshId,
|
|
2479
|
+
nodeLabel: args.nodeLabel,
|
|
2480
|
+
nodeId: args.nodeId || void 0,
|
|
2481
|
+
workspace: readNonEmptyString(args.metadataEvent.workspace),
|
|
2482
|
+
metadataEvent: {
|
|
2483
|
+
...args.metadataEvent,
|
|
2484
|
+
...recoveryContext ? { recoveryContext } : {}
|
|
2485
|
+
},
|
|
2486
|
+
queuedAt: Date.now()
|
|
2487
|
+
})) {
|
|
2479
2488
|
LOG.info("MeshEvents", `Queued ${args.event} for MCP coordinator (mesh ${args.meshId})`);
|
|
2480
2489
|
}
|
|
2481
2490
|
return { success: true, forwarded: 0 };
|
|
@@ -5676,8 +5685,14 @@ async function getGitRepoStatus(workspace, options = {}) {
|
|
|
5676
5685
|
const includeSubmodules = options.includeSubmodules !== false;
|
|
5677
5686
|
try {
|
|
5678
5687
|
const repo = await resolveGitRepository(workspace, options);
|
|
5679
|
-
|
|
5680
|
-
|
|
5688
|
+
let parsed = await readPorcelainStatus(repo, options);
|
|
5689
|
+
let upstreamProbe = getInitialUpstreamProbe(parsed);
|
|
5690
|
+
if (options.refreshUpstream) {
|
|
5691
|
+
upstreamProbe = await refreshTrackedUpstream(repo, parsed, options);
|
|
5692
|
+
if (upstreamProbe.upstreamStatus === "fresh") {
|
|
5693
|
+
parsed = await readPorcelainStatus(repo, options);
|
|
5694
|
+
}
|
|
5695
|
+
}
|
|
5681
5696
|
const head = await readHead(repo, options);
|
|
5682
5697
|
const stashCount = await readStashCount(repo, options);
|
|
5683
5698
|
let submodules;
|
|
@@ -5692,6 +5707,9 @@ async function getGitRepoStatus(workspace, options = {}) {
|
|
|
5692
5707
|
headCommit: head.commit,
|
|
5693
5708
|
headMessage: head.message,
|
|
5694
5709
|
upstream: parsed.upstream,
|
|
5710
|
+
upstreamStatus: parsed.upstream ? upstreamProbe.upstreamStatus : "no_upstream",
|
|
5711
|
+
upstreamFetchedAt: upstreamProbe.upstreamFetchedAt,
|
|
5712
|
+
upstreamFetchError: upstreamProbe.upstreamFetchError,
|
|
5695
5713
|
ahead: parsed.ahead,
|
|
5696
5714
|
behind: parsed.behind,
|
|
5697
5715
|
staged: parsed.staged,
|
|
@@ -5716,6 +5734,60 @@ async function getGitRepoStatus(workspace, options = {}) {
|
|
|
5716
5734
|
);
|
|
5717
5735
|
}
|
|
5718
5736
|
}
|
|
5737
|
+
async function readPorcelainStatus(repo, options) {
|
|
5738
|
+
const statusOutput = await runGit(repo, ["status", "--porcelain=v2", "--branch"], options);
|
|
5739
|
+
return parsePorcelainV2Status(statusOutput.stdout);
|
|
5740
|
+
}
|
|
5741
|
+
function getInitialUpstreamProbe(parsed) {
|
|
5742
|
+
return {
|
|
5743
|
+
upstreamStatus: parsed.upstream ? "unchecked" : "no_upstream"
|
|
5744
|
+
};
|
|
5745
|
+
}
|
|
5746
|
+
async function refreshTrackedUpstream(repo, parsed, options) {
|
|
5747
|
+
if (!parsed.upstream || !parsed.branch) {
|
|
5748
|
+
return { upstreamStatus: "no_upstream" };
|
|
5749
|
+
}
|
|
5750
|
+
const remoteName = await readBranchRemote(repo, parsed.branch, options) ?? inferRemoteName(parsed.upstream);
|
|
5751
|
+
if (!remoteName) {
|
|
5752
|
+
return {
|
|
5753
|
+
upstreamStatus: "stale",
|
|
5754
|
+
upstreamFetchError: `Unable to resolve remote for upstream '${parsed.upstream}'`
|
|
5755
|
+
};
|
|
5756
|
+
}
|
|
5757
|
+
try {
|
|
5758
|
+
await runGit(repo, ["fetch", "--quiet", "--prune", "--no-tags", remoteName], options);
|
|
5759
|
+
return {
|
|
5760
|
+
upstreamStatus: "fresh",
|
|
5761
|
+
upstreamFetchedAt: Date.now()
|
|
5762
|
+
};
|
|
5763
|
+
} catch (error) {
|
|
5764
|
+
return {
|
|
5765
|
+
upstreamStatus: "stale",
|
|
5766
|
+
upstreamFetchError: formatGitError(error)
|
|
5767
|
+
};
|
|
5768
|
+
}
|
|
5769
|
+
}
|
|
5770
|
+
async function readBranchRemote(repo, branch, options) {
|
|
5771
|
+
try {
|
|
5772
|
+
const result = await runGit(repo, ["config", "--get", `branch.${branch}.remote`], options);
|
|
5773
|
+
return result.stdout.trim() || null;
|
|
5774
|
+
} catch {
|
|
5775
|
+
return null;
|
|
5776
|
+
}
|
|
5777
|
+
}
|
|
5778
|
+
function inferRemoteName(upstream) {
|
|
5779
|
+
const [remoteName] = upstream.split("/");
|
|
5780
|
+
return remoteName?.trim() || null;
|
|
5781
|
+
}
|
|
5782
|
+
function formatGitError(error) {
|
|
5783
|
+
if (error instanceof GitCommandError) {
|
|
5784
|
+
return error.stderr || error.message;
|
|
5785
|
+
}
|
|
5786
|
+
if (error instanceof Error) {
|
|
5787
|
+
return error.message;
|
|
5788
|
+
}
|
|
5789
|
+
return String(error);
|
|
5790
|
+
}
|
|
5719
5791
|
function parsePorcelainV2Status(output) {
|
|
5720
5792
|
const parsed = {
|
|
5721
5793
|
branch: null,
|
|
@@ -5810,6 +5882,7 @@ function emptyStatus(workspace, lastCheckedAt, error) {
|
|
|
5810
5882
|
headCommit: null,
|
|
5811
5883
|
headMessage: null,
|
|
5812
5884
|
upstream: null,
|
|
5885
|
+
upstreamStatus: "unavailable",
|
|
5813
5886
|
ahead: 0,
|
|
5814
5887
|
behind: 0,
|
|
5815
5888
|
staged: 0,
|
|
@@ -6090,6 +6163,9 @@ function createGitCompactSummary(status, diffSummary) {
|
|
|
6090
6163
|
isGitRepo: status.isGitRepo,
|
|
6091
6164
|
repoRoot: status.repoRoot,
|
|
6092
6165
|
branch: status.branch,
|
|
6166
|
+
upstreamStatus: status.upstreamStatus,
|
|
6167
|
+
upstreamFetchedAt: status.upstreamFetchedAt,
|
|
6168
|
+
upstreamFetchError: status.upstreamFetchError,
|
|
6093
6169
|
dirty: status.staged > 0 || status.modified > 0 || status.untracked > 0 || status.deleted > 0 || status.renamed > 0 || conflictCount > 0 || changedFiles > 0,
|
|
6094
6170
|
changedFiles,
|
|
6095
6171
|
ahead: status.ahead,
|
|
@@ -6434,7 +6510,7 @@ var defaultSnapshotStore = createGitSnapshotStore({
|
|
|
6434
6510
|
});
|
|
6435
6511
|
function createDefaultGitCommandServices() {
|
|
6436
6512
|
return {
|
|
6437
|
-
getStatus: ({ workspace }) => getGitRepoStatus(workspace),
|
|
6513
|
+
getStatus: ({ workspace, refreshUpstream }) => getGitRepoStatus(workspace, { refreshUpstream }),
|
|
6438
6514
|
getDiffSummary: ({ workspace }) => getGitDiffSummary(workspace),
|
|
6439
6515
|
getDiffFile: ({ workspace, path: filePath }) => getGitFileDiff(workspace, filePath),
|
|
6440
6516
|
createSnapshot: ({ workspace, reason, sessionId, turnId }) => defaultSnapshotStore.create({
|
|
@@ -6520,7 +6596,7 @@ async function handleGitCommand(command, args, services = defaultGitCommandServi
|
|
|
6520
6596
|
switch (command) {
|
|
6521
6597
|
case "git_status": {
|
|
6522
6598
|
if (!services.getStatus) return serviceNotImplemented(command);
|
|
6523
|
-
const status = await runService(() => services.getStatus({ workspace }));
|
|
6599
|
+
const status = await runService(() => services.getStatus({ workspace, refreshUpstream: optionalBoolean(args?.refreshUpstream) }));
|
|
6524
6600
|
return "success" in status ? status : { success: true, status };
|
|
6525
6601
|
}
|
|
6526
6602
|
case "git_diff_summary": {
|
|
@@ -23582,6 +23658,240 @@ function readProviderPriorityFromPolicy(policy) {
|
|
|
23582
23658
|
return true;
|
|
23583
23659
|
});
|
|
23584
23660
|
}
|
|
23661
|
+
function readObjectRecord(value) {
|
|
23662
|
+
return value && typeof value === "object" && !Array.isArray(value) ? value : {};
|
|
23663
|
+
}
|
|
23664
|
+
function readStringValue(...values) {
|
|
23665
|
+
for (const value of values) {
|
|
23666
|
+
if (typeof value === "string" && value.trim()) return value.trim();
|
|
23667
|
+
}
|
|
23668
|
+
return void 0;
|
|
23669
|
+
}
|
|
23670
|
+
function readNumberValue(...values) {
|
|
23671
|
+
for (const value of values) {
|
|
23672
|
+
if (typeof value === "number" && Number.isFinite(value)) return value;
|
|
23673
|
+
}
|
|
23674
|
+
return void 0;
|
|
23675
|
+
}
|
|
23676
|
+
function readBooleanValue(...values) {
|
|
23677
|
+
for (const value of values) {
|
|
23678
|
+
if (typeof value === "boolean") return value;
|
|
23679
|
+
}
|
|
23680
|
+
return void 0;
|
|
23681
|
+
}
|
|
23682
|
+
function readGitSubmodules(value) {
|
|
23683
|
+
if (!Array.isArray(value)) return void 0;
|
|
23684
|
+
const submodules = value.map((entry) => {
|
|
23685
|
+
const submodule = readObjectRecord(entry);
|
|
23686
|
+
const path28 = readStringValue(submodule.path);
|
|
23687
|
+
const commit = readStringValue(submodule.commit);
|
|
23688
|
+
const repoPath = readStringValue(submodule.repoPath, submodule.repo_root);
|
|
23689
|
+
if (!path28 || !commit || !repoPath) return null;
|
|
23690
|
+
return {
|
|
23691
|
+
path: path28,
|
|
23692
|
+
commit,
|
|
23693
|
+
repoPath,
|
|
23694
|
+
dirty: readBooleanValue(submodule.dirty) ?? false,
|
|
23695
|
+
outOfSync: readBooleanValue(submodule.outOfSync, submodule.out_of_sync) ?? false,
|
|
23696
|
+
lastCheckedAt: readNumberValue(submodule.lastCheckedAt, submodule.last_checked_at) ?? Date.now(),
|
|
23697
|
+
...readStringValue(submodule.error) ? { error: readStringValue(submodule.error) } : {}
|
|
23698
|
+
};
|
|
23699
|
+
}).filter((entry) => entry !== null);
|
|
23700
|
+
return submodules.length > 0 ? submodules : void 0;
|
|
23701
|
+
}
|
|
23702
|
+
function buildCachedInlineMeshGitStatus(node) {
|
|
23703
|
+
const cachedStatus = readObjectRecord(node?.cachedStatus);
|
|
23704
|
+
const cachedGit = readObjectRecord(cachedStatus.git);
|
|
23705
|
+
if (Object.keys(cachedGit).length) {
|
|
23706
|
+
const conflictFiles2 = Array.isArray(cachedGit.conflictFiles) ? cachedGit.conflictFiles.filter((value) => typeof value === "string") : [];
|
|
23707
|
+
const conflictCount2 = readNumberValue(cachedGit.conflicts) ?? conflictFiles2.length;
|
|
23708
|
+
const hasConflicts2 = readBooleanValue(cachedGit.hasConflicts) ?? conflictCount2 > 0;
|
|
23709
|
+
const isGitRepo2 = readBooleanValue(cachedGit.isGitRepo);
|
|
23710
|
+
if (isGitRepo2 !== void 0) {
|
|
23711
|
+
const submodules2 = readGitSubmodules(cachedGit.submodules);
|
|
23712
|
+
return {
|
|
23713
|
+
workspace: readStringValue(cachedGit.workspace, node?.workspace) || "",
|
|
23714
|
+
repoRoot: readStringValue(cachedGit.repoRoot, node?.repoRoot, node?.workspace) || null,
|
|
23715
|
+
isGitRepo: isGitRepo2,
|
|
23716
|
+
branch: readStringValue(cachedGit.branch) ?? null,
|
|
23717
|
+
headCommit: readStringValue(cachedGit.headCommit) ?? null,
|
|
23718
|
+
headMessage: readStringValue(cachedGit.headMessage) ?? null,
|
|
23719
|
+
upstream: readStringValue(cachedGit.upstream) ?? null,
|
|
23720
|
+
ahead: readNumberValue(cachedGit.ahead) ?? 0,
|
|
23721
|
+
behind: readNumberValue(cachedGit.behind) ?? 0,
|
|
23722
|
+
staged: readNumberValue(cachedGit.staged) ?? 0,
|
|
23723
|
+
modified: readNumberValue(cachedGit.modified) ?? 0,
|
|
23724
|
+
untracked: readNumberValue(cachedGit.untracked) ?? 0,
|
|
23725
|
+
deleted: readNumberValue(cachedGit.deleted) ?? 0,
|
|
23726
|
+
renamed: readNumberValue(cachedGit.renamed) ?? 0,
|
|
23727
|
+
hasConflicts: hasConflicts2,
|
|
23728
|
+
conflictFiles: conflictFiles2,
|
|
23729
|
+
stashCount: readNumberValue(cachedGit.stashCount) ?? 0,
|
|
23730
|
+
lastCheckedAt: readNumberValue(cachedGit.lastCheckedAt) ?? Date.now(),
|
|
23731
|
+
...submodules2 ? { submodules: submodules2 } : {}
|
|
23732
|
+
};
|
|
23733
|
+
}
|
|
23734
|
+
}
|
|
23735
|
+
const rawGit = readObjectRecord(node?.lastGit ?? node?.last_git);
|
|
23736
|
+
const gitResult = readObjectRecord(rawGit.result);
|
|
23737
|
+
const directStatus = readObjectRecord(rawGit.status);
|
|
23738
|
+
const nestedStatus = readObjectRecord(gitResult.status);
|
|
23739
|
+
const rawProbe = readObjectRecord(node?.lastProbe ?? node?.last_probe);
|
|
23740
|
+
const probeGit = readObjectRecord(rawProbe.git);
|
|
23741
|
+
const probeGitResult = readObjectRecord(probeGit.result);
|
|
23742
|
+
const probeDirectStatus = readObjectRecord(probeGit.status);
|
|
23743
|
+
const probeNestedStatus = readObjectRecord(probeGitResult.status);
|
|
23744
|
+
const status = Object.keys(directStatus).length ? directStatus : Object.keys(nestedStatus).length ? nestedStatus : Object.keys(probeDirectStatus).length ? probeDirectStatus : Object.keys(probeNestedStatus).length ? probeNestedStatus : {};
|
|
23745
|
+
const isGitRepo = readBooleanValue(status.isGitRepo);
|
|
23746
|
+
if (!Object.keys(status).length || isGitRepo === void 0) return void 0;
|
|
23747
|
+
const conflictFiles = Array.isArray(status.conflictFiles) ? status.conflictFiles.filter((value) => typeof value === "string") : [];
|
|
23748
|
+
const conflictCount = readNumberValue(status.conflicts) ?? conflictFiles.length;
|
|
23749
|
+
const hasConflicts = readBooleanValue(status.hasConflicts) ?? conflictCount > 0;
|
|
23750
|
+
const submodules = readGitSubmodules(status.submodules);
|
|
23751
|
+
return {
|
|
23752
|
+
workspace: readStringValue(status.workspace, node?.workspace) || "",
|
|
23753
|
+
repoRoot: readStringValue(status.repoRoot, node?.repoRoot, node?.workspace) || null,
|
|
23754
|
+
isGitRepo,
|
|
23755
|
+
branch: readStringValue(status.branch) ?? null,
|
|
23756
|
+
headCommit: readStringValue(status.headCommit) ?? null,
|
|
23757
|
+
headMessage: readStringValue(status.headMessage) ?? null,
|
|
23758
|
+
upstream: readStringValue(status.upstream) ?? null,
|
|
23759
|
+
ahead: readNumberValue(status.ahead) ?? 0,
|
|
23760
|
+
behind: readNumberValue(status.behind) ?? 0,
|
|
23761
|
+
staged: readNumberValue(status.staged) ?? 0,
|
|
23762
|
+
modified: readNumberValue(status.modified) ?? 0,
|
|
23763
|
+
untracked: readNumberValue(status.untracked) ?? 0,
|
|
23764
|
+
deleted: readNumberValue(status.deleted) ?? 0,
|
|
23765
|
+
renamed: readNumberValue(status.renamed) ?? 0,
|
|
23766
|
+
hasConflicts,
|
|
23767
|
+
conflictFiles,
|
|
23768
|
+
stashCount: readNumberValue(status.stashCount) ?? 0,
|
|
23769
|
+
lastCheckedAt: Date.now(),
|
|
23770
|
+
...submodules ? { submodules } : {}
|
|
23771
|
+
};
|
|
23772
|
+
}
|
|
23773
|
+
function hasGitWorktreeChanges(git) {
|
|
23774
|
+
if (!git) return false;
|
|
23775
|
+
return Number(git.staged || 0) + Number(git.modified || 0) + Number(git.untracked || 0) + Number(git.deleted || 0) + Number(git.renamed || 0) > 0;
|
|
23776
|
+
}
|
|
23777
|
+
function getGitSubmoduleDriftState(git) {
|
|
23778
|
+
const submodules = Array.isArray(git?.submodules) ? git.submodules : [];
|
|
23779
|
+
let dirty = false;
|
|
23780
|
+
let outOfSync = false;
|
|
23781
|
+
for (const entry of submodules) {
|
|
23782
|
+
const submodule = readObjectRecord(entry);
|
|
23783
|
+
if (readBooleanValue(submodule.dirty) === true) dirty = true;
|
|
23784
|
+
if (readBooleanValue(submodule.outOfSync) === true || !!readStringValue(submodule.error)) outOfSync = true;
|
|
23785
|
+
}
|
|
23786
|
+
return { dirty, outOfSync };
|
|
23787
|
+
}
|
|
23788
|
+
function deriveMeshNodeHealthFromGit(git) {
|
|
23789
|
+
if (!git || readBooleanValue(git.isGitRepo) === false) return "degraded";
|
|
23790
|
+
const branch = readStringValue(git.branch);
|
|
23791
|
+
if (!branch) return "degraded";
|
|
23792
|
+
const submoduleDrift = getGitSubmoduleDriftState(git);
|
|
23793
|
+
if (submoduleDrift.outOfSync) return "degraded";
|
|
23794
|
+
if (submoduleDrift.dirty || hasGitWorktreeChanges(git)) return "dirty";
|
|
23795
|
+
return "online";
|
|
23796
|
+
}
|
|
23797
|
+
function readCachedInlineMeshActiveSessions(node) {
|
|
23798
|
+
const cachedStatus = readObjectRecord(node?.cachedStatus);
|
|
23799
|
+
const activeSession = readObjectRecord(cachedStatus.activeSession);
|
|
23800
|
+
const fallbackSession = Object.keys(activeSession).length ? activeSession : readObjectRecord(node?.activeSession ?? node?.active_session);
|
|
23801
|
+
const sessionId = readStringValue(fallbackSession.id, fallbackSession.sessionId, fallbackSession.session_id, node?.activeSessionId, node?.active_session_id, node?.sessionId, node?.session_id);
|
|
23802
|
+
return sessionId ? [sessionId] : [];
|
|
23803
|
+
}
|
|
23804
|
+
function readCachedInlineMeshActiveSessionDetails(node) {
|
|
23805
|
+
const cachedStatus = readObjectRecord(node?.cachedStatus);
|
|
23806
|
+
const activeSession = readObjectRecord(cachedStatus.activeSession);
|
|
23807
|
+
const fallbackSession = Object.keys(activeSession).length ? activeSession : readObjectRecord(node?.activeSession ?? node?.active_session);
|
|
23808
|
+
const sessionId = readStringValue(
|
|
23809
|
+
fallbackSession.id,
|
|
23810
|
+
fallbackSession.sessionId,
|
|
23811
|
+
fallbackSession.session_id,
|
|
23812
|
+
node?.activeSessionId,
|
|
23813
|
+
node?.active_session_id,
|
|
23814
|
+
node?.sessionId,
|
|
23815
|
+
node?.session_id
|
|
23816
|
+
);
|
|
23817
|
+
if (!sessionId) return [];
|
|
23818
|
+
return [{
|
|
23819
|
+
sessionId,
|
|
23820
|
+
providerType: readStringValue(
|
|
23821
|
+
fallbackSession.providerType,
|
|
23822
|
+
fallbackSession.provider_type,
|
|
23823
|
+
fallbackSession.cliType,
|
|
23824
|
+
fallbackSession.cli_type,
|
|
23825
|
+
fallbackSession.provider,
|
|
23826
|
+
node?.providerType,
|
|
23827
|
+
node?.provider_type
|
|
23828
|
+
),
|
|
23829
|
+
state: readStringValue(fallbackSession.status, fallbackSession.state, fallbackSession.lifecycle),
|
|
23830
|
+
lifecycle: readStringValue(fallbackSession.lifecycle),
|
|
23831
|
+
title: readStringValue(fallbackSession.title, fallbackSession.displayName, fallbackSession.display_name) ?? null,
|
|
23832
|
+
workspace: readStringValue(fallbackSession.workspace, node?.workspace) ?? null,
|
|
23833
|
+
lastActivityAt: readStringValue(fallbackSession.lastActivityAt, fallbackSession.last_activity_at) ?? null,
|
|
23834
|
+
recoveryState: readStringValue(fallbackSession.recoveryState, fallbackSession.recovery_state) ?? null,
|
|
23835
|
+
isCached: true
|
|
23836
|
+
}];
|
|
23837
|
+
}
|
|
23838
|
+
function readLiveMeshSessionState(record) {
|
|
23839
|
+
return readStringValue(
|
|
23840
|
+
record?.meta?.sessionStatus,
|
|
23841
|
+
record?.meta?.status,
|
|
23842
|
+
record?.meta?.providerStatus,
|
|
23843
|
+
record?.status,
|
|
23844
|
+
record?.state,
|
|
23845
|
+
record?.lifecycle
|
|
23846
|
+
);
|
|
23847
|
+
}
|
|
23848
|
+
function toIsoTimestamp(value) {
|
|
23849
|
+
if (typeof value === "number" && Number.isFinite(value)) return new Date(value).toISOString();
|
|
23850
|
+
const stringValue = readStringValue(value);
|
|
23851
|
+
return stringValue || null;
|
|
23852
|
+
}
|
|
23853
|
+
function summarizeMeshSessionRecord(record) {
|
|
23854
|
+
return {
|
|
23855
|
+
sessionId: readStringValue(record?.sessionId) || "unknown",
|
|
23856
|
+
providerType: readStringValue(record?.providerType),
|
|
23857
|
+
state: readLiveMeshSessionState(record),
|
|
23858
|
+
lifecycle: readStringValue(record?.lifecycle),
|
|
23859
|
+
surfaceKind: getSessionHostSurfaceKind(record),
|
|
23860
|
+
recoveryState: readStringValue(record?.meta?.runtimeRecoveryState) ?? null,
|
|
23861
|
+
workspace: readStringValue(record?.workspace) ?? null,
|
|
23862
|
+
title: readStringValue(record?.displayName, record?.workspaceLabel) ?? null,
|
|
23863
|
+
lastActivityAt: toIsoTimestamp(record?.updatedAt ?? record?.lastActivityAt ?? record?.last_activity_at),
|
|
23864
|
+
isCached: false
|
|
23865
|
+
};
|
|
23866
|
+
}
|
|
23867
|
+
function applyCachedInlineMeshNodeStatus(status, node) {
|
|
23868
|
+
const cachedStatus = readObjectRecord(node?.cachedStatus);
|
|
23869
|
+
const git = buildCachedInlineMeshGitStatus(node);
|
|
23870
|
+
const error = readStringValue(cachedStatus.error, node?.error);
|
|
23871
|
+
const health = readStringValue(cachedStatus.health, node?.health);
|
|
23872
|
+
const machineStatus = readStringValue(cachedStatus.machineStatus, node?.machineStatus);
|
|
23873
|
+
const lastSeenAt = toIsoTimestamp(cachedStatus.lastSeenAt ?? cachedStatus.last_seen_at ?? node?.lastSeenAt ?? node?.last_seen_at);
|
|
23874
|
+
const updatedAt = toIsoTimestamp(cachedStatus.updatedAt ?? cachedStatus.updated_at ?? node?.updatedAt ?? node?.updated_at);
|
|
23875
|
+
const activeSessions = readCachedInlineMeshActiveSessions(node);
|
|
23876
|
+
const activeSessionDetails = readCachedInlineMeshActiveSessionDetails(node);
|
|
23877
|
+
if (!git && !error && !health && !machineStatus && !lastSeenAt && !updatedAt && activeSessions.length === 0) return false;
|
|
23878
|
+
if (git) status.git = git;
|
|
23879
|
+
if (error) status.error = error;
|
|
23880
|
+
if (machineStatus) status.machineStatus = machineStatus;
|
|
23881
|
+
if (lastSeenAt) status.lastSeenAt = lastSeenAt;
|
|
23882
|
+
if (updatedAt) status.updatedAt = updatedAt;
|
|
23883
|
+
if (activeSessions.length > 0) status.activeSessions = activeSessions;
|
|
23884
|
+
if (activeSessionDetails.length > 0) status.activeSessionDetails = activeSessionDetails;
|
|
23885
|
+
if (health) {
|
|
23886
|
+
status.health = health;
|
|
23887
|
+
return true;
|
|
23888
|
+
}
|
|
23889
|
+
if (git) {
|
|
23890
|
+
status.health = deriveMeshNodeHealthFromGit(git);
|
|
23891
|
+
return true;
|
|
23892
|
+
}
|
|
23893
|
+
return activeSessions.length > 0 || !!machineStatus || !!lastSeenAt || !!updatedAt;
|
|
23894
|
+
}
|
|
23585
23895
|
async function resolveProviderTypeFromPriority(args) {
|
|
23586
23896
|
if (!args.providerPriority.length) {
|
|
23587
23897
|
return { error: `Node '${args.nodeId}' has no providerPriority policy; pass cliType explicitly or configure node.policy.providerPriority` };
|
|
@@ -23983,7 +24293,12 @@ var DaemonCommandRouter = class {
|
|
|
23983
24293
|
}
|
|
23984
24294
|
return this.inlineMeshCache.get(meshId);
|
|
23985
24295
|
}
|
|
23986
|
-
async getMeshForCommand(meshId, inlineMesh) {
|
|
24296
|
+
async getMeshForCommand(meshId, inlineMesh, options) {
|
|
24297
|
+
const preferInline = options?.preferInline === true;
|
|
24298
|
+
if (preferInline) {
|
|
24299
|
+
const cached2 = this.getCachedInlineMesh(meshId, inlineMesh);
|
|
24300
|
+
if (cached2) return { mesh: cached2, inline: true };
|
|
24301
|
+
}
|
|
23987
24302
|
try {
|
|
23988
24303
|
const { getMesh: getMesh3 } = await Promise.resolve().then(() => (init_mesh_config(), mesh_config_exports));
|
|
23989
24304
|
const mesh = getMesh3(meshId);
|
|
@@ -25806,7 +26121,7 @@ ${block}`);
|
|
|
25806
26121
|
const meshId = typeof args?.meshId === "string" ? args.meshId.trim() : "";
|
|
25807
26122
|
if (!meshId) return { success: false, error: "meshId required" };
|
|
25808
26123
|
try {
|
|
25809
|
-
const meshRecord = await this.getMeshForCommand(meshId, args?.inlineMesh);
|
|
26124
|
+
const meshRecord = await this.getMeshForCommand(meshId, args?.inlineMesh, { preferInline: true });
|
|
25810
26125
|
const mesh = meshRecord?.mesh;
|
|
25811
26126
|
if (!mesh) return { success: false, error: "Mesh not found" };
|
|
25812
26127
|
const { getMeshQueueStats: getMeshQueueStats2, getQueue: getQueue2 } = await Promise.resolve().then(() => (init_mesh_work_queue(), mesh_work_queue_exports));
|
|
@@ -25815,84 +26130,102 @@ ${block}`);
|
|
|
25815
26130
|
const { readLedgerEntries: readLedgerEntries2, getLedgerSummary: getLedgerSummary2 } = await Promise.resolve().then(() => (init_mesh_ledger(), mesh_ledger_exports));
|
|
25816
26131
|
const ledgerEntries = readLedgerEntries2(meshId, { tail: 20 });
|
|
25817
26132
|
const ledgerSummary = getLedgerSummary2(meshId);
|
|
26133
|
+
const sessionHostRecords = this.deps.sessionHostControl?.listSessions ? await this.deps.sessionHostControl.listSessions().catch(() => []) : [];
|
|
26134
|
+
const liveMeshSessions = partitionSessionHostRecords(Array.isArray(sessionHostRecords) ? sessionHostRecords : []).liveRuntimes;
|
|
26135
|
+
const localMachineId = loadConfig().machineId || "";
|
|
26136
|
+
const inlineCoordinatorNodeId = meshRecord?.inline && Array.isArray(mesh.nodes) ? readStringValue(mesh.nodes[0]?.id, mesh.nodes[0]?.nodeId) : void 0;
|
|
26137
|
+
const refreshedAt = (/* @__PURE__ */ new Date()).toISOString();
|
|
25818
26138
|
const nodeStatuses = [];
|
|
25819
|
-
for (const node of mesh.nodes || []) {
|
|
26139
|
+
for (const [nodeIndex, node] of (mesh.nodes || []).entries()) {
|
|
26140
|
+
const nodeId = String(node.id || node.nodeId || "");
|
|
26141
|
+
const daemonId = readStringValue(node.daemonId);
|
|
26142
|
+
const providerPriority = readProviderPriorityFromPolicy(node.policy);
|
|
26143
|
+
const isSelfNode = Boolean(
|
|
26144
|
+
nodeId && inlineCoordinatorNodeId && nodeId === inlineCoordinatorNodeId
|
|
26145
|
+
) || Boolean(
|
|
26146
|
+
daemonId && (daemonId === localMachineId || daemonId === this.deps.statusInstanceId)
|
|
26147
|
+
) || Boolean(meshRecord?.inline && nodeIndex === 0);
|
|
25820
26148
|
const status = {
|
|
25821
|
-
nodeId
|
|
26149
|
+
nodeId,
|
|
25822
26150
|
machineLabel: node.machineLabel || node.id || node.nodeId,
|
|
25823
26151
|
workspace: node.workspace,
|
|
25824
26152
|
repoRoot: node.repoRoot,
|
|
25825
26153
|
isLocalWorktree: node.isLocalWorktree,
|
|
25826
26154
|
worktreeBranch: node.worktreeBranch,
|
|
25827
|
-
daemonId
|
|
26155
|
+
daemonId,
|
|
25828
26156
|
machineId: node.machineId,
|
|
26157
|
+
machineStatus: node.machineStatus,
|
|
25829
26158
|
health: "unknown",
|
|
25830
26159
|
providers: node.providers || [],
|
|
25831
|
-
|
|
26160
|
+
providerPriority,
|
|
26161
|
+
activeSessions: [],
|
|
26162
|
+
activeSessionDetails: [],
|
|
26163
|
+
launchReady: false
|
|
25832
26164
|
};
|
|
26165
|
+
if (isSelfNode) {
|
|
26166
|
+
status.connection = {
|
|
26167
|
+
perspective: "selected_coordinator",
|
|
26168
|
+
source: "mesh_peer_status",
|
|
26169
|
+
state: "self",
|
|
26170
|
+
transport: "local",
|
|
26171
|
+
reported: true,
|
|
26172
|
+
reason: "Selected coordinator daemon",
|
|
26173
|
+
lastStateChangeAt: refreshedAt
|
|
26174
|
+
};
|
|
26175
|
+
} else if (daemonId) {
|
|
26176
|
+
const connection = this.deps.getMeshPeerConnectionStatus?.(daemonId);
|
|
26177
|
+
status.connection = connection ?? {
|
|
26178
|
+
perspective: "selected_coordinator",
|
|
26179
|
+
source: "not_reported",
|
|
26180
|
+
state: "unknown",
|
|
26181
|
+
transport: "unknown",
|
|
26182
|
+
reported: false,
|
|
26183
|
+
reason: "No live mesh peer telemetry reported by the selected coordinator yet."
|
|
26184
|
+
};
|
|
26185
|
+
} else {
|
|
26186
|
+
status.connection = {
|
|
26187
|
+
perspective: "selected_coordinator",
|
|
26188
|
+
source: "not_reported",
|
|
26189
|
+
state: "unknown",
|
|
26190
|
+
transport: "unknown",
|
|
26191
|
+
reported: false,
|
|
26192
|
+
reason: "Node has no daemon id, so mesh transport cannot be reported from the selected coordinator."
|
|
26193
|
+
};
|
|
26194
|
+
}
|
|
26195
|
+
const matchedLiveSessionRecords = liveMeshSessions.filter((record) => this.sessionMatchesMeshNode(record, node, nodeId));
|
|
26196
|
+
if (matchedLiveSessionRecords.length > 0) {
|
|
26197
|
+
const sessionIds = matchedLiveSessionRecords.map((record) => typeof record?.sessionId === "string" ? record.sessionId : "").filter(Boolean);
|
|
26198
|
+
const providerTypes = matchedLiveSessionRecords.map((record) => readStringValue(record?.providerType)).filter(Boolean);
|
|
26199
|
+
status.activeSessions = sessionIds;
|
|
26200
|
+
status.activeSessionDetails = matchedLiveSessionRecords.map(summarizeMeshSessionRecord);
|
|
26201
|
+
if (providerTypes.length > 0) {
|
|
26202
|
+
status.providers = Array.from(/* @__PURE__ */ new Set([...Array.isArray(status.providers) ? status.providers : [], ...providerTypes]));
|
|
26203
|
+
}
|
|
26204
|
+
}
|
|
25833
26205
|
if (node.workspace && typeof node.workspace === "string") {
|
|
26206
|
+
if (!fs10.existsSync(node.workspace) && applyCachedInlineMeshNodeStatus(status, node)) {
|
|
26207
|
+
status.launchReady = !!daemonId && (readStringValue(status.machineStatus) === "online" || isSelfNode);
|
|
26208
|
+
nodeStatuses.push(status);
|
|
26209
|
+
continue;
|
|
26210
|
+
}
|
|
25834
26211
|
try {
|
|
25835
|
-
const {
|
|
25836
|
-
|
|
25837
|
-
|
|
25838
|
-
|
|
25839
|
-
|
|
25840
|
-
|
|
25841
|
-
|
|
25842
|
-
});
|
|
25843
|
-
return result.stdout.trim();
|
|
25844
|
-
};
|
|
25845
|
-
const branch = await runGit2(["branch", "--show-current"]).catch(() => "");
|
|
25846
|
-
const porc = await runGit2(["status", "--porcelain"]).catch(() => "");
|
|
25847
|
-
const headCommit = await runGit2(["rev-parse", "--short", "HEAD"]).catch(() => null);
|
|
25848
|
-
const headMessage = await runGit2(["log", "-1", "--format=%s"]).catch(() => null);
|
|
25849
|
-
const upstream = await runGit2(["rev-parse", "--abbrev-ref", "@{upstream}"]).catch(() => null);
|
|
25850
|
-
const aheadBehind = await runGit2(["rev-list", "--left-right", "--count", "@{upstream}...HEAD"]).catch(() => "");
|
|
25851
|
-
const stashCount = await runGit2(["stash", "list"]).catch(() => "");
|
|
25852
|
-
let ahead = 0, behind = 0;
|
|
25853
|
-
if (aheadBehind) {
|
|
25854
|
-
const parts = aheadBehind.split(/\s+/);
|
|
25855
|
-
if (parts.length >= 2) {
|
|
25856
|
-
behind = parseInt(parts[0], 10) || 0;
|
|
25857
|
-
ahead = parseInt(parts[1], 10) || 0;
|
|
25858
|
-
}
|
|
25859
|
-
}
|
|
25860
|
-
const dirty = porc.length > 0;
|
|
25861
|
-
const lines = porc ? porc.split("\n").filter(Boolean) : [];
|
|
25862
|
-
let staged = 0, modified = 0, untracked = 0, deleted = 0, renamed = 0;
|
|
25863
|
-
for (const line of lines) {
|
|
25864
|
-
const xy = line.slice(0, 2);
|
|
25865
|
-
if (xy[0] !== " " && xy[0] !== "?") staged++;
|
|
25866
|
-
if (xy[1] === "M") modified++;
|
|
25867
|
-
if (xy[1] === "D") deleted++;
|
|
25868
|
-
if (xy[0] === "R" || xy[1] === "R") renamed++;
|
|
25869
|
-
if (xy === "??") untracked++;
|
|
26212
|
+
const gitStatus = await getGitRepoStatus(node.workspace, { timeoutMs: 1e4, refreshUpstream: true });
|
|
26213
|
+
status.git = gitStatus;
|
|
26214
|
+
if (gitStatus.isGitRepo) {
|
|
26215
|
+
status.health = deriveMeshNodeHealthFromGit(gitStatus);
|
|
26216
|
+
} else {
|
|
26217
|
+
status.health = "degraded";
|
|
26218
|
+
if (gitStatus.error && !status.error) status.error = gitStatus.error;
|
|
25870
26219
|
}
|
|
25871
|
-
status.git = {
|
|
25872
|
-
workspace: node.workspace,
|
|
25873
|
-
repoRoot: node.workspace,
|
|
25874
|
-
isGitRepo: true,
|
|
25875
|
-
branch: branch || null,
|
|
25876
|
-
headCommit,
|
|
25877
|
-
headMessage,
|
|
25878
|
-
upstream,
|
|
25879
|
-
ahead,
|
|
25880
|
-
behind,
|
|
25881
|
-
staged,
|
|
25882
|
-
modified,
|
|
25883
|
-
untracked,
|
|
25884
|
-
deleted,
|
|
25885
|
-
renamed,
|
|
25886
|
-
hasConflicts: false,
|
|
25887
|
-
conflictFiles: [],
|
|
25888
|
-
stashCount: stashCount ? stashCount.split("\n").filter(Boolean).length : 0,
|
|
25889
|
-
lastCheckedAt: Date.now()
|
|
25890
|
-
};
|
|
25891
|
-
status.health = branch ? dirty ? "dirty" : "online" : "degraded";
|
|
25892
26220
|
} catch {
|
|
25893
|
-
status
|
|
26221
|
+
if (!applyCachedInlineMeshNodeStatus(status, node)) {
|
|
26222
|
+
status.health = "degraded";
|
|
26223
|
+
}
|
|
25894
26224
|
}
|
|
26225
|
+
} else {
|
|
26226
|
+
applyCachedInlineMeshNodeStatus(status, node);
|
|
25895
26227
|
}
|
|
26228
|
+
status.launchReady = !!daemonId && (readStringValue(status.machineStatus) === "online" || isSelfNode);
|
|
25896
26229
|
nodeStatuses.push(status);
|
|
25897
26230
|
}
|
|
25898
26231
|
return {
|
|
@@ -25901,6 +26234,7 @@ ${block}`);
|
|
|
25901
26234
|
meshName: mesh.name,
|
|
25902
26235
|
repoIdentity: mesh.repoIdentity,
|
|
25903
26236
|
defaultBranch: mesh.defaultBranch,
|
|
26237
|
+
refreshedAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
25904
26238
|
nodes: nodeStatuses,
|
|
25905
26239
|
queue: { tasks: queue, summary: queueSummary },
|
|
25906
26240
|
ledger: { entries: ledgerEntries, summary: ledgerSummary }
|
|
@@ -33835,6 +34169,7 @@ async function initDaemonComponents(config) {
|
|
|
33835
34169
|
sessionHostControl: config.sessionHostControl,
|
|
33836
34170
|
statusInstanceId: config.statusInstanceId,
|
|
33837
34171
|
statusVersion: config.statusVersion,
|
|
34172
|
+
getMeshPeerConnectionStatus: config.getMeshPeerConnectionStatus,
|
|
33838
34173
|
getCdpLogFn: config.getCdpLogFn || ((ideType) => LOG.forComponent(`CDP:${ideType}`).asLogFn())
|
|
33839
34174
|
});
|
|
33840
34175
|
poller = new AgentStreamPoller({
|
|
@@ -34109,6 +34444,7 @@ export {
|
|
|
34109
34444
|
prepareSessionChatTailUpdate,
|
|
34110
34445
|
prepareSessionModalUpdate,
|
|
34111
34446
|
probeCdpPort,
|
|
34447
|
+
queuePendingMeshCoordinatorEvent,
|
|
34112
34448
|
readChatHistory,
|
|
34113
34449
|
readLedgerEntries,
|
|
34114
34450
|
readLedgerSlice,
|