adhdev 0.9.82-rc.1 → 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/cli/index.js +528 -83
- package/dist/cli/index.js.map +1 -1
- package/dist/index.js +499 -79
- package/dist/index.js.map +1 -1
- package/package.json +2 -2
- package/vendor/mcp-server/index.js +111 -14
- package/vendor/mcp-server/index.js.map +1 -1
package/dist/cli/index.js
CHANGED
|
@@ -784,8 +784,14 @@ async function getGitRepoStatus(workspace, options = {}) {
|
|
|
784
784
|
const includeSubmodules = options.includeSubmodules !== false;
|
|
785
785
|
try {
|
|
786
786
|
const repo = await resolveGitRepository(workspace, options);
|
|
787
|
-
|
|
788
|
-
|
|
787
|
+
let parsed = await readPorcelainStatus(repo, options);
|
|
788
|
+
let upstreamProbe = getInitialUpstreamProbe(parsed);
|
|
789
|
+
if (options.refreshUpstream) {
|
|
790
|
+
upstreamProbe = await refreshTrackedUpstream(repo, parsed, options);
|
|
791
|
+
if (upstreamProbe.upstreamStatus === "fresh") {
|
|
792
|
+
parsed = await readPorcelainStatus(repo, options);
|
|
793
|
+
}
|
|
794
|
+
}
|
|
789
795
|
const head = await readHead(repo, options);
|
|
790
796
|
const stashCount = await readStashCount(repo, options);
|
|
791
797
|
let submodules;
|
|
@@ -800,6 +806,9 @@ async function getGitRepoStatus(workspace, options = {}) {
|
|
|
800
806
|
headCommit: head.commit,
|
|
801
807
|
headMessage: head.message,
|
|
802
808
|
upstream: parsed.upstream,
|
|
809
|
+
upstreamStatus: parsed.upstream ? upstreamProbe.upstreamStatus : "no_upstream",
|
|
810
|
+
upstreamFetchedAt: upstreamProbe.upstreamFetchedAt,
|
|
811
|
+
upstreamFetchError: upstreamProbe.upstreamFetchError,
|
|
803
812
|
ahead: parsed.ahead,
|
|
804
813
|
behind: parsed.behind,
|
|
805
814
|
staged: parsed.staged,
|
|
@@ -824,6 +833,60 @@ async function getGitRepoStatus(workspace, options = {}) {
|
|
|
824
833
|
);
|
|
825
834
|
}
|
|
826
835
|
}
|
|
836
|
+
async function readPorcelainStatus(repo, options) {
|
|
837
|
+
const statusOutput = await runGit(repo, ["status", "--porcelain=v2", "--branch"], options);
|
|
838
|
+
return parsePorcelainV2Status(statusOutput.stdout);
|
|
839
|
+
}
|
|
840
|
+
function getInitialUpstreamProbe(parsed) {
|
|
841
|
+
return {
|
|
842
|
+
upstreamStatus: parsed.upstream ? "unchecked" : "no_upstream"
|
|
843
|
+
};
|
|
844
|
+
}
|
|
845
|
+
async function refreshTrackedUpstream(repo, parsed, options) {
|
|
846
|
+
if (!parsed.upstream || !parsed.branch) {
|
|
847
|
+
return { upstreamStatus: "no_upstream" };
|
|
848
|
+
}
|
|
849
|
+
const remoteName = await readBranchRemote(repo, parsed.branch, options) ?? inferRemoteName(parsed.upstream);
|
|
850
|
+
if (!remoteName) {
|
|
851
|
+
return {
|
|
852
|
+
upstreamStatus: "stale",
|
|
853
|
+
upstreamFetchError: `Unable to resolve remote for upstream '${parsed.upstream}'`
|
|
854
|
+
};
|
|
855
|
+
}
|
|
856
|
+
try {
|
|
857
|
+
await runGit(repo, ["fetch", "--quiet", "--prune", "--no-tags", remoteName], options);
|
|
858
|
+
return {
|
|
859
|
+
upstreamStatus: "fresh",
|
|
860
|
+
upstreamFetchedAt: Date.now()
|
|
861
|
+
};
|
|
862
|
+
} catch (error48) {
|
|
863
|
+
return {
|
|
864
|
+
upstreamStatus: "stale",
|
|
865
|
+
upstreamFetchError: formatGitError(error48)
|
|
866
|
+
};
|
|
867
|
+
}
|
|
868
|
+
}
|
|
869
|
+
async function readBranchRemote(repo, branch, options) {
|
|
870
|
+
try {
|
|
871
|
+
const result = await runGit(repo, ["config", "--get", `branch.${branch}.remote`], options);
|
|
872
|
+
return result.stdout.trim() || null;
|
|
873
|
+
} catch {
|
|
874
|
+
return null;
|
|
875
|
+
}
|
|
876
|
+
}
|
|
877
|
+
function inferRemoteName(upstream) {
|
|
878
|
+
const [remoteName] = upstream.split("/");
|
|
879
|
+
return remoteName?.trim() || null;
|
|
880
|
+
}
|
|
881
|
+
function formatGitError(error48) {
|
|
882
|
+
if (error48 instanceof GitCommandError) {
|
|
883
|
+
return error48.stderr || error48.message;
|
|
884
|
+
}
|
|
885
|
+
if (error48 instanceof Error) {
|
|
886
|
+
return error48.message;
|
|
887
|
+
}
|
|
888
|
+
return String(error48);
|
|
889
|
+
}
|
|
827
890
|
function parsePorcelainV2Status(output) {
|
|
828
891
|
const parsed = {
|
|
829
892
|
branch: null,
|
|
@@ -918,6 +981,7 @@ function emptyStatus(workspace, lastCheckedAt, error48) {
|
|
|
918
981
|
headCommit: null,
|
|
919
982
|
headMessage: null,
|
|
920
983
|
upstream: null,
|
|
984
|
+
upstreamStatus: "unavailable",
|
|
921
985
|
ahead: 0,
|
|
922
986
|
behind: 0,
|
|
923
987
|
staged: 0,
|
|
@@ -1210,6 +1274,9 @@ function createGitCompactSummary(status, diffSummary) {
|
|
|
1210
1274
|
isGitRepo: status.isGitRepo,
|
|
1211
1275
|
repoRoot: status.repoRoot,
|
|
1212
1276
|
branch: status.branch,
|
|
1277
|
+
upstreamStatus: status.upstreamStatus,
|
|
1278
|
+
upstreamFetchedAt: status.upstreamFetchedAt,
|
|
1279
|
+
upstreamFetchError: status.upstreamFetchError,
|
|
1213
1280
|
dirty: status.staged > 0 || status.modified > 0 || status.untracked > 0 || status.deleted > 0 || status.renamed > 0 || conflictCount > 0 || changedFiles > 0,
|
|
1214
1281
|
changedFiles,
|
|
1215
1282
|
ahead: status.ahead,
|
|
@@ -1537,7 +1604,7 @@ function serviceNotImplemented(command) {
|
|
|
1537
1604
|
}
|
|
1538
1605
|
function createDefaultGitCommandServices() {
|
|
1539
1606
|
return {
|
|
1540
|
-
getStatus: ({ workspace }) => getGitRepoStatus(workspace),
|
|
1607
|
+
getStatus: ({ workspace, refreshUpstream }) => getGitRepoStatus(workspace, { refreshUpstream }),
|
|
1541
1608
|
getDiffSummary: ({ workspace }) => getGitDiffSummary(workspace),
|
|
1542
1609
|
getDiffFile: ({ workspace, path: filePath }) => getGitFileDiff(workspace, filePath),
|
|
1543
1610
|
createSnapshot: ({ workspace, reason, sessionId, turnId }) => defaultSnapshotStore.create({
|
|
@@ -1622,7 +1689,7 @@ async function handleGitCommand(command, args, services = defaultGitCommandServi
|
|
|
1622
1689
|
switch (command) {
|
|
1623
1690
|
case "git_status": {
|
|
1624
1691
|
if (!services.getStatus) return serviceNotImplemented(command);
|
|
1625
|
-
const status = await runService(() => services.getStatus({ workspace }));
|
|
1692
|
+
const status = await runService(() => services.getStatus({ workspace, refreshUpstream: optionalBoolean(args?.refreshUpstream) }));
|
|
1626
1693
|
return "success" in status ? status : { success: true, status };
|
|
1627
1694
|
}
|
|
1628
1695
|
case "git_diff_summary": {
|
|
@@ -4279,10 +4346,18 @@ __export(mesh_events_exports, {
|
|
|
4279
4346
|
drainPendingMeshCoordinatorEvents: () => drainPendingMeshCoordinatorEvents,
|
|
4280
4347
|
getPendingMeshCoordinatorEvents: () => getPendingMeshCoordinatorEvents,
|
|
4281
4348
|
handleMeshForwardEvent: () => handleMeshForwardEvent,
|
|
4349
|
+
queuePendingMeshCoordinatorEvent: () => queuePendingMeshCoordinatorEvent,
|
|
4282
4350
|
setupMeshEventForwarding: () => setupMeshEventForwarding,
|
|
4283
4351
|
triggerMeshQueue: () => triggerMeshQueue,
|
|
4284
4352
|
tryAssignQueueTask: () => tryAssignQueueTask
|
|
4285
4353
|
});
|
|
4354
|
+
function queuePendingMeshCoordinatorEvent(event) {
|
|
4355
|
+
if (pendingMeshCoordinatorEvents.length >= MAX_PENDING_EVENTS) {
|
|
4356
|
+
return false;
|
|
4357
|
+
}
|
|
4358
|
+
pendingMeshCoordinatorEvents.push(event);
|
|
4359
|
+
return true;
|
|
4360
|
+
}
|
|
4286
4361
|
function drainPendingMeshCoordinatorEvents() {
|
|
4287
4362
|
return pendingMeshCoordinatorEvents.splice(0);
|
|
4288
4363
|
}
|
|
@@ -4854,17 +4929,18 @@ function injectMeshSystemMessage(components, args) {
|
|
|
4854
4929
|
return true;
|
|
4855
4930
|
});
|
|
4856
4931
|
if (coordinatorInstances.length === 0) {
|
|
4857
|
-
if (
|
|
4858
|
-
|
|
4859
|
-
|
|
4860
|
-
|
|
4861
|
-
|
|
4862
|
-
|
|
4863
|
-
|
|
4864
|
-
|
|
4865
|
-
}
|
|
4866
|
-
|
|
4867
|
-
|
|
4932
|
+
if (queuePendingMeshCoordinatorEvent({
|
|
4933
|
+
event: args.event,
|
|
4934
|
+
meshId: args.meshId,
|
|
4935
|
+
nodeLabel: args.nodeLabel,
|
|
4936
|
+
nodeId: args.nodeId || void 0,
|
|
4937
|
+
workspace: readNonEmptyString(args.metadataEvent.workspace),
|
|
4938
|
+
metadataEvent: {
|
|
4939
|
+
...args.metadataEvent,
|
|
4940
|
+
...recoveryContext ? { recoveryContext } : {}
|
|
4941
|
+
},
|
|
4942
|
+
queuedAt: Date.now()
|
|
4943
|
+
})) {
|
|
4868
4944
|
LOG.info("MeshEvents", `Queued ${args.event} for MCP coordinator (mesh ${args.meshId})`);
|
|
4869
4945
|
}
|
|
4870
4946
|
return { success: true, forwarded: 0 };
|
|
@@ -46381,6 +46457,240 @@ function readProviderPriorityFromPolicy(policy) {
|
|
|
46381
46457
|
return true;
|
|
46382
46458
|
});
|
|
46383
46459
|
}
|
|
46460
|
+
function readObjectRecord(value) {
|
|
46461
|
+
return value && typeof value === "object" && !Array.isArray(value) ? value : {};
|
|
46462
|
+
}
|
|
46463
|
+
function readStringValue(...values) {
|
|
46464
|
+
for (const value of values) {
|
|
46465
|
+
if (typeof value === "string" && value.trim()) return value.trim();
|
|
46466
|
+
}
|
|
46467
|
+
return void 0;
|
|
46468
|
+
}
|
|
46469
|
+
function readNumberValue(...values) {
|
|
46470
|
+
for (const value of values) {
|
|
46471
|
+
if (typeof value === "number" && Number.isFinite(value)) return value;
|
|
46472
|
+
}
|
|
46473
|
+
return void 0;
|
|
46474
|
+
}
|
|
46475
|
+
function readBooleanValue(...values) {
|
|
46476
|
+
for (const value of values) {
|
|
46477
|
+
if (typeof value === "boolean") return value;
|
|
46478
|
+
}
|
|
46479
|
+
return void 0;
|
|
46480
|
+
}
|
|
46481
|
+
function readGitSubmodules(value) {
|
|
46482
|
+
if (!Array.isArray(value)) return void 0;
|
|
46483
|
+
const submodules = value.map((entry) => {
|
|
46484
|
+
const submodule = readObjectRecord(entry);
|
|
46485
|
+
const path42 = readStringValue(submodule.path);
|
|
46486
|
+
const commit = readStringValue(submodule.commit);
|
|
46487
|
+
const repoPath = readStringValue(submodule.repoPath, submodule.repo_root);
|
|
46488
|
+
if (!path42 || !commit || !repoPath) return null;
|
|
46489
|
+
return {
|
|
46490
|
+
path: path42,
|
|
46491
|
+
commit,
|
|
46492
|
+
repoPath,
|
|
46493
|
+
dirty: readBooleanValue(submodule.dirty) ?? false,
|
|
46494
|
+
outOfSync: readBooleanValue(submodule.outOfSync, submodule.out_of_sync) ?? false,
|
|
46495
|
+
lastCheckedAt: readNumberValue(submodule.lastCheckedAt, submodule.last_checked_at) ?? Date.now(),
|
|
46496
|
+
...readStringValue(submodule.error) ? { error: readStringValue(submodule.error) } : {}
|
|
46497
|
+
};
|
|
46498
|
+
}).filter((entry) => entry !== null);
|
|
46499
|
+
return submodules.length > 0 ? submodules : void 0;
|
|
46500
|
+
}
|
|
46501
|
+
function buildCachedInlineMeshGitStatus(node) {
|
|
46502
|
+
const cachedStatus = readObjectRecord(node?.cachedStatus);
|
|
46503
|
+
const cachedGit = readObjectRecord(cachedStatus.git);
|
|
46504
|
+
if (Object.keys(cachedGit).length) {
|
|
46505
|
+
const conflictFiles2 = Array.isArray(cachedGit.conflictFiles) ? cachedGit.conflictFiles.filter((value) => typeof value === "string") : [];
|
|
46506
|
+
const conflictCount2 = readNumberValue(cachedGit.conflicts) ?? conflictFiles2.length;
|
|
46507
|
+
const hasConflicts2 = readBooleanValue(cachedGit.hasConflicts) ?? conflictCount2 > 0;
|
|
46508
|
+
const isGitRepo2 = readBooleanValue(cachedGit.isGitRepo);
|
|
46509
|
+
if (isGitRepo2 !== void 0) {
|
|
46510
|
+
const submodules2 = readGitSubmodules(cachedGit.submodules);
|
|
46511
|
+
return {
|
|
46512
|
+
workspace: readStringValue(cachedGit.workspace, node?.workspace) || "",
|
|
46513
|
+
repoRoot: readStringValue(cachedGit.repoRoot, node?.repoRoot, node?.workspace) || null,
|
|
46514
|
+
isGitRepo: isGitRepo2,
|
|
46515
|
+
branch: readStringValue(cachedGit.branch) ?? null,
|
|
46516
|
+
headCommit: readStringValue(cachedGit.headCommit) ?? null,
|
|
46517
|
+
headMessage: readStringValue(cachedGit.headMessage) ?? null,
|
|
46518
|
+
upstream: readStringValue(cachedGit.upstream) ?? null,
|
|
46519
|
+
ahead: readNumberValue(cachedGit.ahead) ?? 0,
|
|
46520
|
+
behind: readNumberValue(cachedGit.behind) ?? 0,
|
|
46521
|
+
staged: readNumberValue(cachedGit.staged) ?? 0,
|
|
46522
|
+
modified: readNumberValue(cachedGit.modified) ?? 0,
|
|
46523
|
+
untracked: readNumberValue(cachedGit.untracked) ?? 0,
|
|
46524
|
+
deleted: readNumberValue(cachedGit.deleted) ?? 0,
|
|
46525
|
+
renamed: readNumberValue(cachedGit.renamed) ?? 0,
|
|
46526
|
+
hasConflicts: hasConflicts2,
|
|
46527
|
+
conflictFiles: conflictFiles2,
|
|
46528
|
+
stashCount: readNumberValue(cachedGit.stashCount) ?? 0,
|
|
46529
|
+
lastCheckedAt: readNumberValue(cachedGit.lastCheckedAt) ?? Date.now(),
|
|
46530
|
+
...submodules2 ? { submodules: submodules2 } : {}
|
|
46531
|
+
};
|
|
46532
|
+
}
|
|
46533
|
+
}
|
|
46534
|
+
const rawGit = readObjectRecord(node?.lastGit ?? node?.last_git);
|
|
46535
|
+
const gitResult = readObjectRecord(rawGit.result);
|
|
46536
|
+
const directStatus = readObjectRecord(rawGit.status);
|
|
46537
|
+
const nestedStatus = readObjectRecord(gitResult.status);
|
|
46538
|
+
const rawProbe = readObjectRecord(node?.lastProbe ?? node?.last_probe);
|
|
46539
|
+
const probeGit = readObjectRecord(rawProbe.git);
|
|
46540
|
+
const probeGitResult = readObjectRecord(probeGit.result);
|
|
46541
|
+
const probeDirectStatus = readObjectRecord(probeGit.status);
|
|
46542
|
+
const probeNestedStatus = readObjectRecord(probeGitResult.status);
|
|
46543
|
+
const status = Object.keys(directStatus).length ? directStatus : Object.keys(nestedStatus).length ? nestedStatus : Object.keys(probeDirectStatus).length ? probeDirectStatus : Object.keys(probeNestedStatus).length ? probeNestedStatus : {};
|
|
46544
|
+
const isGitRepo = readBooleanValue(status.isGitRepo);
|
|
46545
|
+
if (!Object.keys(status).length || isGitRepo === void 0) return void 0;
|
|
46546
|
+
const conflictFiles = Array.isArray(status.conflictFiles) ? status.conflictFiles.filter((value) => typeof value === "string") : [];
|
|
46547
|
+
const conflictCount = readNumberValue(status.conflicts) ?? conflictFiles.length;
|
|
46548
|
+
const hasConflicts = readBooleanValue(status.hasConflicts) ?? conflictCount > 0;
|
|
46549
|
+
const submodules = readGitSubmodules(status.submodules);
|
|
46550
|
+
return {
|
|
46551
|
+
workspace: readStringValue(status.workspace, node?.workspace) || "",
|
|
46552
|
+
repoRoot: readStringValue(status.repoRoot, node?.repoRoot, node?.workspace) || null,
|
|
46553
|
+
isGitRepo,
|
|
46554
|
+
branch: readStringValue(status.branch) ?? null,
|
|
46555
|
+
headCommit: readStringValue(status.headCommit) ?? null,
|
|
46556
|
+
headMessage: readStringValue(status.headMessage) ?? null,
|
|
46557
|
+
upstream: readStringValue(status.upstream) ?? null,
|
|
46558
|
+
ahead: readNumberValue(status.ahead) ?? 0,
|
|
46559
|
+
behind: readNumberValue(status.behind) ?? 0,
|
|
46560
|
+
staged: readNumberValue(status.staged) ?? 0,
|
|
46561
|
+
modified: readNumberValue(status.modified) ?? 0,
|
|
46562
|
+
untracked: readNumberValue(status.untracked) ?? 0,
|
|
46563
|
+
deleted: readNumberValue(status.deleted) ?? 0,
|
|
46564
|
+
renamed: readNumberValue(status.renamed) ?? 0,
|
|
46565
|
+
hasConflicts,
|
|
46566
|
+
conflictFiles,
|
|
46567
|
+
stashCount: readNumberValue(status.stashCount) ?? 0,
|
|
46568
|
+
lastCheckedAt: Date.now(),
|
|
46569
|
+
...submodules ? { submodules } : {}
|
|
46570
|
+
};
|
|
46571
|
+
}
|
|
46572
|
+
function hasGitWorktreeChanges(git) {
|
|
46573
|
+
if (!git) return false;
|
|
46574
|
+
return Number(git.staged || 0) + Number(git.modified || 0) + Number(git.untracked || 0) + Number(git.deleted || 0) + Number(git.renamed || 0) > 0;
|
|
46575
|
+
}
|
|
46576
|
+
function getGitSubmoduleDriftState(git) {
|
|
46577
|
+
const submodules = Array.isArray(git?.submodules) ? git.submodules : [];
|
|
46578
|
+
let dirty = false;
|
|
46579
|
+
let outOfSync = false;
|
|
46580
|
+
for (const entry of submodules) {
|
|
46581
|
+
const submodule = readObjectRecord(entry);
|
|
46582
|
+
if (readBooleanValue(submodule.dirty) === true) dirty = true;
|
|
46583
|
+
if (readBooleanValue(submodule.outOfSync) === true || !!readStringValue(submodule.error)) outOfSync = true;
|
|
46584
|
+
}
|
|
46585
|
+
return { dirty, outOfSync };
|
|
46586
|
+
}
|
|
46587
|
+
function deriveMeshNodeHealthFromGit(git) {
|
|
46588
|
+
if (!git || readBooleanValue(git.isGitRepo) === false) return "degraded";
|
|
46589
|
+
const branch = readStringValue(git.branch);
|
|
46590
|
+
if (!branch) return "degraded";
|
|
46591
|
+
const submoduleDrift = getGitSubmoduleDriftState(git);
|
|
46592
|
+
if (submoduleDrift.outOfSync) return "degraded";
|
|
46593
|
+
if (submoduleDrift.dirty || hasGitWorktreeChanges(git)) return "dirty";
|
|
46594
|
+
return "online";
|
|
46595
|
+
}
|
|
46596
|
+
function readCachedInlineMeshActiveSessions(node) {
|
|
46597
|
+
const cachedStatus = readObjectRecord(node?.cachedStatus);
|
|
46598
|
+
const activeSession = readObjectRecord(cachedStatus.activeSession);
|
|
46599
|
+
const fallbackSession = Object.keys(activeSession).length ? activeSession : readObjectRecord(node?.activeSession ?? node?.active_session);
|
|
46600
|
+
const sessionId = readStringValue(fallbackSession.id, fallbackSession.sessionId, fallbackSession.session_id, node?.activeSessionId, node?.active_session_id, node?.sessionId, node?.session_id);
|
|
46601
|
+
return sessionId ? [sessionId] : [];
|
|
46602
|
+
}
|
|
46603
|
+
function readCachedInlineMeshActiveSessionDetails(node) {
|
|
46604
|
+
const cachedStatus = readObjectRecord(node?.cachedStatus);
|
|
46605
|
+
const activeSession = readObjectRecord(cachedStatus.activeSession);
|
|
46606
|
+
const fallbackSession = Object.keys(activeSession).length ? activeSession : readObjectRecord(node?.activeSession ?? node?.active_session);
|
|
46607
|
+
const sessionId = readStringValue(
|
|
46608
|
+
fallbackSession.id,
|
|
46609
|
+
fallbackSession.sessionId,
|
|
46610
|
+
fallbackSession.session_id,
|
|
46611
|
+
node?.activeSessionId,
|
|
46612
|
+
node?.active_session_id,
|
|
46613
|
+
node?.sessionId,
|
|
46614
|
+
node?.session_id
|
|
46615
|
+
);
|
|
46616
|
+
if (!sessionId) return [];
|
|
46617
|
+
return [{
|
|
46618
|
+
sessionId,
|
|
46619
|
+
providerType: readStringValue(
|
|
46620
|
+
fallbackSession.providerType,
|
|
46621
|
+
fallbackSession.provider_type,
|
|
46622
|
+
fallbackSession.cliType,
|
|
46623
|
+
fallbackSession.cli_type,
|
|
46624
|
+
fallbackSession.provider,
|
|
46625
|
+
node?.providerType,
|
|
46626
|
+
node?.provider_type
|
|
46627
|
+
),
|
|
46628
|
+
state: readStringValue(fallbackSession.status, fallbackSession.state, fallbackSession.lifecycle),
|
|
46629
|
+
lifecycle: readStringValue(fallbackSession.lifecycle),
|
|
46630
|
+
title: readStringValue(fallbackSession.title, fallbackSession.displayName, fallbackSession.display_name) ?? null,
|
|
46631
|
+
workspace: readStringValue(fallbackSession.workspace, node?.workspace) ?? null,
|
|
46632
|
+
lastActivityAt: readStringValue(fallbackSession.lastActivityAt, fallbackSession.last_activity_at) ?? null,
|
|
46633
|
+
recoveryState: readStringValue(fallbackSession.recoveryState, fallbackSession.recovery_state) ?? null,
|
|
46634
|
+
isCached: true
|
|
46635
|
+
}];
|
|
46636
|
+
}
|
|
46637
|
+
function readLiveMeshSessionState(record2) {
|
|
46638
|
+
return readStringValue(
|
|
46639
|
+
record2?.meta?.sessionStatus,
|
|
46640
|
+
record2?.meta?.status,
|
|
46641
|
+
record2?.meta?.providerStatus,
|
|
46642
|
+
record2?.status,
|
|
46643
|
+
record2?.state,
|
|
46644
|
+
record2?.lifecycle
|
|
46645
|
+
);
|
|
46646
|
+
}
|
|
46647
|
+
function toIsoTimestamp(value) {
|
|
46648
|
+
if (typeof value === "number" && Number.isFinite(value)) return new Date(value).toISOString();
|
|
46649
|
+
const stringValue = readStringValue(value);
|
|
46650
|
+
return stringValue || null;
|
|
46651
|
+
}
|
|
46652
|
+
function summarizeMeshSessionRecord(record2) {
|
|
46653
|
+
return {
|
|
46654
|
+
sessionId: readStringValue(record2?.sessionId) || "unknown",
|
|
46655
|
+
providerType: readStringValue(record2?.providerType),
|
|
46656
|
+
state: readLiveMeshSessionState(record2),
|
|
46657
|
+
lifecycle: readStringValue(record2?.lifecycle),
|
|
46658
|
+
surfaceKind: getSessionHostSurfaceKind(record2),
|
|
46659
|
+
recoveryState: readStringValue(record2?.meta?.runtimeRecoveryState) ?? null,
|
|
46660
|
+
workspace: readStringValue(record2?.workspace) ?? null,
|
|
46661
|
+
title: readStringValue(record2?.displayName, record2?.workspaceLabel) ?? null,
|
|
46662
|
+
lastActivityAt: toIsoTimestamp(record2?.updatedAt ?? record2?.lastActivityAt ?? record2?.last_activity_at),
|
|
46663
|
+
isCached: false
|
|
46664
|
+
};
|
|
46665
|
+
}
|
|
46666
|
+
function applyCachedInlineMeshNodeStatus(status, node) {
|
|
46667
|
+
const cachedStatus = readObjectRecord(node?.cachedStatus);
|
|
46668
|
+
const git = buildCachedInlineMeshGitStatus(node);
|
|
46669
|
+
const error48 = readStringValue(cachedStatus.error, node?.error);
|
|
46670
|
+
const health = readStringValue(cachedStatus.health, node?.health);
|
|
46671
|
+
const machineStatus = readStringValue(cachedStatus.machineStatus, node?.machineStatus);
|
|
46672
|
+
const lastSeenAt = toIsoTimestamp(cachedStatus.lastSeenAt ?? cachedStatus.last_seen_at ?? node?.lastSeenAt ?? node?.last_seen_at);
|
|
46673
|
+
const updatedAt = toIsoTimestamp(cachedStatus.updatedAt ?? cachedStatus.updated_at ?? node?.updatedAt ?? node?.updated_at);
|
|
46674
|
+
const activeSessions = readCachedInlineMeshActiveSessions(node);
|
|
46675
|
+
const activeSessionDetails = readCachedInlineMeshActiveSessionDetails(node);
|
|
46676
|
+
if (!git && !error48 && !health && !machineStatus && !lastSeenAt && !updatedAt && activeSessions.length === 0) return false;
|
|
46677
|
+
if (git) status.git = git;
|
|
46678
|
+
if (error48) status.error = error48;
|
|
46679
|
+
if (machineStatus) status.machineStatus = machineStatus;
|
|
46680
|
+
if (lastSeenAt) status.lastSeenAt = lastSeenAt;
|
|
46681
|
+
if (updatedAt) status.updatedAt = updatedAt;
|
|
46682
|
+
if (activeSessions.length > 0) status.activeSessions = activeSessions;
|
|
46683
|
+
if (activeSessionDetails.length > 0) status.activeSessionDetails = activeSessionDetails;
|
|
46684
|
+
if (health) {
|
|
46685
|
+
status.health = health;
|
|
46686
|
+
return true;
|
|
46687
|
+
}
|
|
46688
|
+
if (git) {
|
|
46689
|
+
status.health = deriveMeshNodeHealthFromGit(git);
|
|
46690
|
+
return true;
|
|
46691
|
+
}
|
|
46692
|
+
return activeSessions.length > 0 || !!machineStatus || !!lastSeenAt || !!updatedAt;
|
|
46693
|
+
}
|
|
46384
46694
|
async function resolveProviderTypeFromPriority(args) {
|
|
46385
46695
|
if (!args.providerPriority.length) {
|
|
46386
46696
|
return { error: `Node '${args.nodeId}' has no providerPriority policy; pass cliType explicitly or configure node.policy.providerPriority` };
|
|
@@ -46769,6 +47079,7 @@ var init_router = __esm({
|
|
|
46769
47079
|
init_chat_history();
|
|
46770
47080
|
init_ide_detector();
|
|
46771
47081
|
init_cli_detector();
|
|
47082
|
+
init_git_status();
|
|
46772
47083
|
init_logger();
|
|
46773
47084
|
init_command_log();
|
|
46774
47085
|
init_js_yaml();
|
|
@@ -46818,7 +47129,12 @@ var init_router = __esm({
|
|
|
46818
47129
|
}
|
|
46819
47130
|
return this.inlineMeshCache.get(meshId);
|
|
46820
47131
|
}
|
|
46821
|
-
async getMeshForCommand(meshId, inlineMesh) {
|
|
47132
|
+
async getMeshForCommand(meshId, inlineMesh, options) {
|
|
47133
|
+
const preferInline = options?.preferInline === true;
|
|
47134
|
+
if (preferInline) {
|
|
47135
|
+
const cached3 = this.getCachedInlineMesh(meshId, inlineMesh);
|
|
47136
|
+
if (cached3) return { mesh: cached3, inline: true };
|
|
47137
|
+
}
|
|
46822
47138
|
try {
|
|
46823
47139
|
const { getMesh: getMesh3 } = await Promise.resolve().then(() => (init_mesh_config(), mesh_config_exports));
|
|
46824
47140
|
const mesh = getMesh3(meshId);
|
|
@@ -48641,7 +48957,7 @@ ${block}`);
|
|
|
48641
48957
|
const meshId = typeof args?.meshId === "string" ? args.meshId.trim() : "";
|
|
48642
48958
|
if (!meshId) return { success: false, error: "meshId required" };
|
|
48643
48959
|
try {
|
|
48644
|
-
const meshRecord = await this.getMeshForCommand(meshId, args?.inlineMesh);
|
|
48960
|
+
const meshRecord = await this.getMeshForCommand(meshId, args?.inlineMesh, { preferInline: true });
|
|
48645
48961
|
const mesh = meshRecord?.mesh;
|
|
48646
48962
|
if (!mesh) return { success: false, error: "Mesh not found" };
|
|
48647
48963
|
const { getMeshQueueStats: getMeshQueueStats2, getQueue: getQueue2 } = await Promise.resolve().then(() => (init_mesh_work_queue(), mesh_work_queue_exports));
|
|
@@ -48650,84 +48966,102 @@ ${block}`);
|
|
|
48650
48966
|
const { readLedgerEntries: readLedgerEntries2, getLedgerSummary: getLedgerSummary2 } = await Promise.resolve().then(() => (init_mesh_ledger(), mesh_ledger_exports));
|
|
48651
48967
|
const ledgerEntries = readLedgerEntries2(meshId, { tail: 20 });
|
|
48652
48968
|
const ledgerSummary = getLedgerSummary2(meshId);
|
|
48969
|
+
const sessionHostRecords = this.deps.sessionHostControl?.listSessions ? await this.deps.sessionHostControl.listSessions().catch(() => []) : [];
|
|
48970
|
+
const liveMeshSessions = partitionSessionHostRecords(Array.isArray(sessionHostRecords) ? sessionHostRecords : []).liveRuntimes;
|
|
48971
|
+
const localMachineId = loadConfig().machineId || "";
|
|
48972
|
+
const inlineCoordinatorNodeId = meshRecord?.inline && Array.isArray(mesh.nodes) ? readStringValue(mesh.nodes[0]?.id, mesh.nodes[0]?.nodeId) : void 0;
|
|
48973
|
+
const refreshedAt = (/* @__PURE__ */ new Date()).toISOString();
|
|
48653
48974
|
const nodeStatuses = [];
|
|
48654
|
-
for (const node of mesh.nodes || []) {
|
|
48975
|
+
for (const [nodeIndex, node] of (mesh.nodes || []).entries()) {
|
|
48976
|
+
const nodeId = String(node.id || node.nodeId || "");
|
|
48977
|
+
const daemonId = readStringValue(node.daemonId);
|
|
48978
|
+
const providerPriority = readProviderPriorityFromPolicy(node.policy);
|
|
48979
|
+
const isSelfNode = Boolean(
|
|
48980
|
+
nodeId && inlineCoordinatorNodeId && nodeId === inlineCoordinatorNodeId
|
|
48981
|
+
) || Boolean(
|
|
48982
|
+
daemonId && (daemonId === localMachineId || daemonId === this.deps.statusInstanceId)
|
|
48983
|
+
) || Boolean(meshRecord?.inline && nodeIndex === 0);
|
|
48655
48984
|
const status = {
|
|
48656
|
-
nodeId
|
|
48985
|
+
nodeId,
|
|
48657
48986
|
machineLabel: node.machineLabel || node.id || node.nodeId,
|
|
48658
48987
|
workspace: node.workspace,
|
|
48659
48988
|
repoRoot: node.repoRoot,
|
|
48660
48989
|
isLocalWorktree: node.isLocalWorktree,
|
|
48661
48990
|
worktreeBranch: node.worktreeBranch,
|
|
48662
|
-
daemonId
|
|
48991
|
+
daemonId,
|
|
48663
48992
|
machineId: node.machineId,
|
|
48993
|
+
machineStatus: node.machineStatus,
|
|
48664
48994
|
health: "unknown",
|
|
48665
48995
|
providers: node.providers || [],
|
|
48666
|
-
|
|
48996
|
+
providerPriority,
|
|
48997
|
+
activeSessions: [],
|
|
48998
|
+
activeSessionDetails: [],
|
|
48999
|
+
launchReady: false
|
|
48667
49000
|
};
|
|
49001
|
+
if (isSelfNode) {
|
|
49002
|
+
status.connection = {
|
|
49003
|
+
perspective: "selected_coordinator",
|
|
49004
|
+
source: "mesh_peer_status",
|
|
49005
|
+
state: "self",
|
|
49006
|
+
transport: "local",
|
|
49007
|
+
reported: true,
|
|
49008
|
+
reason: "Selected coordinator daemon",
|
|
49009
|
+
lastStateChangeAt: refreshedAt
|
|
49010
|
+
};
|
|
49011
|
+
} else if (daemonId) {
|
|
49012
|
+
const connection = this.deps.getMeshPeerConnectionStatus?.(daemonId);
|
|
49013
|
+
status.connection = connection ?? {
|
|
49014
|
+
perspective: "selected_coordinator",
|
|
49015
|
+
source: "not_reported",
|
|
49016
|
+
state: "unknown",
|
|
49017
|
+
transport: "unknown",
|
|
49018
|
+
reported: false,
|
|
49019
|
+
reason: "No live mesh peer telemetry reported by the selected coordinator yet."
|
|
49020
|
+
};
|
|
49021
|
+
} else {
|
|
49022
|
+
status.connection = {
|
|
49023
|
+
perspective: "selected_coordinator",
|
|
49024
|
+
source: "not_reported",
|
|
49025
|
+
state: "unknown",
|
|
49026
|
+
transport: "unknown",
|
|
49027
|
+
reported: false,
|
|
49028
|
+
reason: "Node has no daemon id, so mesh transport cannot be reported from the selected coordinator."
|
|
49029
|
+
};
|
|
49030
|
+
}
|
|
49031
|
+
const matchedLiveSessionRecords = liveMeshSessions.filter((record2) => this.sessionMatchesMeshNode(record2, node, nodeId));
|
|
49032
|
+
if (matchedLiveSessionRecords.length > 0) {
|
|
49033
|
+
const sessionIds = matchedLiveSessionRecords.map((record2) => typeof record2?.sessionId === "string" ? record2.sessionId : "").filter(Boolean);
|
|
49034
|
+
const providerTypes = matchedLiveSessionRecords.map((record2) => readStringValue(record2?.providerType)).filter(Boolean);
|
|
49035
|
+
status.activeSessions = sessionIds;
|
|
49036
|
+
status.activeSessionDetails = matchedLiveSessionRecords.map(summarizeMeshSessionRecord);
|
|
49037
|
+
if (providerTypes.length > 0) {
|
|
49038
|
+
status.providers = Array.from(/* @__PURE__ */ new Set([...Array.isArray(status.providers) ? status.providers : [], ...providerTypes]));
|
|
49039
|
+
}
|
|
49040
|
+
}
|
|
48668
49041
|
if (node.workspace && typeof node.workspace === "string") {
|
|
49042
|
+
if (!fs10.existsSync(node.workspace) && applyCachedInlineMeshNodeStatus(status, node)) {
|
|
49043
|
+
status.launchReady = !!daemonId && (readStringValue(status.machineStatus) === "online" || isSelfNode);
|
|
49044
|
+
nodeStatuses.push(status);
|
|
49045
|
+
continue;
|
|
49046
|
+
}
|
|
48669
49047
|
try {
|
|
48670
|
-
const {
|
|
48671
|
-
|
|
48672
|
-
|
|
48673
|
-
|
|
48674
|
-
|
|
48675
|
-
|
|
48676
|
-
|
|
48677
|
-
});
|
|
48678
|
-
return result.stdout.trim();
|
|
48679
|
-
};
|
|
48680
|
-
const branch = await runGit2(["branch", "--show-current"]).catch(() => "");
|
|
48681
|
-
const porc = await runGit2(["status", "--porcelain"]).catch(() => "");
|
|
48682
|
-
const headCommit = await runGit2(["rev-parse", "--short", "HEAD"]).catch(() => null);
|
|
48683
|
-
const headMessage = await runGit2(["log", "-1", "--format=%s"]).catch(() => null);
|
|
48684
|
-
const upstream = await runGit2(["rev-parse", "--abbrev-ref", "@{upstream}"]).catch(() => null);
|
|
48685
|
-
const aheadBehind = await runGit2(["rev-list", "--left-right", "--count", "@{upstream}...HEAD"]).catch(() => "");
|
|
48686
|
-
const stashCount = await runGit2(["stash", "list"]).catch(() => "");
|
|
48687
|
-
let ahead = 0, behind = 0;
|
|
48688
|
-
if (aheadBehind) {
|
|
48689
|
-
const parts = aheadBehind.split(/\s+/);
|
|
48690
|
-
if (parts.length >= 2) {
|
|
48691
|
-
behind = parseInt(parts[0], 10) || 0;
|
|
48692
|
-
ahead = parseInt(parts[1], 10) || 0;
|
|
48693
|
-
}
|
|
48694
|
-
}
|
|
48695
|
-
const dirty = porc.length > 0;
|
|
48696
|
-
const lines = porc ? porc.split("\n").filter(Boolean) : [];
|
|
48697
|
-
let staged = 0, modified = 0, untracked = 0, deleted = 0, renamed2 = 0;
|
|
48698
|
-
for (const line of lines) {
|
|
48699
|
-
const xy = line.slice(0, 2);
|
|
48700
|
-
if (xy[0] !== " " && xy[0] !== "?") staged++;
|
|
48701
|
-
if (xy[1] === "M") modified++;
|
|
48702
|
-
if (xy[1] === "D") deleted++;
|
|
48703
|
-
if (xy[0] === "R" || xy[1] === "R") renamed2++;
|
|
48704
|
-
if (xy === "??") untracked++;
|
|
49048
|
+
const gitStatus = await getGitRepoStatus(node.workspace, { timeoutMs: 1e4, refreshUpstream: true });
|
|
49049
|
+
status.git = gitStatus;
|
|
49050
|
+
if (gitStatus.isGitRepo) {
|
|
49051
|
+
status.health = deriveMeshNodeHealthFromGit(gitStatus);
|
|
49052
|
+
} else {
|
|
49053
|
+
status.health = "degraded";
|
|
49054
|
+
if (gitStatus.error && !status.error) status.error = gitStatus.error;
|
|
48705
49055
|
}
|
|
48706
|
-
status.git = {
|
|
48707
|
-
workspace: node.workspace,
|
|
48708
|
-
repoRoot: node.workspace,
|
|
48709
|
-
isGitRepo: true,
|
|
48710
|
-
branch: branch || null,
|
|
48711
|
-
headCommit,
|
|
48712
|
-
headMessage,
|
|
48713
|
-
upstream,
|
|
48714
|
-
ahead,
|
|
48715
|
-
behind,
|
|
48716
|
-
staged,
|
|
48717
|
-
modified,
|
|
48718
|
-
untracked,
|
|
48719
|
-
deleted,
|
|
48720
|
-
renamed: renamed2,
|
|
48721
|
-
hasConflicts: false,
|
|
48722
|
-
conflictFiles: [],
|
|
48723
|
-
stashCount: stashCount ? stashCount.split("\n").filter(Boolean).length : 0,
|
|
48724
|
-
lastCheckedAt: Date.now()
|
|
48725
|
-
};
|
|
48726
|
-
status.health = branch ? dirty ? "dirty" : "online" : "degraded";
|
|
48727
49056
|
} catch {
|
|
48728
|
-
status
|
|
49057
|
+
if (!applyCachedInlineMeshNodeStatus(status, node)) {
|
|
49058
|
+
status.health = "degraded";
|
|
49059
|
+
}
|
|
48729
49060
|
}
|
|
49061
|
+
} else {
|
|
49062
|
+
applyCachedInlineMeshNodeStatus(status, node);
|
|
48730
49063
|
}
|
|
49064
|
+
status.launchReady = !!daemonId && (readStringValue(status.machineStatus) === "online" || isSelfNode);
|
|
48731
49065
|
nodeStatuses.push(status);
|
|
48732
49066
|
}
|
|
48733
49067
|
return {
|
|
@@ -48736,6 +49070,7 @@ ${block}`);
|
|
|
48736
49070
|
meshName: mesh.name,
|
|
48737
49071
|
repoIdentity: mesh.repoIdentity,
|
|
48738
49072
|
defaultBranch: mesh.defaultBranch,
|
|
49073
|
+
refreshedAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
48739
49074
|
nodes: nodeStatuses,
|
|
48740
49075
|
queue: { tasks: queue, summary: queueSummary },
|
|
48741
49076
|
ledger: { entries: ledgerEntries, summary: ledgerSummary }
|
|
@@ -56814,6 +57149,7 @@ async function initDaemonComponents(config2) {
|
|
|
56814
57149
|
sessionHostControl: config2.sessionHostControl,
|
|
56815
57150
|
statusInstanceId: config2.statusInstanceId,
|
|
56816
57151
|
statusVersion: config2.statusVersion,
|
|
57152
|
+
getMeshPeerConnectionStatus: config2.getMeshPeerConnectionStatus,
|
|
56817
57153
|
getCdpLogFn: config2.getCdpLogFn || ((ideType) => LOG.forComponent(`CDP:${ideType}`).asLogFn())
|
|
56818
57154
|
});
|
|
56819
57155
|
poller = new AgentStreamPoller({
|
|
@@ -57115,6 +57451,7 @@ __export(src_exports, {
|
|
|
57115
57451
|
prepareSessionChatTailUpdate: () => prepareSessionChatTailUpdate,
|
|
57116
57452
|
prepareSessionModalUpdate: () => prepareSessionModalUpdate,
|
|
57117
57453
|
probeCdpPort: () => probeCdpPort,
|
|
57454
|
+
queuePendingMeshCoordinatorEvent: () => queuePendingMeshCoordinatorEvent,
|
|
57118
57455
|
readChatHistory: () => readChatHistory,
|
|
57119
57456
|
readLedgerEntries: () => readLedgerEntries,
|
|
57120
57457
|
readLedgerSlice: () => readLedgerSlice,
|
|
@@ -97091,11 +97428,30 @@ var init_daemon_mesh_manager = __esm({
|
|
|
97091
97428
|
nodeDatachannel = null;
|
|
97092
97429
|
peers = /* @__PURE__ */ new Map();
|
|
97093
97430
|
// Map<targetDaemonId, PeerEntry>
|
|
97431
|
+
peerSnapshots = /* @__PURE__ */ new Map();
|
|
97094
97432
|
pendingRequests = /* @__PURE__ */ new Map();
|
|
97095
97433
|
commandCallback;
|
|
97096
97434
|
p2pFailure(message, command, targetDaemonId) {
|
|
97097
97435
|
return new P2pRelayFailureError(message, { command, targetDaemonId });
|
|
97098
97436
|
}
|
|
97437
|
+
updatePeerSnapshot(targetDaemonId, state, patch = {}) {
|
|
97438
|
+
const previous = this.peerSnapshots.get(targetDaemonId);
|
|
97439
|
+
const now = (/* @__PURE__ */ new Date()).toISOString();
|
|
97440
|
+
this.peerSnapshots.set(targetDaemonId, {
|
|
97441
|
+
perspective: "selected_coordinator",
|
|
97442
|
+
source: "mesh_peer_status",
|
|
97443
|
+
reported: true,
|
|
97444
|
+
state,
|
|
97445
|
+
transport: patch.transport ?? previous?.transport ?? "unknown",
|
|
97446
|
+
reason: patch.reason ?? previous?.reason,
|
|
97447
|
+
lastStateChangeAt: now,
|
|
97448
|
+
lastConnectedAt: patch.lastConnectedAt ?? previous?.lastConnectedAt,
|
|
97449
|
+
lastCommandAt: patch.lastCommandAt ?? previous?.lastCommandAt
|
|
97450
|
+
});
|
|
97451
|
+
}
|
|
97452
|
+
getPeerConnectionStatus(targetDaemonId) {
|
|
97453
|
+
return this.peerSnapshots.get(targetDaemonId) ?? null;
|
|
97454
|
+
}
|
|
97099
97455
|
invalidatePeer(targetDaemonId, reason, options = {}) {
|
|
97100
97456
|
const peer = this.peers.get(targetDaemonId);
|
|
97101
97457
|
if (peer?.commandQueue) {
|
|
@@ -97110,6 +97466,11 @@ var init_daemon_mesh_manager = __esm({
|
|
|
97110
97466
|
pending.reject(this.p2pFailure(reason, pending.command, targetDaemonId));
|
|
97111
97467
|
}
|
|
97112
97468
|
}
|
|
97469
|
+
const snapshotState = peer?.state === "closed" ? "closed" : peer?.state === "disconnected" ? "disconnected" : "failed";
|
|
97470
|
+
this.updatePeerSnapshot(targetDaemonId, snapshotState, {
|
|
97471
|
+
reason,
|
|
97472
|
+
transport: peer?.isRelay === true ? "relay" : peer?.isRelay === false ? "direct" : "unknown"
|
|
97473
|
+
});
|
|
97113
97474
|
if (options.closeResources !== false && peer) {
|
|
97114
97475
|
try {
|
|
97115
97476
|
peer.dataChannel?.close?.();
|
|
@@ -97142,6 +97503,7 @@ var init_daemon_mesh_manager = __esm({
|
|
|
97142
97503
|
"send_chat",
|
|
97143
97504
|
"read_chat",
|
|
97144
97505
|
"get_chat_debug_bundle",
|
|
97506
|
+
"get_pending_mesh_events",
|
|
97145
97507
|
"git_status",
|
|
97146
97508
|
"git_diff_summary",
|
|
97147
97509
|
"launch_cli",
|
|
@@ -97229,6 +97591,20 @@ var init_daemon_mesh_manager = __esm({
|
|
|
97229
97591
|
if (!peer) {
|
|
97230
97592
|
throw this.p2pFailure("Failed to initiate P2P connection entry", command, targetDaemonId);
|
|
97231
97593
|
}
|
|
97594
|
+
const lastCommandAt = (/* @__PURE__ */ new Date()).toISOString();
|
|
97595
|
+
if (peer.state === "connected") {
|
|
97596
|
+
this.updatePeerSnapshot(targetDaemonId, "connected", {
|
|
97597
|
+
transport: peer.isRelay === true ? "relay" : peer.isRelay === false ? "direct" : "unknown",
|
|
97598
|
+
lastConnectedAt: this.peerSnapshots.get(targetDaemonId)?.lastConnectedAt,
|
|
97599
|
+
lastCommandAt
|
|
97600
|
+
});
|
|
97601
|
+
} else {
|
|
97602
|
+
this.updatePeerSnapshot(targetDaemonId, "connecting", {
|
|
97603
|
+
transport: peer.isRelay === true ? "relay" : peer.isRelay === false ? "direct" : "unknown",
|
|
97604
|
+
reason: "Waiting for mesh DataChannel to open.",
|
|
97605
|
+
lastCommandAt
|
|
97606
|
+
});
|
|
97607
|
+
}
|
|
97232
97608
|
return new Promise((resolve23, reject) => {
|
|
97233
97609
|
const requestId = `req_${Date.now()}_${Math.random().toString(36).slice(2, 8)}`;
|
|
97234
97610
|
const timer = setTimeout(() => {
|
|
@@ -97372,6 +97748,9 @@ var init_daemon_mesh_manager = __esm({
|
|
|
97372
97748
|
remoteDescriptionSet: false
|
|
97373
97749
|
};
|
|
97374
97750
|
this.peers.set(targetDaemonId, entry);
|
|
97751
|
+
this.updatePeerSnapshot(targetDaemonId, "connecting", {
|
|
97752
|
+
reason: isInitiator ? "P2P mesh connection initiated by the selected coordinator." : "Waiting for the remote daemon to finish the mesh DataChannel handshake."
|
|
97753
|
+
});
|
|
97375
97754
|
pc.onLocalDescription((sdp, type2) => {
|
|
97376
97755
|
this.serverConn.sendMeshCommand(targetDaemonId, type2 === "offer" ? "mesh_p2p_offer" : "mesh_p2p_answer", { sdp, type: type2 });
|
|
97377
97756
|
});
|
|
@@ -97382,7 +97761,26 @@ var init_daemon_mesh_manager = __esm({
|
|
|
97382
97761
|
LOG.info("Mesh", `[Mesh] P2P state with ${targetDaemonId.slice(0, 12)}: ${state}`);
|
|
97383
97762
|
if (state === "connected") {
|
|
97384
97763
|
entry.state = "connected";
|
|
97764
|
+
let transport = "unknown";
|
|
97765
|
+
try {
|
|
97766
|
+
const pair = pc.getSelectedCandidatePair?.();
|
|
97767
|
+
if (pair) {
|
|
97768
|
+
const localType = pair.local?.type || "unknown";
|
|
97769
|
+
const remoteType = pair.remote?.type || "unknown";
|
|
97770
|
+
entry.isRelay = localType === "relay" || remoteType === "relay";
|
|
97771
|
+
transport = entry.isRelay ? "relay" : "direct";
|
|
97772
|
+
LOG.info("Mesh", `[Mesh] Candidate pair with ${targetDaemonId.slice(0, 12)}: local=${localType} remote=${remoteType} \u2192 ${transport}`);
|
|
97773
|
+
}
|
|
97774
|
+
} catch {
|
|
97775
|
+
transport = entry.isRelay === true ? "relay" : entry.isRelay === false ? "direct" : "unknown";
|
|
97776
|
+
}
|
|
97777
|
+
this.updatePeerSnapshot(targetDaemonId, "connected", {
|
|
97778
|
+
transport,
|
|
97779
|
+
reason: transport === "relay" ? "Connected over TURN relay." : transport === "direct" ? "Connected directly peer-to-peer." : "Connected, but selected candidate pair details are unavailable.",
|
|
97780
|
+
lastConnectedAt: (/* @__PURE__ */ new Date()).toISOString()
|
|
97781
|
+
});
|
|
97385
97782
|
} else if (state === "failed" || state === "closed" || state === "disconnected") {
|
|
97783
|
+
entry.state = state;
|
|
97386
97784
|
this.invalidatePeer(targetDaemonId, `P2P state changed to ${state}`, { rejectPending: true, closeResources: false });
|
|
97387
97785
|
}
|
|
97388
97786
|
});
|
|
@@ -97400,6 +97798,11 @@ var init_daemon_mesh_manager = __esm({
|
|
|
97400
97798
|
dc.onOpen(() => {
|
|
97401
97799
|
LOG.info("Mesh", `[Mesh] DataChannel OPEN with ${targetDaemonId.slice(0, 12)}`);
|
|
97402
97800
|
entry.state = "connected";
|
|
97801
|
+
this.updatePeerSnapshot(targetDaemonId, "connected", {
|
|
97802
|
+
transport: entry.isRelay === true ? "relay" : entry.isRelay === false ? "direct" : "unknown",
|
|
97803
|
+
reason: entry.isRelay === true ? "Connected over TURN relay." : entry.isRelay === false ? "Connected directly peer-to-peer." : "DataChannel open; transport details not reported yet.",
|
|
97804
|
+
lastConnectedAt: (/* @__PURE__ */ new Date()).toISOString()
|
|
97805
|
+
});
|
|
97403
97806
|
if (entry.commandQueue) {
|
|
97404
97807
|
const queue = entry.commandQueue;
|
|
97405
97808
|
entry.commandQueue = [];
|
|
@@ -97679,6 +98082,7 @@ var init_adhdev_daemon = __esm({
|
|
|
97679
98082
|
"use strict";
|
|
97680
98083
|
init_server_connection();
|
|
97681
98084
|
init_src();
|
|
98085
|
+
init_mesh_events();
|
|
97682
98086
|
init_daemon_p2p2();
|
|
97683
98087
|
init_screenshot_controller();
|
|
97684
98088
|
init_session_host();
|
|
@@ -97695,7 +98099,7 @@ var init_adhdev_daemon = __esm({
|
|
|
97695
98099
|
init_version();
|
|
97696
98100
|
init_src();
|
|
97697
98101
|
init_runtime_defaults();
|
|
97698
|
-
pkgVersion = resolvePackageVersion({ injectedVersion: "0.9.82-rc.
|
|
98102
|
+
pkgVersion = resolvePackageVersion({ injectedVersion: "0.9.82-rc.10" });
|
|
97699
98103
|
AdhdevDaemon = class _AdhdevDaemon {
|
|
97700
98104
|
localHttpServer = null;
|
|
97701
98105
|
localWss = null;
|
|
@@ -98219,6 +98623,7 @@ ${err?.stack || ""}`);
|
|
|
98219
98623
|
if (!this.meshManager) throw new Error("Mesh manager not initialized");
|
|
98220
98624
|
return this.meshManager.sendCommand(daemonId, command, args);
|
|
98221
98625
|
},
|
|
98626
|
+
getMeshPeerConnectionStatus: (daemonId) => this.meshManager?.getPeerConnectionStatus(daemonId) ?? null,
|
|
98222
98627
|
onStatusChange: () => {
|
|
98223
98628
|
this.invalidateHotChatSnapshotCache();
|
|
98224
98629
|
this.statusReporter?.onStatusChange();
|
|
@@ -98611,6 +99016,21 @@ ${err?.stack || ""}`);
|
|
|
98611
99016
|
await this.meshManager.sendCommand(coordinatorDaemonId, "mesh_forward_event", payload);
|
|
98612
99017
|
LOG.info("MeshEvents", `Relayed ${payload.event} for mesh ${meshId} to coordinator daemon ${coordinatorDaemonId.slice(0, 12)}\u2026`);
|
|
98613
99018
|
} catch (error48) {
|
|
99019
|
+
queuePendingMeshCoordinatorEvent({
|
|
99020
|
+
event: payload.event,
|
|
99021
|
+
meshId,
|
|
99022
|
+
nodeLabel: payload.nodeId ? `Node '${payload.nodeId}'` : payload.workspace ? `Agent at ${payload.workspace}` : "Remote agent",
|
|
99023
|
+
nodeId: payload.nodeId || void 0,
|
|
99024
|
+
workspace: payload.workspace || void 0,
|
|
99025
|
+
metadataEvent: {
|
|
99026
|
+
targetSessionId: payload.targetSessionId,
|
|
99027
|
+
providerType: payload.providerType,
|
|
99028
|
+
providerSessionId: payload.providerSessionId,
|
|
99029
|
+
finalSummary: payload.finalSummary,
|
|
99030
|
+
workspace: payload.workspace
|
|
99031
|
+
},
|
|
99032
|
+
queuedAt: Date.now()
|
|
99033
|
+
});
|
|
98614
99034
|
LOG.warn("MeshEvents", `Failed to relay ${payload.event} for mesh ${meshId}: ${error48?.message || error48}`);
|
|
98615
99035
|
}
|
|
98616
99036
|
}
|
|
@@ -102745,11 +103165,36 @@ function rotateLogs() {
|
|
|
102745
103165
|
rotateLogIfNeeded(LOG_OUT);
|
|
102746
103166
|
rotateLogIfNeeded(LOG_ERR);
|
|
102747
103167
|
}
|
|
102748
|
-
function
|
|
103168
|
+
function normalizeLaunchdPathEntry(entry) {
|
|
103169
|
+
const trimmed = String(entry || "").trim();
|
|
103170
|
+
if (!trimmed) return null;
|
|
103171
|
+
if (trimmed.startsWith("~")) {
|
|
103172
|
+
return import_node_path5.default.join(import_node_os4.default.homedir(), trimmed.slice(1));
|
|
103173
|
+
}
|
|
103174
|
+
return import_node_path5.default.isAbsolute(trimmed) ? trimmed : null;
|
|
103175
|
+
}
|
|
103176
|
+
function buildLaunchdPath(nodeExe, currentPath = process.env.PATH || "") {
|
|
102749
103177
|
const brewPrefix = import_node_fs4.default.existsSync("/opt/homebrew/bin") ? "/opt/homebrew/bin" : "/usr/local/bin";
|
|
102750
|
-
const
|
|
102751
|
-
const
|
|
102752
|
-
const
|
|
103178
|
+
const entries = [];
|
|
103179
|
+
const seen = /* @__PURE__ */ new Set();
|
|
103180
|
+
const addEntry = (value) => {
|
|
103181
|
+
if (!value) return;
|
|
103182
|
+
const normalized = normalizeLaunchdPathEntry(value);
|
|
103183
|
+
if (!normalized || seen.has(normalized)) return;
|
|
103184
|
+
seen.add(normalized);
|
|
103185
|
+
entries.push(normalized);
|
|
103186
|
+
};
|
|
103187
|
+
addEntry(import_node_path5.default.dirname(nodeExe));
|
|
103188
|
+
for (const entry of String(currentPath || "").split(import_node_path5.default.delimiter)) {
|
|
103189
|
+
addEntry(entry);
|
|
103190
|
+
}
|
|
103191
|
+
for (const entry of [brewPrefix, "/usr/local/bin", "/usr/bin", "/bin", "/usr/sbin", "/sbin"]) {
|
|
103192
|
+
addEntry(entry);
|
|
103193
|
+
}
|
|
103194
|
+
return entries.join(":");
|
|
103195
|
+
}
|
|
103196
|
+
function buildPlist(nodeExe, cliExe, currentPath = process.env.PATH || "") {
|
|
103197
|
+
const pathValue = buildLaunchdPath(nodeExe, currentPath);
|
|
102753
103198
|
return `<?xml version="1.0" encoding="UTF-8"?>
|
|
102754
103199
|
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
|
102755
103200
|
<plist version="1.0">
|