adhdev 0.9.82-rc.7 → 0.9.82-rc.9
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 +273 -16
- package/dist/cli/index.js.map +1 -1
- package/dist/index.js +273 -16
- package/dist/index.js.map +1 -1
- package/package.json +2 -2
- package/vendor/mcp-server/index.js +31 -5
- 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": {
|
|
@@ -46524,17 +46591,87 @@ function readCachedInlineMeshActiveSessions(node) {
|
|
|
46524
46591
|
const sessionId = readStringValue(fallbackSession.id, fallbackSession.sessionId, fallbackSession.session_id, node?.activeSessionId, node?.active_session_id, node?.sessionId, node?.session_id);
|
|
46525
46592
|
return sessionId ? [sessionId] : [];
|
|
46526
46593
|
}
|
|
46594
|
+
function readCachedInlineMeshActiveSessionDetails(node) {
|
|
46595
|
+
const cachedStatus = readObjectRecord(node?.cachedStatus);
|
|
46596
|
+
const activeSession = readObjectRecord(cachedStatus.activeSession);
|
|
46597
|
+
const fallbackSession = Object.keys(activeSession).length ? activeSession : readObjectRecord(node?.activeSession ?? node?.active_session);
|
|
46598
|
+
const sessionId = readStringValue(
|
|
46599
|
+
fallbackSession.id,
|
|
46600
|
+
fallbackSession.sessionId,
|
|
46601
|
+
fallbackSession.session_id,
|
|
46602
|
+
node?.activeSessionId,
|
|
46603
|
+
node?.active_session_id,
|
|
46604
|
+
node?.sessionId,
|
|
46605
|
+
node?.session_id
|
|
46606
|
+
);
|
|
46607
|
+
if (!sessionId) return [];
|
|
46608
|
+
return [{
|
|
46609
|
+
sessionId,
|
|
46610
|
+
providerType: readStringValue(
|
|
46611
|
+
fallbackSession.providerType,
|
|
46612
|
+
fallbackSession.provider_type,
|
|
46613
|
+
fallbackSession.cliType,
|
|
46614
|
+
fallbackSession.cli_type,
|
|
46615
|
+
fallbackSession.provider,
|
|
46616
|
+
node?.providerType,
|
|
46617
|
+
node?.provider_type
|
|
46618
|
+
),
|
|
46619
|
+
state: readStringValue(fallbackSession.status, fallbackSession.state, fallbackSession.lifecycle),
|
|
46620
|
+
lifecycle: readStringValue(fallbackSession.lifecycle),
|
|
46621
|
+
title: readStringValue(fallbackSession.title, fallbackSession.displayName, fallbackSession.display_name) ?? null,
|
|
46622
|
+
workspace: readStringValue(fallbackSession.workspace, node?.workspace) ?? null,
|
|
46623
|
+
lastActivityAt: readStringValue(fallbackSession.lastActivityAt, fallbackSession.last_activity_at) ?? null,
|
|
46624
|
+
recoveryState: readStringValue(fallbackSession.recoveryState, fallbackSession.recovery_state) ?? null,
|
|
46625
|
+
isCached: true
|
|
46626
|
+
}];
|
|
46627
|
+
}
|
|
46628
|
+
function readLiveMeshSessionState(record2) {
|
|
46629
|
+
return readStringValue(
|
|
46630
|
+
record2?.meta?.sessionStatus,
|
|
46631
|
+
record2?.meta?.status,
|
|
46632
|
+
record2?.meta?.providerStatus,
|
|
46633
|
+
record2?.status,
|
|
46634
|
+
record2?.state,
|
|
46635
|
+
record2?.lifecycle
|
|
46636
|
+
);
|
|
46637
|
+
}
|
|
46638
|
+
function toIsoTimestamp(value) {
|
|
46639
|
+
if (typeof value === "number" && Number.isFinite(value)) return new Date(value).toISOString();
|
|
46640
|
+
const stringValue = readStringValue(value);
|
|
46641
|
+
return stringValue || null;
|
|
46642
|
+
}
|
|
46643
|
+
function summarizeMeshSessionRecord(record2) {
|
|
46644
|
+
return {
|
|
46645
|
+
sessionId: readStringValue(record2?.sessionId) || "unknown",
|
|
46646
|
+
providerType: readStringValue(record2?.providerType),
|
|
46647
|
+
state: readLiveMeshSessionState(record2),
|
|
46648
|
+
lifecycle: readStringValue(record2?.lifecycle),
|
|
46649
|
+
surfaceKind: getSessionHostSurfaceKind(record2),
|
|
46650
|
+
recoveryState: readStringValue(record2?.meta?.runtimeRecoveryState) ?? null,
|
|
46651
|
+
workspace: readStringValue(record2?.workspace) ?? null,
|
|
46652
|
+
title: readStringValue(record2?.displayName, record2?.workspaceLabel) ?? null,
|
|
46653
|
+
lastActivityAt: toIsoTimestamp(record2?.updatedAt ?? record2?.lastActivityAt ?? record2?.last_activity_at),
|
|
46654
|
+
isCached: false
|
|
46655
|
+
};
|
|
46656
|
+
}
|
|
46527
46657
|
function applyCachedInlineMeshNodeStatus(status, node) {
|
|
46528
46658
|
const cachedStatus = readObjectRecord(node?.cachedStatus);
|
|
46529
46659
|
const git = buildCachedInlineMeshGitStatus(node);
|
|
46530
46660
|
const error48 = readStringValue(cachedStatus.error, node?.error);
|
|
46531
46661
|
const health = readStringValue(cachedStatus.health, node?.health);
|
|
46532
46662
|
const machineStatus = readStringValue(cachedStatus.machineStatus, node?.machineStatus);
|
|
46663
|
+
const lastSeenAt = toIsoTimestamp(cachedStatus.lastSeenAt ?? cachedStatus.last_seen_at ?? node?.lastSeenAt ?? node?.last_seen_at);
|
|
46664
|
+
const updatedAt = toIsoTimestamp(cachedStatus.updatedAt ?? cachedStatus.updated_at ?? node?.updatedAt ?? node?.updated_at);
|
|
46533
46665
|
const activeSessions = readCachedInlineMeshActiveSessions(node);
|
|
46534
|
-
|
|
46666
|
+
const activeSessionDetails = readCachedInlineMeshActiveSessionDetails(node);
|
|
46667
|
+
if (!git && !error48 && !health && !machineStatus && !lastSeenAt && !updatedAt && activeSessions.length === 0) return false;
|
|
46535
46668
|
if (git) status.git = git;
|
|
46536
46669
|
if (error48) status.error = error48;
|
|
46670
|
+
if (machineStatus) status.machineStatus = machineStatus;
|
|
46671
|
+
if (lastSeenAt) status.lastSeenAt = lastSeenAt;
|
|
46672
|
+
if (updatedAt) status.updatedAt = updatedAt;
|
|
46537
46673
|
if (activeSessions.length > 0) status.activeSessions = activeSessions;
|
|
46674
|
+
if (activeSessionDetails.length > 0) status.activeSessionDetails = activeSessionDetails;
|
|
46538
46675
|
if (health) {
|
|
46539
46676
|
status.health = health;
|
|
46540
46677
|
return true;
|
|
@@ -46543,7 +46680,7 @@ function applyCachedInlineMeshNodeStatus(status, node) {
|
|
|
46543
46680
|
status.health = deriveMeshNodeHealthFromGit(git);
|
|
46544
46681
|
return true;
|
|
46545
46682
|
}
|
|
46546
|
-
return activeSessions.length > 0 || !!machineStatus;
|
|
46683
|
+
return activeSessions.length > 0 || !!machineStatus || !!lastSeenAt || !!updatedAt;
|
|
46547
46684
|
}
|
|
46548
46685
|
async function resolveProviderTypeFromPriority(args) {
|
|
46549
46686
|
if (!args.providerPriority.length) {
|
|
@@ -48822,33 +48959,84 @@ ${block}`);
|
|
|
48822
48959
|
const ledgerSummary = getLedgerSummary2(meshId);
|
|
48823
48960
|
const sessionHostRecords = this.deps.sessionHostControl?.listSessions ? await this.deps.sessionHostControl.listSessions().catch(() => []) : [];
|
|
48824
48961
|
const liveMeshSessions = partitionSessionHostRecords(Array.isArray(sessionHostRecords) ? sessionHostRecords : []).liveRuntimes;
|
|
48962
|
+
const localMachineId = loadConfig().machineId || "";
|
|
48963
|
+
const inlineCoordinatorNodeId = meshRecord?.inline && Array.isArray(mesh.nodes) ? readStringValue(mesh.nodes[0]?.id, mesh.nodes[0]?.nodeId) : void 0;
|
|
48964
|
+
const refreshedAt = (/* @__PURE__ */ new Date()).toISOString();
|
|
48825
48965
|
const nodeStatuses = [];
|
|
48826
|
-
for (const node of mesh.nodes || []) {
|
|
48966
|
+
for (const [nodeIndex, node] of (mesh.nodes || []).entries()) {
|
|
48967
|
+
const nodeId = String(node.id || node.nodeId || "");
|
|
48968
|
+
const daemonId = readStringValue(node.daemonId);
|
|
48969
|
+
const providerPriority = readProviderPriorityFromPolicy(node.policy);
|
|
48970
|
+
const isSelfNode = Boolean(
|
|
48971
|
+
nodeId && inlineCoordinatorNodeId && nodeId === inlineCoordinatorNodeId
|
|
48972
|
+
) || Boolean(
|
|
48973
|
+
daemonId && (daemonId === localMachineId || daemonId === this.deps.statusInstanceId)
|
|
48974
|
+
) || Boolean(meshRecord?.inline && nodeIndex === 0);
|
|
48827
48975
|
const status = {
|
|
48828
|
-
nodeId
|
|
48976
|
+
nodeId,
|
|
48829
48977
|
machineLabel: node.machineLabel || node.id || node.nodeId,
|
|
48830
48978
|
workspace: node.workspace,
|
|
48831
48979
|
repoRoot: node.repoRoot,
|
|
48832
48980
|
isLocalWorktree: node.isLocalWorktree,
|
|
48833
48981
|
worktreeBranch: node.worktreeBranch,
|
|
48834
|
-
daemonId
|
|
48982
|
+
daemonId,
|
|
48835
48983
|
machineId: node.machineId,
|
|
48984
|
+
machineStatus: node.machineStatus,
|
|
48836
48985
|
health: "unknown",
|
|
48837
48986
|
providers: node.providers || [],
|
|
48838
|
-
|
|
48987
|
+
providerPriority,
|
|
48988
|
+
activeSessions: [],
|
|
48989
|
+
activeSessionDetails: [],
|
|
48990
|
+
launchReady: false
|
|
48839
48991
|
};
|
|
48840
|
-
|
|
48841
|
-
|
|
48842
|
-
|
|
48843
|
-
|
|
48992
|
+
if (isSelfNode) {
|
|
48993
|
+
status.connection = {
|
|
48994
|
+
perspective: "selected_coordinator",
|
|
48995
|
+
source: "mesh_peer_status",
|
|
48996
|
+
state: "self",
|
|
48997
|
+
transport: "local",
|
|
48998
|
+
reported: true,
|
|
48999
|
+
reason: "Selected coordinator daemon",
|
|
49000
|
+
lastStateChangeAt: refreshedAt
|
|
49001
|
+
};
|
|
49002
|
+
} else if (daemonId) {
|
|
49003
|
+
const connection = this.deps.getMeshPeerConnectionStatus?.(daemonId);
|
|
49004
|
+
status.connection = connection ?? {
|
|
49005
|
+
perspective: "selected_coordinator",
|
|
49006
|
+
source: "not_reported",
|
|
49007
|
+
state: "unknown",
|
|
49008
|
+
transport: "unknown",
|
|
49009
|
+
reported: false,
|
|
49010
|
+
reason: "No live mesh peer telemetry reported by the selected coordinator yet."
|
|
49011
|
+
};
|
|
49012
|
+
} else {
|
|
49013
|
+
status.connection = {
|
|
49014
|
+
perspective: "selected_coordinator",
|
|
49015
|
+
source: "not_reported",
|
|
49016
|
+
state: "unknown",
|
|
49017
|
+
transport: "unknown",
|
|
49018
|
+
reported: false,
|
|
49019
|
+
reason: "Node has no daemon id, so mesh transport cannot be reported from the selected coordinator."
|
|
49020
|
+
};
|
|
49021
|
+
}
|
|
49022
|
+
const matchedLiveSessionRecords = liveMeshSessions.filter((record2) => this.sessionMatchesMeshNode(record2, node, nodeId));
|
|
49023
|
+
if (matchedLiveSessionRecords.length > 0) {
|
|
49024
|
+
const sessionIds = matchedLiveSessionRecords.map((record2) => typeof record2?.sessionId === "string" ? record2.sessionId : "").filter(Boolean);
|
|
49025
|
+
const providerTypes = matchedLiveSessionRecords.map((record2) => readStringValue(record2?.providerType)).filter(Boolean);
|
|
49026
|
+
status.activeSessions = sessionIds;
|
|
49027
|
+
status.activeSessionDetails = matchedLiveSessionRecords.map(summarizeMeshSessionRecord);
|
|
49028
|
+
if (providerTypes.length > 0) {
|
|
49029
|
+
status.providers = Array.from(/* @__PURE__ */ new Set([...Array.isArray(status.providers) ? status.providers : [], ...providerTypes]));
|
|
49030
|
+
}
|
|
48844
49031
|
}
|
|
48845
49032
|
if (node.workspace && typeof node.workspace === "string") {
|
|
48846
49033
|
if (!fs10.existsSync(node.workspace) && applyCachedInlineMeshNodeStatus(status, node)) {
|
|
49034
|
+
status.launchReady = !!daemonId && (readStringValue(status.machineStatus) === "online" || isSelfNode);
|
|
48847
49035
|
nodeStatuses.push(status);
|
|
48848
49036
|
continue;
|
|
48849
49037
|
}
|
|
48850
49038
|
try {
|
|
48851
|
-
const gitStatus = await getGitRepoStatus(node.workspace, { timeoutMs: 1e4 });
|
|
49039
|
+
const gitStatus = await getGitRepoStatus(node.workspace, { timeoutMs: 1e4, refreshUpstream: true });
|
|
48852
49040
|
status.git = gitStatus;
|
|
48853
49041
|
if (gitStatus.isGitRepo) {
|
|
48854
49042
|
status.health = deriveMeshNodeHealthFromGit(gitStatus);
|
|
@@ -48864,6 +49052,7 @@ ${block}`);
|
|
|
48864
49052
|
} else {
|
|
48865
49053
|
applyCachedInlineMeshNodeStatus(status, node);
|
|
48866
49054
|
}
|
|
49055
|
+
status.launchReady = !!daemonId && (readStringValue(status.machineStatus) === "online" || isSelfNode);
|
|
48867
49056
|
nodeStatuses.push(status);
|
|
48868
49057
|
}
|
|
48869
49058
|
return {
|
|
@@ -48872,6 +49061,7 @@ ${block}`);
|
|
|
48872
49061
|
meshName: mesh.name,
|
|
48873
49062
|
repoIdentity: mesh.repoIdentity,
|
|
48874
49063
|
defaultBranch: mesh.defaultBranch,
|
|
49064
|
+
refreshedAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
48875
49065
|
nodes: nodeStatuses,
|
|
48876
49066
|
queue: { tasks: queue, summary: queueSummary },
|
|
48877
49067
|
ledger: { entries: ledgerEntries, summary: ledgerSummary }
|
|
@@ -56950,6 +57140,7 @@ async function initDaemonComponents(config2) {
|
|
|
56950
57140
|
sessionHostControl: config2.sessionHostControl,
|
|
56951
57141
|
statusInstanceId: config2.statusInstanceId,
|
|
56952
57142
|
statusVersion: config2.statusVersion,
|
|
57143
|
+
getMeshPeerConnectionStatus: config2.getMeshPeerConnectionStatus,
|
|
56953
57144
|
getCdpLogFn: config2.getCdpLogFn || ((ideType) => LOG.forComponent(`CDP:${ideType}`).asLogFn())
|
|
56954
57145
|
});
|
|
56955
57146
|
poller = new AgentStreamPoller({
|
|
@@ -97227,11 +97418,30 @@ var init_daemon_mesh_manager = __esm({
|
|
|
97227
97418
|
nodeDatachannel = null;
|
|
97228
97419
|
peers = /* @__PURE__ */ new Map();
|
|
97229
97420
|
// Map<targetDaemonId, PeerEntry>
|
|
97421
|
+
peerSnapshots = /* @__PURE__ */ new Map();
|
|
97230
97422
|
pendingRequests = /* @__PURE__ */ new Map();
|
|
97231
97423
|
commandCallback;
|
|
97232
97424
|
p2pFailure(message, command, targetDaemonId) {
|
|
97233
97425
|
return new P2pRelayFailureError(message, { command, targetDaemonId });
|
|
97234
97426
|
}
|
|
97427
|
+
updatePeerSnapshot(targetDaemonId, state, patch = {}) {
|
|
97428
|
+
const previous = this.peerSnapshots.get(targetDaemonId);
|
|
97429
|
+
const now = (/* @__PURE__ */ new Date()).toISOString();
|
|
97430
|
+
this.peerSnapshots.set(targetDaemonId, {
|
|
97431
|
+
perspective: "selected_coordinator",
|
|
97432
|
+
source: "mesh_peer_status",
|
|
97433
|
+
reported: true,
|
|
97434
|
+
state,
|
|
97435
|
+
transport: patch.transport ?? previous?.transport ?? "unknown",
|
|
97436
|
+
reason: patch.reason ?? previous?.reason,
|
|
97437
|
+
lastStateChangeAt: now,
|
|
97438
|
+
lastConnectedAt: patch.lastConnectedAt ?? previous?.lastConnectedAt,
|
|
97439
|
+
lastCommandAt: patch.lastCommandAt ?? previous?.lastCommandAt
|
|
97440
|
+
});
|
|
97441
|
+
}
|
|
97442
|
+
getPeerConnectionStatus(targetDaemonId) {
|
|
97443
|
+
return this.peerSnapshots.get(targetDaemonId) ?? null;
|
|
97444
|
+
}
|
|
97235
97445
|
invalidatePeer(targetDaemonId, reason, options = {}) {
|
|
97236
97446
|
const peer = this.peers.get(targetDaemonId);
|
|
97237
97447
|
if (peer?.commandQueue) {
|
|
@@ -97246,6 +97456,11 @@ var init_daemon_mesh_manager = __esm({
|
|
|
97246
97456
|
pending.reject(this.p2pFailure(reason, pending.command, targetDaemonId));
|
|
97247
97457
|
}
|
|
97248
97458
|
}
|
|
97459
|
+
const snapshotState = peer?.state === "closed" ? "closed" : peer?.state === "disconnected" ? "disconnected" : "failed";
|
|
97460
|
+
this.updatePeerSnapshot(targetDaemonId, snapshotState, {
|
|
97461
|
+
reason,
|
|
97462
|
+
transport: peer?.isRelay === true ? "relay" : peer?.isRelay === false ? "direct" : "unknown"
|
|
97463
|
+
});
|
|
97249
97464
|
if (options.closeResources !== false && peer) {
|
|
97250
97465
|
try {
|
|
97251
97466
|
peer.dataChannel?.close?.();
|
|
@@ -97365,6 +97580,20 @@ var init_daemon_mesh_manager = __esm({
|
|
|
97365
97580
|
if (!peer) {
|
|
97366
97581
|
throw this.p2pFailure("Failed to initiate P2P connection entry", command, targetDaemonId);
|
|
97367
97582
|
}
|
|
97583
|
+
const lastCommandAt = (/* @__PURE__ */ new Date()).toISOString();
|
|
97584
|
+
if (peer.state === "connected") {
|
|
97585
|
+
this.updatePeerSnapshot(targetDaemonId, "connected", {
|
|
97586
|
+
transport: peer.isRelay === true ? "relay" : peer.isRelay === false ? "direct" : "unknown",
|
|
97587
|
+
lastConnectedAt: this.peerSnapshots.get(targetDaemonId)?.lastConnectedAt,
|
|
97588
|
+
lastCommandAt
|
|
97589
|
+
});
|
|
97590
|
+
} else {
|
|
97591
|
+
this.updatePeerSnapshot(targetDaemonId, "connecting", {
|
|
97592
|
+
transport: peer.isRelay === true ? "relay" : peer.isRelay === false ? "direct" : "unknown",
|
|
97593
|
+
reason: "Waiting for mesh DataChannel to open.",
|
|
97594
|
+
lastCommandAt
|
|
97595
|
+
});
|
|
97596
|
+
}
|
|
97368
97597
|
return new Promise((resolve23, reject) => {
|
|
97369
97598
|
const requestId = `req_${Date.now()}_${Math.random().toString(36).slice(2, 8)}`;
|
|
97370
97599
|
const timer = setTimeout(() => {
|
|
@@ -97508,6 +97737,9 @@ var init_daemon_mesh_manager = __esm({
|
|
|
97508
97737
|
remoteDescriptionSet: false
|
|
97509
97738
|
};
|
|
97510
97739
|
this.peers.set(targetDaemonId, entry);
|
|
97740
|
+
this.updatePeerSnapshot(targetDaemonId, "connecting", {
|
|
97741
|
+
reason: isInitiator ? "P2P mesh connection initiated by the selected coordinator." : "Waiting for the remote daemon to finish the mesh DataChannel handshake."
|
|
97742
|
+
});
|
|
97511
97743
|
pc.onLocalDescription((sdp, type2) => {
|
|
97512
97744
|
this.serverConn.sendMeshCommand(targetDaemonId, type2 === "offer" ? "mesh_p2p_offer" : "mesh_p2p_answer", { sdp, type: type2 });
|
|
97513
97745
|
});
|
|
@@ -97518,7 +97750,26 @@ var init_daemon_mesh_manager = __esm({
|
|
|
97518
97750
|
LOG.info("Mesh", `[Mesh] P2P state with ${targetDaemonId.slice(0, 12)}: ${state}`);
|
|
97519
97751
|
if (state === "connected") {
|
|
97520
97752
|
entry.state = "connected";
|
|
97753
|
+
let transport = "unknown";
|
|
97754
|
+
try {
|
|
97755
|
+
const pair = pc.getSelectedCandidatePair?.();
|
|
97756
|
+
if (pair) {
|
|
97757
|
+
const localType = pair.local?.type || "unknown";
|
|
97758
|
+
const remoteType = pair.remote?.type || "unknown";
|
|
97759
|
+
entry.isRelay = localType === "relay" || remoteType === "relay";
|
|
97760
|
+
transport = entry.isRelay ? "relay" : "direct";
|
|
97761
|
+
LOG.info("Mesh", `[Mesh] Candidate pair with ${targetDaemonId.slice(0, 12)}: local=${localType} remote=${remoteType} \u2192 ${transport}`);
|
|
97762
|
+
}
|
|
97763
|
+
} catch {
|
|
97764
|
+
transport = entry.isRelay === true ? "relay" : entry.isRelay === false ? "direct" : "unknown";
|
|
97765
|
+
}
|
|
97766
|
+
this.updatePeerSnapshot(targetDaemonId, "connected", {
|
|
97767
|
+
transport,
|
|
97768
|
+
reason: transport === "relay" ? "Connected over TURN relay." : transport === "direct" ? "Connected directly peer-to-peer." : "Connected, but selected candidate pair details are unavailable.",
|
|
97769
|
+
lastConnectedAt: (/* @__PURE__ */ new Date()).toISOString()
|
|
97770
|
+
});
|
|
97521
97771
|
} else if (state === "failed" || state === "closed" || state === "disconnected") {
|
|
97772
|
+
entry.state = state;
|
|
97522
97773
|
this.invalidatePeer(targetDaemonId, `P2P state changed to ${state}`, { rejectPending: true, closeResources: false });
|
|
97523
97774
|
}
|
|
97524
97775
|
});
|
|
@@ -97536,6 +97787,11 @@ var init_daemon_mesh_manager = __esm({
|
|
|
97536
97787
|
dc.onOpen(() => {
|
|
97537
97788
|
LOG.info("Mesh", `[Mesh] DataChannel OPEN with ${targetDaemonId.slice(0, 12)}`);
|
|
97538
97789
|
entry.state = "connected";
|
|
97790
|
+
this.updatePeerSnapshot(targetDaemonId, "connected", {
|
|
97791
|
+
transport: entry.isRelay === true ? "relay" : entry.isRelay === false ? "direct" : "unknown",
|
|
97792
|
+
reason: entry.isRelay === true ? "Connected over TURN relay." : entry.isRelay === false ? "Connected directly peer-to-peer." : "DataChannel open; transport details not reported yet.",
|
|
97793
|
+
lastConnectedAt: (/* @__PURE__ */ new Date()).toISOString()
|
|
97794
|
+
});
|
|
97539
97795
|
if (entry.commandQueue) {
|
|
97540
97796
|
const queue = entry.commandQueue;
|
|
97541
97797
|
entry.commandQueue = [];
|
|
@@ -97831,7 +98087,7 @@ var init_adhdev_daemon = __esm({
|
|
|
97831
98087
|
init_version();
|
|
97832
98088
|
init_src();
|
|
97833
98089
|
init_runtime_defaults();
|
|
97834
|
-
pkgVersion = resolvePackageVersion({ injectedVersion: "0.9.82-rc.
|
|
98090
|
+
pkgVersion = resolvePackageVersion({ injectedVersion: "0.9.82-rc.9" });
|
|
97835
98091
|
AdhdevDaemon = class _AdhdevDaemon {
|
|
97836
98092
|
localHttpServer = null;
|
|
97837
98093
|
localWss = null;
|
|
@@ -98355,6 +98611,7 @@ ${err?.stack || ""}`);
|
|
|
98355
98611
|
if (!this.meshManager) throw new Error("Mesh manager not initialized");
|
|
98356
98612
|
return this.meshManager.sendCommand(daemonId, command, args);
|
|
98357
98613
|
},
|
|
98614
|
+
getMeshPeerConnectionStatus: (daemonId) => this.meshManager?.getPeerConnectionStatus(daemonId) ?? null,
|
|
98358
98615
|
onStatusChange: () => {
|
|
98359
98616
|
this.invalidateHotChatSnapshotCache();
|
|
98360
98617
|
this.statusReporter?.onStatusChange();
|