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/index.js
CHANGED
|
@@ -264,8 +264,14 @@ async function getGitRepoStatus(workspace, options = {}) {
|
|
|
264
264
|
const includeSubmodules = options.includeSubmodules !== false;
|
|
265
265
|
try {
|
|
266
266
|
const repo = await resolveGitRepository(workspace, options);
|
|
267
|
-
|
|
268
|
-
|
|
267
|
+
let parsed = await readPorcelainStatus(repo, options);
|
|
268
|
+
let upstreamProbe = getInitialUpstreamProbe(parsed);
|
|
269
|
+
if (options.refreshUpstream) {
|
|
270
|
+
upstreamProbe = await refreshTrackedUpstream(repo, parsed, options);
|
|
271
|
+
if (upstreamProbe.upstreamStatus === "fresh") {
|
|
272
|
+
parsed = await readPorcelainStatus(repo, options);
|
|
273
|
+
}
|
|
274
|
+
}
|
|
269
275
|
const head = await readHead(repo, options);
|
|
270
276
|
const stashCount = await readStashCount(repo, options);
|
|
271
277
|
let submodules;
|
|
@@ -280,6 +286,9 @@ async function getGitRepoStatus(workspace, options = {}) {
|
|
|
280
286
|
headCommit: head.commit,
|
|
281
287
|
headMessage: head.message,
|
|
282
288
|
upstream: parsed.upstream,
|
|
289
|
+
upstreamStatus: parsed.upstream ? upstreamProbe.upstreamStatus : "no_upstream",
|
|
290
|
+
upstreamFetchedAt: upstreamProbe.upstreamFetchedAt,
|
|
291
|
+
upstreamFetchError: upstreamProbe.upstreamFetchError,
|
|
283
292
|
ahead: parsed.ahead,
|
|
284
293
|
behind: parsed.behind,
|
|
285
294
|
staged: parsed.staged,
|
|
@@ -304,6 +313,60 @@ async function getGitRepoStatus(workspace, options = {}) {
|
|
|
304
313
|
);
|
|
305
314
|
}
|
|
306
315
|
}
|
|
316
|
+
async function readPorcelainStatus(repo, options) {
|
|
317
|
+
const statusOutput = await runGit(repo, ["status", "--porcelain=v2", "--branch"], options);
|
|
318
|
+
return parsePorcelainV2Status(statusOutput.stdout);
|
|
319
|
+
}
|
|
320
|
+
function getInitialUpstreamProbe(parsed) {
|
|
321
|
+
return {
|
|
322
|
+
upstreamStatus: parsed.upstream ? "unchecked" : "no_upstream"
|
|
323
|
+
};
|
|
324
|
+
}
|
|
325
|
+
async function refreshTrackedUpstream(repo, parsed, options) {
|
|
326
|
+
if (!parsed.upstream || !parsed.branch) {
|
|
327
|
+
return { upstreamStatus: "no_upstream" };
|
|
328
|
+
}
|
|
329
|
+
const remoteName = await readBranchRemote(repo, parsed.branch, options) ?? inferRemoteName(parsed.upstream);
|
|
330
|
+
if (!remoteName) {
|
|
331
|
+
return {
|
|
332
|
+
upstreamStatus: "stale",
|
|
333
|
+
upstreamFetchError: `Unable to resolve remote for upstream '${parsed.upstream}'`
|
|
334
|
+
};
|
|
335
|
+
}
|
|
336
|
+
try {
|
|
337
|
+
await runGit(repo, ["fetch", "--quiet", "--prune", "--no-tags", remoteName], options);
|
|
338
|
+
return {
|
|
339
|
+
upstreamStatus: "fresh",
|
|
340
|
+
upstreamFetchedAt: Date.now()
|
|
341
|
+
};
|
|
342
|
+
} catch (error48) {
|
|
343
|
+
return {
|
|
344
|
+
upstreamStatus: "stale",
|
|
345
|
+
upstreamFetchError: formatGitError(error48)
|
|
346
|
+
};
|
|
347
|
+
}
|
|
348
|
+
}
|
|
349
|
+
async function readBranchRemote(repo, branch, options) {
|
|
350
|
+
try {
|
|
351
|
+
const result = await runGit(repo, ["config", "--get", `branch.${branch}.remote`], options);
|
|
352
|
+
return result.stdout.trim() || null;
|
|
353
|
+
} catch {
|
|
354
|
+
return null;
|
|
355
|
+
}
|
|
356
|
+
}
|
|
357
|
+
function inferRemoteName(upstream) {
|
|
358
|
+
const [remoteName] = upstream.split("/");
|
|
359
|
+
return remoteName?.trim() || null;
|
|
360
|
+
}
|
|
361
|
+
function formatGitError(error48) {
|
|
362
|
+
if (error48 instanceof GitCommandError) {
|
|
363
|
+
return error48.stderr || error48.message;
|
|
364
|
+
}
|
|
365
|
+
if (error48 instanceof Error) {
|
|
366
|
+
return error48.message;
|
|
367
|
+
}
|
|
368
|
+
return String(error48);
|
|
369
|
+
}
|
|
307
370
|
function parsePorcelainV2Status(output) {
|
|
308
371
|
const parsed = {
|
|
309
372
|
branch: null,
|
|
@@ -398,6 +461,7 @@ function emptyStatus(workspace, lastCheckedAt, error48) {
|
|
|
398
461
|
headCommit: null,
|
|
399
462
|
headMessage: null,
|
|
400
463
|
upstream: null,
|
|
464
|
+
upstreamStatus: "unavailable",
|
|
401
465
|
ahead: 0,
|
|
402
466
|
behind: 0,
|
|
403
467
|
staged: 0,
|
|
@@ -690,6 +754,9 @@ function createGitCompactSummary(status, diffSummary) {
|
|
|
690
754
|
isGitRepo: status.isGitRepo,
|
|
691
755
|
repoRoot: status.repoRoot,
|
|
692
756
|
branch: status.branch,
|
|
757
|
+
upstreamStatus: status.upstreamStatus,
|
|
758
|
+
upstreamFetchedAt: status.upstreamFetchedAt,
|
|
759
|
+
upstreamFetchError: status.upstreamFetchError,
|
|
693
760
|
dirty: status.staged > 0 || status.modified > 0 || status.untracked > 0 || status.deleted > 0 || status.renamed > 0 || conflictCount > 0 || changedFiles > 0,
|
|
694
761
|
changedFiles,
|
|
695
762
|
ahead: status.ahead,
|
|
@@ -1017,7 +1084,7 @@ function serviceNotImplemented(command) {
|
|
|
1017
1084
|
}
|
|
1018
1085
|
function createDefaultGitCommandServices() {
|
|
1019
1086
|
return {
|
|
1020
|
-
getStatus: ({ workspace }) => getGitRepoStatus(workspace),
|
|
1087
|
+
getStatus: ({ workspace, refreshUpstream }) => getGitRepoStatus(workspace, { refreshUpstream }),
|
|
1021
1088
|
getDiffSummary: ({ workspace }) => getGitDiffSummary(workspace),
|
|
1022
1089
|
getDiffFile: ({ workspace, path: filePath }) => getGitFileDiff(workspace, filePath),
|
|
1023
1090
|
createSnapshot: ({ workspace, reason, sessionId, turnId }) => defaultSnapshotStore.create({
|
|
@@ -1102,7 +1169,7 @@ async function handleGitCommand(command, args, services = defaultGitCommandServi
|
|
|
1102
1169
|
switch (command) {
|
|
1103
1170
|
case "git_status": {
|
|
1104
1171
|
if (!services.getStatus) return serviceNotImplemented(command);
|
|
1105
|
-
const status = await runService(() => services.getStatus({ workspace }));
|
|
1172
|
+
const status = await runService(() => services.getStatus({ workspace, refreshUpstream: optionalBoolean(args?.refreshUpstream) }));
|
|
1106
1173
|
return "success" in status ? status : { success: true, status };
|
|
1107
1174
|
}
|
|
1108
1175
|
case "git_diff_summary": {
|
|
@@ -45536,17 +45603,87 @@ function readCachedInlineMeshActiveSessions(node) {
|
|
|
45536
45603
|
const sessionId = readStringValue(fallbackSession.id, fallbackSession.sessionId, fallbackSession.session_id, node?.activeSessionId, node?.active_session_id, node?.sessionId, node?.session_id);
|
|
45537
45604
|
return sessionId ? [sessionId] : [];
|
|
45538
45605
|
}
|
|
45606
|
+
function readCachedInlineMeshActiveSessionDetails(node) {
|
|
45607
|
+
const cachedStatus = readObjectRecord(node?.cachedStatus);
|
|
45608
|
+
const activeSession = readObjectRecord(cachedStatus.activeSession);
|
|
45609
|
+
const fallbackSession = Object.keys(activeSession).length ? activeSession : readObjectRecord(node?.activeSession ?? node?.active_session);
|
|
45610
|
+
const sessionId = readStringValue(
|
|
45611
|
+
fallbackSession.id,
|
|
45612
|
+
fallbackSession.sessionId,
|
|
45613
|
+
fallbackSession.session_id,
|
|
45614
|
+
node?.activeSessionId,
|
|
45615
|
+
node?.active_session_id,
|
|
45616
|
+
node?.sessionId,
|
|
45617
|
+
node?.session_id
|
|
45618
|
+
);
|
|
45619
|
+
if (!sessionId) return [];
|
|
45620
|
+
return [{
|
|
45621
|
+
sessionId,
|
|
45622
|
+
providerType: readStringValue(
|
|
45623
|
+
fallbackSession.providerType,
|
|
45624
|
+
fallbackSession.provider_type,
|
|
45625
|
+
fallbackSession.cliType,
|
|
45626
|
+
fallbackSession.cli_type,
|
|
45627
|
+
fallbackSession.provider,
|
|
45628
|
+
node?.providerType,
|
|
45629
|
+
node?.provider_type
|
|
45630
|
+
),
|
|
45631
|
+
state: readStringValue(fallbackSession.status, fallbackSession.state, fallbackSession.lifecycle),
|
|
45632
|
+
lifecycle: readStringValue(fallbackSession.lifecycle),
|
|
45633
|
+
title: readStringValue(fallbackSession.title, fallbackSession.displayName, fallbackSession.display_name) ?? null,
|
|
45634
|
+
workspace: readStringValue(fallbackSession.workspace, node?.workspace) ?? null,
|
|
45635
|
+
lastActivityAt: readStringValue(fallbackSession.lastActivityAt, fallbackSession.last_activity_at) ?? null,
|
|
45636
|
+
recoveryState: readStringValue(fallbackSession.recoveryState, fallbackSession.recovery_state) ?? null,
|
|
45637
|
+
isCached: true
|
|
45638
|
+
}];
|
|
45639
|
+
}
|
|
45640
|
+
function readLiveMeshSessionState(record2) {
|
|
45641
|
+
return readStringValue(
|
|
45642
|
+
record2?.meta?.sessionStatus,
|
|
45643
|
+
record2?.meta?.status,
|
|
45644
|
+
record2?.meta?.providerStatus,
|
|
45645
|
+
record2?.status,
|
|
45646
|
+
record2?.state,
|
|
45647
|
+
record2?.lifecycle
|
|
45648
|
+
);
|
|
45649
|
+
}
|
|
45650
|
+
function toIsoTimestamp(value) {
|
|
45651
|
+
if (typeof value === "number" && Number.isFinite(value)) return new Date(value).toISOString();
|
|
45652
|
+
const stringValue = readStringValue(value);
|
|
45653
|
+
return stringValue || null;
|
|
45654
|
+
}
|
|
45655
|
+
function summarizeMeshSessionRecord(record2) {
|
|
45656
|
+
return {
|
|
45657
|
+
sessionId: readStringValue(record2?.sessionId) || "unknown",
|
|
45658
|
+
providerType: readStringValue(record2?.providerType),
|
|
45659
|
+
state: readLiveMeshSessionState(record2),
|
|
45660
|
+
lifecycle: readStringValue(record2?.lifecycle),
|
|
45661
|
+
surfaceKind: getSessionHostSurfaceKind(record2),
|
|
45662
|
+
recoveryState: readStringValue(record2?.meta?.runtimeRecoveryState) ?? null,
|
|
45663
|
+
workspace: readStringValue(record2?.workspace) ?? null,
|
|
45664
|
+
title: readStringValue(record2?.displayName, record2?.workspaceLabel) ?? null,
|
|
45665
|
+
lastActivityAt: toIsoTimestamp(record2?.updatedAt ?? record2?.lastActivityAt ?? record2?.last_activity_at),
|
|
45666
|
+
isCached: false
|
|
45667
|
+
};
|
|
45668
|
+
}
|
|
45539
45669
|
function applyCachedInlineMeshNodeStatus(status, node) {
|
|
45540
45670
|
const cachedStatus = readObjectRecord(node?.cachedStatus);
|
|
45541
45671
|
const git = buildCachedInlineMeshGitStatus(node);
|
|
45542
45672
|
const error48 = readStringValue(cachedStatus.error, node?.error);
|
|
45543
45673
|
const health = readStringValue(cachedStatus.health, node?.health);
|
|
45544
45674
|
const machineStatus = readStringValue(cachedStatus.machineStatus, node?.machineStatus);
|
|
45675
|
+
const lastSeenAt = toIsoTimestamp(cachedStatus.lastSeenAt ?? cachedStatus.last_seen_at ?? node?.lastSeenAt ?? node?.last_seen_at);
|
|
45676
|
+
const updatedAt = toIsoTimestamp(cachedStatus.updatedAt ?? cachedStatus.updated_at ?? node?.updatedAt ?? node?.updated_at);
|
|
45545
45677
|
const activeSessions = readCachedInlineMeshActiveSessions(node);
|
|
45546
|
-
|
|
45678
|
+
const activeSessionDetails = readCachedInlineMeshActiveSessionDetails(node);
|
|
45679
|
+
if (!git && !error48 && !health && !machineStatus && !lastSeenAt && !updatedAt && activeSessions.length === 0) return false;
|
|
45547
45680
|
if (git) status.git = git;
|
|
45548
45681
|
if (error48) status.error = error48;
|
|
45682
|
+
if (machineStatus) status.machineStatus = machineStatus;
|
|
45683
|
+
if (lastSeenAt) status.lastSeenAt = lastSeenAt;
|
|
45684
|
+
if (updatedAt) status.updatedAt = updatedAt;
|
|
45549
45685
|
if (activeSessions.length > 0) status.activeSessions = activeSessions;
|
|
45686
|
+
if (activeSessionDetails.length > 0) status.activeSessionDetails = activeSessionDetails;
|
|
45550
45687
|
if (health) {
|
|
45551
45688
|
status.health = health;
|
|
45552
45689
|
return true;
|
|
@@ -45555,7 +45692,7 @@ function applyCachedInlineMeshNodeStatus(status, node) {
|
|
|
45555
45692
|
status.health = deriveMeshNodeHealthFromGit(git);
|
|
45556
45693
|
return true;
|
|
45557
45694
|
}
|
|
45558
|
-
return activeSessions.length > 0 || !!machineStatus;
|
|
45695
|
+
return activeSessions.length > 0 || !!machineStatus || !!lastSeenAt || !!updatedAt;
|
|
45559
45696
|
}
|
|
45560
45697
|
async function resolveProviderTypeFromPriority(args) {
|
|
45561
45698
|
if (!args.providerPriority.length) {
|
|
@@ -47834,33 +47971,84 @@ ${block}`);
|
|
|
47834
47971
|
const ledgerSummary = getLedgerSummary2(meshId);
|
|
47835
47972
|
const sessionHostRecords = this.deps.sessionHostControl?.listSessions ? await this.deps.sessionHostControl.listSessions().catch(() => []) : [];
|
|
47836
47973
|
const liveMeshSessions = partitionSessionHostRecords(Array.isArray(sessionHostRecords) ? sessionHostRecords : []).liveRuntimes;
|
|
47974
|
+
const localMachineId = loadConfig().machineId || "";
|
|
47975
|
+
const inlineCoordinatorNodeId = meshRecord?.inline && Array.isArray(mesh.nodes) ? readStringValue(mesh.nodes[0]?.id, mesh.nodes[0]?.nodeId) : void 0;
|
|
47976
|
+
const refreshedAt = (/* @__PURE__ */ new Date()).toISOString();
|
|
47837
47977
|
const nodeStatuses = [];
|
|
47838
|
-
for (const node of mesh.nodes || []) {
|
|
47978
|
+
for (const [nodeIndex, node] of (mesh.nodes || []).entries()) {
|
|
47979
|
+
const nodeId = String(node.id || node.nodeId || "");
|
|
47980
|
+
const daemonId = readStringValue(node.daemonId);
|
|
47981
|
+
const providerPriority = readProviderPriorityFromPolicy(node.policy);
|
|
47982
|
+
const isSelfNode = Boolean(
|
|
47983
|
+
nodeId && inlineCoordinatorNodeId && nodeId === inlineCoordinatorNodeId
|
|
47984
|
+
) || Boolean(
|
|
47985
|
+
daemonId && (daemonId === localMachineId || daemonId === this.deps.statusInstanceId)
|
|
47986
|
+
) || Boolean(meshRecord?.inline && nodeIndex === 0);
|
|
47839
47987
|
const status = {
|
|
47840
|
-
nodeId
|
|
47988
|
+
nodeId,
|
|
47841
47989
|
machineLabel: node.machineLabel || node.id || node.nodeId,
|
|
47842
47990
|
workspace: node.workspace,
|
|
47843
47991
|
repoRoot: node.repoRoot,
|
|
47844
47992
|
isLocalWorktree: node.isLocalWorktree,
|
|
47845
47993
|
worktreeBranch: node.worktreeBranch,
|
|
47846
|
-
daemonId
|
|
47994
|
+
daemonId,
|
|
47847
47995
|
machineId: node.machineId,
|
|
47996
|
+
machineStatus: node.machineStatus,
|
|
47848
47997
|
health: "unknown",
|
|
47849
47998
|
providers: node.providers || [],
|
|
47850
|
-
|
|
47999
|
+
providerPriority,
|
|
48000
|
+
activeSessions: [],
|
|
48001
|
+
activeSessionDetails: [],
|
|
48002
|
+
launchReady: false
|
|
47851
48003
|
};
|
|
47852
|
-
|
|
47853
|
-
|
|
47854
|
-
|
|
47855
|
-
|
|
48004
|
+
if (isSelfNode) {
|
|
48005
|
+
status.connection = {
|
|
48006
|
+
perspective: "selected_coordinator",
|
|
48007
|
+
source: "mesh_peer_status",
|
|
48008
|
+
state: "self",
|
|
48009
|
+
transport: "local",
|
|
48010
|
+
reported: true,
|
|
48011
|
+
reason: "Selected coordinator daemon",
|
|
48012
|
+
lastStateChangeAt: refreshedAt
|
|
48013
|
+
};
|
|
48014
|
+
} else if (daemonId) {
|
|
48015
|
+
const connection = this.deps.getMeshPeerConnectionStatus?.(daemonId);
|
|
48016
|
+
status.connection = connection ?? {
|
|
48017
|
+
perspective: "selected_coordinator",
|
|
48018
|
+
source: "not_reported",
|
|
48019
|
+
state: "unknown",
|
|
48020
|
+
transport: "unknown",
|
|
48021
|
+
reported: false,
|
|
48022
|
+
reason: "No live mesh peer telemetry reported by the selected coordinator yet."
|
|
48023
|
+
};
|
|
48024
|
+
} else {
|
|
48025
|
+
status.connection = {
|
|
48026
|
+
perspective: "selected_coordinator",
|
|
48027
|
+
source: "not_reported",
|
|
48028
|
+
state: "unknown",
|
|
48029
|
+
transport: "unknown",
|
|
48030
|
+
reported: false,
|
|
48031
|
+
reason: "Node has no daemon id, so mesh transport cannot be reported from the selected coordinator."
|
|
48032
|
+
};
|
|
48033
|
+
}
|
|
48034
|
+
const matchedLiveSessionRecords = liveMeshSessions.filter((record2) => this.sessionMatchesMeshNode(record2, node, nodeId));
|
|
48035
|
+
if (matchedLiveSessionRecords.length > 0) {
|
|
48036
|
+
const sessionIds = matchedLiveSessionRecords.map((record2) => typeof record2?.sessionId === "string" ? record2.sessionId : "").filter(Boolean);
|
|
48037
|
+
const providerTypes = matchedLiveSessionRecords.map((record2) => readStringValue(record2?.providerType)).filter(Boolean);
|
|
48038
|
+
status.activeSessions = sessionIds;
|
|
48039
|
+
status.activeSessionDetails = matchedLiveSessionRecords.map(summarizeMeshSessionRecord);
|
|
48040
|
+
if (providerTypes.length > 0) {
|
|
48041
|
+
status.providers = Array.from(/* @__PURE__ */ new Set([...Array.isArray(status.providers) ? status.providers : [], ...providerTypes]));
|
|
48042
|
+
}
|
|
47856
48043
|
}
|
|
47857
48044
|
if (node.workspace && typeof node.workspace === "string") {
|
|
47858
48045
|
if (!fs10.existsSync(node.workspace) && applyCachedInlineMeshNodeStatus(status, node)) {
|
|
48046
|
+
status.launchReady = !!daemonId && (readStringValue(status.machineStatus) === "online" || isSelfNode);
|
|
47859
48047
|
nodeStatuses.push(status);
|
|
47860
48048
|
continue;
|
|
47861
48049
|
}
|
|
47862
48050
|
try {
|
|
47863
|
-
const gitStatus = await getGitRepoStatus(node.workspace, { timeoutMs: 1e4 });
|
|
48051
|
+
const gitStatus = await getGitRepoStatus(node.workspace, { timeoutMs: 1e4, refreshUpstream: true });
|
|
47864
48052
|
status.git = gitStatus;
|
|
47865
48053
|
if (gitStatus.isGitRepo) {
|
|
47866
48054
|
status.health = deriveMeshNodeHealthFromGit(gitStatus);
|
|
@@ -47876,6 +48064,7 @@ ${block}`);
|
|
|
47876
48064
|
} else {
|
|
47877
48065
|
applyCachedInlineMeshNodeStatus(status, node);
|
|
47878
48066
|
}
|
|
48067
|
+
status.launchReady = !!daemonId && (readStringValue(status.machineStatus) === "online" || isSelfNode);
|
|
47879
48068
|
nodeStatuses.push(status);
|
|
47880
48069
|
}
|
|
47881
48070
|
return {
|
|
@@ -47884,6 +48073,7 @@ ${block}`);
|
|
|
47884
48073
|
meshName: mesh.name,
|
|
47885
48074
|
repoIdentity: mesh.repoIdentity,
|
|
47886
48075
|
defaultBranch: mesh.defaultBranch,
|
|
48076
|
+
refreshedAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
47887
48077
|
nodes: nodeStatuses,
|
|
47888
48078
|
queue: { tasks: queue, summary: queueSummary },
|
|
47889
48079
|
ledger: { entries: ledgerEntries, summary: ledgerSummary }
|
|
@@ -55962,6 +56152,7 @@ async function initDaemonComponents(config2) {
|
|
|
55962
56152
|
sessionHostControl: config2.sessionHostControl,
|
|
55963
56153
|
statusInstanceId: config2.statusInstanceId,
|
|
55964
56154
|
statusVersion: config2.statusVersion,
|
|
56155
|
+
getMeshPeerConnectionStatus: config2.getMeshPeerConnectionStatus,
|
|
55965
56156
|
getCdpLogFn: config2.getCdpLogFn || ((ideType) => LOG.forComponent(`CDP:${ideType}`).asLogFn())
|
|
55966
56157
|
});
|
|
55967
56158
|
poller = new AgentStreamPoller({
|
|
@@ -66054,11 +66245,30 @@ var init_daemon_mesh_manager = __esm({
|
|
|
66054
66245
|
nodeDatachannel = null;
|
|
66055
66246
|
peers = /* @__PURE__ */ new Map();
|
|
66056
66247
|
// Map<targetDaemonId, PeerEntry>
|
|
66248
|
+
peerSnapshots = /* @__PURE__ */ new Map();
|
|
66057
66249
|
pendingRequests = /* @__PURE__ */ new Map();
|
|
66058
66250
|
commandCallback;
|
|
66059
66251
|
p2pFailure(message, command, targetDaemonId) {
|
|
66060
66252
|
return new P2pRelayFailureError(message, { command, targetDaemonId });
|
|
66061
66253
|
}
|
|
66254
|
+
updatePeerSnapshot(targetDaemonId, state, patch = {}) {
|
|
66255
|
+
const previous = this.peerSnapshots.get(targetDaemonId);
|
|
66256
|
+
const now = (/* @__PURE__ */ new Date()).toISOString();
|
|
66257
|
+
this.peerSnapshots.set(targetDaemonId, {
|
|
66258
|
+
perspective: "selected_coordinator",
|
|
66259
|
+
source: "mesh_peer_status",
|
|
66260
|
+
reported: true,
|
|
66261
|
+
state,
|
|
66262
|
+
transport: patch.transport ?? previous?.transport ?? "unknown",
|
|
66263
|
+
reason: patch.reason ?? previous?.reason,
|
|
66264
|
+
lastStateChangeAt: now,
|
|
66265
|
+
lastConnectedAt: patch.lastConnectedAt ?? previous?.lastConnectedAt,
|
|
66266
|
+
lastCommandAt: patch.lastCommandAt ?? previous?.lastCommandAt
|
|
66267
|
+
});
|
|
66268
|
+
}
|
|
66269
|
+
getPeerConnectionStatus(targetDaemonId) {
|
|
66270
|
+
return this.peerSnapshots.get(targetDaemonId) ?? null;
|
|
66271
|
+
}
|
|
66062
66272
|
invalidatePeer(targetDaemonId, reason, options = {}) {
|
|
66063
66273
|
const peer = this.peers.get(targetDaemonId);
|
|
66064
66274
|
if (peer?.commandQueue) {
|
|
@@ -66073,6 +66283,11 @@ var init_daemon_mesh_manager = __esm({
|
|
|
66073
66283
|
pending.reject(this.p2pFailure(reason, pending.command, targetDaemonId));
|
|
66074
66284
|
}
|
|
66075
66285
|
}
|
|
66286
|
+
const snapshotState = peer?.state === "closed" ? "closed" : peer?.state === "disconnected" ? "disconnected" : "failed";
|
|
66287
|
+
this.updatePeerSnapshot(targetDaemonId, snapshotState, {
|
|
66288
|
+
reason,
|
|
66289
|
+
transport: peer?.isRelay === true ? "relay" : peer?.isRelay === false ? "direct" : "unknown"
|
|
66290
|
+
});
|
|
66076
66291
|
if (options.closeResources !== false && peer) {
|
|
66077
66292
|
try {
|
|
66078
66293
|
peer.dataChannel?.close?.();
|
|
@@ -66192,6 +66407,20 @@ var init_daemon_mesh_manager = __esm({
|
|
|
66192
66407
|
if (!peer) {
|
|
66193
66408
|
throw this.p2pFailure("Failed to initiate P2P connection entry", command, targetDaemonId);
|
|
66194
66409
|
}
|
|
66410
|
+
const lastCommandAt = (/* @__PURE__ */ new Date()).toISOString();
|
|
66411
|
+
if (peer.state === "connected") {
|
|
66412
|
+
this.updatePeerSnapshot(targetDaemonId, "connected", {
|
|
66413
|
+
transport: peer.isRelay === true ? "relay" : peer.isRelay === false ? "direct" : "unknown",
|
|
66414
|
+
lastConnectedAt: this.peerSnapshots.get(targetDaemonId)?.lastConnectedAt,
|
|
66415
|
+
lastCommandAt
|
|
66416
|
+
});
|
|
66417
|
+
} else {
|
|
66418
|
+
this.updatePeerSnapshot(targetDaemonId, "connecting", {
|
|
66419
|
+
transport: peer.isRelay === true ? "relay" : peer.isRelay === false ? "direct" : "unknown",
|
|
66420
|
+
reason: "Waiting for mesh DataChannel to open.",
|
|
66421
|
+
lastCommandAt
|
|
66422
|
+
});
|
|
66423
|
+
}
|
|
66195
66424
|
return new Promise((resolve20, reject) => {
|
|
66196
66425
|
const requestId = `req_${Date.now()}_${Math.random().toString(36).slice(2, 8)}`;
|
|
66197
66426
|
const timer = setTimeout(() => {
|
|
@@ -66335,6 +66564,9 @@ var init_daemon_mesh_manager = __esm({
|
|
|
66335
66564
|
remoteDescriptionSet: false
|
|
66336
66565
|
};
|
|
66337
66566
|
this.peers.set(targetDaemonId, entry);
|
|
66567
|
+
this.updatePeerSnapshot(targetDaemonId, "connecting", {
|
|
66568
|
+
reason: isInitiator ? "P2P mesh connection initiated by the selected coordinator." : "Waiting for the remote daemon to finish the mesh DataChannel handshake."
|
|
66569
|
+
});
|
|
66338
66570
|
pc.onLocalDescription((sdp, type2) => {
|
|
66339
66571
|
this.serverConn.sendMeshCommand(targetDaemonId, type2 === "offer" ? "mesh_p2p_offer" : "mesh_p2p_answer", { sdp, type: type2 });
|
|
66340
66572
|
});
|
|
@@ -66345,7 +66577,26 @@ var init_daemon_mesh_manager = __esm({
|
|
|
66345
66577
|
LOG.info("Mesh", `[Mesh] P2P state with ${targetDaemonId.slice(0, 12)}: ${state}`);
|
|
66346
66578
|
if (state === "connected") {
|
|
66347
66579
|
entry.state = "connected";
|
|
66580
|
+
let transport = "unknown";
|
|
66581
|
+
try {
|
|
66582
|
+
const pair = pc.getSelectedCandidatePair?.();
|
|
66583
|
+
if (pair) {
|
|
66584
|
+
const localType = pair.local?.type || "unknown";
|
|
66585
|
+
const remoteType = pair.remote?.type || "unknown";
|
|
66586
|
+
entry.isRelay = localType === "relay" || remoteType === "relay";
|
|
66587
|
+
transport = entry.isRelay ? "relay" : "direct";
|
|
66588
|
+
LOG.info("Mesh", `[Mesh] Candidate pair with ${targetDaemonId.slice(0, 12)}: local=${localType} remote=${remoteType} \u2192 ${transport}`);
|
|
66589
|
+
}
|
|
66590
|
+
} catch {
|
|
66591
|
+
transport = entry.isRelay === true ? "relay" : entry.isRelay === false ? "direct" : "unknown";
|
|
66592
|
+
}
|
|
66593
|
+
this.updatePeerSnapshot(targetDaemonId, "connected", {
|
|
66594
|
+
transport,
|
|
66595
|
+
reason: transport === "relay" ? "Connected over TURN relay." : transport === "direct" ? "Connected directly peer-to-peer." : "Connected, but selected candidate pair details are unavailable.",
|
|
66596
|
+
lastConnectedAt: (/* @__PURE__ */ new Date()).toISOString()
|
|
66597
|
+
});
|
|
66348
66598
|
} else if (state === "failed" || state === "closed" || state === "disconnected") {
|
|
66599
|
+
entry.state = state;
|
|
66349
66600
|
this.invalidatePeer(targetDaemonId, `P2P state changed to ${state}`, { rejectPending: true, closeResources: false });
|
|
66350
66601
|
}
|
|
66351
66602
|
});
|
|
@@ -66363,6 +66614,11 @@ var init_daemon_mesh_manager = __esm({
|
|
|
66363
66614
|
dc.onOpen(() => {
|
|
66364
66615
|
LOG.info("Mesh", `[Mesh] DataChannel OPEN with ${targetDaemonId.slice(0, 12)}`);
|
|
66365
66616
|
entry.state = "connected";
|
|
66617
|
+
this.updatePeerSnapshot(targetDaemonId, "connected", {
|
|
66618
|
+
transport: entry.isRelay === true ? "relay" : entry.isRelay === false ? "direct" : "unknown",
|
|
66619
|
+
reason: entry.isRelay === true ? "Connected over TURN relay." : entry.isRelay === false ? "Connected directly peer-to-peer." : "DataChannel open; transport details not reported yet.",
|
|
66620
|
+
lastConnectedAt: (/* @__PURE__ */ new Date()).toISOString()
|
|
66621
|
+
});
|
|
66366
66622
|
if (entry.commandQueue) {
|
|
66367
66623
|
const queue = entry.commandQueue;
|
|
66368
66624
|
entry.commandQueue = [];
|
|
@@ -66658,7 +66914,7 @@ var init_adhdev_daemon = __esm({
|
|
|
66658
66914
|
init_version();
|
|
66659
66915
|
init_src();
|
|
66660
66916
|
init_runtime_defaults();
|
|
66661
|
-
pkgVersion = resolvePackageVersion({ injectedVersion: "0.9.82-rc.
|
|
66917
|
+
pkgVersion = resolvePackageVersion({ injectedVersion: "0.9.82-rc.9" });
|
|
66662
66918
|
AdhdevDaemon = class _AdhdevDaemon {
|
|
66663
66919
|
localHttpServer = null;
|
|
66664
66920
|
localWss = null;
|
|
@@ -67182,6 +67438,7 @@ ${err?.stack || ""}`);
|
|
|
67182
67438
|
if (!this.meshManager) throw new Error("Mesh manager not initialized");
|
|
67183
67439
|
return this.meshManager.sendCommand(daemonId, command, args);
|
|
67184
67440
|
},
|
|
67441
|
+
getMeshPeerConnectionStatus: (daemonId) => this.meshManager?.getPeerConnectionStatus(daemonId) ?? null,
|
|
67185
67442
|
onStatusChange: () => {
|
|
67186
67443
|
this.invalidateHotChatSnapshotCache();
|
|
67187
67444
|
this.statusReporter?.onStatusChange();
|