adhdev 0.9.82-rc.3 → 0.9.82-rc.30
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 +1465 -716
- package/dist/cli/index.js.map +1 -1
- package/dist/index.js +984 -326
- package/dist/index.js.map +1 -1
- package/package.json +2 -2
- package/vendor/mcp-server/index.js +324 -31
- 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": {
|
|
@@ -3743,6 +3810,36 @@ function getQueuePath(meshId) {
|
|
|
3743
3810
|
const safe = meshId.replace(/[^a-zA-Z0-9_-]/g, "_");
|
|
3744
3811
|
return (0, import_path4.join)(getLedgerDir(), `${safe}.queue.json`);
|
|
3745
3812
|
}
|
|
3813
|
+
function getLockPath(meshId) {
|
|
3814
|
+
const safe = meshId.replace(/[^a-zA-Z0-9_-]/g, "_");
|
|
3815
|
+
return (0, import_path4.join)(getLedgerDir(), `${safe}.queue.lock`);
|
|
3816
|
+
}
|
|
3817
|
+
function withQueueLock(meshId, fn) {
|
|
3818
|
+
const lockPath = getLockPath(meshId);
|
|
3819
|
+
let fd = -1;
|
|
3820
|
+
for (let i = 0; i < 10; i++) {
|
|
3821
|
+
try {
|
|
3822
|
+
fd = (0, import_fs4.openSync)(lockPath, "wx");
|
|
3823
|
+
break;
|
|
3824
|
+
} catch {
|
|
3825
|
+
const deadline = Date.now() + 30;
|
|
3826
|
+
while (Date.now() < deadline) {
|
|
3827
|
+
}
|
|
3828
|
+
}
|
|
3829
|
+
}
|
|
3830
|
+
try {
|
|
3831
|
+
return fn();
|
|
3832
|
+
} finally {
|
|
3833
|
+
if (fd !== -1) try {
|
|
3834
|
+
(0, import_fs4.closeSync)(fd);
|
|
3835
|
+
} catch {
|
|
3836
|
+
}
|
|
3837
|
+
try {
|
|
3838
|
+
(0, import_fs4.unlinkSync)(lockPath);
|
|
3839
|
+
} catch {
|
|
3840
|
+
}
|
|
3841
|
+
}
|
|
3842
|
+
}
|
|
3746
3843
|
function readQueue(meshId) {
|
|
3747
3844
|
const path42 = getQueuePath(meshId);
|
|
3748
3845
|
if (!(0, import_fs4.existsSync)(path42)) return [];
|
|
@@ -3758,20 +3855,22 @@ function writeQueue(meshId, queue) {
|
|
|
3758
3855
|
(0, import_fs4.writeFileSync)(path42, JSON.stringify(queue, null, 2), "utf-8");
|
|
3759
3856
|
}
|
|
3760
3857
|
function enqueueTask(meshId, message, opts) {
|
|
3761
|
-
|
|
3762
|
-
|
|
3763
|
-
|
|
3764
|
-
|
|
3765
|
-
|
|
3766
|
-
|
|
3767
|
-
|
|
3768
|
-
|
|
3769
|
-
|
|
3770
|
-
|
|
3771
|
-
|
|
3772
|
-
|
|
3773
|
-
|
|
3774
|
-
|
|
3858
|
+
return withQueueLock(meshId, () => {
|
|
3859
|
+
const queue = readQueue(meshId);
|
|
3860
|
+
const entry = {
|
|
3861
|
+
id: (0, import_crypto5.randomUUID)(),
|
|
3862
|
+
meshId,
|
|
3863
|
+
message,
|
|
3864
|
+
status: "pending",
|
|
3865
|
+
targetNodeId: opts?.targetNodeId,
|
|
3866
|
+
targetSessionId: opts?.targetSessionId,
|
|
3867
|
+
createdAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
3868
|
+
updatedAt: (/* @__PURE__ */ new Date()).toISOString()
|
|
3869
|
+
};
|
|
3870
|
+
queue.push(entry);
|
|
3871
|
+
writeQueue(meshId, queue);
|
|
3872
|
+
return entry;
|
|
3873
|
+
});
|
|
3775
3874
|
}
|
|
3776
3875
|
function getQueue(meshId, opts) {
|
|
3777
3876
|
let queue = readQueue(meshId);
|
|
@@ -3782,100 +3881,111 @@ function getQueue(meshId, opts) {
|
|
|
3782
3881
|
return queue;
|
|
3783
3882
|
}
|
|
3784
3883
|
function claimNextTask(meshId, nodeId, sessionId) {
|
|
3785
|
-
|
|
3786
|
-
|
|
3787
|
-
|
|
3788
|
-
|
|
3789
|
-
|
|
3790
|
-
|
|
3791
|
-
|
|
3792
|
-
|
|
3793
|
-
|
|
3794
|
-
|
|
3795
|
-
|
|
3796
|
-
|
|
3797
|
-
|
|
3798
|
-
|
|
3799
|
-
|
|
3800
|
-
|
|
3801
|
-
|
|
3802
|
-
|
|
3803
|
-
|
|
3884
|
+
return withQueueLock(meshId, () => {
|
|
3885
|
+
const queue = readQueue(meshId);
|
|
3886
|
+
const hasActiveAssignment = queue.some((q) => q.status === "assigned" && (q.assignedSessionId === sessionId || q.assignedNodeId === nodeId));
|
|
3887
|
+
if (hasActiveAssignment) return null;
|
|
3888
|
+
let targetIdx = queue.findIndex((q) => q.status === "pending" && q.targetSessionId === sessionId);
|
|
3889
|
+
if (targetIdx === -1) {
|
|
3890
|
+
targetIdx = queue.findIndex((q) => q.status === "pending" && q.targetNodeId === nodeId && !q.targetSessionId);
|
|
3891
|
+
}
|
|
3892
|
+
if (targetIdx === -1) {
|
|
3893
|
+
targetIdx = queue.findIndex((q) => q.status === "pending" && !q.targetNodeId && !q.targetSessionId);
|
|
3894
|
+
}
|
|
3895
|
+
if (targetIdx === -1) return null;
|
|
3896
|
+
const entry = queue[targetIdx];
|
|
3897
|
+
entry.status = "assigned";
|
|
3898
|
+
entry.assignedNodeId = nodeId;
|
|
3899
|
+
entry.assignedSessionId = sessionId;
|
|
3900
|
+
entry.dispatchTimestamp = (/* @__PURE__ */ new Date()).toISOString();
|
|
3901
|
+
entry.updatedAt = (/* @__PURE__ */ new Date()).toISOString();
|
|
3902
|
+
writeQueue(meshId, queue);
|
|
3903
|
+
return entry;
|
|
3904
|
+
});
|
|
3804
3905
|
}
|
|
3805
3906
|
function updateTaskStatus(meshId, taskId, status) {
|
|
3806
|
-
|
|
3807
|
-
|
|
3808
|
-
|
|
3809
|
-
|
|
3810
|
-
|
|
3811
|
-
|
|
3812
|
-
|
|
3907
|
+
return withQueueLock(meshId, () => {
|
|
3908
|
+
const queue = readQueue(meshId);
|
|
3909
|
+
const idx = queue.findIndex((q) => q.id === taskId);
|
|
3910
|
+
if (idx === -1) return null;
|
|
3911
|
+
queue[idx].status = status;
|
|
3912
|
+
queue[idx].updatedAt = (/* @__PURE__ */ new Date()).toISOString();
|
|
3913
|
+
writeQueue(meshId, queue);
|
|
3914
|
+
return queue[idx];
|
|
3915
|
+
});
|
|
3813
3916
|
}
|
|
3814
3917
|
function recordTaskAutoLaunch(meshId, taskId, autoLaunch) {
|
|
3815
|
-
|
|
3816
|
-
|
|
3817
|
-
|
|
3818
|
-
|
|
3819
|
-
|
|
3820
|
-
...autoLaunch,
|
|
3821
|
-
updatedAt
|
|
3822
|
-
|
|
3823
|
-
|
|
3824
|
-
|
|
3825
|
-
return queue[idx];
|
|
3918
|
+
return withQueueLock(meshId, () => {
|
|
3919
|
+
const queue = readQueue(meshId);
|
|
3920
|
+
const idx = queue.findIndex((q) => q.id === taskId);
|
|
3921
|
+
if (idx === -1) return null;
|
|
3922
|
+
const now = (/* @__PURE__ */ new Date()).toISOString();
|
|
3923
|
+
queue[idx].autoLaunch = { ...autoLaunch, updatedAt: now };
|
|
3924
|
+
queue[idx].updatedAt = now;
|
|
3925
|
+
writeQueue(meshId, queue);
|
|
3926
|
+
return queue[idx];
|
|
3927
|
+
});
|
|
3826
3928
|
}
|
|
3827
3929
|
function cancelTask(meshId, taskId, opts) {
|
|
3828
|
-
|
|
3829
|
-
|
|
3830
|
-
|
|
3831
|
-
|
|
3832
|
-
|
|
3833
|
-
|
|
3834
|
-
|
|
3835
|
-
|
|
3836
|
-
|
|
3837
|
-
|
|
3930
|
+
return withQueueLock(meshId, () => {
|
|
3931
|
+
const queue = readQueue(meshId);
|
|
3932
|
+
const idx = queue.findIndex((q) => q.id === taskId);
|
|
3933
|
+
if (idx === -1) return null;
|
|
3934
|
+
const now = (/* @__PURE__ */ new Date()).toISOString();
|
|
3935
|
+
queue[idx].status = "cancelled";
|
|
3936
|
+
queue[idx].updatedAt = now;
|
|
3937
|
+
queue[idx].cancelledAt = now;
|
|
3938
|
+
if (opts?.reason) queue[idx].cancelReason = opts.reason;
|
|
3939
|
+
writeQueue(meshId, queue);
|
|
3940
|
+
return queue[idx];
|
|
3941
|
+
});
|
|
3838
3942
|
}
|
|
3839
3943
|
function requeueTask(meshId, taskId, opts) {
|
|
3840
|
-
|
|
3841
|
-
|
|
3842
|
-
|
|
3843
|
-
|
|
3844
|
-
|
|
3845
|
-
|
|
3846
|
-
|
|
3847
|
-
|
|
3848
|
-
|
|
3849
|
-
|
|
3850
|
-
|
|
3851
|
-
|
|
3852
|
-
|
|
3853
|
-
|
|
3854
|
-
|
|
3855
|
-
|
|
3856
|
-
|
|
3857
|
-
|
|
3858
|
-
|
|
3859
|
-
|
|
3860
|
-
|
|
3861
|
-
|
|
3862
|
-
|
|
3863
|
-
|
|
3864
|
-
|
|
3865
|
-
|
|
3866
|
-
|
|
3944
|
+
return withQueueLock(meshId, () => {
|
|
3945
|
+
const queue = readQueue(meshId);
|
|
3946
|
+
const idx = queue.findIndex((q) => q.id === taskId);
|
|
3947
|
+
if (idx === -1) return null;
|
|
3948
|
+
const entry = queue[idx];
|
|
3949
|
+
const now = (/* @__PURE__ */ new Date()).toISOString();
|
|
3950
|
+
entry.status = "pending";
|
|
3951
|
+
delete entry.assignedNodeId;
|
|
3952
|
+
delete entry.assignedSessionId;
|
|
3953
|
+
delete entry.cancelledAt;
|
|
3954
|
+
delete entry.cancelReason;
|
|
3955
|
+
if (opts?.clearTargetNode) delete entry.targetNodeId;
|
|
3956
|
+
if (typeof opts?.targetNodeId === "string") entry.targetNodeId = opts.targetNodeId;
|
|
3957
|
+
if (opts?.clearTargetSession !== false) delete entry.targetSessionId;
|
|
3958
|
+
if (typeof opts?.targetSessionId === "string") entry.targetSessionId = opts.targetSessionId;
|
|
3959
|
+
entry.updatedAt = now;
|
|
3960
|
+
entry.requeuedAt = now;
|
|
3961
|
+
entry.requeueCount = (entry.requeueCount || 0) + 1;
|
|
3962
|
+
if (opts?.reason) entry.requeueReason = opts.reason;
|
|
3963
|
+
writeQueue(meshId, queue);
|
|
3964
|
+
return entry;
|
|
3965
|
+
});
|
|
3966
|
+
}
|
|
3967
|
+
function updateSessionTaskStatus(meshId, sessionId, status, opts) {
|
|
3968
|
+
return withQueueLock(meshId, () => {
|
|
3969
|
+
const queue = readQueue(meshId);
|
|
3970
|
+
const occurredAtTime = opts?.occurredAt ? new Date(opts.occurredAt).getTime() : Number.NaN;
|
|
3971
|
+
const hasOccurredAt = Number.isFinite(occurredAtTime);
|
|
3972
|
+
let bestIdx = -1;
|
|
3973
|
+
let bestTime = 0;
|
|
3974
|
+
for (let i = queue.length - 1; i >= 0; i--) {
|
|
3975
|
+
if (queue[i].assignedSessionId !== sessionId || queue[i].status !== "assigned") continue;
|
|
3867
3976
|
const time3 = new Date(queue[i].dispatchTimestamp || queue[i].updatedAt).getTime();
|
|
3977
|
+
if (hasOccurredAt && Number.isFinite(time3) && time3 > occurredAtTime) continue;
|
|
3868
3978
|
if (time3 > bestTime) {
|
|
3869
3979
|
bestTime = time3;
|
|
3870
3980
|
bestIdx = i;
|
|
3871
3981
|
}
|
|
3872
3982
|
}
|
|
3873
|
-
|
|
3874
|
-
|
|
3875
|
-
|
|
3876
|
-
|
|
3877
|
-
|
|
3878
|
-
|
|
3983
|
+
if (bestIdx === -1) return null;
|
|
3984
|
+
queue[bestIdx].status = status;
|
|
3985
|
+
queue[bestIdx].updatedAt = (/* @__PURE__ */ new Date()).toISOString();
|
|
3986
|
+
writeQueue(meshId, queue);
|
|
3987
|
+
return queue[bestIdx];
|
|
3988
|
+
});
|
|
3879
3989
|
}
|
|
3880
3990
|
function getMeshQueueStats(meshId) {
|
|
3881
3991
|
const queue = readQueue(meshId);
|
|
@@ -4279,18 +4389,75 @@ __export(mesh_events_exports, {
|
|
|
4279
4389
|
drainPendingMeshCoordinatorEvents: () => drainPendingMeshCoordinatorEvents,
|
|
4280
4390
|
getPendingMeshCoordinatorEvents: () => getPendingMeshCoordinatorEvents,
|
|
4281
4391
|
handleMeshForwardEvent: () => handleMeshForwardEvent,
|
|
4392
|
+
queuePendingMeshCoordinatorEvent: () => queuePendingMeshCoordinatorEvent,
|
|
4282
4393
|
setupMeshEventForwarding: () => setupMeshEventForwarding,
|
|
4283
4394
|
triggerMeshQueue: () => triggerMeshQueue,
|
|
4284
4395
|
tryAssignQueueTask: () => tryAssignQueueTask
|
|
4285
4396
|
});
|
|
4286
|
-
function
|
|
4287
|
-
|
|
4397
|
+
function sweepExpiredRemoteIdleSessions() {
|
|
4398
|
+
const now = Date.now();
|
|
4399
|
+
for (const [key, session] of remoteIdleSessions) {
|
|
4400
|
+
if (session.expiresAt <= now) remoteIdleSessions.delete(key);
|
|
4401
|
+
}
|
|
4402
|
+
}
|
|
4403
|
+
function getPendingEventsPath(meshId) {
|
|
4404
|
+
const safe = meshId.replace(/[^a-zA-Z0-9_-]/g, "_");
|
|
4405
|
+
return (0, import_path5.join)(getLedgerDir(), `${safe}.pending-events.jsonl`);
|
|
4288
4406
|
}
|
|
4289
|
-
function
|
|
4290
|
-
|
|
4407
|
+
function queuePendingMeshCoordinatorEvent(event) {
|
|
4408
|
+
try {
|
|
4409
|
+
(0, import_fs6.appendFileSync)(getPendingEventsPath(event.meshId), JSON.stringify(event) + "\n", "utf-8");
|
|
4410
|
+
return true;
|
|
4411
|
+
} catch (e) {
|
|
4412
|
+
LOG.warn("MeshEvents", `Failed to persist pending coordinator event: ${e?.message || e}`);
|
|
4413
|
+
return false;
|
|
4414
|
+
}
|
|
4291
4415
|
}
|
|
4292
|
-
function
|
|
4293
|
-
|
|
4416
|
+
function drainPendingMeshCoordinatorEvents(meshId) {
|
|
4417
|
+
if (!meshId) return [];
|
|
4418
|
+
const path42 = getPendingEventsPath(meshId);
|
|
4419
|
+
if (!(0, import_fs6.existsSync)(path42)) return [];
|
|
4420
|
+
try {
|
|
4421
|
+
const raw = (0, import_fs6.readFileSync)(path42, "utf-8");
|
|
4422
|
+
try {
|
|
4423
|
+
(0, import_fs6.unlinkSync)(path42);
|
|
4424
|
+
} catch {
|
|
4425
|
+
}
|
|
4426
|
+
return raw.split("\n").filter(Boolean).flatMap((line) => {
|
|
4427
|
+
try {
|
|
4428
|
+
return [JSON.parse(line)];
|
|
4429
|
+
} catch {
|
|
4430
|
+
return [];
|
|
4431
|
+
}
|
|
4432
|
+
});
|
|
4433
|
+
} catch {
|
|
4434
|
+
return [];
|
|
4435
|
+
}
|
|
4436
|
+
}
|
|
4437
|
+
function getPendingMeshCoordinatorEvents(meshId) {
|
|
4438
|
+
if (!meshId) return [];
|
|
4439
|
+
const path42 = getPendingEventsPath(meshId);
|
|
4440
|
+
if (!(0, import_fs6.existsSync)(path42)) return [];
|
|
4441
|
+
try {
|
|
4442
|
+
const raw = (0, import_fs6.readFileSync)(path42, "utf-8");
|
|
4443
|
+
return raw.split("\n").filter(Boolean).flatMap((line) => {
|
|
4444
|
+
try {
|
|
4445
|
+
return [JSON.parse(line)];
|
|
4446
|
+
} catch {
|
|
4447
|
+
return [];
|
|
4448
|
+
}
|
|
4449
|
+
});
|
|
4450
|
+
} catch {
|
|
4451
|
+
return [];
|
|
4452
|
+
}
|
|
4453
|
+
}
|
|
4454
|
+
function clearPendingMeshCoordinatorEvents(meshId) {
|
|
4455
|
+
if (!meshId) return;
|
|
4456
|
+
const path42 = getPendingEventsPath(meshId);
|
|
4457
|
+
if ((0, import_fs6.existsSync)(path42)) try {
|
|
4458
|
+
(0, import_fs6.unlinkSync)(path42);
|
|
4459
|
+
} catch {
|
|
4460
|
+
}
|
|
4294
4461
|
}
|
|
4295
4462
|
function readNonEmptyString(value) {
|
|
4296
4463
|
return typeof value === "string" && value.trim() ? value.trim() : "";
|
|
@@ -4336,6 +4503,38 @@ function shouldSuppressIntentionalCleanupStop(args) {
|
|
|
4336
4503
|
if (isIntentionalCleanupStopMetadata(args.metadataEvent)) return true;
|
|
4337
4504
|
return hasRecentIntentionalCleanupStop(args.meshId, args.sessionId, args.nodeId);
|
|
4338
4505
|
}
|
|
4506
|
+
function readEventTimestamp(value) {
|
|
4507
|
+
if (typeof value === "number" && Number.isFinite(value)) return value;
|
|
4508
|
+
if (typeof value === "string" && value.trim()) {
|
|
4509
|
+
const numeric = Number(value);
|
|
4510
|
+
if (Number.isFinite(numeric)) return numeric;
|
|
4511
|
+
const parsed = Date.parse(value);
|
|
4512
|
+
if (Number.isFinite(parsed)) return parsed;
|
|
4513
|
+
}
|
|
4514
|
+
return null;
|
|
4515
|
+
}
|
|
4516
|
+
function buildMeshCompletionFingerprint(args) {
|
|
4517
|
+
const timestampPart = Number.isFinite(args.timestamp) ? String(args.timestamp) : readNonEmptyString(args.finalSummary).slice(0, 200);
|
|
4518
|
+
return [
|
|
4519
|
+
args.meshId,
|
|
4520
|
+
args.event,
|
|
4521
|
+
args.sessionId,
|
|
4522
|
+
args.providerType || "",
|
|
4523
|
+
args.providerSessionId || "",
|
|
4524
|
+
timestampPart
|
|
4525
|
+
].join("::");
|
|
4526
|
+
}
|
|
4527
|
+
function isDuplicateMeshCompletionEvent(args) {
|
|
4528
|
+
const fingerprint = buildMeshCompletionFingerprint(args);
|
|
4529
|
+
if (!fingerprint) return false;
|
|
4530
|
+
const now = Date.now();
|
|
4531
|
+
for (const [key, seenAt] of recentCompletionFingerprints.entries()) {
|
|
4532
|
+
if (now - seenAt > RECENT_COMPLETION_FINGERPRINT_TTL_MS) recentCompletionFingerprints.delete(key);
|
|
4533
|
+
}
|
|
4534
|
+
if (recentCompletionFingerprints.has(fingerprint)) return true;
|
|
4535
|
+
recentCompletionFingerprints.set(fingerprint, now);
|
|
4536
|
+
return false;
|
|
4537
|
+
}
|
|
4339
4538
|
function tryAssignQueueTask(components, meshId, nodeId, sessionId, providerType) {
|
|
4340
4539
|
const task = claimNextTask(meshId, nodeId, sessionId);
|
|
4341
4540
|
if (!task) {
|
|
@@ -4354,7 +4553,16 @@ function tryAssignQueueTask(components, meshId, nodeId, sessionId, providerType)
|
|
|
4354
4553
|
message: task.message
|
|
4355
4554
|
}).catch((e) => {
|
|
4356
4555
|
LOG.error("MeshQueue", `Failed to dispatch task via P2P to remote node ${nodeId}: ${e?.message}`);
|
|
4357
|
-
updateTaskStatus(meshId, task.id, "
|
|
4556
|
+
updateTaskStatus(meshId, task.id, "pending");
|
|
4557
|
+
try {
|
|
4558
|
+
appendLedgerEntry(meshId, {
|
|
4559
|
+
kind: "dispatch_failed",
|
|
4560
|
+
nodeId,
|
|
4561
|
+
sessionId,
|
|
4562
|
+
payload: { taskId: task.id, error: e?.message, retryable: true }
|
|
4563
|
+
});
|
|
4564
|
+
} catch {
|
|
4565
|
+
}
|
|
4358
4566
|
});
|
|
4359
4567
|
return true;
|
|
4360
4568
|
}
|
|
@@ -4688,18 +4896,36 @@ function injectMeshSystemMessage(components, args) {
|
|
|
4688
4896
|
LOG.info("MeshEvents", `Suppressed ${args.event} for intentionally cleanup-stopped session ${eventSessionId || "(unknown session)"}`);
|
|
4689
4897
|
return { success: true, forwarded: 0, suppressed: true, intentionalCleanupStop: true };
|
|
4690
4898
|
}
|
|
4899
|
+
const eventTimestamp = readEventTimestamp(args.metadataEvent.timestamp);
|
|
4900
|
+
if (args.event === "agent:generating_completed" && eventSessionId) {
|
|
4901
|
+
const duplicateCompletion = isDuplicateMeshCompletionEvent({
|
|
4902
|
+
meshId: args.meshId,
|
|
4903
|
+
event: args.event,
|
|
4904
|
+
sessionId: eventSessionId,
|
|
4905
|
+
providerType: readNonEmptyString(args.metadataEvent.providerType) || void 0,
|
|
4906
|
+
providerSessionId: readNonEmptyString(args.metadataEvent.providerSessionId) || void 0,
|
|
4907
|
+
timestamp: eventTimestamp,
|
|
4908
|
+
finalSummary: readNonEmptyString(args.metadataEvent.finalSummary) || void 0
|
|
4909
|
+
});
|
|
4910
|
+
if (duplicateCompletion) {
|
|
4911
|
+
LOG.info("MeshEvents", `Suppressed duplicate completion for mesh ${args.meshId} session ${eventSessionId}`);
|
|
4912
|
+
return { success: true, forwarded: 0, suppressed: true, duplicateCompletion: true };
|
|
4913
|
+
}
|
|
4914
|
+
}
|
|
4691
4915
|
let completedTaskForLedger = null;
|
|
4692
4916
|
if (args.event === "agent:generating_completed") {
|
|
4693
4917
|
const sessionId = resolveEventSessionId(args.metadataEvent, args.sourceInstanceId);
|
|
4694
4918
|
const nodeId = readNonEmptyString(args.nodeId) || readNonEmptyString(args.metadataEvent.meshNodeId);
|
|
4695
4919
|
const providerType = readNonEmptyString(args.metadataEvent.providerType);
|
|
4696
4920
|
if (sessionId) {
|
|
4697
|
-
const completedTask = updateSessionTaskStatus(args.meshId, sessionId, "completed"
|
|
4921
|
+
const completedTask = updateSessionTaskStatus(args.meshId, sessionId, "completed", {
|
|
4922
|
+
occurredAt: eventTimestamp !== null ? new Date(eventTimestamp).toISOString() : void 0
|
|
4923
|
+
});
|
|
4698
4924
|
completedTaskForLedger = completedTask ? { id: completedTask.id } : null;
|
|
4699
4925
|
if (nodeId && providerType) {
|
|
4700
|
-
|
|
4926
|
+
setImmediate(() => {
|
|
4701
4927
|
tryAssignQueueTask(components, args.meshId, nodeId, sessionId, providerType);
|
|
4702
|
-
}
|
|
4928
|
+
});
|
|
4703
4929
|
}
|
|
4704
4930
|
}
|
|
4705
4931
|
} else if (args.event === "agent:ready") {
|
|
@@ -4737,13 +4963,17 @@ function injectMeshSystemMessage(components, args) {
|
|
|
4737
4963
|
}
|
|
4738
4964
|
}
|
|
4739
4965
|
if (sessionId && nodeId && providerType) {
|
|
4740
|
-
|
|
4741
|
-
|
|
4966
|
+
sweepExpiredRemoteIdleSessions();
|
|
4967
|
+
remoteIdleSessions.set(`${nodeId}:${sessionId}`, {
|
|
4968
|
+
nodeId,
|
|
4969
|
+
sessionId,
|
|
4970
|
+
providerType,
|
|
4971
|
+
expiresAt: Date.now() + REMOTE_IDLE_SESSION_TTL_MS
|
|
4972
|
+
});
|
|
4973
|
+
setImmediate(() => {
|
|
4742
4974
|
const assigned = tryAssignQueueTask(components, args.meshId, nodeId, sessionId, providerType);
|
|
4743
|
-
if (assigned) {
|
|
4744
|
-
|
|
4745
|
-
}
|
|
4746
|
-
}, 500);
|
|
4975
|
+
if (assigned) remoteIdleSessions.delete(`${nodeId}:${sessionId}`);
|
|
4976
|
+
});
|
|
4747
4977
|
}
|
|
4748
4978
|
} else if (args.event === "agent:generating_started") {
|
|
4749
4979
|
const sessionId = resolveEventSessionId(args.metadataEvent, args.sourceInstanceId);
|
|
@@ -4854,17 +5084,18 @@ function injectMeshSystemMessage(components, args) {
|
|
|
4854
5084
|
return true;
|
|
4855
5085
|
});
|
|
4856
5086
|
if (coordinatorInstances.length === 0) {
|
|
4857
|
-
if (
|
|
4858
|
-
|
|
4859
|
-
|
|
4860
|
-
|
|
4861
|
-
|
|
4862
|
-
|
|
4863
|
-
|
|
4864
|
-
|
|
4865
|
-
}
|
|
4866
|
-
|
|
4867
|
-
|
|
5087
|
+
if (queuePendingMeshCoordinatorEvent({
|
|
5088
|
+
event: args.event,
|
|
5089
|
+
meshId: args.meshId,
|
|
5090
|
+
nodeLabel: args.nodeLabel,
|
|
5091
|
+
nodeId: args.nodeId || void 0,
|
|
5092
|
+
workspace: readNonEmptyString(args.metadataEvent.workspace),
|
|
5093
|
+
metadataEvent: {
|
|
5094
|
+
...args.metadataEvent,
|
|
5095
|
+
...recoveryContext ? { recoveryContext } : {}
|
|
5096
|
+
},
|
|
5097
|
+
queuedAt: Date.now()
|
|
5098
|
+
})) {
|
|
4868
5099
|
LOG.info("MeshEvents", `Queued ${args.event} for MCP coordinator (mesh ${args.meshId})`);
|
|
4869
5100
|
}
|
|
4870
5101
|
return { success: true, forwarded: 0 };
|
|
@@ -4903,6 +5134,7 @@ function handleMeshForwardEvent(components, payload) {
|
|
|
4903
5134
|
providerType: readNonEmptyString(payload.providerType),
|
|
4904
5135
|
providerSessionId: readNonEmptyString(payload.providerSessionId),
|
|
4905
5136
|
finalSummary: readNonEmptyString(payload.finalSummary) || readNonEmptyString(payload.summary),
|
|
5137
|
+
...payload.timestamp !== void 0 ? { timestamp: payload.timestamp } : {},
|
|
4906
5138
|
intentional: payload.intentional === true,
|
|
4907
5139
|
intentionalStop: payload.intentionalStop === true,
|
|
4908
5140
|
operatorCleanup: payload.operatorCleanup === true,
|
|
@@ -4945,19 +5177,20 @@ function setupMeshEventForwarding(components) {
|
|
|
4945
5177
|
});
|
|
4946
5178
|
});
|
|
4947
5179
|
}
|
|
4948
|
-
var
|
|
5180
|
+
var import_fs6, import_path5, REMOTE_IDLE_SESSION_TTL_MS, remoteIdleSessions, MESH_COORDINATOR_EVENTS, EVENT_TO_LEDGER_KIND, INTENTIONAL_CLEANUP_STOP_SUPPRESSION_MS, RECENT_COMPLETION_FINGERPRINT_TTL_MS, recentCompletionFingerprints, autoLaunchInProgress, autoLaunchCooldownUntil, AUTO_LAUNCH_COOLDOWN_MS;
|
|
4949
5181
|
var init_mesh_events = __esm({
|
|
4950
5182
|
"../../oss/packages/daemon-core/src/mesh/mesh-events.ts"() {
|
|
4951
5183
|
"use strict";
|
|
5184
|
+
import_fs6 = require("fs");
|
|
5185
|
+
import_path5 = require("path");
|
|
4952
5186
|
init_config();
|
|
4953
5187
|
init_mesh_config();
|
|
4954
5188
|
init_cli_detector();
|
|
4955
5189
|
init_logger();
|
|
4956
5190
|
init_mesh_ledger();
|
|
4957
5191
|
init_mesh_work_queue();
|
|
5192
|
+
REMOTE_IDLE_SESSION_TTL_MS = 5 * 60 * 1e3;
|
|
4958
5193
|
remoteIdleSessions = /* @__PURE__ */ new Map();
|
|
4959
|
-
MAX_PENDING_EVENTS = 50;
|
|
4960
|
-
pendingMeshCoordinatorEvents = [];
|
|
4961
5194
|
MESH_COORDINATOR_EVENTS = /* @__PURE__ */ new Set([
|
|
4962
5195
|
"agent:generating_started",
|
|
4963
5196
|
"agent:generating_completed",
|
|
@@ -4973,6 +5206,8 @@ var init_mesh_events = __esm({
|
|
|
4973
5206
|
"monitor:long_generating": "task_stalled"
|
|
4974
5207
|
};
|
|
4975
5208
|
INTENTIONAL_CLEANUP_STOP_SUPPRESSION_MS = 30 * 60 * 1e3;
|
|
5209
|
+
RECENT_COMPLETION_FINGERPRINT_TTL_MS = 10 * 60 * 1e3;
|
|
5210
|
+
recentCompletionFingerprints = /* @__PURE__ */ new Map();
|
|
4976
5211
|
autoLaunchInProgress = /* @__PURE__ */ new Set();
|
|
4977
5212
|
autoLaunchCooldownUntil = /* @__PURE__ */ new Map();
|
|
4978
5213
|
AUTO_LAUNCH_COOLDOWN_MS = 5e3;
|
|
@@ -5100,7 +5335,7 @@ function isPlainObject2(value) {
|
|
|
5100
5335
|
return !!value && typeof value === "object" && !Array.isArray(value);
|
|
5101
5336
|
}
|
|
5102
5337
|
function getStatePath() {
|
|
5103
|
-
return (0,
|
|
5338
|
+
return (0, import_path6.join)(getConfigDir(), "state.json");
|
|
5104
5339
|
}
|
|
5105
5340
|
function normalizeState(raw) {
|
|
5106
5341
|
const parsed = isPlainObject2(raw) ? raw : {};
|
|
@@ -5136,11 +5371,11 @@ function normalizeState(raw) {
|
|
|
5136
5371
|
}
|
|
5137
5372
|
function loadState() {
|
|
5138
5373
|
const statePath = getStatePath();
|
|
5139
|
-
if (!(0,
|
|
5374
|
+
if (!(0, import_fs7.existsSync)(statePath)) {
|
|
5140
5375
|
return { ...DEFAULT_STATE };
|
|
5141
5376
|
}
|
|
5142
5377
|
try {
|
|
5143
|
-
const raw = (0,
|
|
5378
|
+
const raw = (0, import_fs7.readFileSync)(statePath, "utf-8");
|
|
5144
5379
|
return normalizeState(JSON.parse(raw));
|
|
5145
5380
|
} catch {
|
|
5146
5381
|
return { ...DEFAULT_STATE };
|
|
@@ -5149,17 +5384,17 @@ function loadState() {
|
|
|
5149
5384
|
function saveState(state) {
|
|
5150
5385
|
const statePath = getStatePath();
|
|
5151
5386
|
const normalized = normalizeState(state);
|
|
5152
|
-
(0,
|
|
5387
|
+
(0, import_fs7.writeFileSync)(statePath, JSON.stringify(normalized, null, 2), { encoding: "utf-8", mode: 384 });
|
|
5153
5388
|
}
|
|
5154
5389
|
function resetState() {
|
|
5155
5390
|
saveState({ ...DEFAULT_STATE });
|
|
5156
5391
|
}
|
|
5157
|
-
var
|
|
5392
|
+
var import_fs7, import_path6, DEFAULT_STATE;
|
|
5158
5393
|
var init_state_store = __esm({
|
|
5159
5394
|
"../../oss/packages/daemon-core/src/config/state-store.ts"() {
|
|
5160
5395
|
"use strict";
|
|
5161
|
-
|
|
5162
|
-
|
|
5396
|
+
import_fs7 = require("fs");
|
|
5397
|
+
import_path6 = require("path");
|
|
5163
5398
|
init_config();
|
|
5164
5399
|
DEFAULT_STATE = {
|
|
5165
5400
|
recentActivity: [],
|
|
@@ -5192,7 +5427,7 @@ function findCliCommand(command) {
|
|
|
5192
5427
|
if (path10.isAbsolute(trimmed) || trimmed.includes("/") || trimmed.includes("\\") || trimmed.startsWith("~")) {
|
|
5193
5428
|
const candidate = trimmed.startsWith("~") ? path10.join((0, import_os2.homedir)(), trimmed.slice(1)) : trimmed;
|
|
5194
5429
|
const resolved = path10.isAbsolute(candidate) ? candidate : path10.resolve(candidate);
|
|
5195
|
-
return (0,
|
|
5430
|
+
return (0, import_fs8.existsSync)(resolved) ? resolved : null;
|
|
5196
5431
|
}
|
|
5197
5432
|
try {
|
|
5198
5433
|
const result = (0, import_child_process2.execSync)(
|
|
@@ -5223,9 +5458,9 @@ function checkPathExists(paths) {
|
|
|
5223
5458
|
if (normalized.includes("*")) {
|
|
5224
5459
|
const username = home.split(/[\\/]/).pop() || "";
|
|
5225
5460
|
const resolved = normalized.replace("*", username);
|
|
5226
|
-
if ((0,
|
|
5461
|
+
if ((0, import_fs8.existsSync)(resolved)) return resolved;
|
|
5227
5462
|
} else {
|
|
5228
|
-
if ((0,
|
|
5463
|
+
if ((0, import_fs8.existsSync)(normalized)) return normalized;
|
|
5229
5464
|
}
|
|
5230
5465
|
}
|
|
5231
5466
|
return null;
|
|
@@ -5239,7 +5474,7 @@ async function detectIDEs(providerLoader) {
|
|
|
5239
5474
|
let resolvedCli = cliPath;
|
|
5240
5475
|
if (!resolvedCli && appPath && os32 === "darwin") {
|
|
5241
5476
|
const bundledCli = `${appPath}/Contents/Resources/app/bin/${def.cli}`;
|
|
5242
|
-
if ((0,
|
|
5477
|
+
if ((0, import_fs8.existsSync)(bundledCli)) resolvedCli = bundledCli;
|
|
5243
5478
|
}
|
|
5244
5479
|
if (!resolvedCli && appPath && os32 === "win32") {
|
|
5245
5480
|
const { dirname: dirname13 } = await import("path");
|
|
@@ -5252,7 +5487,7 @@ async function detectIDEs(providerLoader) {
|
|
|
5252
5487
|
`${appDir}\\\\resources\\\\app\\\\bin\\\\${def.cli}.cmd`
|
|
5253
5488
|
];
|
|
5254
5489
|
for (const c of candidates) {
|
|
5255
|
-
if ((0,
|
|
5490
|
+
if ((0, import_fs8.existsSync)(c)) {
|
|
5256
5491
|
resolvedCli = c;
|
|
5257
5492
|
break;
|
|
5258
5493
|
}
|
|
@@ -5273,12 +5508,12 @@ async function detectIDEs(providerLoader) {
|
|
|
5273
5508
|
}
|
|
5274
5509
|
return results;
|
|
5275
5510
|
}
|
|
5276
|
-
var import_child_process2,
|
|
5511
|
+
var import_child_process2, import_fs8, import_os2, path10, BUILTIN_IDE_DEFINITIONS, registeredIDEs;
|
|
5277
5512
|
var init_ide_detector = __esm({
|
|
5278
5513
|
"../../oss/packages/daemon-core/src/detection/ide-detector.ts"() {
|
|
5279
5514
|
"use strict";
|
|
5280
5515
|
import_child_process2 = require("child_process");
|
|
5281
|
-
|
|
5516
|
+
import_fs8 = require("fs");
|
|
5282
5517
|
import_os2 = require("os");
|
|
5283
5518
|
path10 = __toESM(require("path"));
|
|
5284
5519
|
BUILTIN_IDE_DEFINITIONS = [];
|
|
@@ -7199,7 +7434,7 @@ var init_status_monitor = __esm({
|
|
|
7199
7434
|
});
|
|
7200
7435
|
|
|
7201
7436
|
// ../../oss/packages/daemon-core/src/providers/chat-message-normalization.ts
|
|
7202
|
-
function extractFinalSummaryFromMessages(messages, maxChars =
|
|
7437
|
+
function extractFinalSummaryFromMessages(messages, maxChars = DEFAULT_FINAL_SUMMARY_MAX_CHARS) {
|
|
7203
7438
|
if (!Array.isArray(messages) || messages.length === 0) return "";
|
|
7204
7439
|
for (let i = messages.length - 1; i >= 0; i--) {
|
|
7205
7440
|
const msg = messages[i];
|
|
@@ -7501,11 +7736,12 @@ function filterInternalChatMessages(messages) {
|
|
|
7501
7736
|
function filterChatMessagesByVisibility(messages, surface) {
|
|
7502
7737
|
return (Array.isArray(messages) ? messages : []).filter((message) => classifyChatMessageVisibility(message).surface === surface);
|
|
7503
7738
|
}
|
|
7504
|
-
var BUILTIN_CHAT_MESSAGE_KINDS, CHAT_MESSAGE_VISIBILITIES, CHAT_MESSAGE_TRANSCRIPT_VISIBILITIES, CHAT_MESSAGE_AUDIENCES, CHAT_MESSAGE_SOURCES, CHAT_MESSAGE_ACTIVITY_SOURCES, CHAT_MESSAGE_INTERNAL_SOURCES, KNOWN_CHAT_MESSAGE_KINDS, CHAT_MESSAGE_KIND_ALIASES, EXPLICIT_HIDDEN_VISIBILITIES, EXPLICIT_VISIBLE_VISIBILITIES, HIDDEN_AUDIENCES, ACTIVITY_SOURCE_SET, INTERNAL_SOURCE_SET;
|
|
7739
|
+
var DEFAULT_FINAL_SUMMARY_MAX_CHARS, BUILTIN_CHAT_MESSAGE_KINDS, CHAT_MESSAGE_VISIBILITIES, CHAT_MESSAGE_TRANSCRIPT_VISIBILITIES, CHAT_MESSAGE_AUDIENCES, CHAT_MESSAGE_SOURCES, CHAT_MESSAGE_ACTIVITY_SOURCES, CHAT_MESSAGE_INTERNAL_SOURCES, KNOWN_CHAT_MESSAGE_KINDS, CHAT_MESSAGE_KIND_ALIASES, EXPLICIT_HIDDEN_VISIBILITIES, EXPLICIT_VISIBLE_VISIBILITIES, HIDDEN_AUDIENCES, ACTIVITY_SOURCE_SET, INTERNAL_SOURCE_SET;
|
|
7505
7740
|
var init_chat_message_normalization = __esm({
|
|
7506
7741
|
"../../oss/packages/daemon-core/src/providers/chat-message-normalization.ts"() {
|
|
7507
7742
|
"use strict";
|
|
7508
7743
|
init_contracts();
|
|
7744
|
+
DEFAULT_FINAL_SUMMARY_MAX_CHARS = 4e3;
|
|
7509
7745
|
BUILTIN_CHAT_MESSAGE_KINDS = ["standard", "thought", "tool", "terminal", "system"];
|
|
7510
7746
|
CHAT_MESSAGE_VISIBILITIES = ["user", "debug", "internal", "hidden"];
|
|
7511
7747
|
CHAT_MESSAGE_TRANSCRIPT_VISIBILITIES = ["visible", "chat", "user", "debug", "internal", "hidden"];
|
|
@@ -37725,7 +37961,7 @@ function commandExists(command) {
|
|
|
37725
37961
|
const trimmed = command.trim();
|
|
37726
37962
|
if (!trimmed) return false;
|
|
37727
37963
|
if (isExplicitCommand(trimmed)) {
|
|
37728
|
-
return (0,
|
|
37964
|
+
return (0, import_fs9.existsSync)(expandExecutable(trimmed));
|
|
37729
37965
|
}
|
|
37730
37966
|
try {
|
|
37731
37967
|
(0, import_child_process6.execFileSync)(process.platform === "win32" ? "where" : "which", [trimmed], {
|
|
@@ -37746,10 +37982,10 @@ function hasCliArg(args, flag) {
|
|
|
37746
37982
|
}
|
|
37747
37983
|
function ensureEmptyDelegatedMcpConfig(workspace) {
|
|
37748
37984
|
const baseDir = path19.join(os16.tmpdir(), "adhdev-delegated-agent-empty-mcp");
|
|
37749
|
-
(0,
|
|
37985
|
+
(0, import_fs9.mkdirSync)(baseDir, { recursive: true });
|
|
37750
37986
|
const workspaceHash = crypto4.createHash("sha256").update(path19.resolve(workspace || os16.tmpdir())).digest("hex").slice(0, 16);
|
|
37751
37987
|
const filePath = path19.join(baseDir, `${workspaceHash}.json`);
|
|
37752
|
-
(0,
|
|
37988
|
+
(0, import_fs9.writeFileSync)(filePath, JSON.stringify({ mcpServers: {} }, null, 2), "utf-8");
|
|
37753
37989
|
return filePath;
|
|
37754
37990
|
}
|
|
37755
37991
|
function buildCoordinatorDelegatedCliLaunchOptions(input) {
|
|
@@ -37876,14 +38112,14 @@ function resolveCliSessionBinding(provider, normalizedType, cliArgs, requestedRe
|
|
|
37876
38112
|
launchMode: "new"
|
|
37877
38113
|
};
|
|
37878
38114
|
}
|
|
37879
|
-
var os16, path19, crypto4,
|
|
38115
|
+
var os16, path19, crypto4, import_fs9, import_child_process6, chalkModule, chalkApi, COORDINATOR_DELEGATED_ENV_UNSETS, DaemonCliManager;
|
|
37880
38116
|
var init_cli_manager = __esm({
|
|
37881
38117
|
"../../oss/packages/daemon-core/src/commands/cli-manager.ts"() {
|
|
37882
38118
|
"use strict";
|
|
37883
38119
|
os16 = __toESM(require("os"));
|
|
37884
38120
|
path19 = __toESM(require("path"));
|
|
37885
38121
|
crypto4 = __toESM(require("crypto"));
|
|
37886
|
-
|
|
38122
|
+
import_fs9 = require("fs");
|
|
37887
38123
|
import_child_process6 = require("child_process");
|
|
37888
38124
|
init_source2();
|
|
37889
38125
|
init_provider_cli_adapter();
|
|
@@ -38797,7 +39033,7 @@ function createFsWatchInstance(path42, options, listener, errHandler, emitRaw) {
|
|
|
38797
39033
|
}
|
|
38798
39034
|
};
|
|
38799
39035
|
try {
|
|
38800
|
-
return (0,
|
|
39036
|
+
return (0, import_fs10.watch)(path42, {
|
|
38801
39037
|
persistent: options.persistent
|
|
38802
39038
|
}, handleEvent);
|
|
38803
39039
|
} catch (error48) {
|
|
@@ -38805,11 +39041,11 @@ function createFsWatchInstance(path42, options, listener, errHandler, emitRaw) {
|
|
|
38805
39041
|
return void 0;
|
|
38806
39042
|
}
|
|
38807
39043
|
}
|
|
38808
|
-
var
|
|
39044
|
+
var import_fs10, import_promises5, sysPath, import_os3, STR_DATA, STR_END, STR_CLOSE, EMPTY_FN, pl, isWindows, isMacos, isLinux, isFreeBSD, isIBMi, EVENTS, EV, THROTTLE_MODE_WATCH, statMethods, KEY_LISTENERS, KEY_ERR, KEY_RAW, HANDLER_KEYS, binaryExtensions, isBinaryPath, foreach, addAndConvert, clearItem, delFromSet, isEmptySet, FsWatchInstances, fsWatchBroadcast, setFsWatchListener, FsWatchFileInstances, setFsWatchFileListener, NodeFsHandler;
|
|
38809
39045
|
var init_handler2 = __esm({
|
|
38810
39046
|
"../../oss/node_modules/chokidar/esm/handler.js"() {
|
|
38811
39047
|
"use strict";
|
|
38812
|
-
|
|
39048
|
+
import_fs10 = require("fs");
|
|
38813
39049
|
import_promises5 = require("fs/promises");
|
|
38814
39050
|
sysPath = __toESM(require("path"), 1);
|
|
38815
39051
|
import_os3 = require("os");
|
|
@@ -39213,7 +39449,7 @@ var init_handler2 = __esm({
|
|
|
39213
39449
|
let cont = FsWatchFileInstances.get(fullPath);
|
|
39214
39450
|
const copts = cont && cont.options;
|
|
39215
39451
|
if (copts && (copts.persistent < options.persistent || copts.interval > options.interval)) {
|
|
39216
|
-
(0,
|
|
39452
|
+
(0, import_fs10.unwatchFile)(fullPath);
|
|
39217
39453
|
cont = void 0;
|
|
39218
39454
|
}
|
|
39219
39455
|
if (cont) {
|
|
@@ -39224,7 +39460,7 @@ var init_handler2 = __esm({
|
|
|
39224
39460
|
listeners: listener,
|
|
39225
39461
|
rawEmitters: rawEmitter,
|
|
39226
39462
|
options,
|
|
39227
|
-
watcher: (0,
|
|
39463
|
+
watcher: (0, import_fs10.watchFile)(fullPath, options, (curr, prev) => {
|
|
39228
39464
|
foreach(cont.rawEmitters, (rawEmitter2) => {
|
|
39229
39465
|
rawEmitter2(EV.CHANGE, fullPath, { curr, prev });
|
|
39230
39466
|
});
|
|
@@ -39241,7 +39477,7 @@ var init_handler2 = __esm({
|
|
|
39241
39477
|
delFromSet(cont, KEY_RAW, rawEmitter);
|
|
39242
39478
|
if (isEmptySet(cont.listeners)) {
|
|
39243
39479
|
FsWatchFileInstances.delete(fullPath);
|
|
39244
|
-
(0,
|
|
39480
|
+
(0, import_fs10.unwatchFile)(fullPath);
|
|
39245
39481
|
cont.options = cont.watcher = void 0;
|
|
39246
39482
|
Object.freeze(cont);
|
|
39247
39483
|
}
|
|
@@ -39619,11 +39855,11 @@ function watch(paths, options = {}) {
|
|
|
39619
39855
|
watcher.add(paths);
|
|
39620
39856
|
return watcher;
|
|
39621
39857
|
}
|
|
39622
|
-
var
|
|
39858
|
+
var import_fs11, import_promises6, import_events2, sysPath2, SLASH, SLASH_SLASH, ONE_DOT, TWO_DOTS, STRING_TYPE, BACK_SLASH_RE, DOUBLE_SLASH_RE, DOT_RE, REPLACER_RE, isMatcherObject, unifyPaths, toUnix, normalizePathToUnix, normalizeIgnored, getAbsolutePath, EMPTY_SET, DirEntry, STAT_METHOD_F, STAT_METHOD_L, WatchHelper, FSWatcher;
|
|
39623
39859
|
var init_esm2 = __esm({
|
|
39624
39860
|
"../../oss/node_modules/chokidar/esm/index.js"() {
|
|
39625
39861
|
"use strict";
|
|
39626
|
-
|
|
39862
|
+
import_fs11 = require("fs");
|
|
39627
39863
|
import_promises6 = require("fs/promises");
|
|
39628
39864
|
import_events2 = require("events");
|
|
39629
39865
|
sysPath2 = __toESM(require("path"), 1);
|
|
@@ -40101,7 +40337,7 @@ var init_esm2 = __esm({
|
|
|
40101
40337
|
const now = /* @__PURE__ */ new Date();
|
|
40102
40338
|
const writes = this._pendingWrites;
|
|
40103
40339
|
function awaitWriteFinishFn(prevStat) {
|
|
40104
|
-
(0,
|
|
40340
|
+
(0, import_fs11.stat)(fullPath, (err, curStat) => {
|
|
40105
40341
|
if (err || !writes.has(path42)) {
|
|
40106
40342
|
if (err && err.code !== "ENOENT")
|
|
40107
40343
|
awfEmit(err);
|
|
@@ -46402,52 +46638,33 @@ function readBooleanValue(...values) {
|
|
|
46402
46638
|
}
|
|
46403
46639
|
return void 0;
|
|
46404
46640
|
}
|
|
46405
|
-
function
|
|
46406
|
-
|
|
46407
|
-
const
|
|
46408
|
-
|
|
46409
|
-
const
|
|
46410
|
-
const
|
|
46411
|
-
const
|
|
46412
|
-
|
|
46413
|
-
|
|
46414
|
-
|
|
46415
|
-
|
|
46416
|
-
|
|
46417
|
-
|
|
46418
|
-
|
|
46419
|
-
|
|
46420
|
-
|
|
46421
|
-
|
|
46422
|
-
|
|
46423
|
-
|
|
46424
|
-
|
|
46425
|
-
|
|
46426
|
-
untracked: readNumberValue(cachedGit.untracked) ?? 0,
|
|
46427
|
-
deleted: readNumberValue(cachedGit.deleted) ?? 0,
|
|
46428
|
-
renamed: readNumberValue(cachedGit.renamed) ?? 0,
|
|
46429
|
-
hasConflicts: hasConflicts2,
|
|
46430
|
-
conflictFiles: conflictFiles2,
|
|
46431
|
-
stashCount: readNumberValue(cachedGit.stashCount) ?? 0,
|
|
46432
|
-
lastCheckedAt: readNumberValue(cachedGit.lastCheckedAt) ?? Date.now()
|
|
46433
|
-
};
|
|
46434
|
-
}
|
|
46435
|
-
}
|
|
46436
|
-
const rawGit = readObjectRecord(node?.lastGit ?? node?.last_git);
|
|
46437
|
-
const gitResult = readObjectRecord(rawGit.result);
|
|
46438
|
-
const directStatus = readObjectRecord(rawGit.status);
|
|
46439
|
-
const nestedStatus = readObjectRecord(gitResult.status);
|
|
46440
|
-
const rawProbe = readObjectRecord(node?.lastProbe ?? node?.last_probe);
|
|
46441
|
-
const probeGit = readObjectRecord(rawProbe.git);
|
|
46442
|
-
const probeGitResult = readObjectRecord(probeGit.result);
|
|
46443
|
-
const probeDirectStatus = readObjectRecord(probeGit.status);
|
|
46444
|
-
const probeNestedStatus = readObjectRecord(probeGitResult.status);
|
|
46445
|
-
const status = Object.keys(directStatus).length ? directStatus : Object.keys(nestedStatus).length ? nestedStatus : Object.keys(probeDirectStatus).length ? probeDirectStatus : Object.keys(probeNestedStatus).length ? probeNestedStatus : {};
|
|
46641
|
+
function readGitSubmodules(value) {
|
|
46642
|
+
if (!Array.isArray(value)) return void 0;
|
|
46643
|
+
const submodules = value.map((entry) => {
|
|
46644
|
+
const submodule = readObjectRecord(entry);
|
|
46645
|
+
const path42 = readStringValue(submodule.path);
|
|
46646
|
+
const commit = readStringValue(submodule.commit);
|
|
46647
|
+
const repoPath = readStringValue(submodule.repoPath, submodule.repo_root);
|
|
46648
|
+
if (!path42 || !commit || !repoPath) return null;
|
|
46649
|
+
return {
|
|
46650
|
+
path: path42,
|
|
46651
|
+
commit,
|
|
46652
|
+
repoPath,
|
|
46653
|
+
dirty: readBooleanValue(submodule.dirty) ?? false,
|
|
46654
|
+
outOfSync: readBooleanValue(submodule.outOfSync, submodule.out_of_sync) ?? false,
|
|
46655
|
+
lastCheckedAt: readNumberValue(submodule.lastCheckedAt, submodule.last_checked_at) ?? Date.now(),
|
|
46656
|
+
...readStringValue(submodule.error) ? { error: readStringValue(submodule.error) } : {}
|
|
46657
|
+
};
|
|
46658
|
+
}).filter((entry) => entry !== null);
|
|
46659
|
+
return submodules.length > 0 ? submodules : void 0;
|
|
46660
|
+
}
|
|
46661
|
+
function normalizeInlineMeshGitStatus(status, node, options) {
|
|
46446
46662
|
const isGitRepo = readBooleanValue(status.isGitRepo);
|
|
46447
46663
|
if (!Object.keys(status).length || isGitRepo === void 0) return void 0;
|
|
46448
46664
|
const conflictFiles = Array.isArray(status.conflictFiles) ? status.conflictFiles.filter((value) => typeof value === "string") : [];
|
|
46449
46665
|
const conflictCount = readNumberValue(status.conflicts) ?? conflictFiles.length;
|
|
46450
46666
|
const hasConflicts = readBooleanValue(status.hasConflicts) ?? conflictCount > 0;
|
|
46667
|
+
const submodules = readGitSubmodules(status.submodules);
|
|
46451
46668
|
return {
|
|
46452
46669
|
workspace: readStringValue(status.workspace, node?.workspace) || "",
|
|
46453
46670
|
repoRoot: readStringValue(status.repoRoot, node?.repoRoot, node?.workspace) || null,
|
|
@@ -46466,29 +46683,285 @@ function buildCachedInlineMeshGitStatus(node) {
|
|
|
46466
46683
|
hasConflicts,
|
|
46467
46684
|
conflictFiles,
|
|
46468
46685
|
stashCount: readNumberValue(status.stashCount) ?? 0,
|
|
46469
|
-
lastCheckedAt: Date.now()
|
|
46686
|
+
lastCheckedAt: options?.lastCheckedAt ?? readNumberValue(status.lastCheckedAt) ?? Date.now(),
|
|
46687
|
+
...submodules ? { submodules } : {}
|
|
46688
|
+
};
|
|
46689
|
+
}
|
|
46690
|
+
function buildInlineMeshTransitGitStatus(node) {
|
|
46691
|
+
const rawGit = readObjectRecord(node?.lastGit ?? node?.last_git);
|
|
46692
|
+
const gitResult = readObjectRecord(rawGit.result);
|
|
46693
|
+
const directStatus = readObjectRecord(rawGit.status);
|
|
46694
|
+
const nestedStatus = readObjectRecord(gitResult.status);
|
|
46695
|
+
const rawProbe = readObjectRecord(node?.lastProbe ?? node?.last_probe);
|
|
46696
|
+
const probeGit = readObjectRecord(rawProbe.git);
|
|
46697
|
+
const probeGitResult = readObjectRecord(probeGit.result);
|
|
46698
|
+
const probeDirectStatus = readObjectRecord(probeGit.status);
|
|
46699
|
+
const probeNestedStatus = readObjectRecord(probeGitResult.status);
|
|
46700
|
+
const status = Object.keys(directStatus).length ? directStatus : Object.keys(nestedStatus).length ? nestedStatus : Object.keys(probeDirectStatus).length ? probeDirectStatus : Object.keys(probeNestedStatus).length ? probeNestedStatus : {};
|
|
46701
|
+
return normalizeInlineMeshGitStatus(status, node, { lastCheckedAt: Date.now() });
|
|
46702
|
+
}
|
|
46703
|
+
function buildCachedInlineMeshGitStatus(node) {
|
|
46704
|
+
const liveGit = buildInlineMeshTransitGitStatus(node);
|
|
46705
|
+
if (liveGit) return liveGit;
|
|
46706
|
+
const cachedStatus = readObjectRecord(node?.cachedStatus);
|
|
46707
|
+
const cachedGit = readObjectRecord(cachedStatus.git);
|
|
46708
|
+
if (!Object.keys(cachedGit).length) return void 0;
|
|
46709
|
+
return normalizeInlineMeshGitStatus(cachedGit, node);
|
|
46710
|
+
}
|
|
46711
|
+
function shouldDiscardCachedInlineMeshStatus(node) {
|
|
46712
|
+
const cachedStatus = readObjectRecord(node?.cachedStatus);
|
|
46713
|
+
if (!Object.keys(cachedStatus).length) return false;
|
|
46714
|
+
const cachedGit = readObjectRecord(cachedStatus.git);
|
|
46715
|
+
const workspaceError = readStringValue(cachedStatus.error, node?.error);
|
|
46716
|
+
if (workspaceError && /workspace must be an existing directory/i.test(workspaceError)) return true;
|
|
46717
|
+
const isGitRepo = readBooleanValue(cachedGit.isGitRepo);
|
|
46718
|
+
const branch = readStringValue(cachedGit.branch);
|
|
46719
|
+
const headCommit = readStringValue(cachedGit.headCommit);
|
|
46720
|
+
return isGitRepo === false && !branch && !headCommit;
|
|
46721
|
+
}
|
|
46722
|
+
function stripInlineMeshTransientNodeState(node) {
|
|
46723
|
+
if (!node || typeof node !== "object" || Array.isArray(node)) return node;
|
|
46724
|
+
const {
|
|
46725
|
+
cachedStatus,
|
|
46726
|
+
lastGit: _lastGit,
|
|
46727
|
+
last_git: _lastGitLegacy,
|
|
46728
|
+
lastProbe: _lastProbe,
|
|
46729
|
+
last_probe: _lastProbeLegacy,
|
|
46730
|
+
error: _error,
|
|
46731
|
+
health: _health,
|
|
46732
|
+
machineStatus: _machineStatus,
|
|
46733
|
+
lastSeenAt: _lastSeenAt,
|
|
46734
|
+
last_seen_at: _lastSeenAtLegacy,
|
|
46735
|
+
updatedAt: _updatedAt,
|
|
46736
|
+
updated_at: _updatedAtLegacy,
|
|
46737
|
+
activeSession: _activeSession,
|
|
46738
|
+
active_session: _activeSessionLegacy,
|
|
46739
|
+
activeSessionId: _activeSessionId,
|
|
46740
|
+
active_session_id: _activeSessionIdLegacy,
|
|
46741
|
+
sessionId: _sessionId,
|
|
46742
|
+
session_id: _sessionIdLegacy,
|
|
46743
|
+
providerType: _providerType,
|
|
46744
|
+
provider_type: _providerTypeLegacy,
|
|
46745
|
+
providers: _providers,
|
|
46746
|
+
...rest
|
|
46747
|
+
} = node;
|
|
46748
|
+
if (cachedStatus && !shouldDiscardCachedInlineMeshStatus(node)) {
|
|
46749
|
+
return { ...rest, cachedStatus };
|
|
46750
|
+
}
|
|
46751
|
+
return rest;
|
|
46752
|
+
}
|
|
46753
|
+
function hasInlineMeshTransientNodeState(node) {
|
|
46754
|
+
if (!node || typeof node !== "object" || Array.isArray(node)) return false;
|
|
46755
|
+
return "cachedStatus" in node || "lastGit" in node || "last_git" in node || "lastProbe" in node || "last_probe" in node || "error" in node || "health" in node || "machineStatus" in node || "lastSeenAt" in node || "last_seen_at" in node || "updatedAt" in node || "updated_at" in node || "activeSession" in node || "active_session" in node || "activeSessionId" in node || "active_session_id" in node || "sessionId" in node || "session_id" in node || "providerType" in node || "provider_type" in node || "providers" in node;
|
|
46756
|
+
}
|
|
46757
|
+
function readInlineMeshNodeId(node) {
|
|
46758
|
+
return readStringValue(node?.id, node?.nodeId) || "";
|
|
46759
|
+
}
|
|
46760
|
+
function sanitizeInlineMesh(inlineMesh) {
|
|
46761
|
+
if (!inlineMesh || typeof inlineMesh !== "object" || Array.isArray(inlineMesh)) return inlineMesh;
|
|
46762
|
+
if (!Array.isArray(inlineMesh.nodes)) return inlineMesh;
|
|
46763
|
+
let changed = false;
|
|
46764
|
+
const nodes = inlineMesh.nodes.map((node) => {
|
|
46765
|
+
if (!hasInlineMeshTransientNodeState(node)) return node;
|
|
46766
|
+
changed = true;
|
|
46767
|
+
return stripInlineMeshTransientNodeState(node);
|
|
46768
|
+
});
|
|
46769
|
+
if (!changed) return inlineMesh;
|
|
46770
|
+
return {
|
|
46771
|
+
...inlineMesh,
|
|
46772
|
+
nodes
|
|
46773
|
+
};
|
|
46774
|
+
}
|
|
46775
|
+
function reconcileInlineMeshCache(cached2, incoming) {
|
|
46776
|
+
if (!cached2 || typeof cached2 !== "object" || Array.isArray(cached2)) return incoming;
|
|
46777
|
+
if (!incoming || typeof incoming !== "object" || Array.isArray(incoming)) return cached2;
|
|
46778
|
+
const cachedNodes = Array.isArray(cached2.nodes) ? cached2.nodes : [];
|
|
46779
|
+
const incomingNodes = Array.isArray(incoming.nodes) ? incoming.nodes : [];
|
|
46780
|
+
if (!cachedNodes.length || !incomingNodes.length) return { ...cached2, ...incoming };
|
|
46781
|
+
const incomingById = /* @__PURE__ */ new Map();
|
|
46782
|
+
for (const node of incomingNodes) {
|
|
46783
|
+
const nodeId = readInlineMeshNodeId(node);
|
|
46784
|
+
if (nodeId) incomingById.set(nodeId, node);
|
|
46785
|
+
}
|
|
46786
|
+
const nodes = cachedNodes.map((cachedNode) => {
|
|
46787
|
+
const nodeId = readInlineMeshNodeId(cachedNode);
|
|
46788
|
+
const incomingNode = nodeId ? incomingById.get(nodeId) : void 0;
|
|
46789
|
+
if (!incomingNode) return cachedNode;
|
|
46790
|
+
if (hasInlineMeshTransientNodeState(incomingNode)) {
|
|
46791
|
+
return { ...cachedNode, ...incomingNode };
|
|
46792
|
+
}
|
|
46793
|
+
return { ...stripInlineMeshTransientNodeState(cachedNode), ...incomingNode };
|
|
46794
|
+
});
|
|
46795
|
+
return {
|
|
46796
|
+
...cached2,
|
|
46797
|
+
...incoming,
|
|
46798
|
+
nodes
|
|
46470
46799
|
};
|
|
46471
46800
|
}
|
|
46472
|
-
function
|
|
46801
|
+
function hasGitWorktreeChanges(git) {
|
|
46802
|
+
if (!git) return false;
|
|
46803
|
+
return Number(git.staged || 0) + Number(git.modified || 0) + Number(git.untracked || 0) + Number(git.deleted || 0) + Number(git.renamed || 0) > 0;
|
|
46804
|
+
}
|
|
46805
|
+
function getGitSubmoduleDriftState(git) {
|
|
46806
|
+
const submodules = Array.isArray(git?.submodules) ? git.submodules : [];
|
|
46807
|
+
let dirty = false;
|
|
46808
|
+
let outOfSync = false;
|
|
46809
|
+
for (const entry of submodules) {
|
|
46810
|
+
const submodule = readObjectRecord(entry);
|
|
46811
|
+
if (readBooleanValue(submodule.dirty) === true) dirty = true;
|
|
46812
|
+
if (readBooleanValue(submodule.outOfSync) === true || !!readStringValue(submodule.error)) outOfSync = true;
|
|
46813
|
+
}
|
|
46814
|
+
return { dirty, outOfSync };
|
|
46815
|
+
}
|
|
46816
|
+
function deriveMeshNodeHealthFromGit(git) {
|
|
46817
|
+
if (!git || readBooleanValue(git.isGitRepo) === false) return "degraded";
|
|
46818
|
+
const branch = readStringValue(git.branch);
|
|
46819
|
+
if (!branch) return "degraded";
|
|
46820
|
+
const submoduleDrift = getGitSubmoduleDriftState(git);
|
|
46821
|
+
if (submoduleDrift.outOfSync) return "degraded";
|
|
46822
|
+
if (submoduleDrift.dirty || hasGitWorktreeChanges(git)) return "dirty";
|
|
46823
|
+
return "online";
|
|
46824
|
+
}
|
|
46825
|
+
function readCachedInlineMeshActiveSessions(node) {
|
|
46473
46826
|
const cachedStatus = readObjectRecord(node?.cachedStatus);
|
|
46474
|
-
const
|
|
46475
|
-
const
|
|
46476
|
-
const
|
|
46827
|
+
const activeSession = readObjectRecord(cachedStatus.activeSession);
|
|
46828
|
+
const fallbackSession = Object.keys(activeSession).length ? activeSession : readObjectRecord(node?.activeSession ?? node?.active_session);
|
|
46829
|
+
const sessionId = readStringValue(fallbackSession.id, fallbackSession.sessionId, fallbackSession.session_id, node?.activeSessionId, node?.active_session_id, node?.sessionId, node?.session_id);
|
|
46830
|
+
return sessionId ? [sessionId] : [];
|
|
46831
|
+
}
|
|
46832
|
+
function readCachedInlineMeshActiveSessionDetails(node) {
|
|
46833
|
+
const cachedStatus = readObjectRecord(node?.cachedStatus);
|
|
46834
|
+
const activeSession = readObjectRecord(cachedStatus.activeSession);
|
|
46835
|
+
const fallbackSession = Object.keys(activeSession).length ? activeSession : readObjectRecord(node?.activeSession ?? node?.active_session);
|
|
46836
|
+
const sessionId = readStringValue(
|
|
46837
|
+
fallbackSession.id,
|
|
46838
|
+
fallbackSession.sessionId,
|
|
46839
|
+
fallbackSession.session_id,
|
|
46840
|
+
node?.activeSessionId,
|
|
46841
|
+
node?.active_session_id,
|
|
46842
|
+
node?.sessionId,
|
|
46843
|
+
node?.session_id
|
|
46844
|
+
);
|
|
46845
|
+
if (!sessionId) return [];
|
|
46846
|
+
return [{
|
|
46847
|
+
sessionId,
|
|
46848
|
+
providerType: readStringValue(
|
|
46849
|
+
fallbackSession.providerType,
|
|
46850
|
+
fallbackSession.provider_type,
|
|
46851
|
+
fallbackSession.cliType,
|
|
46852
|
+
fallbackSession.cli_type,
|
|
46853
|
+
fallbackSession.provider,
|
|
46854
|
+
node?.providerType,
|
|
46855
|
+
node?.provider_type
|
|
46856
|
+
),
|
|
46857
|
+
state: readStringValue(fallbackSession.status, fallbackSession.state, fallbackSession.lifecycle),
|
|
46858
|
+
lifecycle: readStringValue(fallbackSession.lifecycle),
|
|
46859
|
+
title: readStringValue(fallbackSession.title, fallbackSession.displayName, fallbackSession.display_name) ?? null,
|
|
46860
|
+
workspace: readStringValue(fallbackSession.workspace, node?.workspace) ?? null,
|
|
46861
|
+
lastActivityAt: readStringValue(fallbackSession.lastActivityAt, fallbackSession.last_activity_at) ?? null,
|
|
46862
|
+
recoveryState: readStringValue(fallbackSession.recoveryState, fallbackSession.recovery_state) ?? null,
|
|
46863
|
+
isCached: true
|
|
46864
|
+
}];
|
|
46865
|
+
}
|
|
46866
|
+
function readLiveMeshSessionState(record2) {
|
|
46867
|
+
return readStringValue(
|
|
46868
|
+
record2?.meta?.sessionStatus,
|
|
46869
|
+
record2?.meta?.status,
|
|
46870
|
+
record2?.meta?.providerStatus,
|
|
46871
|
+
record2?.status,
|
|
46872
|
+
record2?.state,
|
|
46873
|
+
record2?.lifecycle
|
|
46874
|
+
);
|
|
46875
|
+
}
|
|
46876
|
+
function toIsoTimestamp(value) {
|
|
46877
|
+
if (typeof value === "number" && Number.isFinite(value)) return new Date(value).toISOString();
|
|
46878
|
+
const stringValue = readStringValue(value);
|
|
46879
|
+
return stringValue || null;
|
|
46880
|
+
}
|
|
46881
|
+
function summarizeMeshSessionRecord(record2) {
|
|
46882
|
+
return {
|
|
46883
|
+
sessionId: readStringValue(record2?.sessionId) || "unknown",
|
|
46884
|
+
providerType: readStringValue(record2?.providerType),
|
|
46885
|
+
state: readLiveMeshSessionState(record2),
|
|
46886
|
+
lifecycle: readStringValue(record2?.lifecycle),
|
|
46887
|
+
surfaceKind: getSessionHostSurfaceKind(record2),
|
|
46888
|
+
recoveryState: readStringValue(record2?.meta?.runtimeRecoveryState) ?? null,
|
|
46889
|
+
workspace: readStringValue(record2?.workspace) ?? null,
|
|
46890
|
+
title: readStringValue(record2?.displayName, record2?.workspaceLabel) ?? null,
|
|
46891
|
+
lastActivityAt: toIsoTimestamp(record2?.updatedAt ?? record2?.lastActivityAt ?? record2?.last_activity_at),
|
|
46892
|
+
isCached: false
|
|
46893
|
+
};
|
|
46894
|
+
}
|
|
46895
|
+
function liveSessionRecordMatchesMeshNode(record2, meshId, nodeId) {
|
|
46896
|
+
const recordNodeId = readStringValue(record2?.meta?.meshNodeId);
|
|
46897
|
+
if (!recordNodeId || recordNodeId !== nodeId) return false;
|
|
46898
|
+
const recordMeshId = readStringValue(record2?.meta?.meshNodeFor);
|
|
46899
|
+
return !recordMeshId || recordMeshId === meshId;
|
|
46900
|
+
}
|
|
46901
|
+
function liveSessionRecordMatchesMeshWorkspace(record2, meshId, workspace) {
|
|
46902
|
+
const recordWorkspace = readStringValue(record2?.workspace);
|
|
46903
|
+
if (!recordWorkspace || !workspace || recordWorkspace !== workspace) return false;
|
|
46904
|
+
const recordMeshId = readStringValue(record2?.meta?.meshNodeFor);
|
|
46905
|
+
if (recordMeshId) return recordMeshId === meshId;
|
|
46906
|
+
return record2?.meta?.launchedByCoordinator === true || !!readStringValue(record2?.meta?.meshNodeId);
|
|
46907
|
+
}
|
|
46908
|
+
function readLiveMeshNodeWorkspace(args) {
|
|
46909
|
+
const directNodeWorkspace = args.liveSessionRecords.find((record2) => liveSessionRecordMatchesMeshNode(record2, args.meshId, args.nodeId) && readStringValue(record2?.workspace));
|
|
46910
|
+
if (directNodeWorkspace) {
|
|
46911
|
+
return readStringValue(directNodeWorkspace.workspace) || "";
|
|
46912
|
+
}
|
|
46913
|
+
if (args.allowCoordinatorSession) {
|
|
46914
|
+
const coordinatorWorkspace = args.liveSessionRecords.find((record2) => readStringValue(record2?.meta?.meshCoordinatorFor) === args.meshId && readStringValue(record2?.workspace));
|
|
46915
|
+
if (coordinatorWorkspace) {
|
|
46916
|
+
return readStringValue(coordinatorWorkspace.workspace) || "";
|
|
46917
|
+
}
|
|
46918
|
+
}
|
|
46919
|
+
return "";
|
|
46920
|
+
}
|
|
46921
|
+
function collectLiveMeshSessionRecords(args) {
|
|
46922
|
+
const matches = args.liveSessionRecords.filter((record2) => {
|
|
46923
|
+
const nodeWorkspace = readStringValue(args.node?.workspace);
|
|
46924
|
+
if (liveSessionRecordMatchesMeshNode(record2, args.meshId, args.nodeId)) return true;
|
|
46925
|
+
return !!nodeWorkspace && liveSessionRecordMatchesMeshWorkspace(record2, args.meshId, nodeWorkspace);
|
|
46926
|
+
});
|
|
46927
|
+
if (args.allowCoordinatorSession) {
|
|
46928
|
+
for (const record2 of args.liveSessionRecords) {
|
|
46929
|
+
if (readStringValue(record2?.meta?.meshCoordinatorFor) !== args.meshId) continue;
|
|
46930
|
+
const sessionId = readStringValue(record2?.sessionId);
|
|
46931
|
+
if (sessionId && matches.some((entry) => readStringValue(entry?.sessionId) === sessionId)) continue;
|
|
46932
|
+
matches.push(record2);
|
|
46933
|
+
}
|
|
46934
|
+
}
|
|
46935
|
+
return matches;
|
|
46936
|
+
}
|
|
46937
|
+
function applyCachedInlineMeshNodeStatus(status, node, options) {
|
|
46938
|
+
const cachedStatus = readObjectRecord(node?.cachedStatus);
|
|
46939
|
+
const liveGit = buildInlineMeshTransitGitStatus(node);
|
|
46940
|
+
const git = options?.skipGit ? void 0 : liveGit ?? buildCachedInlineMeshGitStatus(node);
|
|
46941
|
+
const error48 = options?.skipError ? void 0 : liveGit ? void 0 : readStringValue(cachedStatus.error, node?.error);
|
|
46942
|
+
const health = options?.skipHealth ? void 0 : liveGit ? void 0 : readStringValue(cachedStatus.health, node?.health);
|
|
46477
46943
|
const machineStatus = readStringValue(cachedStatus.machineStatus, node?.machineStatus);
|
|
46478
|
-
|
|
46479
|
-
|
|
46944
|
+
const lastSeenAt = toIsoTimestamp(cachedStatus.lastSeenAt ?? cachedStatus.last_seen_at ?? node?.lastSeenAt ?? node?.last_seen_at);
|
|
46945
|
+
const updatedAt = toIsoTimestamp(cachedStatus.updatedAt ?? cachedStatus.updated_at ?? node?.updatedAt ?? node?.updated_at);
|
|
46946
|
+
const activeSessions = readCachedInlineMeshActiveSessions(node);
|
|
46947
|
+
const activeSessionDetails = readCachedInlineMeshActiveSessionDetails(node);
|
|
46948
|
+
if (!git && !error48 && !health && !machineStatus && !lastSeenAt && !updatedAt && activeSessions.length === 0) return false;
|
|
46480
46949
|
if (git) status.git = git;
|
|
46481
46950
|
if (error48) status.error = error48;
|
|
46951
|
+
if (machineStatus) status.machineStatus = machineStatus;
|
|
46952
|
+
if (lastSeenAt) status.lastSeenAt = lastSeenAt;
|
|
46953
|
+
if (updatedAt) status.updatedAt = updatedAt;
|
|
46954
|
+
if (activeSessions.length > 0) status.activeSessions = activeSessions;
|
|
46955
|
+
if (activeSessionDetails.length > 0) status.activeSessionDetails = activeSessionDetails;
|
|
46482
46956
|
if (health) {
|
|
46483
46957
|
status.health = health;
|
|
46484
46958
|
return true;
|
|
46485
46959
|
}
|
|
46486
46960
|
if (git) {
|
|
46487
|
-
|
|
46488
|
-
status.health = git.isGitRepo === false ? "degraded" : dirty ? "dirty" : "online";
|
|
46961
|
+
status.health = deriveMeshNodeHealthFromGit(git);
|
|
46489
46962
|
return true;
|
|
46490
46963
|
}
|
|
46491
|
-
return
|
|
46964
|
+
return activeSessions.length > 0 || !!machineStatus || !!lastSeenAt || !!updatedAt;
|
|
46492
46965
|
}
|
|
46493
46966
|
async function resolveProviderTypeFromPriority(args) {
|
|
46494
46967
|
if (!args.providerPriority.length) {
|
|
@@ -46521,7 +46994,7 @@ function truncateValidationOutput(value) {
|
|
|
46521
46994
|
}
|
|
46522
46995
|
function readPackageScripts(workspace) {
|
|
46523
46996
|
try {
|
|
46524
|
-
const packageJsonPath = (0,
|
|
46997
|
+
const packageJsonPath = (0, import_path7.join)(workspace, "package.json");
|
|
46525
46998
|
const parsed = JSON.parse(fs10.readFileSync(packageJsonPath, "utf-8"));
|
|
46526
46999
|
return parsed?.scripts && typeof parsed.scripts === "object" && !Array.isArray(parsed.scripts) ? parsed.scripts : {};
|
|
46527
47000
|
} catch {
|
|
@@ -46729,13 +47202,13 @@ function serializeMeshCoordinatorMcpConfig(config2, format) {
|
|
|
46729
47202
|
}
|
|
46730
47203
|
function resolveHermesUserHome() {
|
|
46731
47204
|
const explicitHome = process.env.HERMES_HOME?.trim();
|
|
46732
|
-
return explicitHome || (0,
|
|
47205
|
+
return explicitHome || (0, import_path7.join)((0, import_os4.homedir)(), ".hermes");
|
|
46733
47206
|
}
|
|
46734
47207
|
function loadHermesCoordinatorBaseConfig(targetConfigPath) {
|
|
46735
47208
|
const sourceHome = resolveHermesUserHome();
|
|
46736
|
-
const sourceConfigPath = (0,
|
|
47209
|
+
const sourceConfigPath = (0, import_path7.join)(sourceHome, "config.yaml");
|
|
46737
47210
|
if (!fs10.existsSync(sourceConfigPath)) return { config: {}, sourceHome, sourceConfigPath };
|
|
46738
|
-
if ((0,
|
|
47211
|
+
if ((0, import_path7.resolve)(sourceConfigPath) === (0, import_path7.resolve)(targetConfigPath)) return { config: {}, sourceHome, sourceConfigPath };
|
|
46739
47212
|
const parsed = parseMeshCoordinatorMcpConfig(fs10.readFileSync(sourceConfigPath, "utf-8"), "hermes_config_yaml");
|
|
46740
47213
|
const { mcp_servers: _mcpServers, ...baseConfig } = parsed;
|
|
46741
47214
|
return { config: baseConfig, sourceHome, sourceConfigPath };
|
|
@@ -46769,10 +47242,10 @@ function stripHermesCoordinatorTempModelProviderOverrides(config2) {
|
|
|
46769
47242
|
return sanitized;
|
|
46770
47243
|
}
|
|
46771
47244
|
function copyHermesCoordinatorCredentialFiles(sourceHome, targetHome) {
|
|
46772
|
-
if ((0,
|
|
47245
|
+
if ((0, import_path7.resolve)(sourceHome) === (0, import_path7.resolve)(targetHome)) return;
|
|
46773
47246
|
for (const fileName of [".env", "auth.json"]) {
|
|
46774
|
-
const sourcePath = (0,
|
|
46775
|
-
const targetPath = (0,
|
|
47247
|
+
const sourcePath = (0, import_path7.join)(sourceHome, fileName);
|
|
47248
|
+
const targetPath = (0, import_path7.join)(targetHome, fileName);
|
|
46776
47249
|
if (!fs10.existsSync(sourcePath)) continue;
|
|
46777
47250
|
try {
|
|
46778
47251
|
fs10.copyFileSync(sourcePath, targetPath);
|
|
@@ -46862,7 +47335,7 @@ function summarizeSessionHostPruneResult(result) {
|
|
|
46862
47335
|
keptCount: Array.isArray(value.keptSessionIds) ? value.keptSessionIds.length : void 0
|
|
46863
47336
|
};
|
|
46864
47337
|
}
|
|
46865
|
-
var import_os4,
|
|
47338
|
+
var import_os4, import_path7, fs10, CHANNEL_NPM_TAG, CHANNEL_SERVER_URL, REFINE_VALIDATION_CATEGORIES, REFINE_VALIDATION_TIMEOUT_MS, REFINE_VALIDATION_OUTPUT_LIMIT_BYTES, REFINE_VALIDATION_SUMMARY_CHARS, REFINE_VALIDATION_MAX_COMMANDS, CHAT_COMMANDS, READ_DEBUG_ENABLED2, DaemonCommandRouter;
|
|
46866
47339
|
var init_router = __esm({
|
|
46867
47340
|
"../../oss/packages/daemon-core/src/commands/router.ts"() {
|
|
46868
47341
|
"use strict";
|
|
@@ -46878,6 +47351,7 @@ var init_router = __esm({
|
|
|
46878
47351
|
init_chat_history();
|
|
46879
47352
|
init_ide_detector();
|
|
46880
47353
|
init_cli_detector();
|
|
47354
|
+
init_git_status();
|
|
46881
47355
|
init_logger();
|
|
46882
47356
|
init_command_log();
|
|
46883
47357
|
init_js_yaml();
|
|
@@ -46891,7 +47365,7 @@ var init_router = __esm({
|
|
|
46891
47365
|
init_snapshot();
|
|
46892
47366
|
init_upgrade_helper();
|
|
46893
47367
|
import_os4 = require("os");
|
|
46894
|
-
|
|
47368
|
+
import_path7 = require("path");
|
|
46895
47369
|
fs10 = __toESM(require("fs"));
|
|
46896
47370
|
CHANNEL_NPM_TAG = { stable: "latest", preview: "next" };
|
|
46897
47371
|
CHANNEL_SERVER_URL = {
|
|
@@ -46922,25 +47396,40 @@ var init_router = __esm({
|
|
|
46922
47396
|
}
|
|
46923
47397
|
getCachedInlineMesh(meshId, inlineMesh) {
|
|
46924
47398
|
if (inlineMesh && typeof inlineMesh === "object") {
|
|
46925
|
-
this.
|
|
46926
|
-
return inlineMesh;
|
|
47399
|
+
return this.warmInlineMeshCache(meshId, inlineMesh);
|
|
46927
47400
|
}
|
|
46928
47401
|
return this.inlineMeshCache.get(meshId);
|
|
46929
47402
|
}
|
|
47403
|
+
warmInlineMeshCache(meshId, inlineMesh) {
|
|
47404
|
+
if (!inlineMesh || typeof inlineMesh !== "object") return void 0;
|
|
47405
|
+
const sanitizedInlineMesh = sanitizeInlineMesh(inlineMesh);
|
|
47406
|
+
const cached2 = this.inlineMeshCache.get(meshId);
|
|
47407
|
+
if (cached2) {
|
|
47408
|
+
const merged = reconcileInlineMeshCache(cached2, sanitizedInlineMesh);
|
|
47409
|
+
this.inlineMeshCache.set(meshId, merged);
|
|
47410
|
+
return merged;
|
|
47411
|
+
}
|
|
47412
|
+
this.inlineMeshCache.set(meshId, sanitizedInlineMesh);
|
|
47413
|
+
return sanitizedInlineMesh;
|
|
47414
|
+
}
|
|
46930
47415
|
async getMeshForCommand(meshId, inlineMesh, options) {
|
|
46931
47416
|
const preferInline = options?.preferInline === true;
|
|
46932
47417
|
if (preferInline) {
|
|
46933
|
-
const cached3 = this.getCachedInlineMesh(meshId
|
|
46934
|
-
if (cached3) return { mesh: cached3, inline: true };
|
|
47418
|
+
const cached3 = this.getCachedInlineMesh(meshId);
|
|
47419
|
+
if (cached3) return { mesh: cached3, inline: true, source: "inline_cache" };
|
|
47420
|
+
const warmedInline2 = this.warmInlineMeshCache(meshId, inlineMesh);
|
|
47421
|
+
if (warmedInline2) return { mesh: warmedInline2, inline: true, source: "inline_bootstrap" };
|
|
46935
47422
|
}
|
|
46936
47423
|
try {
|
|
46937
47424
|
const { getMesh: getMesh3 } = await Promise.resolve().then(() => (init_mesh_config(), mesh_config_exports));
|
|
46938
47425
|
const mesh = getMesh3(meshId);
|
|
46939
|
-
if (mesh) return { mesh, inline: false };
|
|
47426
|
+
if (mesh) return { mesh, inline: false, source: "local_config" };
|
|
46940
47427
|
} catch {
|
|
46941
47428
|
}
|
|
46942
|
-
const cached2 = this.getCachedInlineMesh(meshId
|
|
46943
|
-
|
|
47429
|
+
const cached2 = this.getCachedInlineMesh(meshId);
|
|
47430
|
+
if (cached2) return { mesh: cached2, inline: true, source: "inline_cache" };
|
|
47431
|
+
const warmedInline = this.warmInlineMeshCache(meshId, inlineMesh);
|
|
47432
|
+
return warmedInline ? { mesh: warmedInline, inline: true, source: "inline_bootstrap" } : null;
|
|
46944
47433
|
}
|
|
46945
47434
|
updateInlineMeshNode(meshId, mesh, node) {
|
|
46946
47435
|
if (!mesh || !Array.isArray(mesh.nodes) || !node?.id) return;
|
|
@@ -47005,7 +47494,7 @@ var init_router = __esm({
|
|
|
47005
47494
|
}
|
|
47006
47495
|
const { resolveWorktreePath: resolveWorktreePath2, listWorktrees: listWorktrees2, removeWorktree: removeWorktree2 } = await Promise.resolve().then(() => (init_git_worktree(), git_worktree_exports));
|
|
47007
47496
|
const normalizePath3 = (value) => {
|
|
47008
|
-
const resolved = (0,
|
|
47497
|
+
const resolved = (0, import_path7.resolve)(value);
|
|
47009
47498
|
try {
|
|
47010
47499
|
return fs10.realpathSync(resolved);
|
|
47011
47500
|
} catch {
|
|
@@ -47169,6 +47658,7 @@ var init_router = __esm({
|
|
|
47169
47658
|
const deletedSessionIds = [];
|
|
47170
47659
|
const skippedSessionIds = [];
|
|
47171
47660
|
const skippedLiveSessionIds = [];
|
|
47661
|
+
const skippedCoordinatorSessionIds = [];
|
|
47172
47662
|
const deleteUnsupportedSessionIds = [];
|
|
47173
47663
|
const recordsRemainSessionIds = [];
|
|
47174
47664
|
const errors = [];
|
|
@@ -47201,6 +47691,12 @@ var init_router = __esm({
|
|
|
47201
47691
|
const completed = this.isCompletedHostedSession(record2);
|
|
47202
47692
|
const surfaceKind = getSessionHostSurfaceKind(record2);
|
|
47203
47693
|
const liveRuntime = surfaceKind === "live_runtime";
|
|
47694
|
+
const coordinatorSession = readStringValue(record2?.meta?.meshCoordinatorFor) === args.meshId;
|
|
47695
|
+
if (!hasExplicitSessionIds && coordinatorSession) {
|
|
47696
|
+
skippedSessionIds.push(sessionId);
|
|
47697
|
+
skippedCoordinatorSessionIds.push(sessionId);
|
|
47698
|
+
continue;
|
|
47699
|
+
}
|
|
47204
47700
|
if (!hasExplicitSessionIds && liveRuntime) {
|
|
47205
47701
|
skippedSessionIds.push(sessionId);
|
|
47206
47702
|
skippedLiveSessionIds.push(sessionId);
|
|
@@ -47266,6 +47762,7 @@ var init_router = __esm({
|
|
|
47266
47762
|
deletedSessionIds,
|
|
47267
47763
|
skippedSessionIds,
|
|
47268
47764
|
skippedLiveSessionIds,
|
|
47765
|
+
skippedCoordinatorSessionIds,
|
|
47269
47766
|
...deleteUnsupported ? {
|
|
47270
47767
|
deleteUnsupported: true,
|
|
47271
47768
|
effectiveCleanup: args.mode === "stop_and_delete" ? "stopped_only_records_remain" : "delete_unsupported_records_remain",
|
|
@@ -47398,7 +47895,8 @@ var init_router = __esm({
|
|
|
47398
47895
|
return handleMeshForwardEvent({ instanceManager: this.deps.instanceManager }, args);
|
|
47399
47896
|
}
|
|
47400
47897
|
case "get_pending_mesh_events": {
|
|
47401
|
-
const
|
|
47898
|
+
const meshId = typeof args?.meshId === "string" ? args.meshId.trim() : "";
|
|
47899
|
+
const events = drainPendingMeshCoordinatorEvents(meshId || void 0);
|
|
47402
47900
|
return { success: true, events };
|
|
47403
47901
|
}
|
|
47404
47902
|
case "launch_cli":
|
|
@@ -47927,14 +48425,8 @@ var init_router = __esm({
|
|
|
47927
48425
|
case "get_mesh": {
|
|
47928
48426
|
const meshId = typeof args?.meshId === "string" ? args.meshId.trim() : "";
|
|
47929
48427
|
if (!meshId) return { success: false, error: "meshId required" };
|
|
47930
|
-
|
|
47931
|
-
|
|
47932
|
-
const mesh = getMesh3(meshId);
|
|
47933
|
-
if (mesh) return { success: true, mesh };
|
|
47934
|
-
} catch {
|
|
47935
|
-
}
|
|
47936
|
-
const cached2 = this.inlineMeshCache.get(meshId);
|
|
47937
|
-
if (cached2) return { success: true, mesh: cached2 };
|
|
48428
|
+
const meshRecord = await this.getMeshForCommand(meshId, args?.inlineMesh, { preferInline: true });
|
|
48429
|
+
if (meshRecord?.mesh) return { success: true, mesh: meshRecord.mesh };
|
|
47938
48430
|
return { success: false, error: "Mesh not found" };
|
|
47939
48431
|
}
|
|
47940
48432
|
case "create_mesh": {
|
|
@@ -48456,7 +48948,14 @@ var init_router = __esm({
|
|
|
48456
48948
|
cliType
|
|
48457
48949
|
};
|
|
48458
48950
|
}
|
|
48459
|
-
const
|
|
48951
|
+
const sessionHostRecords = this.deps.sessionHostControl?.listSessions ? await this.deps.sessionHostControl.listSessions().catch(() => []) : [];
|
|
48952
|
+
const liveMeshSessions = partitionSessionHostRecords(Array.isArray(sessionHostRecords) ? sessionHostRecords : []).liveRuntimes;
|
|
48953
|
+
const workspace = readLiveMeshNodeWorkspace({
|
|
48954
|
+
meshId,
|
|
48955
|
+
nodeId: String(coordinatorNode.id || coordinatorNode.nodeId || preferredCoordinatorNodeId || ""),
|
|
48956
|
+
liveSessionRecords: liveMeshSessions,
|
|
48957
|
+
allowCoordinatorSession: true
|
|
48958
|
+
}) || (typeof coordinatorNode.workspace === "string" ? coordinatorNode.workspace.trim() : "");
|
|
48460
48959
|
if (!workspace) return { success: false, error: "Coordinator node workspace required", meshId, cliType };
|
|
48461
48960
|
if (!cliType) {
|
|
48462
48961
|
const resolved = await resolveProviderTypeFromPriority({
|
|
@@ -48618,7 +49117,7 @@ ${block}`);
|
|
|
48618
49117
|
workspace
|
|
48619
49118
|
};
|
|
48620
49119
|
}
|
|
48621
|
-
const { existsSync:
|
|
49120
|
+
const { existsSync: existsSync33, readFileSync: readFileSync24, writeFileSync: writeFileSync18, copyFileSync: copyFileSync5, mkdirSync: mkdirSync22 } = await import("fs");
|
|
48622
49121
|
const { dirname: dirname13 } = await import("path");
|
|
48623
49122
|
const mcpConfigPath = coordinatorSetup.configPath;
|
|
48624
49123
|
const hermesManualFallback = cliType === "hermes-cli" && configFormat === "hermes_config_yaml" ? createHermesManualMeshCoordinatorSetup(meshId, workspace) : null;
|
|
@@ -48661,14 +49160,14 @@ ${block}`);
|
|
|
48661
49160
|
if (hermesManualFallback) return returnManualFallback(message);
|
|
48662
49161
|
return { success: false, code: "mesh_coordinator_config_write_failed", error: message, meshId, cliType, workspace };
|
|
48663
49162
|
}
|
|
48664
|
-
const hadExistingMcpConfig =
|
|
49163
|
+
const hadExistingMcpConfig = existsSync33(mcpConfigPath);
|
|
48665
49164
|
let existingMcpConfig = hermesBaseConfig?.config || {};
|
|
48666
49165
|
if (hermesBaseConfig) {
|
|
48667
49166
|
copyHermesCoordinatorCredentialFiles(hermesBaseConfig.sourceHome, dirname13(mcpConfigPath));
|
|
48668
49167
|
}
|
|
48669
49168
|
if (hadExistingMcpConfig) {
|
|
48670
49169
|
try {
|
|
48671
|
-
const parsedExistingMcpConfig = parseMeshCoordinatorMcpConfig(
|
|
49170
|
+
const parsedExistingMcpConfig = parseMeshCoordinatorMcpConfig(readFileSync24(mcpConfigPath, "utf-8"), configFormat);
|
|
48672
49171
|
const existingCoordinatorConfig = hermesManualFallback ? stripHermesCoordinatorTempModelProviderOverrides(parsedExistingMcpConfig) : parsedExistingMcpConfig;
|
|
48673
49172
|
existingMcpConfig = { ...existingMcpConfig, ...existingCoordinatorConfig };
|
|
48674
49173
|
copyFileSync5(mcpConfigPath, mcpConfigPath + ".backup");
|
|
@@ -48764,92 +49263,157 @@ ${block}`);
|
|
|
48764
49263
|
const { readLedgerEntries: readLedgerEntries2, getLedgerSummary: getLedgerSummary2 } = await Promise.resolve().then(() => (init_mesh_ledger(), mesh_ledger_exports));
|
|
48765
49264
|
const ledgerEntries = readLedgerEntries2(meshId, { tail: 20 });
|
|
48766
49265
|
const ledgerSummary = getLedgerSummary2(meshId);
|
|
49266
|
+
const sessionHostRecords = this.deps.sessionHostControl?.listSessions ? await this.deps.sessionHostControl.listSessions().catch(() => []) : [];
|
|
49267
|
+
const liveMeshSessions = partitionSessionHostRecords(Array.isArray(sessionHostRecords) ? sessionHostRecords : []).liveRuntimes;
|
|
49268
|
+
const localMachineId = loadConfig().machineId || "";
|
|
49269
|
+
const selectedCoordinatorNodeId = readStringValue(
|
|
49270
|
+
mesh.coordinator?.preferredNodeId,
|
|
49271
|
+
mesh.nodes?.[0]?.id,
|
|
49272
|
+
mesh.nodes?.[0]?.nodeId
|
|
49273
|
+
);
|
|
49274
|
+
const inlineCoordinatorNodeId = meshRecord?.inline && Array.isArray(mesh.nodes) ? selectedCoordinatorNodeId : void 0;
|
|
49275
|
+
const refreshedAt = (/* @__PURE__ */ new Date()).toISOString();
|
|
48767
49276
|
const nodeStatuses = [];
|
|
48768
|
-
for (const node of mesh.nodes || []) {
|
|
49277
|
+
for (const [nodeIndex, node] of (mesh.nodes || []).entries()) {
|
|
49278
|
+
const nodeId = String(node.id || node.nodeId || "");
|
|
49279
|
+
const daemonId = readStringValue(node.daemonId);
|
|
49280
|
+
const providerPriority = readProviderPriorityFromPolicy(node.policy);
|
|
49281
|
+
const isSelfNode = Boolean(
|
|
49282
|
+
nodeId && inlineCoordinatorNodeId && nodeId === inlineCoordinatorNodeId
|
|
49283
|
+
) || Boolean(
|
|
49284
|
+
daemonId && (daemonId === localMachineId || daemonId === this.deps.statusInstanceId)
|
|
49285
|
+
) || Boolean(meshRecord?.inline && nodeIndex === 0);
|
|
48769
49286
|
const status = {
|
|
48770
|
-
nodeId
|
|
49287
|
+
nodeId,
|
|
48771
49288
|
machineLabel: node.machineLabel || node.id || node.nodeId,
|
|
48772
49289
|
workspace: node.workspace,
|
|
48773
49290
|
repoRoot: node.repoRoot,
|
|
48774
49291
|
isLocalWorktree: node.isLocalWorktree,
|
|
48775
49292
|
worktreeBranch: node.worktreeBranch,
|
|
48776
|
-
daemonId
|
|
49293
|
+
daemonId,
|
|
48777
49294
|
machineId: node.machineId,
|
|
49295
|
+
machineStatus: node.machineStatus,
|
|
48778
49296
|
health: "unknown",
|
|
48779
49297
|
providers: node.providers || [],
|
|
48780
|
-
|
|
49298
|
+
providerPriority,
|
|
49299
|
+
activeSessions: [],
|
|
49300
|
+
activeSessionDetails: [],
|
|
49301
|
+
launchReady: false
|
|
48781
49302
|
};
|
|
48782
|
-
if (
|
|
48783
|
-
|
|
48784
|
-
|
|
48785
|
-
|
|
49303
|
+
if (isSelfNode) {
|
|
49304
|
+
status.connection = {
|
|
49305
|
+
perspective: "selected_coordinator",
|
|
49306
|
+
source: "mesh_peer_status",
|
|
49307
|
+
state: "self",
|
|
49308
|
+
transport: "local",
|
|
49309
|
+
reported: true,
|
|
49310
|
+
reason: "Selected coordinator daemon",
|
|
49311
|
+
lastStateChangeAt: refreshedAt
|
|
49312
|
+
};
|
|
49313
|
+
} else if (daemonId) {
|
|
49314
|
+
const connection = this.deps.getMeshPeerConnectionStatus?.(daemonId);
|
|
49315
|
+
status.connection = connection ?? {
|
|
49316
|
+
perspective: "selected_coordinator",
|
|
49317
|
+
source: "not_reported",
|
|
49318
|
+
state: "unknown",
|
|
49319
|
+
transport: "unknown",
|
|
49320
|
+
reported: false,
|
|
49321
|
+
reason: "No live mesh peer telemetry reported by the selected coordinator yet."
|
|
49322
|
+
};
|
|
49323
|
+
} else {
|
|
49324
|
+
status.connection = {
|
|
49325
|
+
perspective: "selected_coordinator",
|
|
49326
|
+
source: "not_reported",
|
|
49327
|
+
state: "unknown",
|
|
49328
|
+
transport: "unknown",
|
|
49329
|
+
reported: false,
|
|
49330
|
+
reason: "Node has no daemon id, so mesh transport cannot be reported from the selected coordinator."
|
|
49331
|
+
};
|
|
49332
|
+
}
|
|
49333
|
+
const matchedLiveSessionRecords = collectLiveMeshSessionRecords({
|
|
49334
|
+
meshId,
|
|
49335
|
+
node,
|
|
49336
|
+
nodeId,
|
|
49337
|
+
liveSessionRecords: liveMeshSessions,
|
|
49338
|
+
allowCoordinatorSession: nodeId === selectedCoordinatorNodeId
|
|
49339
|
+
});
|
|
49340
|
+
const workspace = readLiveMeshNodeWorkspace({
|
|
49341
|
+
meshId,
|
|
49342
|
+
nodeId,
|
|
49343
|
+
liveSessionRecords: matchedLiveSessionRecords,
|
|
49344
|
+
allowCoordinatorSession: nodeId === selectedCoordinatorNodeId
|
|
49345
|
+
}) || (typeof node.workspace === "string" ? node.workspace : "");
|
|
49346
|
+
status.workspace = workspace || node.workspace;
|
|
49347
|
+
if (matchedLiveSessionRecords.length > 0) {
|
|
49348
|
+
const sessionIds = matchedLiveSessionRecords.map((record2) => typeof record2?.sessionId === "string" ? record2.sessionId : "").filter(Boolean);
|
|
49349
|
+
const providerTypes = matchedLiveSessionRecords.map((record2) => readStringValue(record2?.providerType)).filter(Boolean);
|
|
49350
|
+
status.activeSessions = sessionIds;
|
|
49351
|
+
status.activeSessionDetails = matchedLiveSessionRecords.map(summarizeMeshSessionRecord);
|
|
49352
|
+
if (providerTypes.length > 0) {
|
|
49353
|
+
status.providers = Array.from(/* @__PURE__ */ new Set([...Array.isArray(status.providers) ? status.providers : [], ...providerTypes]));
|
|
48786
49354
|
}
|
|
48787
|
-
|
|
48788
|
-
|
|
48789
|
-
|
|
48790
|
-
|
|
48791
|
-
|
|
48792
|
-
|
|
48793
|
-
|
|
48794
|
-
|
|
48795
|
-
|
|
48796
|
-
|
|
48797
|
-
|
|
48798
|
-
|
|
48799
|
-
|
|
48800
|
-
|
|
48801
|
-
|
|
48802
|
-
|
|
48803
|
-
|
|
48804
|
-
const stashCount = await runGit2(["stash", "list"]).catch(() => "");
|
|
48805
|
-
let ahead = 0, behind = 0;
|
|
48806
|
-
if (aheadBehind) {
|
|
48807
|
-
const parts = aheadBehind.split(/\s+/);
|
|
48808
|
-
if (parts.length >= 2) {
|
|
48809
|
-
behind = parseInt(parts[0], 10) || 0;
|
|
48810
|
-
ahead = parseInt(parts[1], 10) || 0;
|
|
49355
|
+
}
|
|
49356
|
+
if (workspace) {
|
|
49357
|
+
if (!fs10.existsSync(workspace)) {
|
|
49358
|
+
let remoteProbeApplied = false;
|
|
49359
|
+
if (!isSelfNode && daemonId && this.deps.dispatchMeshCommand) {
|
|
49360
|
+
try {
|
|
49361
|
+
const remoteResult = await Promise.race([
|
|
49362
|
+
this.deps.dispatchMeshCommand(daemonId, "git_status", { workspace }),
|
|
49363
|
+
new Promise((_2, reject) => setTimeout(() => reject(new Error("timeout")), 8e3))
|
|
49364
|
+
]);
|
|
49365
|
+
const remoteGit = remoteResult?.status ?? remoteResult?.git ?? remoteResult;
|
|
49366
|
+
if (remoteGit && typeof remoteGit === "object" && typeof remoteGit.isGitRepo === "boolean") {
|
|
49367
|
+
status.git = remoteGit;
|
|
49368
|
+
status.health = remoteGit.isGitRepo ? deriveMeshNodeHealthFromGit(remoteGit) : "degraded";
|
|
49369
|
+
remoteProbeApplied = true;
|
|
49370
|
+
}
|
|
49371
|
+
} catch {
|
|
48811
49372
|
}
|
|
48812
49373
|
}
|
|
48813
|
-
|
|
48814
|
-
|
|
48815
|
-
|
|
48816
|
-
|
|
48817
|
-
|
|
48818
|
-
|
|
48819
|
-
|
|
48820
|
-
|
|
48821
|
-
if (
|
|
48822
|
-
|
|
49374
|
+
if (!remoteProbeApplied) {
|
|
49375
|
+
const connectionState = readStringValue(status.connection?.state);
|
|
49376
|
+
const inlineTransitGit = buildInlineMeshTransitGitStatus(node);
|
|
49377
|
+
const pendingPeerGitProbe = !inlineTransitGit && !isSelfNode && !!daemonId && (readStringValue(status.machineStatus) === "online" || readStringValue(status.health) === "online" || connectionState === "connecting" || connectionState === "connected" || connectionState === "unknown");
|
|
49378
|
+
if (pendingPeerGitProbe) {
|
|
49379
|
+
status.gitProbePending = true;
|
|
49380
|
+
status.health = "unknown";
|
|
49381
|
+
}
|
|
49382
|
+
if (applyCachedInlineMeshNodeStatus(
|
|
49383
|
+
status,
|
|
49384
|
+
node,
|
|
49385
|
+
pendingPeerGitProbe ? { skipGit: true, skipError: true, skipHealth: true } : void 0
|
|
49386
|
+
)) {
|
|
49387
|
+
status.launchReady = !!daemonId && (readStringValue(status.machineStatus) === "online" || isSelfNode);
|
|
49388
|
+
nodeStatuses.push(status);
|
|
49389
|
+
continue;
|
|
49390
|
+
}
|
|
49391
|
+
if (meshRecord?.source === "inline_cache" && !isSelfNode) {
|
|
49392
|
+
status.launchReady = !!daemonId && (readStringValue(status.machineStatus) === "online" || isSelfNode);
|
|
49393
|
+
nodeStatuses.push(status);
|
|
49394
|
+
continue;
|
|
49395
|
+
}
|
|
48823
49396
|
}
|
|
48824
|
-
|
|
48825
|
-
|
|
48826
|
-
|
|
48827
|
-
|
|
48828
|
-
|
|
48829
|
-
|
|
48830
|
-
|
|
48831
|
-
|
|
48832
|
-
|
|
48833
|
-
|
|
48834
|
-
|
|
48835
|
-
|
|
48836
|
-
|
|
48837
|
-
|
|
48838
|
-
renamed: renamed2,
|
|
48839
|
-
hasConflicts: false,
|
|
48840
|
-
conflictFiles: [],
|
|
48841
|
-
stashCount: stashCount ? stashCount.split("\n").filter(Boolean).length : 0,
|
|
48842
|
-
lastCheckedAt: Date.now()
|
|
48843
|
-
};
|
|
48844
|
-
status.health = branch ? dirty ? "dirty" : "online" : "degraded";
|
|
48845
|
-
} catch {
|
|
48846
|
-
if (!applyCachedInlineMeshNodeStatus(status, node)) {
|
|
48847
|
-
status.health = "degraded";
|
|
49397
|
+
} else {
|
|
49398
|
+
try {
|
|
49399
|
+
const gitStatus = await getGitRepoStatus(workspace, { timeoutMs: 1e4, refreshUpstream: true });
|
|
49400
|
+
status.git = gitStatus;
|
|
49401
|
+
if (gitStatus.isGitRepo) {
|
|
49402
|
+
status.health = deriveMeshNodeHealthFromGit(gitStatus);
|
|
49403
|
+
} else {
|
|
49404
|
+
status.health = "degraded";
|
|
49405
|
+
if (gitStatus.error && !status.error) status.error = gitStatus.error;
|
|
49406
|
+
}
|
|
49407
|
+
} catch {
|
|
49408
|
+
if (!applyCachedInlineMeshNodeStatus(status, node)) {
|
|
49409
|
+
status.health = "degraded";
|
|
49410
|
+
}
|
|
48848
49411
|
}
|
|
48849
49412
|
}
|
|
48850
49413
|
} else {
|
|
48851
49414
|
applyCachedInlineMeshNodeStatus(status, node);
|
|
48852
49415
|
}
|
|
49416
|
+
status.launchReady = !!daemonId && (readStringValue(status.machineStatus) === "online" || isSelfNode);
|
|
48853
49417
|
nodeStatuses.push(status);
|
|
48854
49418
|
}
|
|
48855
49419
|
return {
|
|
@@ -48858,6 +49422,12 @@ ${block}`);
|
|
|
48858
49422
|
meshName: mesh.name,
|
|
48859
49423
|
repoIdentity: mesh.repoIdentity,
|
|
48860
49424
|
defaultBranch: mesh.defaultBranch,
|
|
49425
|
+
refreshedAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
49426
|
+
sourceOfTruth: {
|
|
49427
|
+
membership: meshRecord?.source === "inline_cache" ? "coordinator_inline_mesh_cache" : meshRecord?.source === "local_config" ? "local_mesh_config" : "inline_bootstrap_snapshot",
|
|
49428
|
+
coordinatorOwnsLiveTruth: meshRecord?.source !== "inline_bootstrap",
|
|
49429
|
+
historicalEvidenceOnly: ["recoveryHints", "ledger.summary", "queue.summary"]
|
|
49430
|
+
},
|
|
48861
49431
|
nodes: nodeStatuses,
|
|
48862
49432
|
queue: { tasks: queue, summary: queueSummary },
|
|
48863
49433
|
ledger: { entries: ledgerEntries, summary: ledgerSummary }
|
|
@@ -56936,6 +57506,7 @@ async function initDaemonComponents(config2) {
|
|
|
56936
57506
|
sessionHostControl: config2.sessionHostControl,
|
|
56937
57507
|
statusInstanceId: config2.statusInstanceId,
|
|
56938
57508
|
statusVersion: config2.statusVersion,
|
|
57509
|
+
getMeshPeerConnectionStatus: config2.getMeshPeerConnectionStatus,
|
|
56939
57510
|
getCdpLogFn: config2.getCdpLogFn || ((ideType) => LOG.forComponent(`CDP:${ideType}`).asLogFn())
|
|
56940
57511
|
});
|
|
56941
57512
|
poller = new AgentStreamPoller({
|
|
@@ -57237,6 +57808,7 @@ __export(src_exports, {
|
|
|
57237
57808
|
prepareSessionChatTailUpdate: () => prepareSessionChatTailUpdate,
|
|
57238
57809
|
prepareSessionModalUpdate: () => prepareSessionModalUpdate,
|
|
57239
57810
|
probeCdpPort: () => probeCdpPort,
|
|
57811
|
+
queuePendingMeshCoordinatorEvent: () => queuePendingMeshCoordinatorEvent,
|
|
57240
57812
|
readChatHistory: () => readChatHistory,
|
|
57241
57813
|
readLedgerEntries: () => readLedgerEntries,
|
|
57242
57814
|
readLedgerSlice: () => readLedgerSlice,
|
|
@@ -72139,7 +72711,7 @@ var require_buffer_list = __commonJS({
|
|
|
72139
72711
|
}
|
|
72140
72712
|
}, {
|
|
72141
72713
|
key: "join",
|
|
72142
|
-
value: function
|
|
72714
|
+
value: function join40(s) {
|
|
72143
72715
|
if (this.length === 0) return "";
|
|
72144
72716
|
var p = this.head;
|
|
72145
72717
|
var ret = "" + p.data;
|
|
@@ -86198,13 +86770,13 @@ function splitStringBySpace(str2) {
|
|
|
86198
86770
|
}
|
|
86199
86771
|
return pieces;
|
|
86200
86772
|
}
|
|
86201
|
-
var import_chardet, import_child_process12,
|
|
86773
|
+
var import_chardet, import_child_process12, import_fs12, import_node_path3, import_node_os3, import_node_crypto3, import_iconv_lite, ExternalEditor;
|
|
86202
86774
|
var init_esm4 = __esm({
|
|
86203
86775
|
"../../node_modules/@inquirer/external-editor/dist/esm/index.js"() {
|
|
86204
86776
|
"use strict";
|
|
86205
86777
|
import_chardet = __toESM(require_lib(), 1);
|
|
86206
86778
|
import_child_process12 = require("child_process");
|
|
86207
|
-
|
|
86779
|
+
import_fs12 = require("fs");
|
|
86208
86780
|
import_node_path3 = __toESM(require("path"), 1);
|
|
86209
86781
|
import_node_os3 = __toESM(require("os"), 1);
|
|
86210
86782
|
import_node_crypto3 = require("crypto");
|
|
@@ -86280,14 +86852,14 @@ var init_esm4 = __esm({
|
|
|
86280
86852
|
if (Object.prototype.hasOwnProperty.call(this.fileOptions, "mode")) {
|
|
86281
86853
|
opt.mode = this.fileOptions.mode;
|
|
86282
86854
|
}
|
|
86283
|
-
(0,
|
|
86855
|
+
(0, import_fs12.writeFileSync)(this.tempFile, this.text, opt);
|
|
86284
86856
|
} catch (createFileError) {
|
|
86285
86857
|
throw new CreateFileError(createFileError);
|
|
86286
86858
|
}
|
|
86287
86859
|
}
|
|
86288
86860
|
readTemporaryFile() {
|
|
86289
86861
|
try {
|
|
86290
|
-
const tempFileBuffer = (0,
|
|
86862
|
+
const tempFileBuffer = (0, import_fs12.readFileSync)(this.tempFile);
|
|
86291
86863
|
if (tempFileBuffer.length === 0) {
|
|
86292
86864
|
this.text = "";
|
|
86293
86865
|
} else {
|
|
@@ -86303,7 +86875,7 @@ var init_esm4 = __esm({
|
|
|
86303
86875
|
}
|
|
86304
86876
|
removeTemporaryFile() {
|
|
86305
86877
|
try {
|
|
86306
|
-
(0,
|
|
86878
|
+
(0, import_fs12.unlinkSync)(this.tempFile);
|
|
86307
86879
|
} catch (removeFileError) {
|
|
86308
86880
|
throw new RemoveFileError(removeFileError);
|
|
86309
86881
|
}
|
|
@@ -88005,25 +88577,25 @@ function resolvePackageVersion(options) {
|
|
|
88005
88577
|
const injectedVersion = options?.injectedVersion || "unknown";
|
|
88006
88578
|
const dir = options?.dirname || __dirname;
|
|
88007
88579
|
const possiblePaths = [
|
|
88008
|
-
(0,
|
|
88009
|
-
(0,
|
|
88010
|
-
(0,
|
|
88580
|
+
(0, import_path8.join)(dir, "..", "..", "package.json"),
|
|
88581
|
+
(0, import_path8.join)(dir, "..", "package.json"),
|
|
88582
|
+
(0, import_path8.join)(dir, "package.json")
|
|
88011
88583
|
];
|
|
88012
88584
|
for (const p of possiblePaths) {
|
|
88013
88585
|
try {
|
|
88014
|
-
const data = JSON.parse((0,
|
|
88586
|
+
const data = JSON.parse((0, import_fs13.readFileSync)(p, "utf-8"));
|
|
88015
88587
|
if (data.version) return data.version;
|
|
88016
88588
|
} catch {
|
|
88017
88589
|
}
|
|
88018
88590
|
}
|
|
88019
88591
|
return injectedVersion;
|
|
88020
88592
|
}
|
|
88021
|
-
var
|
|
88593
|
+
var import_fs13, import_path8;
|
|
88022
88594
|
var init_version = __esm({
|
|
88023
88595
|
"src/version.ts"() {
|
|
88024
88596
|
"use strict";
|
|
88025
|
-
|
|
88026
|
-
|
|
88597
|
+
import_fs13 = require("fs");
|
|
88598
|
+
import_path8 = require("path");
|
|
88027
88599
|
}
|
|
88028
88600
|
});
|
|
88029
88601
|
|
|
@@ -89959,7 +90531,7 @@ var require_filesystem = __commonJS({
|
|
|
89959
90531
|
var LDD_PATH = "/usr/bin/ldd";
|
|
89960
90532
|
var SELF_PATH = "/proc/self/exe";
|
|
89961
90533
|
var MAX_LENGTH = 2048;
|
|
89962
|
-
var
|
|
90534
|
+
var readFileSync24 = (path42) => {
|
|
89963
90535
|
const fd = fs24.openSync(path42, "r");
|
|
89964
90536
|
const buffer = Buffer.alloc(MAX_LENGTH);
|
|
89965
90537
|
const bytesRead = fs24.readSync(fd, buffer, 0, MAX_LENGTH, 0);
|
|
@@ -89984,7 +90556,7 @@ var require_filesystem = __commonJS({
|
|
|
89984
90556
|
module2.exports = {
|
|
89985
90557
|
LDD_PATH,
|
|
89986
90558
|
SELF_PATH,
|
|
89987
|
-
readFileSync:
|
|
90559
|
+
readFileSync: readFileSync24,
|
|
89988
90560
|
readFile: readFile2
|
|
89989
90561
|
};
|
|
89990
90562
|
}
|
|
@@ -90033,7 +90605,7 @@ var require_detect_libc = __commonJS({
|
|
|
90033
90605
|
"use strict";
|
|
90034
90606
|
var childProcess = require("child_process");
|
|
90035
90607
|
var { isLinux: isLinux2, getReport } = require_process();
|
|
90036
|
-
var { LDD_PATH, SELF_PATH, readFile: readFile2, readFileSync:
|
|
90608
|
+
var { LDD_PATH, SELF_PATH, readFile: readFile2, readFileSync: readFileSync24 } = require_filesystem();
|
|
90037
90609
|
var { interpreterPath } = require_elf();
|
|
90038
90610
|
var cachedFamilyInterpreter;
|
|
90039
90611
|
var cachedFamilyFilesystem;
|
|
@@ -90125,7 +90697,7 @@ var require_detect_libc = __commonJS({
|
|
|
90125
90697
|
}
|
|
90126
90698
|
cachedFamilyFilesystem = null;
|
|
90127
90699
|
try {
|
|
90128
|
-
const lddContent =
|
|
90700
|
+
const lddContent = readFileSync24(LDD_PATH);
|
|
90129
90701
|
cachedFamilyFilesystem = getFamilyFromLddContent(lddContent);
|
|
90130
90702
|
} catch (e) {
|
|
90131
90703
|
}
|
|
@@ -90150,7 +90722,7 @@ var require_detect_libc = __commonJS({
|
|
|
90150
90722
|
}
|
|
90151
90723
|
cachedFamilyInterpreter = null;
|
|
90152
90724
|
try {
|
|
90153
|
-
const selfContent =
|
|
90725
|
+
const selfContent = readFileSync24(SELF_PATH);
|
|
90154
90726
|
const path42 = interpreterPath(selfContent);
|
|
90155
90727
|
cachedFamilyInterpreter = familyFromInterpreterPath(path42);
|
|
90156
90728
|
} catch (e) {
|
|
@@ -90214,7 +90786,7 @@ var require_detect_libc = __commonJS({
|
|
|
90214
90786
|
}
|
|
90215
90787
|
cachedVersionFilesystem = null;
|
|
90216
90788
|
try {
|
|
90217
|
-
const lddContent =
|
|
90789
|
+
const lddContent = readFileSync24(LDD_PATH);
|
|
90218
90790
|
const versionMatch = lddContent.match(RE_GLIBC_VERSION);
|
|
90219
90791
|
if (versionMatch) {
|
|
90220
90792
|
cachedVersionFilesystem = versionMatch[1];
|
|
@@ -97213,11 +97785,30 @@ var init_daemon_mesh_manager = __esm({
|
|
|
97213
97785
|
nodeDatachannel = null;
|
|
97214
97786
|
peers = /* @__PURE__ */ new Map();
|
|
97215
97787
|
// Map<targetDaemonId, PeerEntry>
|
|
97788
|
+
peerSnapshots = /* @__PURE__ */ new Map();
|
|
97216
97789
|
pendingRequests = /* @__PURE__ */ new Map();
|
|
97217
97790
|
commandCallback;
|
|
97218
97791
|
p2pFailure(message, command, targetDaemonId) {
|
|
97219
97792
|
return new P2pRelayFailureError(message, { command, targetDaemonId });
|
|
97220
97793
|
}
|
|
97794
|
+
updatePeerSnapshot(targetDaemonId, state, patch = {}) {
|
|
97795
|
+
const previous = this.peerSnapshots.get(targetDaemonId);
|
|
97796
|
+
const now = (/* @__PURE__ */ new Date()).toISOString();
|
|
97797
|
+
this.peerSnapshots.set(targetDaemonId, {
|
|
97798
|
+
perspective: "selected_coordinator",
|
|
97799
|
+
source: "mesh_peer_status",
|
|
97800
|
+
reported: true,
|
|
97801
|
+
state,
|
|
97802
|
+
transport: patch.transport ?? previous?.transport ?? "unknown",
|
|
97803
|
+
reason: patch.reason ?? previous?.reason,
|
|
97804
|
+
lastStateChangeAt: now,
|
|
97805
|
+
lastConnectedAt: patch.lastConnectedAt ?? previous?.lastConnectedAt,
|
|
97806
|
+
lastCommandAt: patch.lastCommandAt ?? previous?.lastCommandAt
|
|
97807
|
+
});
|
|
97808
|
+
}
|
|
97809
|
+
getPeerConnectionStatus(targetDaemonId) {
|
|
97810
|
+
return this.peerSnapshots.get(targetDaemonId) ?? null;
|
|
97811
|
+
}
|
|
97221
97812
|
invalidatePeer(targetDaemonId, reason, options = {}) {
|
|
97222
97813
|
const peer = this.peers.get(targetDaemonId);
|
|
97223
97814
|
if (peer?.commandQueue) {
|
|
@@ -97232,6 +97823,11 @@ var init_daemon_mesh_manager = __esm({
|
|
|
97232
97823
|
pending.reject(this.p2pFailure(reason, pending.command, targetDaemonId));
|
|
97233
97824
|
}
|
|
97234
97825
|
}
|
|
97826
|
+
const snapshotState = peer?.state === "closed" ? "closed" : peer?.state === "disconnected" ? "disconnected" : "failed";
|
|
97827
|
+
this.updatePeerSnapshot(targetDaemonId, snapshotState, {
|
|
97828
|
+
reason,
|
|
97829
|
+
transport: peer?.isRelay === true ? "relay" : peer?.isRelay === false ? "direct" : "unknown"
|
|
97830
|
+
});
|
|
97235
97831
|
if (options.closeResources !== false && peer) {
|
|
97236
97832
|
try {
|
|
97237
97833
|
peer.dataChannel?.close?.();
|
|
@@ -97264,6 +97860,7 @@ var init_daemon_mesh_manager = __esm({
|
|
|
97264
97860
|
"send_chat",
|
|
97265
97861
|
"read_chat",
|
|
97266
97862
|
"get_chat_debug_bundle",
|
|
97863
|
+
"get_pending_mesh_events",
|
|
97267
97864
|
"git_status",
|
|
97268
97865
|
"git_diff_summary",
|
|
97269
97866
|
"launch_cli",
|
|
@@ -97351,6 +97948,20 @@ var init_daemon_mesh_manager = __esm({
|
|
|
97351
97948
|
if (!peer) {
|
|
97352
97949
|
throw this.p2pFailure("Failed to initiate P2P connection entry", command, targetDaemonId);
|
|
97353
97950
|
}
|
|
97951
|
+
const lastCommandAt = (/* @__PURE__ */ new Date()).toISOString();
|
|
97952
|
+
if (peer.state === "connected") {
|
|
97953
|
+
this.updatePeerSnapshot(targetDaemonId, "connected", {
|
|
97954
|
+
transport: peer.isRelay === true ? "relay" : peer.isRelay === false ? "direct" : "unknown",
|
|
97955
|
+
lastConnectedAt: this.peerSnapshots.get(targetDaemonId)?.lastConnectedAt,
|
|
97956
|
+
lastCommandAt
|
|
97957
|
+
});
|
|
97958
|
+
} else {
|
|
97959
|
+
this.updatePeerSnapshot(targetDaemonId, "connecting", {
|
|
97960
|
+
transport: peer.isRelay === true ? "relay" : peer.isRelay === false ? "direct" : "unknown",
|
|
97961
|
+
reason: "Waiting for mesh DataChannel to open.",
|
|
97962
|
+
lastCommandAt
|
|
97963
|
+
});
|
|
97964
|
+
}
|
|
97354
97965
|
return new Promise((resolve23, reject) => {
|
|
97355
97966
|
const requestId = `req_${Date.now()}_${Math.random().toString(36).slice(2, 8)}`;
|
|
97356
97967
|
const timer = setTimeout(() => {
|
|
@@ -97494,6 +98105,9 @@ var init_daemon_mesh_manager = __esm({
|
|
|
97494
98105
|
remoteDescriptionSet: false
|
|
97495
98106
|
};
|
|
97496
98107
|
this.peers.set(targetDaemonId, entry);
|
|
98108
|
+
this.updatePeerSnapshot(targetDaemonId, "connecting", {
|
|
98109
|
+
reason: isInitiator ? "P2P mesh connection initiated by the selected coordinator." : "Waiting for the remote daemon to finish the mesh DataChannel handshake."
|
|
98110
|
+
});
|
|
97497
98111
|
pc.onLocalDescription((sdp, type2) => {
|
|
97498
98112
|
this.serverConn.sendMeshCommand(targetDaemonId, type2 === "offer" ? "mesh_p2p_offer" : "mesh_p2p_answer", { sdp, type: type2 });
|
|
97499
98113
|
});
|
|
@@ -97504,7 +98118,26 @@ var init_daemon_mesh_manager = __esm({
|
|
|
97504
98118
|
LOG.info("Mesh", `[Mesh] P2P state with ${targetDaemonId.slice(0, 12)}: ${state}`);
|
|
97505
98119
|
if (state === "connected") {
|
|
97506
98120
|
entry.state = "connected";
|
|
98121
|
+
let transport = "unknown";
|
|
98122
|
+
try {
|
|
98123
|
+
const pair = pc.getSelectedCandidatePair?.();
|
|
98124
|
+
if (pair) {
|
|
98125
|
+
const localType = pair.local?.type || "unknown";
|
|
98126
|
+
const remoteType = pair.remote?.type || "unknown";
|
|
98127
|
+
entry.isRelay = localType === "relay" || remoteType === "relay";
|
|
98128
|
+
transport = entry.isRelay ? "relay" : "direct";
|
|
98129
|
+
LOG.info("Mesh", `[Mesh] Candidate pair with ${targetDaemonId.slice(0, 12)}: local=${localType} remote=${remoteType} \u2192 ${transport}`);
|
|
98130
|
+
}
|
|
98131
|
+
} catch {
|
|
98132
|
+
transport = entry.isRelay === true ? "relay" : entry.isRelay === false ? "direct" : "unknown";
|
|
98133
|
+
}
|
|
98134
|
+
this.updatePeerSnapshot(targetDaemonId, "connected", {
|
|
98135
|
+
transport,
|
|
98136
|
+
reason: transport === "relay" ? "Connected over TURN relay." : transport === "direct" ? "Connected directly peer-to-peer." : "Connected, but selected candidate pair details are unavailable.",
|
|
98137
|
+
lastConnectedAt: (/* @__PURE__ */ new Date()).toISOString()
|
|
98138
|
+
});
|
|
97507
98139
|
} else if (state === "failed" || state === "closed" || state === "disconnected") {
|
|
98140
|
+
entry.state = state;
|
|
97508
98141
|
this.invalidatePeer(targetDaemonId, `P2P state changed to ${state}`, { rejectPending: true, closeResources: false });
|
|
97509
98142
|
}
|
|
97510
98143
|
});
|
|
@@ -97522,6 +98155,11 @@ var init_daemon_mesh_manager = __esm({
|
|
|
97522
98155
|
dc.onOpen(() => {
|
|
97523
98156
|
LOG.info("Mesh", `[Mesh] DataChannel OPEN with ${targetDaemonId.slice(0, 12)}`);
|
|
97524
98157
|
entry.state = "connected";
|
|
98158
|
+
this.updatePeerSnapshot(targetDaemonId, "connected", {
|
|
98159
|
+
transport: entry.isRelay === true ? "relay" : entry.isRelay === false ? "direct" : "unknown",
|
|
98160
|
+
reason: entry.isRelay === true ? "Connected over TURN relay." : entry.isRelay === false ? "Connected directly peer-to-peer." : "DataChannel open; transport details not reported yet.",
|
|
98161
|
+
lastConnectedAt: (/* @__PURE__ */ new Date()).toISOString()
|
|
98162
|
+
});
|
|
97525
98163
|
if (entry.commandQueue) {
|
|
97526
98164
|
const queue = entry.commandQueue;
|
|
97527
98165
|
entry.commandQueue = [];
|
|
@@ -97801,6 +98439,7 @@ var init_adhdev_daemon = __esm({
|
|
|
97801
98439
|
"use strict";
|
|
97802
98440
|
init_server_connection();
|
|
97803
98441
|
init_src();
|
|
98442
|
+
init_mesh_events();
|
|
97804
98443
|
init_daemon_p2p2();
|
|
97805
98444
|
init_screenshot_controller();
|
|
97806
98445
|
init_session_host();
|
|
@@ -97817,7 +98456,7 @@ var init_adhdev_daemon = __esm({
|
|
|
97817
98456
|
init_version();
|
|
97818
98457
|
init_src();
|
|
97819
98458
|
init_runtime_defaults();
|
|
97820
|
-
pkgVersion = resolvePackageVersion({ injectedVersion: "0.9.82-rc.
|
|
98459
|
+
pkgVersion = resolvePackageVersion({ injectedVersion: "0.9.82-rc.30" });
|
|
97821
98460
|
AdhdevDaemon = class _AdhdevDaemon {
|
|
97822
98461
|
localHttpServer = null;
|
|
97823
98462
|
localWss = null;
|
|
@@ -98341,6 +98980,7 @@ ${err?.stack || ""}`);
|
|
|
98341
98980
|
if (!this.meshManager) throw new Error("Mesh manager not initialized");
|
|
98342
98981
|
return this.meshManager.sendCommand(daemonId, command, args);
|
|
98343
98982
|
},
|
|
98983
|
+
getMeshPeerConnectionStatus: (daemonId) => this.meshManager?.getPeerConnectionStatus(daemonId) ?? null,
|
|
98344
98984
|
onStatusChange: () => {
|
|
98345
98985
|
this.invalidateHotChatSnapshotCache();
|
|
98346
98986
|
this.statusReporter?.onStatusChange();
|
|
@@ -98710,6 +99350,7 @@ ${err?.stack || ""}`);
|
|
|
98710
99350
|
const meshId = this.readMeshString(settings.meshNodeFor);
|
|
98711
99351
|
const coordinatorDaemonId = this.readMeshString(settings.meshCoordinatorDaemonId);
|
|
98712
99352
|
if (!meshId || !coordinatorDaemonId) return;
|
|
99353
|
+
const relayTimestamp = typeof event.timestamp === "number" && Number.isFinite(event.timestamp) ? event.timestamp : this.readMeshString(event.timestamp) || void 0;
|
|
98713
99354
|
const payload = {
|
|
98714
99355
|
event: this.readMeshString(event.event),
|
|
98715
99356
|
meshId,
|
|
@@ -98718,7 +99359,8 @@ ${err?.stack || ""}`);
|
|
|
98718
99359
|
targetSessionId: this.readMeshString(event.targetSessionId) || instanceId,
|
|
98719
99360
|
providerType: this.readMeshString(event.providerType),
|
|
98720
99361
|
providerSessionId: this.readMeshString(event.providerSessionId),
|
|
98721
|
-
finalSummary: this.readMeshString(event.finalSummary) || this.readMeshString(event.summary)
|
|
99362
|
+
finalSummary: this.readMeshString(event.finalSummary) || this.readMeshString(event.summary),
|
|
99363
|
+
...relayTimestamp !== void 0 ? { timestamp: relayTimestamp } : {}
|
|
98722
99364
|
};
|
|
98723
99365
|
if (coordinatorDaemonId === localDaemonId) {
|
|
98724
99366
|
try {
|
|
@@ -98733,6 +99375,22 @@ ${err?.stack || ""}`);
|
|
|
98733
99375
|
await this.meshManager.sendCommand(coordinatorDaemonId, "mesh_forward_event", payload);
|
|
98734
99376
|
LOG.info("MeshEvents", `Relayed ${payload.event} for mesh ${meshId} to coordinator daemon ${coordinatorDaemonId.slice(0, 12)}\u2026`);
|
|
98735
99377
|
} catch (error48) {
|
|
99378
|
+
queuePendingMeshCoordinatorEvent({
|
|
99379
|
+
event: payload.event,
|
|
99380
|
+
meshId,
|
|
99381
|
+
nodeLabel: payload.nodeId ? `Node '${payload.nodeId}'` : payload.workspace ? `Agent at ${payload.workspace}` : "Remote agent",
|
|
99382
|
+
nodeId: payload.nodeId || void 0,
|
|
99383
|
+
workspace: payload.workspace || void 0,
|
|
99384
|
+
metadataEvent: {
|
|
99385
|
+
targetSessionId: payload.targetSessionId,
|
|
99386
|
+
providerType: payload.providerType,
|
|
99387
|
+
providerSessionId: payload.providerSessionId,
|
|
99388
|
+
finalSummary: payload.finalSummary,
|
|
99389
|
+
workspace: payload.workspace,
|
|
99390
|
+
...payload.timestamp !== void 0 ? { timestamp: payload.timestamp } : {}
|
|
99391
|
+
},
|
|
99392
|
+
queuedAt: Date.now()
|
|
99393
|
+
});
|
|
98736
99394
|
LOG.warn("MeshEvents", `Failed to relay ${payload.event} for mesh ${meshId}: ${error48?.message || error48}`);
|
|
98737
99395
|
}
|
|
98738
99396
|
}
|
|
@@ -99639,6 +100297,420 @@ var init_runtime_target_trace = __esm({
|
|
|
99639
100297
|
}
|
|
99640
100298
|
});
|
|
99641
100299
|
|
|
100300
|
+
// src/cli/service-commands.ts
|
|
100301
|
+
var service_commands_exports = {};
|
|
100302
|
+
__export(service_commands_exports, {
|
|
100303
|
+
buildPlist: () => buildPlist,
|
|
100304
|
+
installAutoStartServiceForCurrentProcess: () => installAutoStartServiceForCurrentProcess,
|
|
100305
|
+
isAutoStartServiceInstalled: () => isAutoStartServiceInstalled,
|
|
100306
|
+
registerServiceCommands: () => registerServiceCommands
|
|
100307
|
+
});
|
|
100308
|
+
function getDarwinPlistPath() {
|
|
100309
|
+
return import_node_path5.default.join(import_node_os4.default.homedir(), "Library", "LaunchAgents", `${LAUNCHD_LABEL}.plist`);
|
|
100310
|
+
}
|
|
100311
|
+
function getWindowsStartupDir() {
|
|
100312
|
+
const appData = process.env.APPDATA || import_node_path5.default.join(import_node_os4.default.homedir(), "AppData", "Roaming");
|
|
100313
|
+
return import_node_path5.default.join(appData, "Microsoft", "Windows", "Start Menu", "Programs", "Startup");
|
|
100314
|
+
}
|
|
100315
|
+
function getWindowsVbsPath() {
|
|
100316
|
+
return import_node_path5.default.join(getWindowsStartupDir(), "adhdev-daemon.vbs");
|
|
100317
|
+
}
|
|
100318
|
+
function resolveCliPath() {
|
|
100319
|
+
return import_node_fs4.default.realpathSync(process.argv[1]);
|
|
100320
|
+
}
|
|
100321
|
+
function ensureDir(dir) {
|
|
100322
|
+
if (!import_node_fs4.default.existsSync(dir)) import_node_fs4.default.mkdirSync(dir, { recursive: true });
|
|
100323
|
+
}
|
|
100324
|
+
async function fetchHealth() {
|
|
100325
|
+
const controller = new AbortController();
|
|
100326
|
+
const timer = setTimeout(() => controller.abort(), DEFAULT_LOCAL_DAEMON_HEALTH_TIMEOUT_MS2);
|
|
100327
|
+
try {
|
|
100328
|
+
const res = await fetch(`http://127.0.0.1:${DEFAULT_DAEMON_PORT}/health`, { signal: controller.signal });
|
|
100329
|
+
if (!res.ok) return null;
|
|
100330
|
+
return await res.json();
|
|
100331
|
+
} catch {
|
|
100332
|
+
return null;
|
|
100333
|
+
} finally {
|
|
100334
|
+
clearTimeout(timer);
|
|
100335
|
+
}
|
|
100336
|
+
}
|
|
100337
|
+
function getProcessInfo(pid) {
|
|
100338
|
+
try {
|
|
100339
|
+
if (process.platform === "win32") {
|
|
100340
|
+
const out = (0, import_node_child_process4.execSync)(`tasklist /FI "PID eq ${pid}" /FO CSV /NH`, { encoding: "utf-8" });
|
|
100341
|
+
const match = out.match(/"(\d[\d,]+)\sK"/);
|
|
100342
|
+
const memKB = match ? parseInt(match[1].replace(/,/g, ""), 10) : 0;
|
|
100343
|
+
return { uptime: "-", memMB: Math.round(memKB / 1024) };
|
|
100344
|
+
} else {
|
|
100345
|
+
const out = (0, import_node_child_process4.execSync)(`ps -o etime=,rss= -p ${pid}`, { encoding: "utf-8" }).trim();
|
|
100346
|
+
const parts = out.split(/\s+/);
|
|
100347
|
+
const etime = parts[0] || "-";
|
|
100348
|
+
const rssKB = parseInt(parts[1] || "0", 10);
|
|
100349
|
+
return { uptime: formatElapsed(etime), memMB: Math.round(rssKB / 1024) };
|
|
100350
|
+
}
|
|
100351
|
+
} catch {
|
|
100352
|
+
return null;
|
|
100353
|
+
}
|
|
100354
|
+
}
|
|
100355
|
+
function formatElapsed(etime) {
|
|
100356
|
+
const parts = etime.replace("-", ":").split(":").map(Number);
|
|
100357
|
+
if (parts.length === 4) return `${parts[0]}d ${parts[1]}h ${parts[2]}m`;
|
|
100358
|
+
if (parts.length === 3) return `${parts[0]}h ${parts[1]}m`;
|
|
100359
|
+
if (parts.length === 2) return `${parts[0]}m ${parts[1]}s`;
|
|
100360
|
+
return etime;
|
|
100361
|
+
}
|
|
100362
|
+
function rotateLogIfNeeded(logPath) {
|
|
100363
|
+
try {
|
|
100364
|
+
if (!import_node_fs4.default.existsSync(logPath)) return;
|
|
100365
|
+
const stat5 = import_node_fs4.default.statSync(logPath);
|
|
100366
|
+
if (stat5.size > MAX_LOG_SIZE2) {
|
|
100367
|
+
const rotated = logPath + ".old";
|
|
100368
|
+
if (import_node_fs4.default.existsSync(rotated)) import_node_fs4.default.unlinkSync(rotated);
|
|
100369
|
+
import_node_fs4.default.renameSync(logPath, rotated);
|
|
100370
|
+
import_node_fs4.default.writeFileSync(logPath, `[log rotated at ${(/* @__PURE__ */ new Date()).toISOString()}]
|
|
100371
|
+
`, "utf-8");
|
|
100372
|
+
}
|
|
100373
|
+
} catch {
|
|
100374
|
+
}
|
|
100375
|
+
}
|
|
100376
|
+
function rotateLogs() {
|
|
100377
|
+
rotateLogIfNeeded(LOG_OUT);
|
|
100378
|
+
rotateLogIfNeeded(LOG_ERR);
|
|
100379
|
+
}
|
|
100380
|
+
function normalizeLaunchdPathEntry(entry) {
|
|
100381
|
+
const trimmed = String(entry || "").trim();
|
|
100382
|
+
if (!trimmed) return null;
|
|
100383
|
+
if (trimmed.startsWith("~")) {
|
|
100384
|
+
return import_node_path5.default.join(import_node_os4.default.homedir(), trimmed.slice(1));
|
|
100385
|
+
}
|
|
100386
|
+
return import_node_path5.default.isAbsolute(trimmed) ? trimmed : null;
|
|
100387
|
+
}
|
|
100388
|
+
function buildLaunchdPath(nodeExe, currentPath = process.env.PATH || "") {
|
|
100389
|
+
const brewPrefix = import_node_fs4.default.existsSync("/opt/homebrew/bin") ? "/opt/homebrew/bin" : "/usr/local/bin";
|
|
100390
|
+
const entries = [];
|
|
100391
|
+
const seen = /* @__PURE__ */ new Set();
|
|
100392
|
+
const addEntry = (value) => {
|
|
100393
|
+
if (!value) return;
|
|
100394
|
+
const normalized = normalizeLaunchdPathEntry(value);
|
|
100395
|
+
if (!normalized || seen.has(normalized)) return;
|
|
100396
|
+
seen.add(normalized);
|
|
100397
|
+
entries.push(normalized);
|
|
100398
|
+
};
|
|
100399
|
+
addEntry(import_node_path5.default.dirname(nodeExe));
|
|
100400
|
+
for (const entry of String(currentPath || "").split(import_node_path5.default.delimiter)) {
|
|
100401
|
+
addEntry(entry);
|
|
100402
|
+
}
|
|
100403
|
+
for (const entry of [brewPrefix, "/usr/local/bin", "/usr/bin", "/bin", "/usr/sbin", "/sbin"]) {
|
|
100404
|
+
addEntry(entry);
|
|
100405
|
+
}
|
|
100406
|
+
return entries.join(":");
|
|
100407
|
+
}
|
|
100408
|
+
function buildPlist(nodeExe, cliExe, currentPath = process.env.PATH || "") {
|
|
100409
|
+
const pathValue = buildLaunchdPath(nodeExe, currentPath);
|
|
100410
|
+
return `<?xml version="1.0" encoding="UTF-8"?>
|
|
100411
|
+
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
|
100412
|
+
<plist version="1.0">
|
|
100413
|
+
<dict>
|
|
100414
|
+
<key>Label</key>
|
|
100415
|
+
<string>${LAUNCHD_LABEL}</string>
|
|
100416
|
+
<key>ProgramArguments</key>
|
|
100417
|
+
<array>
|
|
100418
|
+
<string>${nodeExe}</string>
|
|
100419
|
+
<string>${cliExe}</string>
|
|
100420
|
+
<string>daemon</string>
|
|
100421
|
+
</array>
|
|
100422
|
+
<key>RunAtLoad</key>
|
|
100423
|
+
<true/>
|
|
100424
|
+
<key>KeepAlive</key>
|
|
100425
|
+
<dict>
|
|
100426
|
+
<key>SuccessfulExit</key>
|
|
100427
|
+
<false/>
|
|
100428
|
+
</dict>
|
|
100429
|
+
<key>ThrottleInterval</key>
|
|
100430
|
+
<integer>30</integer>
|
|
100431
|
+
<key>StandardOutPath</key>
|
|
100432
|
+
<string>${LOG_OUT}</string>
|
|
100433
|
+
<key>StandardErrorPath</key>
|
|
100434
|
+
<string>${LOG_ERR}</string>
|
|
100435
|
+
<key>EnvironmentVariables</key>
|
|
100436
|
+
<dict>
|
|
100437
|
+
<key>PATH</key>
|
|
100438
|
+
<string>${pathValue}</string>
|
|
100439
|
+
</dict>
|
|
100440
|
+
</dict>
|
|
100441
|
+
</plist>`;
|
|
100442
|
+
}
|
|
100443
|
+
function installDarwin(nodeExe, cliExe) {
|
|
100444
|
+
const plistPath = getDarwinPlistPath();
|
|
100445
|
+
ensureDir(ADHDEV_DIR);
|
|
100446
|
+
ensureDir(import_node_path5.default.dirname(plistPath));
|
|
100447
|
+
import_node_fs4.default.writeFileSync(plistPath, buildPlist(nodeExe, cliExe), "utf-8");
|
|
100448
|
+
console.log(source_default.gray(` Plist: ${plistPath}`));
|
|
100449
|
+
try {
|
|
100450
|
+
(0, import_node_child_process4.execSync)(`launchctl unload "${plistPath}" 2>/dev/null`, { stdio: "ignore" });
|
|
100451
|
+
} catch {
|
|
100452
|
+
}
|
|
100453
|
+
try {
|
|
100454
|
+
(0, import_node_child_process4.execSync)(`launchctl load -w "${plistPath}"`, { stdio: "ignore" });
|
|
100455
|
+
console.log(source_default.green("\n \u2713 Registered as LaunchAgent \u2014 daemon will start on login."));
|
|
100456
|
+
console.log(source_default.gray(` Logs: ~/.adhdev/daemon-launchd.{out,err}`));
|
|
100457
|
+
} catch (e) {
|
|
100458
|
+
console.log(source_default.red(`
|
|
100459
|
+
\u2717 launchctl load failed: ${e.message}`));
|
|
100460
|
+
}
|
|
100461
|
+
}
|
|
100462
|
+
function uninstallDarwin() {
|
|
100463
|
+
const plistPath = getDarwinPlistPath();
|
|
100464
|
+
if (!import_node_fs4.default.existsSync(plistPath)) {
|
|
100465
|
+
console.log(source_default.yellow("\n \u26A0 Service is not installed."));
|
|
100466
|
+
return;
|
|
100467
|
+
}
|
|
100468
|
+
try {
|
|
100469
|
+
(0, import_node_child_process4.execSync)(`launchctl unload "${plistPath}" 2>/dev/null`, { stdio: "ignore" });
|
|
100470
|
+
} catch {
|
|
100471
|
+
}
|
|
100472
|
+
import_node_fs4.default.unlinkSync(plistPath);
|
|
100473
|
+
console.log(source_default.green("\n \u2713 Removed LaunchAgent. Daemon will no longer auto-start."));
|
|
100474
|
+
}
|
|
100475
|
+
function isInstalledDarwin() {
|
|
100476
|
+
return import_node_fs4.default.existsSync(getDarwinPlistPath());
|
|
100477
|
+
}
|
|
100478
|
+
function buildVbs(nodeExe, cliExe) {
|
|
100479
|
+
const logFile = import_node_path5.default.join(ADHDEV_DIR, "daemon-service.log").replace(/\\/g, "\\\\");
|
|
100480
|
+
const escapedNodeExe = nodeExe.replace(/\\/g, "\\\\");
|
|
100481
|
+
const escapedCliExe = cliExe.replace(/\\/g, "\\\\");
|
|
100482
|
+
return `' ADHDev Daemon Auto-Start (generated by adhdev service install)
|
|
100483
|
+
Set WshShell = CreateObject("WScript.Shell")
|
|
100484
|
+
WshShell.Run "cmd.exe /c """"${escapedNodeExe}"""" """"${escapedCliExe}"""" daemon >> """"${logFile}"""" 2>&1", 0, False
|
|
100485
|
+
`;
|
|
100486
|
+
}
|
|
100487
|
+
function installWindows(nodeExe, cliExe) {
|
|
100488
|
+
const vbsPath = getWindowsVbsPath();
|
|
100489
|
+
ensureDir(ADHDEV_DIR);
|
|
100490
|
+
ensureDir(import_node_path5.default.dirname(vbsPath));
|
|
100491
|
+
import_node_fs4.default.writeFileSync(vbsPath, buildVbs(nodeExe, cliExe), "utf-8");
|
|
100492
|
+
console.log(source_default.gray(` Startup script: ${vbsPath}`));
|
|
100493
|
+
console.log(source_default.green("\n \u2713 Registered in Startup folder \u2014 daemon will start on login (hidden)."));
|
|
100494
|
+
console.log(source_default.gray(` Logs: ${import_node_path5.default.join(ADHDEV_DIR, "daemon-service.log")}`));
|
|
100495
|
+
console.log(source_default.gray(" To start now without rebooting, run: adhdev daemon"));
|
|
100496
|
+
}
|
|
100497
|
+
function uninstallWindows() {
|
|
100498
|
+
const vbsPath = getWindowsVbsPath();
|
|
100499
|
+
if (!import_node_fs4.default.existsSync(vbsPath)) {
|
|
100500
|
+
console.log(source_default.yellow("\n \u26A0 Service is not installed."));
|
|
100501
|
+
return;
|
|
100502
|
+
}
|
|
100503
|
+
import_node_fs4.default.unlinkSync(vbsPath);
|
|
100504
|
+
console.log(source_default.green("\n \u2713 Removed Startup script. Daemon will no longer auto-start."));
|
|
100505
|
+
console.log(source_default.gray(" Note: a currently running daemon is not affected. Stop with: adhdev daemon:stop"));
|
|
100506
|
+
}
|
|
100507
|
+
function isInstalledWindows() {
|
|
100508
|
+
return import_node_fs4.default.existsSync(getWindowsVbsPath());
|
|
100509
|
+
}
|
|
100510
|
+
function isAutoStartServiceInstalled(platform12 = import_node_os4.default.platform()) {
|
|
100511
|
+
if (platform12 === "darwin") return isInstalledDarwin();
|
|
100512
|
+
if (platform12 === "win32") return isInstalledWindows();
|
|
100513
|
+
return false;
|
|
100514
|
+
}
|
|
100515
|
+
function installAutoStartServiceForCurrentProcess(platform12 = import_node_os4.default.platform()) {
|
|
100516
|
+
const nodeExe = process.execPath;
|
|
100517
|
+
const cliExe = resolveCliPath();
|
|
100518
|
+
if (platform12 === "darwin") {
|
|
100519
|
+
installDarwin(nodeExe, cliExe);
|
|
100520
|
+
return true;
|
|
100521
|
+
}
|
|
100522
|
+
if (platform12 === "win32") {
|
|
100523
|
+
installWindows(nodeExe, cliExe);
|
|
100524
|
+
return true;
|
|
100525
|
+
}
|
|
100526
|
+
return false;
|
|
100527
|
+
}
|
|
100528
|
+
function registerServiceCommands(program2) {
|
|
100529
|
+
const svc = program2.command("service").description("\u{1F50C} Manage ADHDev as an OS background auto-start service");
|
|
100530
|
+
svc.command("install").description("Register ADHDev daemon to start automatically on login").action(async () => {
|
|
100531
|
+
console.log(source_default.bold("\n \u{1F680} Installing ADHDev Background Service"));
|
|
100532
|
+
const platform12 = import_node_os4.default.platform();
|
|
100533
|
+
const nodeExe = process.execPath;
|
|
100534
|
+
const cliExe = resolveCliPath();
|
|
100535
|
+
console.log(source_default.gray(` Node: ${nodeExe}`));
|
|
100536
|
+
console.log(source_default.gray(` CLI: ${cliExe}`));
|
|
100537
|
+
console.log(source_default.gray(` Platform: ${platform12}`));
|
|
100538
|
+
if (!installAutoStartServiceForCurrentProcess(platform12)) {
|
|
100539
|
+
console.log(source_default.yellow("\n \u26A0 Auto-start service install is not supported on this platform."));
|
|
100540
|
+
console.log(source_default.gray(" On Linux, create a systemd user unit manually:"));
|
|
100541
|
+
console.log(source_default.gray(" ~/.config/systemd/user/adhdev-daemon.service"));
|
|
100542
|
+
}
|
|
100543
|
+
console.log();
|
|
100544
|
+
});
|
|
100545
|
+
svc.command("uninstall").description("Remove the OS background service").action(async () => {
|
|
100546
|
+
console.log(source_default.bold("\n \u{1F5D1}\uFE0F Removing ADHDev Background Service"));
|
|
100547
|
+
const platform12 = import_node_os4.default.platform();
|
|
100548
|
+
if (platform12 === "darwin") {
|
|
100549
|
+
uninstallDarwin();
|
|
100550
|
+
} else if (platform12 === "win32") {
|
|
100551
|
+
uninstallWindows();
|
|
100552
|
+
} else {
|
|
100553
|
+
console.log(source_default.yellow("\n \u26A0 Not supported on this platform."));
|
|
100554
|
+
}
|
|
100555
|
+
console.log();
|
|
100556
|
+
});
|
|
100557
|
+
svc.command("status").description("Show service installation state and live daemon health").action(async () => {
|
|
100558
|
+
const platform12 = import_node_os4.default.platform();
|
|
100559
|
+
const installed = isAutoStartServiceInstalled(platform12);
|
|
100560
|
+
if (installed) {
|
|
100561
|
+
console.log(source_default.green("\n \u2713 Service is installed."));
|
|
100562
|
+
if (platform12 === "darwin") console.log(source_default.gray(` Plist: ${getDarwinPlistPath()}`));
|
|
100563
|
+
else console.log(source_default.gray(` Script: ${getWindowsVbsPath()}`));
|
|
100564
|
+
} else {
|
|
100565
|
+
console.log(source_default.gray("\n \u2717 Service is not installed. Run: adhdev service install"));
|
|
100566
|
+
}
|
|
100567
|
+
const health = await fetchHealth();
|
|
100568
|
+
if (health?.ok && health.pid) {
|
|
100569
|
+
const info = getProcessInfo(health.pid);
|
|
100570
|
+
if (info) {
|
|
100571
|
+
console.log(source_default.green(` \u2713 Daemon running \u2014 PID ${health.pid}, uptime ${info.uptime}, ${info.memMB} MB`));
|
|
100572
|
+
} else {
|
|
100573
|
+
console.log(source_default.green(` \u2713 Daemon running \u2014 PID ${health.pid}`));
|
|
100574
|
+
}
|
|
100575
|
+
} else {
|
|
100576
|
+
console.log(source_default.yellow(" \u2717 Daemon is not running."));
|
|
100577
|
+
}
|
|
100578
|
+
const outSize = import_node_fs4.default.existsSync(LOG_OUT) ? import_node_fs4.default.statSync(LOG_OUT).size : 0;
|
|
100579
|
+
const errSize = import_node_fs4.default.existsSync(LOG_ERR) ? import_node_fs4.default.statSync(LOG_ERR).size : 0;
|
|
100580
|
+
if (outSize > 0 || errSize > 0) {
|
|
100581
|
+
console.log(source_default.gray(` Logs: stdout ${formatBytes(outSize)}, stderr ${formatBytes(errSize)}`));
|
|
100582
|
+
}
|
|
100583
|
+
console.log();
|
|
100584
|
+
});
|
|
100585
|
+
svc.command("logs").description("View daemon service logs").option("--err", "Show stderr log instead of stdout").option("--clear", "Truncate all log files").option("-n, --lines <count>", "Number of lines to show", "30").action(async (options) => {
|
|
100586
|
+
if (options.clear) {
|
|
100587
|
+
for (const f of [LOG_OUT, LOG_ERR]) {
|
|
100588
|
+
if (import_node_fs4.default.existsSync(f)) import_node_fs4.default.writeFileSync(f, "", "utf-8");
|
|
100589
|
+
}
|
|
100590
|
+
console.log(source_default.green("\n \u2713 Logs cleared.\n"));
|
|
100591
|
+
return;
|
|
100592
|
+
}
|
|
100593
|
+
const logFile = options.err ? LOG_ERR : LOG_OUT;
|
|
100594
|
+
if (!import_node_fs4.default.existsSync(logFile)) {
|
|
100595
|
+
console.log(source_default.gray(`
|
|
100596
|
+
No log file found: ${logFile}
|
|
100597
|
+
`));
|
|
100598
|
+
return;
|
|
100599
|
+
}
|
|
100600
|
+
const lines = parseInt(options.lines, 10) || 30;
|
|
100601
|
+
console.log(source_default.gray(`
|
|
100602
|
+
\u2500\u2500 ${options.err ? "stderr" : "stdout"}: ${logFile} (last ${lines} lines) \u2500\u2500
|
|
100603
|
+
`));
|
|
100604
|
+
const content = import_node_fs4.default.readFileSync(logFile, "utf-8");
|
|
100605
|
+
const allLines = content.split("\n");
|
|
100606
|
+
const lastLines = allLines.slice(-lines).join("\n");
|
|
100607
|
+
if (lastLines.trim()) console.log(lastLines);
|
|
100608
|
+
console.log(source_default.gray("\n (watching for new output, Ctrl+C to stop)\n"));
|
|
100609
|
+
let offset = Buffer.byteLength(content, "utf-8");
|
|
100610
|
+
const watcher = import_node_fs4.default.watchFile(logFile, { interval: 500 }, () => {
|
|
100611
|
+
try {
|
|
100612
|
+
const stat5 = import_node_fs4.default.statSync(logFile);
|
|
100613
|
+
if (stat5.size > offset) {
|
|
100614
|
+
const fd = import_node_fs4.default.openSync(logFile, "r");
|
|
100615
|
+
const buf = Buffer.alloc(stat5.size - offset);
|
|
100616
|
+
import_node_fs4.default.readSync(fd, buf, 0, buf.length, offset);
|
|
100617
|
+
import_node_fs4.default.closeSync(fd);
|
|
100618
|
+
process.stdout.write(buf.toString("utf-8"));
|
|
100619
|
+
offset = stat5.size;
|
|
100620
|
+
} else if (stat5.size < offset) {
|
|
100621
|
+
offset = 0;
|
|
100622
|
+
}
|
|
100623
|
+
} catch {
|
|
100624
|
+
}
|
|
100625
|
+
});
|
|
100626
|
+
const cleanup = () => {
|
|
100627
|
+
import_node_fs4.default.unwatchFile(logFile);
|
|
100628
|
+
process.exit(0);
|
|
100629
|
+
};
|
|
100630
|
+
process.on("SIGINT", cleanup);
|
|
100631
|
+
process.on("SIGTERM", cleanup);
|
|
100632
|
+
});
|
|
100633
|
+
svc.command("restart").description("Restart the daemon process (service will auto-relaunch)").action(async () => {
|
|
100634
|
+
const platform12 = import_node_os4.default.platform();
|
|
100635
|
+
const installed = isAutoStartServiceInstalled(platform12);
|
|
100636
|
+
if (!installed) {
|
|
100637
|
+
console.log(source_default.yellow("\n \u26A0 Service is not installed. Use `adhdev daemon:restart` for manual restart."));
|
|
100638
|
+
console.log(source_default.gray(" Or install the service first: adhdev service install\n"));
|
|
100639
|
+
return;
|
|
100640
|
+
}
|
|
100641
|
+
rotateLogs();
|
|
100642
|
+
if (platform12 === "darwin") {
|
|
100643
|
+
console.log(source_default.cyan("\n Refreshing LaunchAgent definition and reloading service..."));
|
|
100644
|
+
installAutoStartServiceForCurrentProcess(platform12);
|
|
100645
|
+
console.log();
|
|
100646
|
+
return;
|
|
100647
|
+
}
|
|
100648
|
+
const health = await fetchHealth();
|
|
100649
|
+
if (!health?.pid) {
|
|
100650
|
+
console.log(source_default.yellow("\n \u26A0 Daemon is not currently running."));
|
|
100651
|
+
console.log(source_default.gray(" Start with: adhdev daemon\n"));
|
|
100652
|
+
return;
|
|
100653
|
+
}
|
|
100654
|
+
console.log(source_default.cyan(`
|
|
100655
|
+
Stopping daemon (PID ${health.pid})...`));
|
|
100656
|
+
try {
|
|
100657
|
+
process.kill(health.pid, "SIGTERM");
|
|
100658
|
+
} catch {
|
|
100659
|
+
console.log(source_default.yellow(" Could not send SIGTERM. Process may have already exited."));
|
|
100660
|
+
}
|
|
100661
|
+
await new Promise((r) => setTimeout(r, 2e3));
|
|
100662
|
+
if (platform12 === "win32") {
|
|
100663
|
+
const vbsPath = getWindowsVbsPath();
|
|
100664
|
+
if (import_node_fs4.default.existsSync(vbsPath)) {
|
|
100665
|
+
try {
|
|
100666
|
+
(0, import_node_child_process4.execSync)(`wscript.exe "${vbsPath}"`, { stdio: "ignore", windowsHide: true });
|
|
100667
|
+
} catch {
|
|
100668
|
+
}
|
|
100669
|
+
}
|
|
100670
|
+
}
|
|
100671
|
+
let restarted = false;
|
|
100672
|
+
for (let i = 0; i < 8; i++) {
|
|
100673
|
+
await new Promise((r) => setTimeout(r, 1e3));
|
|
100674
|
+
const newHealth = await fetchHealth();
|
|
100675
|
+
if (newHealth?.ok && newHealth.pid !== health.pid) {
|
|
100676
|
+
restarted = true;
|
|
100677
|
+
const info = getProcessInfo(newHealth.pid);
|
|
100678
|
+
console.log(source_default.green(` \u2713 Daemon restarted \u2014 new PID ${newHealth.pid}${info ? `, ${info.memMB} MB` : ""}`));
|
|
100679
|
+
break;
|
|
100680
|
+
}
|
|
100681
|
+
}
|
|
100682
|
+
if (!restarted) {
|
|
100683
|
+
console.log(source_default.yellow(" \u26A0 Daemon did not restart within 10s."));
|
|
100684
|
+
console.log(source_default.gray(" Check: adhdev service logs --err"));
|
|
100685
|
+
}
|
|
100686
|
+
console.log();
|
|
100687
|
+
});
|
|
100688
|
+
}
|
|
100689
|
+
function formatBytes(bytes) {
|
|
100690
|
+
if (bytes === 0) return "0 B";
|
|
100691
|
+
if (bytes < 1024) return `${bytes} B`;
|
|
100692
|
+
if (bytes < 1024 * 1024) return `${(bytes / 1024).toFixed(1)} KB`;
|
|
100693
|
+
return `${(bytes / (1024 * 1024)).toFixed(1)} MB`;
|
|
100694
|
+
}
|
|
100695
|
+
var import_node_fs4, import_node_path5, import_node_os4, import_node_child_process4, DEFAULT_LOCAL_DAEMON_HEALTH_TIMEOUT_MS2, LAUNCHD_LABEL, ADHDEV_DIR, LOG_OUT, LOG_ERR, MAX_LOG_SIZE2;
|
|
100696
|
+
var init_service_commands = __esm({
|
|
100697
|
+
"src/cli/service-commands.ts"() {
|
|
100698
|
+
"use strict";
|
|
100699
|
+
import_node_fs4 = __toESM(require("fs"));
|
|
100700
|
+
import_node_path5 = __toESM(require("path"));
|
|
100701
|
+
import_node_os4 = __toESM(require("os"));
|
|
100702
|
+
import_node_child_process4 = require("child_process");
|
|
100703
|
+
init_source();
|
|
100704
|
+
init_src();
|
|
100705
|
+
DEFAULT_LOCAL_DAEMON_HEALTH_TIMEOUT_MS2 = 1500;
|
|
100706
|
+
LAUNCHD_LABEL = "dev.adhf.daemon";
|
|
100707
|
+
ADHDEV_DIR = import_node_path5.default.join(import_node_os4.default.homedir(), ".adhdev");
|
|
100708
|
+
LOG_OUT = import_node_path5.default.join(ADHDEV_DIR, "daemon-launchd.out");
|
|
100709
|
+
LOG_ERR = import_node_path5.default.join(ADHDEV_DIR, "daemon-launchd.err");
|
|
100710
|
+
MAX_LOG_SIZE2 = 10 * 1024 * 1024;
|
|
100711
|
+
}
|
|
100712
|
+
});
|
|
100713
|
+
|
|
99642
100714
|
// ../../oss/packages/web-core/src/constants/supported.ts
|
|
99643
100715
|
var supported_exports = {};
|
|
99644
100716
|
__export(supported_exports, {
|
|
@@ -101612,7 +102684,7 @@ function formatDebugTraceEntryLine(entry) {
|
|
|
101612
102684
|
}
|
|
101613
102685
|
|
|
101614
102686
|
// src/cli/daemon-commands.ts
|
|
101615
|
-
var
|
|
102687
|
+
var DEFAULT_LOCAL_DAEMON_HEALTH_TIMEOUT_MS3 = 1500;
|
|
101616
102688
|
var DEFAULT_TRACE_FOLLOW_INTERVAL_MS = 1500;
|
|
101617
102689
|
var DEFAULT_DAEMON_PORT_TEXT = String(DEFAULT_DAEMON_PORT);
|
|
101618
102690
|
var DEV_SERVER_PORT2 = 19280;
|
|
@@ -101640,6 +102712,15 @@ async function resolveConfiguredUpdateChannel() {
|
|
|
101640
102712
|
function releaseChannelLabel(channel) {
|
|
101641
102713
|
return `${channel} (${CHANNEL_NPM_TAG3[channel]})`;
|
|
101642
102714
|
}
|
|
102715
|
+
function buildDaemonRestartCommandArgv(options = {}) {
|
|
102716
|
+
const cliPath = options.cliPath || process.argv[1];
|
|
102717
|
+
const daemonPort = options.daemonPort || DEFAULT_DAEMON_PORT_TEXT;
|
|
102718
|
+
const platform12 = options.platform || process.platform;
|
|
102719
|
+
if (platform12 === "darwin" && options.serviceInstalled) {
|
|
102720
|
+
return [cliPath, "service", "install"];
|
|
102721
|
+
}
|
|
102722
|
+
return [cliPath, "daemon", "-p", daemonPort];
|
|
102723
|
+
}
|
|
101643
102724
|
async function persistReleaseChannel(channel) {
|
|
101644
102725
|
const { updateConfig: updateConfig2 } = await Promise.resolve().then(() => (init_src(), src_exports));
|
|
101645
102726
|
updateConfig2({ updateChannel: channel, serverUrl: CHANNEL_SERVER_URL3[channel] });
|
|
@@ -101650,7 +102731,7 @@ function hideCommand(command) {
|
|
|
101650
102731
|
}
|
|
101651
102732
|
async function fetchLocalDaemonHealth(port) {
|
|
101652
102733
|
const controller = new AbortController();
|
|
101653
|
-
const timer = setTimeout(() => controller.abort(),
|
|
102734
|
+
const timer = setTimeout(() => controller.abort(), DEFAULT_LOCAL_DAEMON_HEALTH_TIMEOUT_MS3);
|
|
101654
102735
|
try {
|
|
101655
102736
|
const res = await fetch(`http://127.0.0.1:${port}/health`, { signal: controller.signal });
|
|
101656
102737
|
if (!res.ok) return null;
|
|
@@ -102016,6 +103097,9 @@ async function runDaemonUpgrade(options, pkgVersion3) {
|
|
|
102016
103097
|
} else {
|
|
102017
103098
|
console.log(source_default.cyan(`
|
|
102018
103099
|
Upgrading v${currentVersion} \u2192 v${latest}...`));
|
|
103100
|
+
const { isAutoStartServiceInstalled: isAutoStartServiceInstalled2 } = await Promise.resolve().then(() => (init_service_commands(), service_commands_exports));
|
|
103101
|
+
const serviceInstalled = isAutoStartServiceInstalled2();
|
|
103102
|
+
const shouldRefreshInstalledService = options.restart !== false && process.platform === "darwin" && serviceInstalled;
|
|
102019
103103
|
const daemonWasRunning = options.restart !== false && isDaemonRunning2();
|
|
102020
103104
|
if (daemonWasRunning) {
|
|
102021
103105
|
stopDaemon2();
|
|
@@ -102027,10 +103111,22 @@ async function runDaemonUpgrade(options, pkgVersion3) {
|
|
|
102027
103111
|
packageName: "adhdev",
|
|
102028
103112
|
targetVersion: latest,
|
|
102029
103113
|
parentPid: process.pid,
|
|
102030
|
-
restartArgv:
|
|
103114
|
+
restartArgv: shouldRefreshInstalledService ? buildDaemonRestartCommandArgv({
|
|
103115
|
+
cliPath: process.argv[1],
|
|
103116
|
+
daemonPort: DEFAULT_DAEMON_PORT_TEXT,
|
|
103117
|
+
platform: process.platform,
|
|
103118
|
+
serviceInstalled
|
|
103119
|
+
}) : daemonWasRunning ? buildDaemonRestartCommandArgv({
|
|
103120
|
+
cliPath: process.argv[1],
|
|
103121
|
+
daemonPort: DEFAULT_DAEMON_PORT_TEXT,
|
|
103122
|
+
platform: process.platform,
|
|
103123
|
+
serviceInstalled
|
|
103124
|
+
}) : [],
|
|
102031
103125
|
cwd: process.cwd()
|
|
102032
103126
|
});
|
|
102033
|
-
if (
|
|
103127
|
+
if (shouldRefreshInstalledService) {
|
|
103128
|
+
console.log(source_default.cyan(" Upgrading and refreshing background service in background..."));
|
|
103129
|
+
} else if (daemonWasRunning) {
|
|
102034
103130
|
console.log(source_default.cyan(" Upgrading and restarting daemon in background..."));
|
|
102035
103131
|
} else {
|
|
102036
103132
|
console.log(source_default.cyan(" Upgrading in background..."));
|
|
@@ -102042,29 +103138,44 @@ async function runDaemonUpgrade(options, pkgVersion3) {
|
|
|
102042
103138
|
return;
|
|
102043
103139
|
}
|
|
102044
103140
|
}
|
|
102045
|
-
if (options.restart !== false
|
|
102046
|
-
|
|
102047
|
-
|
|
102048
|
-
|
|
102049
|
-
|
|
102050
|
-
|
|
102051
|
-
|
|
102052
|
-
|
|
102053
|
-
|
|
102054
|
-
windowsHide: true,
|
|
102055
|
-
env: { ...process.env }
|
|
102056
|
-
});
|
|
102057
|
-
child.unref();
|
|
102058
|
-
await new Promise((r) => setTimeout(r, 3e3));
|
|
103141
|
+
if (options.restart !== false) {
|
|
103142
|
+
const { installAutoStartServiceForCurrentProcess: installAutoStartServiceForCurrentProcess2, isAutoStartServiceInstalled: isAutoStartServiceInstalled2 } = await Promise.resolve().then(() => (init_service_commands(), service_commands_exports));
|
|
103143
|
+
const serviceInstalled = isAutoStartServiceInstalled2();
|
|
103144
|
+
if (process.platform === "darwin" && serviceInstalled) {
|
|
103145
|
+
console.log(source_default.yellow("\n Refreshing LaunchAgent definition..."));
|
|
103146
|
+
installAutoStartServiceForCurrentProcess2(process.platform);
|
|
103147
|
+
console.log();
|
|
103148
|
+
return;
|
|
103149
|
+
}
|
|
102059
103150
|
if (isDaemonRunning2()) {
|
|
102060
|
-
console.log(source_default.
|
|
103151
|
+
console.log(source_default.yellow("\n Restarting daemon..."));
|
|
103152
|
+
stopDaemon2();
|
|
103153
|
+
await new Promise((r) => setTimeout(r, 2e3));
|
|
103154
|
+
stopManagedSessionHostProcess2();
|
|
103155
|
+
await new Promise((r) => setTimeout(r, 500));
|
|
103156
|
+
const child = spawn7(process.execPath, buildDaemonRestartCommandArgv({
|
|
103157
|
+
cliPath: process.argv[1],
|
|
103158
|
+
daemonPort: DEFAULT_DAEMON_PORT_TEXT,
|
|
103159
|
+
platform: process.platform,
|
|
103160
|
+
serviceInstalled
|
|
103161
|
+
}), {
|
|
103162
|
+
detached: true,
|
|
103163
|
+
stdio: "ignore",
|
|
103164
|
+
windowsHide: true,
|
|
103165
|
+
env: { ...process.env }
|
|
103166
|
+
});
|
|
103167
|
+
child.unref();
|
|
103168
|
+
await new Promise((r) => setTimeout(r, 3e3));
|
|
103169
|
+
if (isDaemonRunning2()) {
|
|
103170
|
+
console.log(source_default.green(` \u2713 Daemon restarted with new version
|
|
102061
103171
|
`));
|
|
102062
|
-
|
|
102063
|
-
|
|
103172
|
+
} else {
|
|
103173
|
+
console.log(source_default.yellow(` \u26A0 Daemon not detected. Start manually: adhdev daemon
|
|
102064
103174
|
`));
|
|
103175
|
+
}
|
|
103176
|
+
} else {
|
|
103177
|
+
console.log(source_default.gray("\n Daemon was not running. Start with: adhdev daemon\n"));
|
|
102065
103178
|
}
|
|
102066
|
-
} else if (options.restart !== false) {
|
|
102067
|
-
console.log(source_default.gray("\n Daemon was not running. Start with: adhdev daemon\n"));
|
|
102068
103179
|
} else {
|
|
102069
103180
|
console.log(source_default.green("\n \u2713 Upgrade complete (daemon not restarted)\n"));
|
|
102070
103181
|
}
|
|
@@ -102235,7 +103346,7 @@ function registerDaemonCommands(program2, pkgVersion3) {
|
|
|
102235
103346
|
}
|
|
102236
103347
|
try {
|
|
102237
103348
|
const controller = new AbortController();
|
|
102238
|
-
const timer = setTimeout(() => controller.abort(),
|
|
103349
|
+
const timer = setTimeout(() => controller.abort(), DEFAULT_LOCAL_DAEMON_HEALTH_TIMEOUT_MS3);
|
|
102239
103350
|
const res = await fetch(`${DEV_SERVER_BASE_URL}/api/status`, { signal: controller.signal });
|
|
102240
103351
|
clearTimeout(timer);
|
|
102241
103352
|
if (res.ok) {
|
|
@@ -102782,373 +103893,8 @@ function buildDoctorAdvice(input) {
|
|
|
102782
103893
|
return advice;
|
|
102783
103894
|
}
|
|
102784
103895
|
|
|
102785
|
-
// src/cli/service-commands.ts
|
|
102786
|
-
var import_node_fs4 = __toESM(require("fs"));
|
|
102787
|
-
var import_node_path5 = __toESM(require("path"));
|
|
102788
|
-
var import_node_os4 = __toESM(require("os"));
|
|
102789
|
-
var import_node_child_process4 = require("child_process");
|
|
102790
|
-
init_source();
|
|
102791
|
-
init_src();
|
|
102792
|
-
var DEFAULT_LOCAL_DAEMON_HEALTH_TIMEOUT_MS3 = 1500;
|
|
102793
|
-
var LAUNCHD_LABEL = "dev.adhf.daemon";
|
|
102794
|
-
var ADHDEV_DIR = import_node_path5.default.join(import_node_os4.default.homedir(), ".adhdev");
|
|
102795
|
-
var LOG_OUT = import_node_path5.default.join(ADHDEV_DIR, "daemon-launchd.out");
|
|
102796
|
-
var LOG_ERR = import_node_path5.default.join(ADHDEV_DIR, "daemon-launchd.err");
|
|
102797
|
-
var MAX_LOG_SIZE2 = 10 * 1024 * 1024;
|
|
102798
|
-
function getDarwinPlistPath() {
|
|
102799
|
-
return import_node_path5.default.join(import_node_os4.default.homedir(), "Library", "LaunchAgents", `${LAUNCHD_LABEL}.plist`);
|
|
102800
|
-
}
|
|
102801
|
-
function getWindowsStartupDir() {
|
|
102802
|
-
const appData = process.env.APPDATA || import_node_path5.default.join(import_node_os4.default.homedir(), "AppData", "Roaming");
|
|
102803
|
-
return import_node_path5.default.join(appData, "Microsoft", "Windows", "Start Menu", "Programs", "Startup");
|
|
102804
|
-
}
|
|
102805
|
-
function getWindowsVbsPath() {
|
|
102806
|
-
return import_node_path5.default.join(getWindowsStartupDir(), "adhdev-daemon.vbs");
|
|
102807
|
-
}
|
|
102808
|
-
function resolveCliPath() {
|
|
102809
|
-
return import_node_fs4.default.realpathSync(process.argv[1]);
|
|
102810
|
-
}
|
|
102811
|
-
function ensureDir(dir) {
|
|
102812
|
-
if (!import_node_fs4.default.existsSync(dir)) import_node_fs4.default.mkdirSync(dir, { recursive: true });
|
|
102813
|
-
}
|
|
102814
|
-
async function fetchHealth() {
|
|
102815
|
-
const controller = new AbortController();
|
|
102816
|
-
const timer = setTimeout(() => controller.abort(), DEFAULT_LOCAL_DAEMON_HEALTH_TIMEOUT_MS3);
|
|
102817
|
-
try {
|
|
102818
|
-
const res = await fetch(`http://127.0.0.1:${DEFAULT_DAEMON_PORT}/health`, { signal: controller.signal });
|
|
102819
|
-
if (!res.ok) return null;
|
|
102820
|
-
return await res.json();
|
|
102821
|
-
} catch {
|
|
102822
|
-
return null;
|
|
102823
|
-
} finally {
|
|
102824
|
-
clearTimeout(timer);
|
|
102825
|
-
}
|
|
102826
|
-
}
|
|
102827
|
-
function getProcessInfo(pid) {
|
|
102828
|
-
try {
|
|
102829
|
-
if (process.platform === "win32") {
|
|
102830
|
-
const out = (0, import_node_child_process4.execSync)(`tasklist /FI "PID eq ${pid}" /FO CSV /NH`, { encoding: "utf-8" });
|
|
102831
|
-
const match = out.match(/"(\d[\d,]+)\sK"/);
|
|
102832
|
-
const memKB = match ? parseInt(match[1].replace(/,/g, ""), 10) : 0;
|
|
102833
|
-
return { uptime: "-", memMB: Math.round(memKB / 1024) };
|
|
102834
|
-
} else {
|
|
102835
|
-
const out = (0, import_node_child_process4.execSync)(`ps -o etime=,rss= -p ${pid}`, { encoding: "utf-8" }).trim();
|
|
102836
|
-
const parts = out.split(/\s+/);
|
|
102837
|
-
const etime = parts[0] || "-";
|
|
102838
|
-
const rssKB = parseInt(parts[1] || "0", 10);
|
|
102839
|
-
return { uptime: formatElapsed(etime), memMB: Math.round(rssKB / 1024) };
|
|
102840
|
-
}
|
|
102841
|
-
} catch {
|
|
102842
|
-
return null;
|
|
102843
|
-
}
|
|
102844
|
-
}
|
|
102845
|
-
function formatElapsed(etime) {
|
|
102846
|
-
const parts = etime.replace("-", ":").split(":").map(Number);
|
|
102847
|
-
if (parts.length === 4) return `${parts[0]}d ${parts[1]}h ${parts[2]}m`;
|
|
102848
|
-
if (parts.length === 3) return `${parts[0]}h ${parts[1]}m`;
|
|
102849
|
-
if (parts.length === 2) return `${parts[0]}m ${parts[1]}s`;
|
|
102850
|
-
return etime;
|
|
102851
|
-
}
|
|
102852
|
-
function rotateLogIfNeeded(logPath) {
|
|
102853
|
-
try {
|
|
102854
|
-
if (!import_node_fs4.default.existsSync(logPath)) return;
|
|
102855
|
-
const stat5 = import_node_fs4.default.statSync(logPath);
|
|
102856
|
-
if (stat5.size > MAX_LOG_SIZE2) {
|
|
102857
|
-
const rotated = logPath + ".old";
|
|
102858
|
-
if (import_node_fs4.default.existsSync(rotated)) import_node_fs4.default.unlinkSync(rotated);
|
|
102859
|
-
import_node_fs4.default.renameSync(logPath, rotated);
|
|
102860
|
-
import_node_fs4.default.writeFileSync(logPath, `[log rotated at ${(/* @__PURE__ */ new Date()).toISOString()}]
|
|
102861
|
-
`, "utf-8");
|
|
102862
|
-
}
|
|
102863
|
-
} catch {
|
|
102864
|
-
}
|
|
102865
|
-
}
|
|
102866
|
-
function rotateLogs() {
|
|
102867
|
-
rotateLogIfNeeded(LOG_OUT);
|
|
102868
|
-
rotateLogIfNeeded(LOG_ERR);
|
|
102869
|
-
}
|
|
102870
|
-
function buildPlist(nodeExe, cliExe) {
|
|
102871
|
-
const brewPrefix = import_node_fs4.default.existsSync("/opt/homebrew/bin") ? "/opt/homebrew/bin" : "/usr/local/bin";
|
|
102872
|
-
const nodeDir = import_node_path5.default.dirname(nodeExe);
|
|
102873
|
-
const pathEntries = /* @__PURE__ */ new Set([nodeDir, brewPrefix, "/usr/local/bin", "/usr/bin", "/bin", "/usr/sbin", "/sbin"]);
|
|
102874
|
-
const pathValue = Array.from(pathEntries).join(":");
|
|
102875
|
-
return `<?xml version="1.0" encoding="UTF-8"?>
|
|
102876
|
-
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
|
102877
|
-
<plist version="1.0">
|
|
102878
|
-
<dict>
|
|
102879
|
-
<key>Label</key>
|
|
102880
|
-
<string>${LAUNCHD_LABEL}</string>
|
|
102881
|
-
<key>ProgramArguments</key>
|
|
102882
|
-
<array>
|
|
102883
|
-
<string>${nodeExe}</string>
|
|
102884
|
-
<string>${cliExe}</string>
|
|
102885
|
-
<string>daemon</string>
|
|
102886
|
-
</array>
|
|
102887
|
-
<key>RunAtLoad</key>
|
|
102888
|
-
<true/>
|
|
102889
|
-
<key>KeepAlive</key>
|
|
102890
|
-
<dict>
|
|
102891
|
-
<key>SuccessfulExit</key>
|
|
102892
|
-
<false/>
|
|
102893
|
-
</dict>
|
|
102894
|
-
<key>ThrottleInterval</key>
|
|
102895
|
-
<integer>30</integer>
|
|
102896
|
-
<key>StandardOutPath</key>
|
|
102897
|
-
<string>${LOG_OUT}</string>
|
|
102898
|
-
<key>StandardErrorPath</key>
|
|
102899
|
-
<string>${LOG_ERR}</string>
|
|
102900
|
-
<key>EnvironmentVariables</key>
|
|
102901
|
-
<dict>
|
|
102902
|
-
<key>PATH</key>
|
|
102903
|
-
<string>${pathValue}</string>
|
|
102904
|
-
</dict>
|
|
102905
|
-
</dict>
|
|
102906
|
-
</plist>`;
|
|
102907
|
-
}
|
|
102908
|
-
function installDarwin(nodeExe, cliExe) {
|
|
102909
|
-
const plistPath = getDarwinPlistPath();
|
|
102910
|
-
ensureDir(ADHDEV_DIR);
|
|
102911
|
-
ensureDir(import_node_path5.default.dirname(plistPath));
|
|
102912
|
-
import_node_fs4.default.writeFileSync(plistPath, buildPlist(nodeExe, cliExe), "utf-8");
|
|
102913
|
-
console.log(source_default.gray(` Plist: ${plistPath}`));
|
|
102914
|
-
try {
|
|
102915
|
-
(0, import_node_child_process4.execSync)(`launchctl unload "${plistPath}" 2>/dev/null`, { stdio: "ignore" });
|
|
102916
|
-
} catch {
|
|
102917
|
-
}
|
|
102918
|
-
try {
|
|
102919
|
-
(0, import_node_child_process4.execSync)(`launchctl load -w "${plistPath}"`, { stdio: "ignore" });
|
|
102920
|
-
console.log(source_default.green("\n \u2713 Registered as LaunchAgent \u2014 daemon will start on login."));
|
|
102921
|
-
console.log(source_default.gray(` Logs: ~/.adhdev/daemon-launchd.{out,err}`));
|
|
102922
|
-
} catch (e) {
|
|
102923
|
-
console.log(source_default.red(`
|
|
102924
|
-
\u2717 launchctl load failed: ${e.message}`));
|
|
102925
|
-
}
|
|
102926
|
-
}
|
|
102927
|
-
function uninstallDarwin() {
|
|
102928
|
-
const plistPath = getDarwinPlistPath();
|
|
102929
|
-
if (!import_node_fs4.default.existsSync(plistPath)) {
|
|
102930
|
-
console.log(source_default.yellow("\n \u26A0 Service is not installed."));
|
|
102931
|
-
return;
|
|
102932
|
-
}
|
|
102933
|
-
try {
|
|
102934
|
-
(0, import_node_child_process4.execSync)(`launchctl unload "${plistPath}" 2>/dev/null`, { stdio: "ignore" });
|
|
102935
|
-
} catch {
|
|
102936
|
-
}
|
|
102937
|
-
import_node_fs4.default.unlinkSync(plistPath);
|
|
102938
|
-
console.log(source_default.green("\n \u2713 Removed LaunchAgent. Daemon will no longer auto-start."));
|
|
102939
|
-
}
|
|
102940
|
-
function isInstalledDarwin() {
|
|
102941
|
-
return import_node_fs4.default.existsSync(getDarwinPlistPath());
|
|
102942
|
-
}
|
|
102943
|
-
function buildVbs(nodeExe, cliExe) {
|
|
102944
|
-
const logFile = import_node_path5.default.join(ADHDEV_DIR, "daemon-service.log").replace(/\\/g, "\\\\");
|
|
102945
|
-
const escapedNodeExe = nodeExe.replace(/\\/g, "\\\\");
|
|
102946
|
-
const escapedCliExe = cliExe.replace(/\\/g, "\\\\");
|
|
102947
|
-
return `' ADHDev Daemon Auto-Start (generated by adhdev service install)
|
|
102948
|
-
Set WshShell = CreateObject("WScript.Shell")
|
|
102949
|
-
WshShell.Run "cmd.exe /c """"${escapedNodeExe}"""" """"${escapedCliExe}"""" daemon >> """"${logFile}"""" 2>&1", 0, False
|
|
102950
|
-
`;
|
|
102951
|
-
}
|
|
102952
|
-
function installWindows(nodeExe, cliExe) {
|
|
102953
|
-
const vbsPath = getWindowsVbsPath();
|
|
102954
|
-
ensureDir(ADHDEV_DIR);
|
|
102955
|
-
ensureDir(import_node_path5.default.dirname(vbsPath));
|
|
102956
|
-
import_node_fs4.default.writeFileSync(vbsPath, buildVbs(nodeExe, cliExe), "utf-8");
|
|
102957
|
-
console.log(source_default.gray(` Startup script: ${vbsPath}`));
|
|
102958
|
-
console.log(source_default.green("\n \u2713 Registered in Startup folder \u2014 daemon will start on login (hidden)."));
|
|
102959
|
-
console.log(source_default.gray(` Logs: ${import_node_path5.default.join(ADHDEV_DIR, "daemon-service.log")}`));
|
|
102960
|
-
console.log(source_default.gray(" To start now without rebooting, run: adhdev daemon"));
|
|
102961
|
-
}
|
|
102962
|
-
function uninstallWindows() {
|
|
102963
|
-
const vbsPath = getWindowsVbsPath();
|
|
102964
|
-
if (!import_node_fs4.default.existsSync(vbsPath)) {
|
|
102965
|
-
console.log(source_default.yellow("\n \u26A0 Service is not installed."));
|
|
102966
|
-
return;
|
|
102967
|
-
}
|
|
102968
|
-
import_node_fs4.default.unlinkSync(vbsPath);
|
|
102969
|
-
console.log(source_default.green("\n \u2713 Removed Startup script. Daemon will no longer auto-start."));
|
|
102970
|
-
console.log(source_default.gray(" Note: a currently running daemon is not affected. Stop with: adhdev daemon:stop"));
|
|
102971
|
-
}
|
|
102972
|
-
function isInstalledWindows() {
|
|
102973
|
-
return import_node_fs4.default.existsSync(getWindowsVbsPath());
|
|
102974
|
-
}
|
|
102975
|
-
function registerServiceCommands(program2) {
|
|
102976
|
-
const svc = program2.command("service").description("\u{1F50C} Manage ADHDev as an OS background auto-start service");
|
|
102977
|
-
svc.command("install").description("Register ADHDev daemon to start automatically on login").action(async () => {
|
|
102978
|
-
console.log(source_default.bold("\n \u{1F680} Installing ADHDev Background Service"));
|
|
102979
|
-
const platform12 = import_node_os4.default.platform();
|
|
102980
|
-
const nodeExe = process.execPath;
|
|
102981
|
-
const cliExe = resolveCliPath();
|
|
102982
|
-
console.log(source_default.gray(` Node: ${nodeExe}`));
|
|
102983
|
-
console.log(source_default.gray(` CLI: ${cliExe}`));
|
|
102984
|
-
console.log(source_default.gray(` Platform: ${platform12}`));
|
|
102985
|
-
if (platform12 === "darwin") {
|
|
102986
|
-
installDarwin(nodeExe, cliExe);
|
|
102987
|
-
} else if (platform12 === "win32") {
|
|
102988
|
-
installWindows(nodeExe, cliExe);
|
|
102989
|
-
} else {
|
|
102990
|
-
console.log(source_default.yellow("\n \u26A0 Auto-start service install is not supported on this platform."));
|
|
102991
|
-
console.log(source_default.gray(" On Linux, create a systemd user unit manually:"));
|
|
102992
|
-
console.log(source_default.gray(" ~/.config/systemd/user/adhdev-daemon.service"));
|
|
102993
|
-
}
|
|
102994
|
-
console.log();
|
|
102995
|
-
});
|
|
102996
|
-
svc.command("uninstall").description("Remove the OS background service").action(async () => {
|
|
102997
|
-
console.log(source_default.bold("\n \u{1F5D1}\uFE0F Removing ADHDev Background Service"));
|
|
102998
|
-
const platform12 = import_node_os4.default.platform();
|
|
102999
|
-
if (platform12 === "darwin") {
|
|
103000
|
-
uninstallDarwin();
|
|
103001
|
-
} else if (platform12 === "win32") {
|
|
103002
|
-
uninstallWindows();
|
|
103003
|
-
} else {
|
|
103004
|
-
console.log(source_default.yellow("\n \u26A0 Not supported on this platform."));
|
|
103005
|
-
}
|
|
103006
|
-
console.log();
|
|
103007
|
-
});
|
|
103008
|
-
svc.command("status").description("Show service installation state and live daemon health").action(async () => {
|
|
103009
|
-
const platform12 = import_node_os4.default.platform();
|
|
103010
|
-
const installed = platform12 === "darwin" ? isInstalledDarwin() : platform12 === "win32" ? isInstalledWindows() : false;
|
|
103011
|
-
if (installed) {
|
|
103012
|
-
console.log(source_default.green("\n \u2713 Service is installed."));
|
|
103013
|
-
if (platform12 === "darwin") console.log(source_default.gray(` Plist: ${getDarwinPlistPath()}`));
|
|
103014
|
-
else console.log(source_default.gray(` Script: ${getWindowsVbsPath()}`));
|
|
103015
|
-
} else {
|
|
103016
|
-
console.log(source_default.gray("\n \u2717 Service is not installed. Run: adhdev service install"));
|
|
103017
|
-
}
|
|
103018
|
-
const health = await fetchHealth();
|
|
103019
|
-
if (health?.ok && health.pid) {
|
|
103020
|
-
const info = getProcessInfo(health.pid);
|
|
103021
|
-
if (info) {
|
|
103022
|
-
console.log(source_default.green(` \u2713 Daemon running \u2014 PID ${health.pid}, uptime ${info.uptime}, ${info.memMB} MB`));
|
|
103023
|
-
} else {
|
|
103024
|
-
console.log(source_default.green(` \u2713 Daemon running \u2014 PID ${health.pid}`));
|
|
103025
|
-
}
|
|
103026
|
-
} else {
|
|
103027
|
-
console.log(source_default.yellow(" \u2717 Daemon is not running."));
|
|
103028
|
-
}
|
|
103029
|
-
const outSize = import_node_fs4.default.existsSync(LOG_OUT) ? import_node_fs4.default.statSync(LOG_OUT).size : 0;
|
|
103030
|
-
const errSize = import_node_fs4.default.existsSync(LOG_ERR) ? import_node_fs4.default.statSync(LOG_ERR).size : 0;
|
|
103031
|
-
if (outSize > 0 || errSize > 0) {
|
|
103032
|
-
console.log(source_default.gray(` Logs: stdout ${formatBytes(outSize)}, stderr ${formatBytes(errSize)}`));
|
|
103033
|
-
}
|
|
103034
|
-
console.log();
|
|
103035
|
-
});
|
|
103036
|
-
svc.command("logs").description("View daemon service logs").option("--err", "Show stderr log instead of stdout").option("--clear", "Truncate all log files").option("-n, --lines <count>", "Number of lines to show", "30").action(async (options) => {
|
|
103037
|
-
if (options.clear) {
|
|
103038
|
-
for (const f of [LOG_OUT, LOG_ERR]) {
|
|
103039
|
-
if (import_node_fs4.default.existsSync(f)) import_node_fs4.default.writeFileSync(f, "", "utf-8");
|
|
103040
|
-
}
|
|
103041
|
-
console.log(source_default.green("\n \u2713 Logs cleared.\n"));
|
|
103042
|
-
return;
|
|
103043
|
-
}
|
|
103044
|
-
const logFile = options.err ? LOG_ERR : LOG_OUT;
|
|
103045
|
-
if (!import_node_fs4.default.existsSync(logFile)) {
|
|
103046
|
-
console.log(source_default.gray(`
|
|
103047
|
-
No log file found: ${logFile}
|
|
103048
|
-
`));
|
|
103049
|
-
return;
|
|
103050
|
-
}
|
|
103051
|
-
const lines = parseInt(options.lines, 10) || 30;
|
|
103052
|
-
console.log(source_default.gray(`
|
|
103053
|
-
\u2500\u2500 ${options.err ? "stderr" : "stdout"}: ${logFile} (last ${lines} lines) \u2500\u2500
|
|
103054
|
-
`));
|
|
103055
|
-
const content = import_node_fs4.default.readFileSync(logFile, "utf-8");
|
|
103056
|
-
const allLines = content.split("\n");
|
|
103057
|
-
const lastLines = allLines.slice(-lines).join("\n");
|
|
103058
|
-
if (lastLines.trim()) console.log(lastLines);
|
|
103059
|
-
console.log(source_default.gray("\n (watching for new output, Ctrl+C to stop)\n"));
|
|
103060
|
-
let offset = Buffer.byteLength(content, "utf-8");
|
|
103061
|
-
const watcher = import_node_fs4.default.watchFile(logFile, { interval: 500 }, () => {
|
|
103062
|
-
try {
|
|
103063
|
-
const stat5 = import_node_fs4.default.statSync(logFile);
|
|
103064
|
-
if (stat5.size > offset) {
|
|
103065
|
-
const fd = import_node_fs4.default.openSync(logFile, "r");
|
|
103066
|
-
const buf = Buffer.alloc(stat5.size - offset);
|
|
103067
|
-
import_node_fs4.default.readSync(fd, buf, 0, buf.length, offset);
|
|
103068
|
-
import_node_fs4.default.closeSync(fd);
|
|
103069
|
-
process.stdout.write(buf.toString("utf-8"));
|
|
103070
|
-
offset = stat5.size;
|
|
103071
|
-
} else if (stat5.size < offset) {
|
|
103072
|
-
offset = 0;
|
|
103073
|
-
}
|
|
103074
|
-
} catch {
|
|
103075
|
-
}
|
|
103076
|
-
});
|
|
103077
|
-
const cleanup = () => {
|
|
103078
|
-
import_node_fs4.default.unwatchFile(logFile);
|
|
103079
|
-
process.exit(0);
|
|
103080
|
-
};
|
|
103081
|
-
process.on("SIGINT", cleanup);
|
|
103082
|
-
process.on("SIGTERM", cleanup);
|
|
103083
|
-
});
|
|
103084
|
-
svc.command("restart").description("Restart the daemon process (service will auto-relaunch)").action(async () => {
|
|
103085
|
-
const platform12 = import_node_os4.default.platform();
|
|
103086
|
-
const installed = platform12 === "darwin" ? isInstalledDarwin() : platform12 === "win32" ? isInstalledWindows() : false;
|
|
103087
|
-
if (!installed) {
|
|
103088
|
-
console.log(source_default.yellow("\n \u26A0 Service is not installed. Use `adhdev daemon:restart` for manual restart."));
|
|
103089
|
-
console.log(source_default.gray(" Or install the service first: adhdev service install\n"));
|
|
103090
|
-
return;
|
|
103091
|
-
}
|
|
103092
|
-
rotateLogs();
|
|
103093
|
-
const health = await fetchHealth();
|
|
103094
|
-
if (!health?.pid) {
|
|
103095
|
-
console.log(source_default.yellow("\n \u26A0 Daemon is not currently running."));
|
|
103096
|
-
if (platform12 === "darwin") {
|
|
103097
|
-
console.log(source_default.gray(" Starting via launchctl..."));
|
|
103098
|
-
try {
|
|
103099
|
-
(0, import_node_child_process4.execSync)(`launchctl start ${LAUNCHD_LABEL}`, { stdio: "ignore" });
|
|
103100
|
-
console.log(source_default.green(" \u2713 Started.\n"));
|
|
103101
|
-
} catch {
|
|
103102
|
-
console.log(source_default.red(" \u2717 Failed to start. Check: adhdev service logs --err\n"));
|
|
103103
|
-
}
|
|
103104
|
-
} else {
|
|
103105
|
-
console.log(source_default.gray(" Start with: adhdev daemon\n"));
|
|
103106
|
-
}
|
|
103107
|
-
return;
|
|
103108
|
-
}
|
|
103109
|
-
console.log(source_default.cyan(`
|
|
103110
|
-
Stopping daemon (PID ${health.pid})...`));
|
|
103111
|
-
try {
|
|
103112
|
-
process.kill(health.pid, "SIGTERM");
|
|
103113
|
-
} catch {
|
|
103114
|
-
console.log(source_default.yellow(" Could not send SIGTERM. Process may have already exited."));
|
|
103115
|
-
}
|
|
103116
|
-
await new Promise((r) => setTimeout(r, 2e3));
|
|
103117
|
-
if (platform12 === "win32") {
|
|
103118
|
-
const vbsPath = getWindowsVbsPath();
|
|
103119
|
-
if (import_node_fs4.default.existsSync(vbsPath)) {
|
|
103120
|
-
try {
|
|
103121
|
-
(0, import_node_child_process4.execSync)(`wscript.exe "${vbsPath}"`, { stdio: "ignore", windowsHide: true });
|
|
103122
|
-
} catch {
|
|
103123
|
-
}
|
|
103124
|
-
}
|
|
103125
|
-
}
|
|
103126
|
-
let restarted = false;
|
|
103127
|
-
for (let i = 0; i < 8; i++) {
|
|
103128
|
-
await new Promise((r) => setTimeout(r, 1e3));
|
|
103129
|
-
const newHealth = await fetchHealth();
|
|
103130
|
-
if (newHealth?.ok && newHealth.pid !== health.pid) {
|
|
103131
|
-
restarted = true;
|
|
103132
|
-
const info = getProcessInfo(newHealth.pid);
|
|
103133
|
-
console.log(source_default.green(` \u2713 Daemon restarted \u2014 new PID ${newHealth.pid}${info ? `, ${info.memMB} MB` : ""}`));
|
|
103134
|
-
break;
|
|
103135
|
-
}
|
|
103136
|
-
}
|
|
103137
|
-
if (!restarted) {
|
|
103138
|
-
console.log(source_default.yellow(" \u26A0 Daemon did not restart within 10s."));
|
|
103139
|
-
console.log(source_default.gray(" Check: adhdev service logs --err"));
|
|
103140
|
-
}
|
|
103141
|
-
console.log();
|
|
103142
|
-
});
|
|
103143
|
-
}
|
|
103144
|
-
function formatBytes(bytes) {
|
|
103145
|
-
if (bytes === 0) return "0 B";
|
|
103146
|
-
if (bytes < 1024) return `${bytes} B`;
|
|
103147
|
-
if (bytes < 1024 * 1024) return `${(bytes / 1024).toFixed(1)} KB`;
|
|
103148
|
-
return `${(bytes / (1024 * 1024)).toFixed(1)} MB`;
|
|
103149
|
-
}
|
|
103150
|
-
|
|
103151
103896
|
// src/cli/doctor-commands.ts
|
|
103897
|
+
init_service_commands();
|
|
103152
103898
|
function resolvePackageRoot() {
|
|
103153
103899
|
return path39.resolve(__dirname, "..", "..");
|
|
103154
103900
|
}
|
|
@@ -104640,6 +105386,9 @@ function registerCdpCommands(program2) {
|
|
|
104640
105386
|
});
|
|
104641
105387
|
}
|
|
104642
105388
|
|
|
105389
|
+
// src/cli/index.ts
|
|
105390
|
+
init_service_commands();
|
|
105391
|
+
|
|
104643
105392
|
// src/cli/mcp-commands.ts
|
|
104644
105393
|
var import_node_child_process5 = require("child_process");
|
|
104645
105394
|
var fs23 = __toESM(require("fs"));
|