@adhdev/daemon-core 0.9.82-rc.48 → 0.9.82-rc.49
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/commands/router.d.ts +1 -0
- package/dist/config/mesh-config.d.ts +66 -1
- package/dist/index.d.ts +5 -2
- package/dist/index.js +954 -212
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +928 -198
- package/dist/index.mjs.map +1 -1
- package/dist/mesh/mesh-host-ownership.d.ts +9 -0
- package/dist/mesh/mesh-ledger.d.ts +1 -1
- package/dist/mesh/mesh-work-queue.d.ts +8 -4
- package/dist/mesh/refine-config.d.ts +119 -0
- package/dist/repo-mesh-types.d.ts +32 -0
- package/package.json +1 -1
- package/src/commands/router.ts +412 -178
- package/src/config/mesh-config.ts +244 -1
- package/src/index.ts +23 -1
- package/src/mesh/mesh-host-ownership.ts +73 -0
- package/src/mesh/mesh-ledger.ts +1 -0
- package/src/mesh/mesh-work-queue.ts +14 -3
- package/src/mesh/refine-config.ts +306 -0
- package/src/repo-mesh-types.ts +36 -0
package/dist/index.mjs
CHANGED
|
@@ -657,23 +657,97 @@ var init_config = __esm({
|
|
|
657
657
|
}
|
|
658
658
|
});
|
|
659
659
|
|
|
660
|
+
// src/mesh/mesh-host-ownership.ts
|
|
661
|
+
function readObject(value) {
|
|
662
|
+
return value && typeof value === "object" && !Array.isArray(value) ? value : null;
|
|
663
|
+
}
|
|
664
|
+
function readString(value) {
|
|
665
|
+
return typeof value === "string" && value.trim() ? value.trim() : void 0;
|
|
666
|
+
}
|
|
667
|
+
function normalizeMeshDaemonRole(value) {
|
|
668
|
+
return value === "host" || value === "member" ? value : void 0;
|
|
669
|
+
}
|
|
670
|
+
function resolveMeshHostStatus(mesh) {
|
|
671
|
+
const meshRecord = readObject(mesh);
|
|
672
|
+
const raw = readObject(meshRecord?.meshHost);
|
|
673
|
+
const role = normalizeMeshDaemonRole(raw?.role) ?? "host";
|
|
674
|
+
const pairing = readObject(raw?.pairing);
|
|
675
|
+
const normalized = {
|
|
676
|
+
role,
|
|
677
|
+
canOwnCoordinator: role === "host",
|
|
678
|
+
canOwnQueue: role === "host",
|
|
679
|
+
defaulted: !raw
|
|
680
|
+
};
|
|
681
|
+
const hostDaemonId = readString(raw?.hostDaemonId);
|
|
682
|
+
const hostNodeId = readString(raw?.hostNodeId);
|
|
683
|
+
const hostAddress = readString(raw?.hostAddress);
|
|
684
|
+
if (hostDaemonId) normalized.hostDaemonId = hostDaemonId;
|
|
685
|
+
if (hostNodeId) normalized.hostNodeId = hostNodeId;
|
|
686
|
+
if (hostAddress) normalized.hostAddress = hostAddress;
|
|
687
|
+
if (pairing) {
|
|
688
|
+
const status = pairing.status === "pairing" || pairing.status === "paired" || pairing.status === "rejected" || pairing.status === "revoked" ? pairing.status : "not_configured";
|
|
689
|
+
normalized.pairing = {
|
|
690
|
+
status,
|
|
691
|
+
...readString(pairing.tokenId) ? { tokenId: readString(pairing.tokenId) } : {},
|
|
692
|
+
...readString(pairing.joinedAt) ? { joinedAt: readString(pairing.joinedAt) } : {},
|
|
693
|
+
...readString(pairing.lastPairedAt) ? { lastPairedAt: readString(pairing.lastPairedAt) } : {},
|
|
694
|
+
...readString(pairing.lastRejectedAt) ? { lastRejectedAt: readString(pairing.lastRejectedAt) } : {},
|
|
695
|
+
...readString(pairing.expiresAt) ? { expiresAt: readString(pairing.expiresAt) } : {}
|
|
696
|
+
};
|
|
697
|
+
}
|
|
698
|
+
return normalized;
|
|
699
|
+
}
|
|
700
|
+
function isMeshHostOwner(mesh) {
|
|
701
|
+
return resolveMeshHostStatus(mesh).role === "host";
|
|
702
|
+
}
|
|
703
|
+
function buildMeshHostRequiredFailure(mesh, operation) {
|
|
704
|
+
const meshHost = resolveMeshHostStatus(mesh);
|
|
705
|
+
return {
|
|
706
|
+
success: false,
|
|
707
|
+
code: "mesh_host_required",
|
|
708
|
+
error: `Mesh Host daemon required for ${operation}; member daemons must pair with the host and cannot own coordinator/queue mutations.`,
|
|
709
|
+
meshHost
|
|
710
|
+
};
|
|
711
|
+
}
|
|
712
|
+
function requireMeshHostQueueOwner(opts) {
|
|
713
|
+
if (opts?.ownerRole === "member") {
|
|
714
|
+
throw new Error("Mesh Host daemon required to mutate mesh queue; member daemons must use the host-owned queue.");
|
|
715
|
+
}
|
|
716
|
+
}
|
|
717
|
+
function createDefaultMeshHostMetadata() {
|
|
718
|
+
return {
|
|
719
|
+
role: "host",
|
|
720
|
+
pairing: { status: "not_configured" }
|
|
721
|
+
};
|
|
722
|
+
}
|
|
723
|
+
var init_mesh_host_ownership = __esm({
|
|
724
|
+
"src/mesh/mesh-host-ownership.ts"() {
|
|
725
|
+
"use strict";
|
|
726
|
+
}
|
|
727
|
+
});
|
|
728
|
+
|
|
660
729
|
// src/config/mesh-config.ts
|
|
661
730
|
var mesh_config_exports = {};
|
|
662
731
|
__export(mesh_config_exports, {
|
|
663
732
|
addNode: () => addNode,
|
|
733
|
+
applyMeshHostJoinRequest: () => applyMeshHostJoinRequest,
|
|
734
|
+
configureMeshHostPairing: () => configureMeshHostPairing,
|
|
664
735
|
createMesh: () => createMesh,
|
|
736
|
+
createMeshHostPairingToken: () => createMeshHostPairingToken,
|
|
665
737
|
deleteMesh: () => deleteMesh,
|
|
666
738
|
getMesh: () => getMesh,
|
|
667
739
|
getMeshByRepo: () => getMeshByRepo,
|
|
668
740
|
listMeshes: () => listMeshes,
|
|
741
|
+
markMeshHostPairingJoined: () => markMeshHostPairingJoined,
|
|
669
742
|
normalizeRepoIdentity: () => normalizeRepoIdentity,
|
|
670
743
|
removeNode: () => removeNode,
|
|
744
|
+
tokenIdForManualPairing: () => tokenIdForManualPairing,
|
|
671
745
|
updateMesh: () => updateMesh,
|
|
672
746
|
updateNode: () => updateNode
|
|
673
747
|
});
|
|
674
748
|
import { existsSync as existsSync4, readFileSync as readFileSync2, writeFileSync as writeFileSync2 } from "fs";
|
|
675
749
|
import { join as join4 } from "path";
|
|
676
|
-
import { randomUUID as randomUUID3 } from "crypto";
|
|
750
|
+
import { createHash, randomBytes, randomUUID as randomUUID3 } from "crypto";
|
|
677
751
|
function getMeshConfigPath() {
|
|
678
752
|
return join4(getConfigDir(), "meshes.json");
|
|
679
753
|
}
|
|
@@ -746,6 +820,7 @@ function createMesh(opts) {
|
|
|
746
820
|
defaultBranch: opts.defaultBranch,
|
|
747
821
|
policy: mergeMeshPolicy(void 0, opts.policy),
|
|
748
822
|
coordinator: opts.coordinator || {},
|
|
823
|
+
meshHost: opts.meshHost || createDefaultMeshHostMetadata(),
|
|
749
824
|
nodes: [],
|
|
750
825
|
createdAt: now,
|
|
751
826
|
updatedAt: now
|
|
@@ -762,6 +837,7 @@ function updateMesh(meshId, opts) {
|
|
|
762
837
|
if (opts.defaultBranch !== void 0) mesh.defaultBranch = opts.defaultBranch;
|
|
763
838
|
if (opts.policy) mesh.policy = mergeMeshPolicy(mesh.policy, opts.policy);
|
|
764
839
|
if (opts.coordinator) mesh.coordinator = opts.coordinator;
|
|
840
|
+
if (opts.meshHost) mesh.meshHost = opts.meshHost;
|
|
765
841
|
mesh.updatedAt = (/* @__PURE__ */ new Date()).toISOString();
|
|
766
842
|
saveMeshConfig(config);
|
|
767
843
|
return mesh;
|
|
@@ -774,6 +850,186 @@ function deleteMesh(meshId) {
|
|
|
774
850
|
saveMeshConfig(config);
|
|
775
851
|
return true;
|
|
776
852
|
}
|
|
853
|
+
function normalizeManualHostAddress(hostAddress) {
|
|
854
|
+
const normalized = hostAddress.trim().replace(/\/+$/, "");
|
|
855
|
+
if (!normalized) throw new Error("hostAddress required");
|
|
856
|
+
let parsed;
|
|
857
|
+
try {
|
|
858
|
+
parsed = new URL(normalized);
|
|
859
|
+
} catch {
|
|
860
|
+
throw new Error("hostAddress must be a valid http(s) or ws(s) URL");
|
|
861
|
+
}
|
|
862
|
+
if (!["http:", "https:", "ws:", "wss:"].includes(parsed.protocol)) {
|
|
863
|
+
throw new Error("hostAddress must use http, https, ws, or wss");
|
|
864
|
+
}
|
|
865
|
+
return normalized;
|
|
866
|
+
}
|
|
867
|
+
function tokenIdForManualPairing(token) {
|
|
868
|
+
return `tok_${createHash("sha256").update(token).digest("hex").slice(0, 16)}`;
|
|
869
|
+
}
|
|
870
|
+
function normalizeTokenExpiry(value) {
|
|
871
|
+
if (typeof value !== "string" || !value.trim()) return void 0;
|
|
872
|
+
const date = new Date(value);
|
|
873
|
+
if (Number.isNaN(date.getTime())) throw new Error("expiresAt must be a valid ISO date");
|
|
874
|
+
return date.toISOString();
|
|
875
|
+
}
|
|
876
|
+
function assertPairingTokenValid(pairing, rawToken, nowIso) {
|
|
877
|
+
const token = rawToken.trim();
|
|
878
|
+
if (!token) return { ok: false, reason: "token required" };
|
|
879
|
+
const presentedTokenId = tokenIdForManualPairing(token);
|
|
880
|
+
const expectedTokenId = pairing?.tokenId;
|
|
881
|
+
if (!expectedTokenId || pairing?.status === "not_configured" || pairing?.status === "revoked") {
|
|
882
|
+
return { ok: false, reason: "host pairing token is not configured", presentedTokenId };
|
|
883
|
+
}
|
|
884
|
+
if (pairing.expiresAt && new Date(pairing.expiresAt).getTime() <= new Date(nowIso).getTime()) {
|
|
885
|
+
return { ok: false, reason: "host pairing token expired", expectedTokenId, presentedTokenId };
|
|
886
|
+
}
|
|
887
|
+
if (presentedTokenId !== expectedTokenId) {
|
|
888
|
+
return { ok: false, reason: "invalid pairing token", expectedTokenId, presentedTokenId };
|
|
889
|
+
}
|
|
890
|
+
return { ok: true, tokenId: presentedTokenId };
|
|
891
|
+
}
|
|
892
|
+
function configureMeshHostPairing(meshId, opts) {
|
|
893
|
+
const hostAddress = normalizeManualHostAddress(opts.hostAddress);
|
|
894
|
+
const token = opts.token.trim();
|
|
895
|
+
if (!token) throw new Error("token required");
|
|
896
|
+
const config = loadMeshConfig();
|
|
897
|
+
const mesh = config.meshes.find((m) => m.id === meshId);
|
|
898
|
+
if (!mesh) return void 0;
|
|
899
|
+
const now = opts.now || (/* @__PURE__ */ new Date()).toISOString();
|
|
900
|
+
const previous = mesh.meshHost || createDefaultMeshHostMetadata();
|
|
901
|
+
const meshHost = {
|
|
902
|
+
...previous,
|
|
903
|
+
role: "member",
|
|
904
|
+
hostAddress,
|
|
905
|
+
pairing: {
|
|
906
|
+
status: "pairing",
|
|
907
|
+
tokenId: tokenIdForManualPairing(token),
|
|
908
|
+
lastPairedAt: now
|
|
909
|
+
}
|
|
910
|
+
};
|
|
911
|
+
mesh.meshHost = meshHost;
|
|
912
|
+
mesh.updatedAt = now;
|
|
913
|
+
saveMeshConfig(config);
|
|
914
|
+
return { mesh, meshHost, hostAddress };
|
|
915
|
+
}
|
|
916
|
+
function createMeshHostPairingToken(meshId, opts = {}) {
|
|
917
|
+
const config = loadMeshConfig();
|
|
918
|
+
const mesh = config.meshes.find((m) => m.id === meshId);
|
|
919
|
+
if (!mesh) return void 0;
|
|
920
|
+
const now = opts.now || (/* @__PURE__ */ new Date()).toISOString();
|
|
921
|
+
const token = (opts.token || `mhj_${randomBytes(24).toString("base64url")}`).trim();
|
|
922
|
+
if (!token) throw new Error("token required");
|
|
923
|
+
const tokenId = tokenIdForManualPairing(token);
|
|
924
|
+
const expiresAt = normalizeTokenExpiry(opts.expiresAt);
|
|
925
|
+
const previous = mesh.meshHost || createDefaultMeshHostMetadata();
|
|
926
|
+
if (previous.role === "member") {
|
|
927
|
+
throw new Error("Mesh Host daemon required to create host pairing tokens; member daemons cannot mint host join tokens.");
|
|
928
|
+
}
|
|
929
|
+
const meshHost = {
|
|
930
|
+
...previous,
|
|
931
|
+
role: "host",
|
|
932
|
+
pairing: {
|
|
933
|
+
status: "pairing",
|
|
934
|
+
tokenId,
|
|
935
|
+
lastPairedAt: now,
|
|
936
|
+
...expiresAt ? { expiresAt } : {}
|
|
937
|
+
}
|
|
938
|
+
};
|
|
939
|
+
mesh.meshHost = meshHost;
|
|
940
|
+
mesh.updatedAt = now;
|
|
941
|
+
saveMeshConfig(config);
|
|
942
|
+
return { mesh, meshHost, token, tokenId, ...expiresAt ? { expiresAt } : {} };
|
|
943
|
+
}
|
|
944
|
+
function applyMeshHostJoinRequest(meshId, opts) {
|
|
945
|
+
const config = loadMeshConfig();
|
|
946
|
+
const mesh = config.meshes.find((m) => m.id === meshId);
|
|
947
|
+
if (!mesh) return void 0;
|
|
948
|
+
const now = opts.now || (/* @__PURE__ */ new Date()).toISOString();
|
|
949
|
+
const previous = mesh.meshHost || createDefaultMeshHostMetadata();
|
|
950
|
+
if (previous.role === "member") {
|
|
951
|
+
return { accepted: false, mesh, meshHost: previous, reason: "Mesh Host daemon required to accept join requests" };
|
|
952
|
+
}
|
|
953
|
+
const meshHost = { ...previous, role: "host" };
|
|
954
|
+
const validation = assertPairingTokenValid(meshHost.pairing, opts.token, now);
|
|
955
|
+
if (!validation.ok) {
|
|
956
|
+
mesh.meshHost = {
|
|
957
|
+
...meshHost,
|
|
958
|
+
pairing: {
|
|
959
|
+
...meshHost.pairing || { status: "not_configured" },
|
|
960
|
+
status: "rejected",
|
|
961
|
+
lastRejectedAt: now
|
|
962
|
+
}
|
|
963
|
+
};
|
|
964
|
+
mesh.updatedAt = now;
|
|
965
|
+
saveMeshConfig(config);
|
|
966
|
+
return { accepted: false, mesh, meshHost: mesh.meshHost, tokenId: validation.presentedTokenId, reason: validation.reason };
|
|
967
|
+
}
|
|
968
|
+
const workspace = opts.memberNode.workspace.trim();
|
|
969
|
+
if (!workspace) throw new Error("memberNode.workspace required");
|
|
970
|
+
const memberId = opts.memberNode.id?.trim();
|
|
971
|
+
let node = mesh.nodes.find((n) => memberId && n.id === memberId || n.workspace === workspace);
|
|
972
|
+
if (node) {
|
|
973
|
+
node.workspace = workspace;
|
|
974
|
+
node.repoRoot = opts.memberNode.repoRoot;
|
|
975
|
+
node.daemonId = opts.memberNode.daemonId;
|
|
976
|
+
node.machineId = opts.memberNode.machineId;
|
|
977
|
+
node.userOverrides = opts.memberNode.userOverrides || node.userOverrides || {};
|
|
978
|
+
node.policy = { ...node.policy || {}, ...opts.memberNode.policy || {} };
|
|
979
|
+
node.role = "member";
|
|
980
|
+
} else {
|
|
981
|
+
if (mesh.nodes.length >= 10) throw new Error("Maximum 10 nodes per mesh");
|
|
982
|
+
node = {
|
|
983
|
+
id: memberId || `node_${randomUUID3().replace(/-/g, "")}`,
|
|
984
|
+
workspace,
|
|
985
|
+
repoRoot: opts.memberNode.repoRoot,
|
|
986
|
+
daemonId: opts.memberNode.daemonId,
|
|
987
|
+
machineId: opts.memberNode.machineId,
|
|
988
|
+
userOverrides: opts.memberNode.userOverrides || {},
|
|
989
|
+
policy: opts.memberNode.policy || {},
|
|
990
|
+
role: "member"
|
|
991
|
+
};
|
|
992
|
+
mesh.nodes.push(node);
|
|
993
|
+
}
|
|
994
|
+
mesh.meshHost = {
|
|
995
|
+
...meshHost,
|
|
996
|
+
pairing: {
|
|
997
|
+
...meshHost.pairing || {},
|
|
998
|
+
status: "paired",
|
|
999
|
+
tokenId: validation.tokenId,
|
|
1000
|
+
joinedAt: now,
|
|
1001
|
+
lastPairedAt: meshHost.pairing?.lastPairedAt || now,
|
|
1002
|
+
...meshHost.pairing?.expiresAt ? { expiresAt: meshHost.pairing.expiresAt } : {}
|
|
1003
|
+
}
|
|
1004
|
+
};
|
|
1005
|
+
mesh.updatedAt = now;
|
|
1006
|
+
saveMeshConfig(config);
|
|
1007
|
+
return { accepted: true, mesh, meshHost: mesh.meshHost, node, tokenId: validation.tokenId };
|
|
1008
|
+
}
|
|
1009
|
+
function markMeshHostPairingJoined(meshId, opts) {
|
|
1010
|
+
const config = loadMeshConfig();
|
|
1011
|
+
const mesh = config.meshes.find((m) => m.id === meshId);
|
|
1012
|
+
if (!mesh) return void 0;
|
|
1013
|
+
const now = opts.joinedAt || (/* @__PURE__ */ new Date()).toISOString();
|
|
1014
|
+
const previous = mesh.meshHost || createDefaultMeshHostMetadata();
|
|
1015
|
+
const tokenId = opts.tokenId || (opts.token ? tokenIdForManualPairing(opts.token) : previous.pairing?.tokenId);
|
|
1016
|
+
mesh.meshHost = {
|
|
1017
|
+
...previous,
|
|
1018
|
+
role: "member",
|
|
1019
|
+
...opts.hostDaemonId ? { hostDaemonId: opts.hostDaemonId } : {},
|
|
1020
|
+
...opts.hostNodeId ? { hostNodeId: opts.hostNodeId } : {},
|
|
1021
|
+
pairing: {
|
|
1022
|
+
...previous.pairing || {},
|
|
1023
|
+
status: "paired",
|
|
1024
|
+
...tokenId ? { tokenId } : {},
|
|
1025
|
+
joinedAt: now,
|
|
1026
|
+
lastPairedAt: previous.pairing?.lastPairedAt || now
|
|
1027
|
+
}
|
|
1028
|
+
};
|
|
1029
|
+
mesh.updatedAt = now;
|
|
1030
|
+
saveMeshConfig(config);
|
|
1031
|
+
return { mesh, meshHost: mesh.meshHost };
|
|
1032
|
+
}
|
|
777
1033
|
function addNode(meshId, opts) {
|
|
778
1034
|
const config = loadMeshConfig();
|
|
779
1035
|
const mesh = config.meshes.find((m) => m.id === meshId);
|
|
@@ -794,7 +1050,8 @@ function addNode(meshId, opts) {
|
|
|
794
1050
|
policy: opts.policy || {},
|
|
795
1051
|
isLocalWorktree: opts.isLocalWorktree,
|
|
796
1052
|
worktreeBranch: opts.worktreeBranch,
|
|
797
|
-
clonedFromNodeId: opts.clonedFromNodeId
|
|
1053
|
+
clonedFromNodeId: opts.clonedFromNodeId,
|
|
1054
|
+
role: opts.role
|
|
798
1055
|
};
|
|
799
1056
|
mesh.nodes.push(node);
|
|
800
1057
|
mesh.updatedAt = (/* @__PURE__ */ new Date()).toISOString();
|
|
@@ -830,6 +1087,7 @@ var init_mesh_config = __esm({
|
|
|
830
1087
|
"use strict";
|
|
831
1088
|
init_config();
|
|
832
1089
|
init_repo_mesh_types();
|
|
1090
|
+
init_mesh_host_ownership();
|
|
833
1091
|
SESSION_CLEANUP_MODES = /* @__PURE__ */ new Set(["preserve", "stop", "delete_stopped", "stop_and_delete"]);
|
|
834
1092
|
SPAWNED_SESSION_VISIBILITY_MODES = /* @__PURE__ */ new Set(["visible", "hidden"]);
|
|
835
1093
|
}
|
|
@@ -1007,8 +1265,8 @@ __export(mesh_ledger_exports, {
|
|
|
1007
1265
|
readLedgerEntries: () => readLedgerEntries,
|
|
1008
1266
|
readLedgerSlice: () => readLedgerSlice
|
|
1009
1267
|
});
|
|
1010
|
-
import { existsSync as
|
|
1011
|
-
import { join as
|
|
1268
|
+
import { existsSync as existsSync6, mkdirSync as mkdirSync3, readFileSync as readFileSync4, appendFileSync, statSync as statSync2, renameSync } from "fs";
|
|
1269
|
+
import { join as join6 } from "path";
|
|
1012
1270
|
import { randomUUID as randomUUID4 } from "crypto";
|
|
1013
1271
|
import { EventEmitter } from "events";
|
|
1014
1272
|
function isIntentionalCleanupStopEntry(entry) {
|
|
@@ -1017,19 +1275,19 @@ function isIntentionalCleanupStopEntry(entry) {
|
|
|
1017
1275
|
return payload.intentional === true && (payload.reason === "operator_cleanup" || payload.intentionalStopReason === "operator_cleanup" || payload.source === "mesh_cleanup_sessions" || payload.source === "mesh_remove_node");
|
|
1018
1276
|
}
|
|
1019
1277
|
function getLedgerDir() {
|
|
1020
|
-
const dir =
|
|
1021
|
-
if (!
|
|
1278
|
+
const dir = join6(getConfigDir(), LEDGER_DIR_NAME);
|
|
1279
|
+
if (!existsSync6(dir)) {
|
|
1022
1280
|
mkdirSync3(dir, { recursive: true, mode: 448 });
|
|
1023
1281
|
}
|
|
1024
1282
|
return dir;
|
|
1025
1283
|
}
|
|
1026
1284
|
function getLedgerPath(meshId) {
|
|
1027
1285
|
const safe = meshId.replace(/[^a-zA-Z0-9_-]/g, "_");
|
|
1028
|
-
return
|
|
1286
|
+
return join6(getLedgerDir(), `${safe}.jsonl`);
|
|
1029
1287
|
}
|
|
1030
1288
|
function getRotatedPath(meshId, index) {
|
|
1031
1289
|
const safe = meshId.replace(/[^a-zA-Z0-9_-]/g, "_");
|
|
1032
|
-
return
|
|
1290
|
+
return join6(getLedgerDir(), `${safe}.${index}.jsonl`);
|
|
1033
1291
|
}
|
|
1034
1292
|
function buildTaskCompletionEvidence(opts) {
|
|
1035
1293
|
const providerSessionId = opts.providerSessionId?.trim() || void 0;
|
|
@@ -1070,7 +1328,7 @@ function appendLedgerEntry(meshId, partial) {
|
|
|
1070
1328
|
...partial
|
|
1071
1329
|
};
|
|
1072
1330
|
const filePath = getLedgerPath(meshId);
|
|
1073
|
-
if (
|
|
1331
|
+
if (existsSync6(filePath)) {
|
|
1074
1332
|
try {
|
|
1075
1333
|
const stat2 = statSync2(filePath);
|
|
1076
1334
|
if (stat2.size >= MAX_FILE_SIZE_BYTES) {
|
|
@@ -1137,10 +1395,10 @@ function appendRemoteLedgerEntries(meshId, entries) {
|
|
|
1137
1395
|
}
|
|
1138
1396
|
function readLedgerEntries(meshId, opts) {
|
|
1139
1397
|
const filePath = getLedgerPath(meshId);
|
|
1140
|
-
if (!
|
|
1398
|
+
if (!existsSync6(filePath)) return [];
|
|
1141
1399
|
let content;
|
|
1142
1400
|
try {
|
|
1143
|
-
content =
|
|
1401
|
+
content = readFileSync4(filePath, "utf-8");
|
|
1144
1402
|
} catch {
|
|
1145
1403
|
return [];
|
|
1146
1404
|
}
|
|
@@ -1312,7 +1570,7 @@ function getSessionRecoveryContext(meshId, opts) {
|
|
|
1312
1570
|
}
|
|
1313
1571
|
function rotateLedgerFile(meshId, currentPath) {
|
|
1314
1572
|
let index = 1;
|
|
1315
|
-
while (
|
|
1573
|
+
while (existsSync6(getRotatedPath(meshId, index))) {
|
|
1316
1574
|
index++;
|
|
1317
1575
|
if (index > 10) break;
|
|
1318
1576
|
}
|
|
@@ -1351,16 +1609,16 @@ __export(mesh_work_queue_exports, {
|
|
|
1351
1609
|
updateSessionTaskStatus: () => updateSessionTaskStatus,
|
|
1352
1610
|
updateTaskStatus: () => updateTaskStatus
|
|
1353
1611
|
});
|
|
1354
|
-
import { existsSync as
|
|
1355
|
-
import { join as
|
|
1612
|
+
import { existsSync as existsSync7, writeFileSync as writeFileSync3, readFileSync as readFileSync5, openSync, closeSync, unlinkSync } from "fs";
|
|
1613
|
+
import { join as join7 } from "path";
|
|
1356
1614
|
import { randomUUID as randomUUID5 } from "crypto";
|
|
1357
1615
|
function getQueuePath(meshId) {
|
|
1358
1616
|
const safe = meshId.replace(/[^a-zA-Z0-9_-]/g, "_");
|
|
1359
|
-
return
|
|
1617
|
+
return join7(getLedgerDir(), `${safe}.queue.json`);
|
|
1360
1618
|
}
|
|
1361
1619
|
function getLockPath(meshId) {
|
|
1362
1620
|
const safe = meshId.replace(/[^a-zA-Z0-9_-]/g, "_");
|
|
1363
|
-
return
|
|
1621
|
+
return join7(getLedgerDir(), `${safe}.queue.lock`);
|
|
1364
1622
|
}
|
|
1365
1623
|
function withQueueLock(meshId, fn) {
|
|
1366
1624
|
const lockPath = getLockPath(meshId);
|
|
@@ -1390,9 +1648,9 @@ function withQueueLock(meshId, fn) {
|
|
|
1390
1648
|
}
|
|
1391
1649
|
function readQueue(meshId) {
|
|
1392
1650
|
const path28 = getQueuePath(meshId);
|
|
1393
|
-
if (!
|
|
1651
|
+
if (!existsSync7(path28)) return [];
|
|
1394
1652
|
try {
|
|
1395
|
-
const content =
|
|
1653
|
+
const content = readFileSync5(path28, "utf-8");
|
|
1396
1654
|
return JSON.parse(content);
|
|
1397
1655
|
} catch {
|
|
1398
1656
|
return [];
|
|
@@ -1403,6 +1661,7 @@ function writeQueue(meshId, queue) {
|
|
|
1403
1661
|
writeFileSync3(path28, JSON.stringify(queue, null, 2), "utf-8");
|
|
1404
1662
|
}
|
|
1405
1663
|
function enqueueTask(meshId, message, opts) {
|
|
1664
|
+
requireMeshHostQueueOwner(opts);
|
|
1406
1665
|
return withQueueLock(meshId, () => {
|
|
1407
1666
|
const queue = readQueue(meshId);
|
|
1408
1667
|
const entry = {
|
|
@@ -1451,7 +1710,8 @@ function claimNextTask(meshId, nodeId, sessionId) {
|
|
|
1451
1710
|
return entry;
|
|
1452
1711
|
});
|
|
1453
1712
|
}
|
|
1454
|
-
function updateTaskStatus(meshId, taskId, status) {
|
|
1713
|
+
function updateTaskStatus(meshId, taskId, status, opts) {
|
|
1714
|
+
requireMeshHostQueueOwner(opts);
|
|
1455
1715
|
return withQueueLock(meshId, () => {
|
|
1456
1716
|
const queue = readQueue(meshId);
|
|
1457
1717
|
const idx = queue.findIndex((q) => q.id === taskId);
|
|
@@ -1475,6 +1735,7 @@ function recordTaskAutoLaunch(meshId, taskId, autoLaunch) {
|
|
|
1475
1735
|
});
|
|
1476
1736
|
}
|
|
1477
1737
|
function cancelTask(meshId, taskId, opts) {
|
|
1738
|
+
requireMeshHostQueueOwner(opts);
|
|
1478
1739
|
return withQueueLock(meshId, () => {
|
|
1479
1740
|
const queue = readQueue(meshId);
|
|
1480
1741
|
const idx = queue.findIndex((q) => q.id === taskId);
|
|
@@ -1489,6 +1750,7 @@ function cancelTask(meshId, taskId, opts) {
|
|
|
1489
1750
|
});
|
|
1490
1751
|
}
|
|
1491
1752
|
function requeueTask(meshId, taskId, opts) {
|
|
1753
|
+
requireMeshHostQueueOwner(opts);
|
|
1492
1754
|
return withQueueLock(meshId, () => {
|
|
1493
1755
|
const queue = readQueue(meshId);
|
|
1494
1756
|
const idx = queue.findIndex((q) => q.id === taskId);
|
|
@@ -1573,6 +1835,7 @@ var init_mesh_work_queue = __esm({
|
|
|
1573
1835
|
"src/mesh/mesh-work-queue.ts"() {
|
|
1574
1836
|
"use strict";
|
|
1575
1837
|
init_mesh_ledger();
|
|
1838
|
+
init_mesh_host_ownership();
|
|
1576
1839
|
ACTIVE_MESH_QUEUE_STATUSES = ["pending", "assigned"];
|
|
1577
1840
|
HISTORICAL_MESH_QUEUE_STATUSES = ["completed", "failed", "cancelled"];
|
|
1578
1841
|
}
|
|
@@ -1582,7 +1845,7 @@ var init_mesh_work_queue = __esm({
|
|
|
1582
1845
|
import { exec } from "child_process";
|
|
1583
1846
|
import * as os2 from "os";
|
|
1584
1847
|
import * as path8 from "path";
|
|
1585
|
-
import { existsSync as
|
|
1848
|
+
import { existsSync as existsSync8 } from "fs";
|
|
1586
1849
|
function parseVersion(raw) {
|
|
1587
1850
|
const match = raw.match(/v?(\d+\.\d+(?:\.\d+)?(?:-[a-zA-Z0-9.]+)?)/);
|
|
1588
1851
|
return match ? match[1] : raw.split("\n")[0].slice(0, 100);
|
|
@@ -1606,7 +1869,7 @@ function resolveCommandPath(command) {
|
|
|
1606
1869
|
if (isExplicitCommandPath(trimmed)) {
|
|
1607
1870
|
const expanded = expandHome(trimmed);
|
|
1608
1871
|
const candidate = path8.isAbsolute(expanded) ? expanded : path8.resolve(expanded);
|
|
1609
|
-
return
|
|
1872
|
+
return existsSync8(candidate) ? candidate : null;
|
|
1610
1873
|
}
|
|
1611
1874
|
return null;
|
|
1612
1875
|
}
|
|
@@ -1938,8 +2201,8 @@ __export(mesh_events_exports, {
|
|
|
1938
2201
|
triggerMeshQueue: () => triggerMeshQueue,
|
|
1939
2202
|
tryAssignQueueTask: () => tryAssignQueueTask
|
|
1940
2203
|
});
|
|
1941
|
-
import { appendFileSync as appendFileSync3, existsSync as
|
|
1942
|
-
import { join as
|
|
2204
|
+
import { appendFileSync as appendFileSync3, existsSync as existsSync10, readFileSync as readFileSync6, unlinkSync as unlinkSync3 } from "fs";
|
|
2205
|
+
import { join as join10 } from "path";
|
|
1943
2206
|
function sweepExpiredRemoteIdleSessions() {
|
|
1944
2207
|
const now = Date.now();
|
|
1945
2208
|
for (const [key, session] of remoteIdleSessions) {
|
|
@@ -1948,7 +2211,7 @@ function sweepExpiredRemoteIdleSessions() {
|
|
|
1948
2211
|
}
|
|
1949
2212
|
function getPendingEventsPath(meshId) {
|
|
1950
2213
|
const safe = meshId.replace(/[^a-zA-Z0-9_-]/g, "_");
|
|
1951
|
-
return
|
|
2214
|
+
return join10(getLedgerDir(), `${safe}.pending-events.jsonl`);
|
|
1952
2215
|
}
|
|
1953
2216
|
function queuePendingMeshCoordinatorEvent(event) {
|
|
1954
2217
|
try {
|
|
@@ -1962,9 +2225,9 @@ function queuePendingMeshCoordinatorEvent(event) {
|
|
|
1962
2225
|
function drainPendingMeshCoordinatorEvents(meshId) {
|
|
1963
2226
|
if (!meshId) return [];
|
|
1964
2227
|
const path28 = getPendingEventsPath(meshId);
|
|
1965
|
-
if (!
|
|
2228
|
+
if (!existsSync10(path28)) return [];
|
|
1966
2229
|
try {
|
|
1967
|
-
const raw =
|
|
2230
|
+
const raw = readFileSync6(path28, "utf-8");
|
|
1968
2231
|
try {
|
|
1969
2232
|
unlinkSync3(path28);
|
|
1970
2233
|
} catch {
|
|
@@ -1983,9 +2246,9 @@ function drainPendingMeshCoordinatorEvents(meshId) {
|
|
|
1983
2246
|
function getPendingMeshCoordinatorEvents(meshId) {
|
|
1984
2247
|
if (!meshId) return [];
|
|
1985
2248
|
const path28 = getPendingEventsPath(meshId);
|
|
1986
|
-
if (!
|
|
2249
|
+
if (!existsSync10(path28)) return [];
|
|
1987
2250
|
try {
|
|
1988
|
-
const raw =
|
|
2251
|
+
const raw = readFileSync6(path28, "utf-8");
|
|
1989
2252
|
return raw.split("\n").filter(Boolean).flatMap((line) => {
|
|
1990
2253
|
try {
|
|
1991
2254
|
return [JSON.parse(line)];
|
|
@@ -2000,7 +2263,7 @@ function getPendingMeshCoordinatorEvents(meshId) {
|
|
|
2000
2263
|
function clearPendingMeshCoordinatorEvents(meshId) {
|
|
2001
2264
|
if (!meshId) return;
|
|
2002
2265
|
const path28 = getPendingEventsPath(meshId);
|
|
2003
|
-
if (
|
|
2266
|
+
if (existsSync10(path28)) try {
|
|
2004
2267
|
unlinkSync3(path28);
|
|
2005
2268
|
} catch {
|
|
2006
2269
|
}
|
|
@@ -7561,6 +7824,238 @@ function getSavedProviderSessions(state, filters) {
|
|
|
7561
7824
|
init_mesh_config();
|
|
7562
7825
|
init_coordinator_prompt();
|
|
7563
7826
|
|
|
7827
|
+
// src/mesh/refine-config.ts
|
|
7828
|
+
import { existsSync as existsSync5, readFileSync as readFileSync3 } from "fs";
|
|
7829
|
+
import { join as join5 } from "path";
|
|
7830
|
+
import * as yaml from "js-yaml";
|
|
7831
|
+
var MESH_REFINE_VALIDATION_CATEGORIES = ["typecheck", "test", "lint", "build"];
|
|
7832
|
+
var MESH_REFINE_CONFIG_LOCATIONS = [
|
|
7833
|
+
".adhdev/refine.json",
|
|
7834
|
+
".adhdev/refine.yaml",
|
|
7835
|
+
".adhdev/refine.yml",
|
|
7836
|
+
".adhdev/repo-mesh-refine.json",
|
|
7837
|
+
".adhdev/repo-mesh-refine.yaml",
|
|
7838
|
+
".adhdev/repo-mesh-refine.yml",
|
|
7839
|
+
"repo-mesh.refine.json",
|
|
7840
|
+
"repo-mesh.refine.yaml",
|
|
7841
|
+
"repo-mesh.refine.yml"
|
|
7842
|
+
];
|
|
7843
|
+
var MESH_REFINE_CONFIG_SCHEMA = {
|
|
7844
|
+
$schema: "https://json-schema.org/draft/2020-12/schema",
|
|
7845
|
+
title: "ADHDev Repo Mesh Refinery Config",
|
|
7846
|
+
type: "object",
|
|
7847
|
+
additionalProperties: false,
|
|
7848
|
+
required: ["version"],
|
|
7849
|
+
properties: {
|
|
7850
|
+
version: { const: 1 },
|
|
7851
|
+
validation: {
|
|
7852
|
+
type: "object",
|
|
7853
|
+
additionalProperties: false,
|
|
7854
|
+
properties: {
|
|
7855
|
+
required: { type: "boolean", default: true },
|
|
7856
|
+
commands: {
|
|
7857
|
+
type: "array",
|
|
7858
|
+
minItems: 1,
|
|
7859
|
+
maxItems: 8,
|
|
7860
|
+
items: {
|
|
7861
|
+
type: "object",
|
|
7862
|
+
additionalProperties: false,
|
|
7863
|
+
required: ["command"],
|
|
7864
|
+
properties: {
|
|
7865
|
+
command: { type: "string", minLength: 1 },
|
|
7866
|
+
args: { type: "array", items: { type: "string" } },
|
|
7867
|
+
category: { enum: [...MESH_REFINE_VALIDATION_CATEGORIES, "custom"] },
|
|
7868
|
+
cwd: { type: "string" },
|
|
7869
|
+
timeoutMs: { type: "number", minimum: 1e3, maximum: 6e5 },
|
|
7870
|
+
env: { type: "object", additionalProperties: { type: "string" } }
|
|
7871
|
+
}
|
|
7872
|
+
}
|
|
7873
|
+
}
|
|
7874
|
+
}
|
|
7875
|
+
}
|
|
7876
|
+
}
|
|
7877
|
+
};
|
|
7878
|
+
function isRecord(value) {
|
|
7879
|
+
return !!value && typeof value === "object" && !Array.isArray(value);
|
|
7880
|
+
}
|
|
7881
|
+
function tokenizeCommandString(command) {
|
|
7882
|
+
const trimmed = command.trim();
|
|
7883
|
+
if (!trimmed) return null;
|
|
7884
|
+
if (/[;&|<>`$\\\n\r'\"]/.test(trimmed)) return null;
|
|
7885
|
+
const tokens = trimmed.split(/\s+/).filter(Boolean);
|
|
7886
|
+
if (!tokens.length) return null;
|
|
7887
|
+
if (tokens.some((token) => !/^[A-Za-z0-9_@./:=+-]+$/.test(token))) return null;
|
|
7888
|
+
return tokens;
|
|
7889
|
+
}
|
|
7890
|
+
function validateCategory(value) {
|
|
7891
|
+
return typeof value === "string" && [...MESH_REFINE_VALIDATION_CATEGORIES, "custom"].includes(value) ? value : "custom";
|
|
7892
|
+
}
|
|
7893
|
+
function normalizeCommandConfig(entry, source) {
|
|
7894
|
+
if (!isRecord(entry) || typeof entry.command !== "string") {
|
|
7895
|
+
return { rejected: { source, reason: "validation command must be an object with a command string" } };
|
|
7896
|
+
}
|
|
7897
|
+
const commandText = entry.command.trim();
|
|
7898
|
+
const explicitArgs = Array.isArray(entry.args) ? entry.args : void 0;
|
|
7899
|
+
if (explicitArgs && !explicitArgs.every((arg) => typeof arg === "string")) {
|
|
7900
|
+
return { rejected: { source, command: commandText, reason: "args must be an array of strings" } };
|
|
7901
|
+
}
|
|
7902
|
+
let command = commandText;
|
|
7903
|
+
let args = explicitArgs ? [...explicitArgs] : [];
|
|
7904
|
+
if (!explicitArgs) {
|
|
7905
|
+
const tokens = tokenizeCommandString(commandText);
|
|
7906
|
+
if (!tokens) return { rejected: { source, command: commandText, reason: "unsafe command string is not allowlisted" } };
|
|
7907
|
+
command = tokens[0];
|
|
7908
|
+
args = tokens.slice(1);
|
|
7909
|
+
} else if (!tokenizeCommandString(command)) {
|
|
7910
|
+
return { rejected: { source, command: commandText, reason: "unsafe executable name is not allowlisted" } };
|
|
7911
|
+
}
|
|
7912
|
+
if (args.some((arg) => /[\n\r\0]/.test(arg))) {
|
|
7913
|
+
return { rejected: { source, command: commandText, reason: "args cannot contain control characters" } };
|
|
7914
|
+
}
|
|
7915
|
+
if (entry.cwd !== void 0 && typeof entry.cwd !== "string") {
|
|
7916
|
+
return { rejected: { source, command: commandText, reason: "cwd must be a string when provided" } };
|
|
7917
|
+
}
|
|
7918
|
+
if (entry.timeoutMs !== void 0 && (typeof entry.timeoutMs !== "number" || !Number.isFinite(entry.timeoutMs) || entry.timeoutMs < 1e3 || entry.timeoutMs > 6e5)) {
|
|
7919
|
+
return { rejected: { source, command: commandText, reason: "timeoutMs must be between 1000 and 600000" } };
|
|
7920
|
+
}
|
|
7921
|
+
if (entry.env !== void 0 && (!isRecord(entry.env) || !Object.values(entry.env).every((value) => typeof value === "string"))) {
|
|
7922
|
+
return { rejected: { source, command: commandText, reason: "env must be an object of string values" } };
|
|
7923
|
+
}
|
|
7924
|
+
return {
|
|
7925
|
+
command: {
|
|
7926
|
+
command,
|
|
7927
|
+
args,
|
|
7928
|
+
displayCommand: [command, ...args].join(" "),
|
|
7929
|
+
category: validateCategory(entry.category),
|
|
7930
|
+
source,
|
|
7931
|
+
...typeof entry.cwd === "string" && entry.cwd.trim() ? { cwd: entry.cwd.trim() } : {},
|
|
7932
|
+
...typeof entry.timeoutMs === "number" ? { timeoutMs: entry.timeoutMs } : {},
|
|
7933
|
+
...isRecord(entry.env) ? { env: entry.env } : {}
|
|
7934
|
+
}
|
|
7935
|
+
};
|
|
7936
|
+
}
|
|
7937
|
+
function validateMeshRefineConfig(config, source = "inline") {
|
|
7938
|
+
const errors = [];
|
|
7939
|
+
const commands = [];
|
|
7940
|
+
const rejectedCommands = [];
|
|
7941
|
+
if (!isRecord(config)) return { valid: false, errors: ["config must be an object"], commands, rejectedCommands };
|
|
7942
|
+
if (config.version !== 1) errors.push("version must be 1");
|
|
7943
|
+
const validation = config.validation;
|
|
7944
|
+
if (validation !== void 0 && !isRecord(validation)) errors.push("validation must be an object");
|
|
7945
|
+
const rawCommands = isRecord(validation) ? validation.commands : void 0;
|
|
7946
|
+
if (rawCommands !== void 0 && !Array.isArray(rawCommands)) errors.push("validation.commands must be an array");
|
|
7947
|
+
if (Array.isArray(rawCommands)) {
|
|
7948
|
+
rawCommands.forEach((entry, index) => {
|
|
7949
|
+
const normalized = normalizeCommandConfig(entry, `${source}:validation.commands[${index}]`);
|
|
7950
|
+
if (normalized.command) commands.push(normalized.command);
|
|
7951
|
+
if (normalized.rejected) rejectedCommands.push(normalized.rejected);
|
|
7952
|
+
});
|
|
7953
|
+
}
|
|
7954
|
+
if (rejectedCommands.length) errors.push("one or more validation commands are invalid");
|
|
7955
|
+
return { valid: errors.length === 0, errors, commands, rejectedCommands };
|
|
7956
|
+
}
|
|
7957
|
+
function parseConfigText(path28, text) {
|
|
7958
|
+
if (/\.json$/i.test(path28)) return JSON.parse(text);
|
|
7959
|
+
return yaml.load(text);
|
|
7960
|
+
}
|
|
7961
|
+
function loadMeshRefineConfig(mesh, workspace) {
|
|
7962
|
+
const policy = mesh?.policy && typeof mesh.policy === "object" && !Array.isArray(mesh.policy) ? mesh.policy : {};
|
|
7963
|
+
const inline = mesh?.refineConfig || policy.refineConfig || policy.refine;
|
|
7964
|
+
if (inline !== void 0) {
|
|
7965
|
+
const validation = validateMeshRefineConfig(inline, "mesh.policy.refineConfig");
|
|
7966
|
+
if (!validation.valid) return { source: "mesh.policy.refineConfig", sourceType: "invalid", error: String(validation.rejectedCommands[0]?.reason || validation.errors.join("; ")) };
|
|
7967
|
+
return { config: inline, source: "mesh.policy.refineConfig", sourceType: "mesh_policy" };
|
|
7968
|
+
}
|
|
7969
|
+
for (const relative3 of MESH_REFINE_CONFIG_LOCATIONS) {
|
|
7970
|
+
const configPath = join5(workspace, relative3);
|
|
7971
|
+
if (!existsSync5(configPath)) continue;
|
|
7972
|
+
try {
|
|
7973
|
+
const parsed = parseConfigText(configPath, readFileSync3(configPath, "utf-8"));
|
|
7974
|
+
const validation = validateMeshRefineConfig(parsed, relative3);
|
|
7975
|
+
if (!validation.valid) return { source: relative3, sourceType: "invalid", path: configPath, error: String(validation.rejectedCommands[0]?.reason || validation.errors.join("; ")) };
|
|
7976
|
+
return { config: parsed, source: relative3, sourceType: "repo_file", path: configPath };
|
|
7977
|
+
} catch (error) {
|
|
7978
|
+
return { source: relative3, sourceType: "invalid", path: configPath, error: error?.message || String(error) };
|
|
7979
|
+
}
|
|
7980
|
+
}
|
|
7981
|
+
return {
|
|
7982
|
+
source: "unavailable",
|
|
7983
|
+
sourceType: "unavailable",
|
|
7984
|
+
error: `No repo mesh/refine config found. Checked: ${MESH_REFINE_CONFIG_LOCATIONS.join(", ")}`
|
|
7985
|
+
};
|
|
7986
|
+
}
|
|
7987
|
+
function readPackageScripts(workspace) {
|
|
7988
|
+
try {
|
|
7989
|
+
const parsed = JSON.parse(readFileSync3(join5(workspace, "package.json"), "utf-8"));
|
|
7990
|
+
return isRecord(parsed?.scripts) ? parsed.scripts : {};
|
|
7991
|
+
} catch {
|
|
7992
|
+
return {};
|
|
7993
|
+
}
|
|
7994
|
+
}
|
|
7995
|
+
function collectProjectContextSuggestions(mesh) {
|
|
7996
|
+
const commands = mesh?.projectContext?.commands;
|
|
7997
|
+
if (!isRecord(commands)) return [];
|
|
7998
|
+
const suggestions = [];
|
|
7999
|
+
for (const category of MESH_REFINE_VALIDATION_CATEGORIES) {
|
|
8000
|
+
const entries = Array.isArray(commands[category]) ? commands[category] : [];
|
|
8001
|
+
for (const entry of entries) {
|
|
8002
|
+
if (isRecord(entry) && typeof entry.command === "string") suggestions.push({ command: entry.command, category });
|
|
8003
|
+
}
|
|
8004
|
+
}
|
|
8005
|
+
return suggestions;
|
|
8006
|
+
}
|
|
8007
|
+
function collectPackageScriptSuggestions(workspace) {
|
|
8008
|
+
const scripts = readPackageScripts(workspace);
|
|
8009
|
+
const suggestions = [];
|
|
8010
|
+
for (const category of MESH_REFINE_VALIDATION_CATEGORIES) {
|
|
8011
|
+
for (const scriptName of Object.keys(scripts)) {
|
|
8012
|
+
if (scriptName === category || scriptName.startsWith(`${category}:`)) {
|
|
8013
|
+
suggestions.push({ command: "npm", args: ["run", scriptName], category });
|
|
8014
|
+
}
|
|
8015
|
+
}
|
|
8016
|
+
}
|
|
8017
|
+
return suggestions;
|
|
8018
|
+
}
|
|
8019
|
+
function suggestMeshRefineConfig(mesh, workspace) {
|
|
8020
|
+
const seen = /* @__PURE__ */ new Set();
|
|
8021
|
+
const suggestions = [];
|
|
8022
|
+
for (const entry of [...collectProjectContextSuggestions(mesh), ...collectPackageScriptSuggestions(workspace)]) {
|
|
8023
|
+
const key = `${entry.command} ${(entry.args || []).join(" ")}`.trim();
|
|
8024
|
+
if (seen.has(key)) continue;
|
|
8025
|
+
seen.add(key);
|
|
8026
|
+
suggestions.push(entry);
|
|
8027
|
+
}
|
|
8028
|
+
return {
|
|
8029
|
+
suggestions,
|
|
8030
|
+
suggestedConfig: suggestions.length ? { version: 1, validation: { required: true, commands: suggestions.slice(0, 4) } } : void 0
|
|
8031
|
+
};
|
|
8032
|
+
}
|
|
8033
|
+
function resolveMeshRefineValidationPlan(mesh, workspace) {
|
|
8034
|
+
const loaded = loadMeshRefineConfig(mesh, workspace);
|
|
8035
|
+
const suggestion = suggestMeshRefineConfig(mesh, workspace);
|
|
8036
|
+
if (!loaded.config) {
|
|
8037
|
+
return {
|
|
8038
|
+
source: loaded.source,
|
|
8039
|
+
sourceType: loaded.sourceType,
|
|
8040
|
+
commands: [],
|
|
8041
|
+
rejectedCommands: loaded.error ? [{ source: loaded.source, reason: loaded.error }] : [],
|
|
8042
|
+
suggestions: suggestion.suggestions,
|
|
8043
|
+
suggestedConfig: suggestion.suggestedConfig,
|
|
8044
|
+
unavailableReason: loaded.error || "validation_unavailable: repo mesh/refine config missing"
|
|
8045
|
+
};
|
|
8046
|
+
}
|
|
8047
|
+
const validation = validateMeshRefineConfig(loaded.config, loaded.source);
|
|
8048
|
+
return {
|
|
8049
|
+
source: loaded.path || loaded.source,
|
|
8050
|
+
sourceType: loaded.sourceType,
|
|
8051
|
+
commands: validation.commands,
|
|
8052
|
+
rejectedCommands: validation.rejectedCommands,
|
|
8053
|
+
suggestions: suggestion.suggestions,
|
|
8054
|
+
suggestedConfig: suggestion.suggestedConfig,
|
|
8055
|
+
unavailableReason: validation.commands.length ? void 0 : "validation_unavailable: repo mesh/refine config has no validation.commands"
|
|
8056
|
+
};
|
|
8057
|
+
}
|
|
8058
|
+
|
|
7564
8059
|
// src/mesh/mesh-sync.ts
|
|
7565
8060
|
init_mesh_config();
|
|
7566
8061
|
async function syncMeshes(transport) {
|
|
@@ -7680,6 +8175,7 @@ function buildMeshLedgerReconciliationEvidence(meshId, replicas) {
|
|
|
7680
8175
|
|
|
7681
8176
|
// src/index.ts
|
|
7682
8177
|
init_mesh_work_queue();
|
|
8178
|
+
init_mesh_host_ownership();
|
|
7683
8179
|
init_mesh_events();
|
|
7684
8180
|
|
|
7685
8181
|
// src/mesh/p2p-relay-failure.ts
|
|
@@ -7794,8 +8290,8 @@ var P2pRelayFailureError = class extends Error {
|
|
|
7794
8290
|
|
|
7795
8291
|
// src/config/state-store.ts
|
|
7796
8292
|
init_config();
|
|
7797
|
-
import { existsSync as
|
|
7798
|
-
import { join as
|
|
8293
|
+
import { existsSync as existsSync11, readFileSync as readFileSync7, writeFileSync as writeFileSync4 } from "fs";
|
|
8294
|
+
import { join as join11 } from "path";
|
|
7799
8295
|
var DEFAULT_STATE = {
|
|
7800
8296
|
recentActivity: [],
|
|
7801
8297
|
savedProviderSessions: [],
|
|
@@ -7808,7 +8304,7 @@ function isPlainObject2(value) {
|
|
|
7808
8304
|
return !!value && typeof value === "object" && !Array.isArray(value);
|
|
7809
8305
|
}
|
|
7810
8306
|
function getStatePath() {
|
|
7811
|
-
return
|
|
8307
|
+
return join11(getConfigDir(), "state.json");
|
|
7812
8308
|
}
|
|
7813
8309
|
function normalizeState(raw) {
|
|
7814
8310
|
const parsed = isPlainObject2(raw) ? raw : {};
|
|
@@ -7844,11 +8340,11 @@ function normalizeState(raw) {
|
|
|
7844
8340
|
}
|
|
7845
8341
|
function loadState() {
|
|
7846
8342
|
const statePath = getStatePath();
|
|
7847
|
-
if (!
|
|
8343
|
+
if (!existsSync11(statePath)) {
|
|
7848
8344
|
return { ...DEFAULT_STATE };
|
|
7849
8345
|
}
|
|
7850
8346
|
try {
|
|
7851
|
-
const raw =
|
|
8347
|
+
const raw = readFileSync7(statePath, "utf-8");
|
|
7852
8348
|
return normalizeState(JSON.parse(raw));
|
|
7853
8349
|
} catch {
|
|
7854
8350
|
return { ...DEFAULT_STATE };
|
|
@@ -7865,7 +8361,7 @@ function resetState() {
|
|
|
7865
8361
|
|
|
7866
8362
|
// src/detection/ide-detector.ts
|
|
7867
8363
|
import { execSync } from "child_process";
|
|
7868
|
-
import { existsSync as
|
|
8364
|
+
import { existsSync as existsSync12 } from "fs";
|
|
7869
8365
|
import { platform as platform2, homedir as homedir5 } from "os";
|
|
7870
8366
|
import * as path10 from "path";
|
|
7871
8367
|
var BUILTIN_IDE_DEFINITIONS = [];
|
|
@@ -7889,7 +8385,7 @@ function findCliCommand(command) {
|
|
|
7889
8385
|
if (path10.isAbsolute(trimmed) || trimmed.includes("/") || trimmed.includes("\\") || trimmed.startsWith("~")) {
|
|
7890
8386
|
const candidate = trimmed.startsWith("~") ? path10.join(homedir5(), trimmed.slice(1)) : trimmed;
|
|
7891
8387
|
const resolved = path10.isAbsolute(candidate) ? candidate : path10.resolve(candidate);
|
|
7892
|
-
return
|
|
8388
|
+
return existsSync12(resolved) ? resolved : null;
|
|
7893
8389
|
}
|
|
7894
8390
|
try {
|
|
7895
8391
|
const result = execSync(
|
|
@@ -7920,9 +8416,9 @@ function checkPathExists(paths) {
|
|
|
7920
8416
|
if (normalized.includes("*")) {
|
|
7921
8417
|
const username = home.split(/[\\/]/).pop() || "";
|
|
7922
8418
|
const resolved = normalized.replace("*", username);
|
|
7923
|
-
if (
|
|
8419
|
+
if (existsSync12(resolved)) return resolved;
|
|
7924
8420
|
} else {
|
|
7925
|
-
if (
|
|
8421
|
+
if (existsSync12(normalized)) return normalized;
|
|
7926
8422
|
}
|
|
7927
8423
|
}
|
|
7928
8424
|
return null;
|
|
@@ -7936,7 +8432,7 @@ async function detectIDEs(providerLoader) {
|
|
|
7936
8432
|
let resolvedCli = cliPath;
|
|
7937
8433
|
if (!resolvedCli && appPath && os22 === "darwin") {
|
|
7938
8434
|
const bundledCli = `${appPath}/Contents/Resources/app/bin/${def.cli}`;
|
|
7939
|
-
if (
|
|
8435
|
+
if (existsSync12(bundledCli)) resolvedCli = bundledCli;
|
|
7940
8436
|
}
|
|
7941
8437
|
if (!resolvedCli && appPath && os22 === "win32") {
|
|
7942
8438
|
const { dirname: dirname9 } = await import("path");
|
|
@@ -7949,7 +8445,7 @@ async function detectIDEs(providerLoader) {
|
|
|
7949
8445
|
`${appDir}\\\\resources\\\\app\\\\bin\\\\${def.cli}.cmd`
|
|
7950
8446
|
];
|
|
7951
8447
|
for (const c of candidates) {
|
|
7952
|
-
if (
|
|
8448
|
+
if (existsSync12(c)) {
|
|
7953
8449
|
resolvedCli = c;
|
|
7954
8450
|
break;
|
|
7955
8451
|
}
|
|
@@ -17105,7 +17601,7 @@ init_config();
|
|
|
17105
17601
|
import * as os13 from "os";
|
|
17106
17602
|
import * as path18 from "path";
|
|
17107
17603
|
import * as crypto4 from "crypto";
|
|
17108
|
-
import { existsSync as
|
|
17604
|
+
import { existsSync as existsSync16, mkdirSync as mkdirSync9, writeFileSync as writeFileSync9 } from "fs";
|
|
17109
17605
|
import { execFileSync } from "child_process";
|
|
17110
17606
|
import chalk from "chalk";
|
|
17111
17607
|
|
|
@@ -19579,7 +20075,7 @@ function commandExists(command) {
|
|
|
19579
20075
|
const trimmed = command.trim();
|
|
19580
20076
|
if (!trimmed) return false;
|
|
19581
20077
|
if (isExplicitCommand(trimmed)) {
|
|
19582
|
-
return
|
|
20078
|
+
return existsSync16(expandExecutable(trimmed));
|
|
19583
20079
|
}
|
|
19584
20080
|
try {
|
|
19585
20081
|
execFileSync(process.platform === "win32" ? "where" : "which", [trimmed], {
|
|
@@ -22843,15 +23339,15 @@ cleanOldFiles();
|
|
|
22843
23339
|
|
|
22844
23340
|
// src/commands/router.ts
|
|
22845
23341
|
init_logger();
|
|
22846
|
-
import * as
|
|
23342
|
+
import * as yaml2 from "js-yaml";
|
|
22847
23343
|
|
|
22848
23344
|
// src/commands/mesh-coordinator.ts
|
|
22849
23345
|
import { execFileSync as execFileSync2 } from "child_process";
|
|
22850
|
-
import { createHash as
|
|
22851
|
-
import { existsSync as
|
|
23346
|
+
import { createHash as createHash3 } from "crypto";
|
|
23347
|
+
import { existsSync as existsSync19, readdirSync as readdirSync7, realpathSync as realpathSync2 } from "fs";
|
|
22852
23348
|
import { createRequire as createRequire2 } from "module";
|
|
22853
23349
|
import * as os17 from "os";
|
|
22854
|
-
import { dirname as dirname4, isAbsolute as isAbsolute11, join as
|
|
23350
|
+
import { dirname as dirname4, isAbsolute as isAbsolute11, join as join22, resolve as resolve13 } from "path";
|
|
22855
23351
|
var DEFAULT_SERVER_NAME = "adhdev-mesh";
|
|
22856
23352
|
var DEFAULT_ADHDEV_MCP_COMMAND = "adhdev-mcp";
|
|
22857
23353
|
var HERMES_CLI_TYPE = "hermes-cli";
|
|
@@ -22874,7 +23370,7 @@ function resolveHermesMeshCoordinatorSetup(options) {
|
|
|
22874
23370
|
reason: "Could not resolve the ADHDev MCP server entrypoint and a Node runtime with WebSocket support for daemon IPC mode"
|
|
22875
23371
|
};
|
|
22876
23372
|
}
|
|
22877
|
-
const configPath =
|
|
23373
|
+
const configPath = join22(resolveHermesCoordinatorHome(options.meshId, options.workspace), "config.yaml");
|
|
22878
23374
|
if (!configPath.trim()) {
|
|
22879
23375
|
return createHermesManualMeshCoordinatorSetup(options.meshId, options.workspace);
|
|
22880
23376
|
}
|
|
@@ -22994,15 +23490,15 @@ function renderMeshCoordinatorTemplate(template, values) {
|
|
|
22994
23490
|
function resolveHermesCoordinatorHome(meshId, workspace) {
|
|
22995
23491
|
const key = `${meshId || "mesh"}
|
|
22996
23492
|
${resolve13(workspace || os17.tmpdir())}`;
|
|
22997
|
-
const hash =
|
|
22998
|
-
return
|
|
23493
|
+
const hash = createHash3("sha256").update(key).digest("hex").slice(0, 16);
|
|
23494
|
+
return join22(os17.tmpdir(), `adhdev-hermes-mesh-coordinator-${hash}`);
|
|
22999
23495
|
}
|
|
23000
23496
|
function resolveMcpConfigPath(configPath, workspace) {
|
|
23001
23497
|
const trimmed = configPath.trim();
|
|
23002
23498
|
if (trimmed === "~") return os17.homedir();
|
|
23003
|
-
if (trimmed.startsWith("~/")) return
|
|
23499
|
+
if (trimmed.startsWith("~/")) return join22(os17.homedir(), trimmed.slice(2));
|
|
23004
23500
|
if (isAbsolute11(trimmed)) return trimmed;
|
|
23005
|
-
return
|
|
23501
|
+
return join22(workspace, trimmed);
|
|
23006
23502
|
}
|
|
23007
23503
|
function resolveAdhdevMcpServerLaunch(options) {
|
|
23008
23504
|
const entryPath = resolveAdhdevMcpEntryPath(options.adhdevMcpEntryPath);
|
|
@@ -23058,15 +23554,15 @@ function addNodeCandidatesFromPath(pathValue, addCandidate) {
|
|
|
23058
23554
|
for (const entry of (pathValue || "").split(":")) {
|
|
23059
23555
|
const dir = entry.trim();
|
|
23060
23556
|
if (!dir) continue;
|
|
23061
|
-
addCandidate(
|
|
23557
|
+
addCandidate(join22(dir, "node"));
|
|
23062
23558
|
}
|
|
23063
23559
|
}
|
|
23064
23560
|
function addNodeCandidatesFromNvm(homeDir, addCandidate) {
|
|
23065
|
-
const versionsDir =
|
|
23561
|
+
const versionsDir = join22(homeDir, ".nvm", "versions", "node");
|
|
23066
23562
|
try {
|
|
23067
23563
|
const versionDirs = readdirSync7(versionsDir, { withFileTypes: true }).filter((entry) => entry.isDirectory()).map((entry) => entry.name).sort(compareNodeVersionNamesDescending);
|
|
23068
23564
|
for (const versionDir of versionDirs) {
|
|
23069
|
-
addCandidate(
|
|
23565
|
+
addCandidate(join22(versionsDir, versionDir, "bin", "node"));
|
|
23070
23566
|
}
|
|
23071
23567
|
} catch {
|
|
23072
23568
|
}
|
|
@@ -23117,7 +23613,7 @@ function resolveAdhdevMcpEntryPath(explicitPath) {
|
|
|
23117
23613
|
if (normalized) return normalized;
|
|
23118
23614
|
}
|
|
23119
23615
|
try {
|
|
23120
|
-
const requireBase = process.argv[1] ? normalizeExistingPath(process.argv[1]) || process.argv[1] :
|
|
23616
|
+
const requireBase = process.argv[1] ? normalizeExistingPath(process.argv[1]) || process.argv[1] : join22(process.cwd(), "adhdev-daemon.js");
|
|
23121
23617
|
const req = createRequire2(requireBase);
|
|
23122
23618
|
const resolvedModule = req.resolve("@adhdev/mcp-server");
|
|
23123
23619
|
return normalizeExistingPath(resolvedModule) || resolvedModule;
|
|
@@ -23127,7 +23623,7 @@ function resolveAdhdevMcpEntryPath(explicitPath) {
|
|
|
23127
23623
|
}
|
|
23128
23624
|
function normalizeExistingPath(filePath) {
|
|
23129
23625
|
try {
|
|
23130
|
-
if (!
|
|
23626
|
+
if (!existsSync19(filePath)) return null;
|
|
23131
23627
|
return realpathSync2.native(filePath);
|
|
23132
23628
|
} catch {
|
|
23133
23629
|
return null;
|
|
@@ -23136,6 +23632,7 @@ function normalizeExistingPath(filePath) {
|
|
|
23136
23632
|
|
|
23137
23633
|
// src/commands/router.ts
|
|
23138
23634
|
init_mesh_events();
|
|
23635
|
+
init_mesh_host_ownership();
|
|
23139
23636
|
|
|
23140
23637
|
// src/status/snapshot.ts
|
|
23141
23638
|
init_config();
|
|
@@ -24431,11 +24928,9 @@ async function resolveProviderTypeFromPriority(args) {
|
|
|
24431
24928
|
}
|
|
24432
24929
|
return { error: `No usable provider detected for node '${args.nodeId}' from providerPriority: ${failed.join("; ")}` };
|
|
24433
24930
|
}
|
|
24434
|
-
var REFINE_VALIDATION_CATEGORIES = ["typecheck", "test", "lint", "build"];
|
|
24435
24931
|
var REFINE_VALIDATION_TIMEOUT_MS = 12e4;
|
|
24436
24932
|
var REFINE_VALIDATION_OUTPUT_LIMIT_BYTES = 128 * 1024;
|
|
24437
24933
|
var REFINE_VALIDATION_SUMMARY_CHARS = 2e3;
|
|
24438
|
-
var REFINE_VALIDATION_MAX_COMMANDS = 4;
|
|
24439
24934
|
var REFINE_PATCH_EQUIVALENCE_OUTPUT_LIMIT_BYTES = 4 * 1024 * 1024;
|
|
24440
24935
|
function truncateValidationOutput(value) {
|
|
24441
24936
|
const text = typeof value === "string" ? value : value == null ? "" : String(value);
|
|
@@ -24519,141 +25014,30 @@ async function runMeshRefinePatchEquivalenceGate(repoRoot, baseHead, branchHead)
|
|
|
24519
25014
|
};
|
|
24520
25015
|
}
|
|
24521
25016
|
}
|
|
24522
|
-
function
|
|
24523
|
-
|
|
24524
|
-
const packageJsonPath = pathJoin(workspace, "package.json");
|
|
24525
|
-
const parsed = JSON.parse(fs10.readFileSync(packageJsonPath, "utf-8"));
|
|
24526
|
-
return parsed?.scripts && typeof parsed.scripts === "object" && !Array.isArray(parsed.scripts) ? parsed.scripts : {};
|
|
24527
|
-
} catch {
|
|
24528
|
-
return {};
|
|
24529
|
-
}
|
|
24530
|
-
}
|
|
24531
|
-
function tokenizeValidationCommand(command) {
|
|
24532
|
-
const trimmed = command.trim();
|
|
24533
|
-
if (!trimmed) return null;
|
|
24534
|
-
if (/[;&|<>`$\\\n\r'\"]/.test(trimmed)) return null;
|
|
24535
|
-
const tokens = trimmed.split(/\s+/).filter(Boolean);
|
|
24536
|
-
if (!tokens.length) return null;
|
|
24537
|
-
if (tokens.some((token) => !/^[A-Za-z0-9_@./:=+-]+$/.test(token))) return null;
|
|
24538
|
-
return tokens;
|
|
24539
|
-
}
|
|
24540
|
-
function scriptMatchesValidationCategory(scriptName, category) {
|
|
24541
|
-
return scriptName === category || scriptName.startsWith(`${category}:`);
|
|
24542
|
-
}
|
|
24543
|
-
function parsePackageManagerValidationCommand(rawCommand, category, scripts, source) {
|
|
24544
|
-
const tokens = tokenizeValidationCommand(rawCommand);
|
|
24545
|
-
if (!tokens) {
|
|
24546
|
-
return { rejected: { command: rawCommand, category, source, reason: "unsafe command string is not allowlisted" } };
|
|
24547
|
-
}
|
|
24548
|
-
const [binary, second, third, ...rest] = tokens;
|
|
24549
|
-
let scriptName = "";
|
|
24550
|
-
let command = binary;
|
|
24551
|
-
let args = [];
|
|
24552
|
-
if ((binary === "npm" || binary === "pnpm" || binary === "bun") && second === "run" && third) {
|
|
24553
|
-
scriptName = third;
|
|
24554
|
-
args = ["run", scriptName, ...rest];
|
|
24555
|
-
} else if (binary === "npm" && second === "test" && !third) {
|
|
24556
|
-
scriptName = "test";
|
|
24557
|
-
args = ["test"];
|
|
24558
|
-
} else if (binary === "yarn" && second === "run" && third) {
|
|
24559
|
-
scriptName = third;
|
|
24560
|
-
args = ["run", scriptName, ...rest];
|
|
24561
|
-
} else if (binary === "yarn" && second && !third) {
|
|
24562
|
-
scriptName = second;
|
|
24563
|
-
args = [scriptName];
|
|
24564
|
-
} else {
|
|
24565
|
-
return { rejected: { command: rawCommand, category, source, reason: "command is not a supported package-manager script invocation" } };
|
|
24566
|
-
}
|
|
24567
|
-
if (!scriptName || !Object.prototype.hasOwnProperty.call(scripts, scriptName)) {
|
|
24568
|
-
return { rejected: { command: rawCommand, category, source, script: scriptName, reason: "script is not declared in package.json" } };
|
|
24569
|
-
}
|
|
24570
|
-
if (!scriptMatchesValidationCategory(scriptName, category)) {
|
|
24571
|
-
return { rejected: { command: rawCommand, category, source, script: scriptName, reason: "script name is outside the validation category allowlist" } };
|
|
24572
|
-
}
|
|
24573
|
-
return {
|
|
24574
|
-
command: {
|
|
24575
|
-
command,
|
|
24576
|
-
args,
|
|
24577
|
-
displayCommand: [command, ...args].join(" "),
|
|
24578
|
-
category,
|
|
24579
|
-
source
|
|
24580
|
-
}
|
|
24581
|
-
};
|
|
24582
|
-
}
|
|
24583
|
-
function collectProjectContextValidationCandidates(mesh) {
|
|
24584
|
-
const commands = mesh?.projectContext?.commands;
|
|
24585
|
-
if (!commands || typeof commands !== "object" || Array.isArray(commands)) return [];
|
|
24586
|
-
const candidates = [];
|
|
24587
|
-
for (const category of REFINE_VALIDATION_CATEGORIES) {
|
|
24588
|
-
const entries = Array.isArray(commands[category]) ? commands[category] : [];
|
|
24589
|
-
for (const entry of entries) {
|
|
24590
|
-
if (typeof entry?.command !== "string") continue;
|
|
24591
|
-
candidates.push({
|
|
24592
|
-
command: entry.command,
|
|
24593
|
-
category,
|
|
24594
|
-
source: typeof entry.sourcePath === "string" ? entry.sourcePath : "projectContext.commands",
|
|
24595
|
-
confidence: typeof entry.confidence === "string" ? entry.confidence : void 0
|
|
24596
|
-
});
|
|
24597
|
-
}
|
|
24598
|
-
}
|
|
24599
|
-
return candidates.sort((a, b) => {
|
|
24600
|
-
const rank = (value) => value === "high" ? 0 : value === "medium" ? 1 : 2;
|
|
24601
|
-
return rank(a.confidence) - rank(b.confidence);
|
|
24602
|
-
});
|
|
24603
|
-
}
|
|
24604
|
-
function collectPolicyValidationCandidates(mesh) {
|
|
24605
|
-
const policy = mesh?.policy && typeof mesh.policy === "object" && !Array.isArray(mesh.policy) ? mesh.policy : {};
|
|
24606
|
-
const configured = Array.isArray(policy.validationCommands) ? policy.validationCommands : Array.isArray(policy.validationGate?.commands) ? policy.validationGate.commands : [];
|
|
24607
|
-
return configured.map((entry) => typeof entry === "string" ? { command: entry, category: "", source: "mesh.policy.validationCommands" } : entry).filter((entry) => entry && typeof entry.command === "string").map((entry) => {
|
|
24608
|
-
const commandText = entry.command.trim();
|
|
24609
|
-
const category = REFINE_VALIDATION_CATEGORIES.find((cat) => commandText.includes(` ${cat}`)) ?? "";
|
|
24610
|
-
return { command: commandText, category, source: "mesh.policy.validationCommands" };
|
|
24611
|
-
}).filter((entry) => !!entry.category);
|
|
24612
|
-
}
|
|
24613
|
-
function selectMeshRefineValidationCommands(mesh, workspace) {
|
|
24614
|
-
const scripts = readPackageScripts(workspace);
|
|
24615
|
-
const rejectedCommands = [];
|
|
24616
|
-
const selected = [];
|
|
24617
|
-
const seen = /* @__PURE__ */ new Set();
|
|
24618
|
-
const candidates = [
|
|
24619
|
-
...collectPolicyValidationCandidates(mesh),
|
|
24620
|
-
...collectProjectContextValidationCandidates(mesh)
|
|
24621
|
-
];
|
|
24622
|
-
for (const candidate of candidates) {
|
|
24623
|
-
const parsed = parsePackageManagerValidationCommand(candidate.command, candidate.category, scripts, candidate.source);
|
|
24624
|
-
if (parsed.rejected) {
|
|
24625
|
-
rejectedCommands.push(parsed.rejected);
|
|
24626
|
-
continue;
|
|
24627
|
-
}
|
|
24628
|
-
if (!parsed.command || seen.has(parsed.command.displayCommand)) continue;
|
|
24629
|
-
selected.push(parsed.command);
|
|
24630
|
-
seen.add(parsed.command.displayCommand);
|
|
24631
|
-
if (selected.length >= REFINE_VALIDATION_MAX_COMMANDS) break;
|
|
24632
|
-
}
|
|
24633
|
-
if (!selected.length && candidates.length === 0) {
|
|
24634
|
-
for (const category of REFINE_VALIDATION_CATEGORIES) {
|
|
24635
|
-
if (!Object.prototype.hasOwnProperty.call(scripts, category)) continue;
|
|
24636
|
-
const fallback = parsePackageManagerValidationCommand(`npm run ${category}`, category, scripts, "package.json:scripts");
|
|
24637
|
-
if (fallback.command && !seen.has(fallback.command.displayCommand)) {
|
|
24638
|
-
selected.push(fallback.command);
|
|
24639
|
-
seen.add(fallback.command.displayCommand);
|
|
24640
|
-
} else if (fallback.rejected) {
|
|
24641
|
-
rejectedCommands.push(fallback.rejected);
|
|
24642
|
-
}
|
|
24643
|
-
if (selected.length >= 2) break;
|
|
24644
|
-
}
|
|
24645
|
-
}
|
|
25017
|
+
function buildMeshRefineValidationPlan(mesh, workspace) {
|
|
25018
|
+
const plan = resolveMeshRefineValidationPlan(mesh, workspace);
|
|
24646
25019
|
return {
|
|
24647
|
-
|
|
24648
|
-
|
|
24649
|
-
|
|
25020
|
+
source: plan.source,
|
|
25021
|
+
sourceType: plan.sourceType,
|
|
25022
|
+
commands: plan.commands.map((command) => ({
|
|
25023
|
+
displayCommand: command.displayCommand,
|
|
25024
|
+
category: command.category,
|
|
25025
|
+
source: command.source,
|
|
25026
|
+
cwd: command.cwd,
|
|
25027
|
+
timeoutMs: command.timeoutMs
|
|
25028
|
+
})),
|
|
25029
|
+
unavailableReason: plan.unavailableReason,
|
|
25030
|
+
rejectedCommands: plan.rejectedCommands,
|
|
25031
|
+
suggestions: plan.suggestions,
|
|
25032
|
+
suggestedConfig: plan.suggestedConfig,
|
|
25033
|
+
note: plan.sourceType === "unavailable" ? "No validation command will be executed until a repo mesh/refine config is provided. Heuristics are suggestions only." : "Validation commands are resolved from repo mesh/refine config; heuristics are suggestions only."
|
|
24650
25034
|
};
|
|
24651
25035
|
}
|
|
24652
25036
|
async function runMeshRefineValidationGate(mesh, workspace) {
|
|
24653
25037
|
const { execFile: execFile3 } = await import("child_process");
|
|
24654
25038
|
const { promisify: promisify3 } = await import("util");
|
|
24655
25039
|
const execFileAsync3 = promisify3(execFile3);
|
|
24656
|
-
const selection =
|
|
25040
|
+
const selection = resolveMeshRefineValidationPlan(mesh, workspace);
|
|
24657
25041
|
const summary = {
|
|
24658
25042
|
status: "skipped",
|
|
24659
25043
|
required: true,
|
|
@@ -24661,21 +25045,27 @@ async function runMeshRefineValidationGate(mesh, workspace) {
|
|
|
24661
25045
|
rejectedCommands: selection.rejectedCommands,
|
|
24662
25046
|
skippedReason: void 0,
|
|
24663
25047
|
timeoutMs: REFINE_VALIDATION_TIMEOUT_MS,
|
|
24664
|
-
outputLimitBytes: REFINE_VALIDATION_OUTPUT_LIMIT_BYTES
|
|
25048
|
+
outputLimitBytes: REFINE_VALIDATION_OUTPUT_LIMIT_BYTES,
|
|
25049
|
+
configSource: selection.source,
|
|
25050
|
+
configSourceType: selection.sourceType,
|
|
25051
|
+
suggestions: selection.suggestions,
|
|
25052
|
+
suggestedConfig: selection.suggestedConfig
|
|
24665
25053
|
};
|
|
24666
25054
|
if (!selection.commands.length) {
|
|
24667
|
-
summary.skippedReason = "validation_unavailable:
|
|
25055
|
+
summary.skippedReason = selection.unavailableReason || "validation_unavailable: repo mesh/refine config did not provide executable validation.commands";
|
|
24668
25056
|
return summary;
|
|
24669
25057
|
}
|
|
24670
25058
|
for (const candidate of selection.commands) {
|
|
24671
25059
|
const startedAt = Date.now();
|
|
25060
|
+
const cwd = candidate.cwd ? pathResolve(workspace, candidate.cwd) : workspace;
|
|
25061
|
+
const timeout = candidate.timeoutMs || REFINE_VALIDATION_TIMEOUT_MS;
|
|
24672
25062
|
try {
|
|
24673
25063
|
const result = await execFileAsync3(candidate.command, candidate.args, {
|
|
24674
|
-
cwd
|
|
25064
|
+
cwd,
|
|
24675
25065
|
encoding: "utf8",
|
|
24676
|
-
timeout
|
|
25066
|
+
timeout,
|
|
24677
25067
|
maxBuffer: REFINE_VALIDATION_OUTPUT_LIMIT_BYTES,
|
|
24678
|
-
env: { ...process.env, CI: process.env.CI || "1" }
|
|
25068
|
+
env: { ...process.env, CI: process.env.CI || "1", ...candidate.env || {} }
|
|
24679
25069
|
});
|
|
24680
25070
|
summary.commandsRun.push({
|
|
24681
25071
|
command: candidate.command,
|
|
@@ -24683,6 +25073,7 @@ async function runMeshRefineValidationGate(mesh, workspace) {
|
|
|
24683
25073
|
displayCommand: candidate.displayCommand,
|
|
24684
25074
|
category: candidate.category,
|
|
24685
25075
|
source: candidate.source,
|
|
25076
|
+
cwd,
|
|
24686
25077
|
passed: true,
|
|
24687
25078
|
exitCode: 0,
|
|
24688
25079
|
durationMs: Date.now() - startedAt,
|
|
@@ -24696,6 +25087,7 @@ async function runMeshRefineValidationGate(mesh, workspace) {
|
|
|
24696
25087
|
displayCommand: candidate.displayCommand,
|
|
24697
25088
|
category: candidate.category,
|
|
24698
25089
|
source: candidate.source,
|
|
25090
|
+
cwd,
|
|
24699
25091
|
passed: false,
|
|
24700
25092
|
exitCode: typeof error?.code === "number" ? error.code : null,
|
|
24701
25093
|
signal: typeof error?.signal === "string" ? error.signal : null,
|
|
@@ -24712,7 +25104,7 @@ async function runMeshRefineValidationGate(mesh, workspace) {
|
|
|
24712
25104
|
return summary;
|
|
24713
25105
|
}
|
|
24714
25106
|
function loadYamlModule() {
|
|
24715
|
-
return
|
|
25107
|
+
return yaml2;
|
|
24716
25108
|
}
|
|
24717
25109
|
function getMcpServersKey(format) {
|
|
24718
25110
|
return format === "hermes_config_yaml" ? "mcp_servers" : "mcpServers";
|
|
@@ -24870,6 +25262,34 @@ function summarizeSessionHostPruneResult(result) {
|
|
|
24870
25262
|
keptCount: Array.isArray(value.keptSessionIds) ? value.keptSessionIds.length : void 0
|
|
24871
25263
|
};
|
|
24872
25264
|
}
|
|
25265
|
+
function normalizeStandaloneHostCommandUrl(hostAddress) {
|
|
25266
|
+
const raw = hostAddress.trim();
|
|
25267
|
+
if (!raw) throw new Error("hostAddress required");
|
|
25268
|
+
const url = new URL(raw.replace(/^ws:/, "http:").replace(/^wss:/, "https:"));
|
|
25269
|
+
url.pathname = "/api/v1/command";
|
|
25270
|
+
url.search = "";
|
|
25271
|
+
url.hash = "";
|
|
25272
|
+
return url.toString();
|
|
25273
|
+
}
|
|
25274
|
+
function buildMemberJoinNode(mesh, args, fallbackDaemonId) {
|
|
25275
|
+
const requestedNodeId = typeof args?.memberNodeId === "string" ? args.memberNodeId.trim() : "";
|
|
25276
|
+
const explicit = args?.memberNode && typeof args.memberNode === "object" && !Array.isArray(args.memberNode) ? args.memberNode : null;
|
|
25277
|
+
const configured = Array.isArray(mesh?.nodes) ? requestedNodeId ? mesh.nodes.find((node) => node?.id === requestedNodeId || node?.nodeId === requestedNodeId) : mesh.nodes[0] : null;
|
|
25278
|
+
const source = explicit || configured;
|
|
25279
|
+
const workspace = typeof source?.workspace === "string" && source.workspace.trim() ? source.workspace.trim() : typeof args?.workspace === "string" && args.workspace.trim() ? args.workspace.trim() : process.cwd();
|
|
25280
|
+
if (!workspace) return null;
|
|
25281
|
+
const nodeId = typeof source?.id === "string" && source.id.trim() ? source.id.trim() : typeof source?.nodeId === "string" && source.nodeId.trim() ? source.nodeId.trim() : void 0;
|
|
25282
|
+
return {
|
|
25283
|
+
...nodeId ? { id: nodeId } : {},
|
|
25284
|
+
workspace,
|
|
25285
|
+
...typeof source?.repoRoot === "string" && source.repoRoot.trim() ? { repoRoot: source.repoRoot.trim() } : {},
|
|
25286
|
+
...typeof source?.daemonId === "string" && source.daemonId.trim() ? { daemonId: source.daemonId.trim() } : fallbackDaemonId ? { daemonId: fallbackDaemonId } : {},
|
|
25287
|
+
...typeof source?.machineId === "string" && source.machineId.trim() ? { machineId: source.machineId.trim() } : {},
|
|
25288
|
+
userOverrides: source?.userOverrides && typeof source.userOverrides === "object" && !Array.isArray(source.userOverrides) ? source.userOverrides : {},
|
|
25289
|
+
policy: source?.policy && typeof source.policy === "object" && !Array.isArray(source.policy) ? source.policy : {},
|
|
25290
|
+
role: "member"
|
|
25291
|
+
};
|
|
25292
|
+
}
|
|
24873
25293
|
var DaemonCommandRouter = class {
|
|
24874
25294
|
deps;
|
|
24875
25295
|
/** In-memory cache for cloud-originating meshes passed via inlineMesh.
|
|
@@ -25043,6 +25463,16 @@ var DaemonCommandRouter = class {
|
|
|
25043
25463
|
invalidateAggregateMeshStatus(meshId) {
|
|
25044
25464
|
this.aggregateMeshStatusCache.delete(meshId);
|
|
25045
25465
|
}
|
|
25466
|
+
async requireMeshHostMutationOwner(meshId, inlineMesh, operation) {
|
|
25467
|
+
const meshRecord = await this.getMeshForCommand(meshId, inlineMesh, { preferInline: true });
|
|
25468
|
+
const mesh = meshRecord?.mesh;
|
|
25469
|
+
if (!mesh) return { success: false, error: "Mesh not found" };
|
|
25470
|
+
const meshHost = resolveMeshHostStatus(mesh);
|
|
25471
|
+
if (!meshHost.canOwnCoordinator || !meshHost.canOwnQueue) {
|
|
25472
|
+
return { ...buildMeshHostRequiredFailure(mesh, operation), success: false, meshId };
|
|
25473
|
+
}
|
|
25474
|
+
return null;
|
|
25475
|
+
}
|
|
25046
25476
|
updateInlineMeshNode(meshId, mesh, node) {
|
|
25047
25477
|
if (!mesh || !Array.isArray(mesh.nodes) || !node?.id) return;
|
|
25048
25478
|
const idx = mesh.nodes.findIndex((entry) => entry?.id === node.id || entry?.nodeId === node.id);
|
|
@@ -26081,7 +26511,8 @@ var DaemonCommandRouter = class {
|
|
|
26081
26511
|
if (!name) return { success: false, error: "name required" };
|
|
26082
26512
|
try {
|
|
26083
26513
|
const { createMesh: createMesh2 } = await Promise.resolve().then(() => (init_mesh_config(), mesh_config_exports));
|
|
26084
|
-
const
|
|
26514
|
+
const meshHost = args?.meshHost && typeof args.meshHost === "object" && !Array.isArray(args.meshHost) ? args.meshHost : void 0;
|
|
26515
|
+
const mesh = createMesh2({ name, repoIdentity, repoRemoteUrl, defaultBranch, policy: args?.policy, meshHost });
|
|
26085
26516
|
return { success: true, mesh };
|
|
26086
26517
|
} catch (e) {
|
|
26087
26518
|
return { success: false, error: e.message };
|
|
@@ -26097,6 +26528,7 @@ var DaemonCommandRouter = class {
|
|
|
26097
26528
|
if (typeof args?.defaultBranch === "string") patch.defaultBranch = args.defaultBranch;
|
|
26098
26529
|
if (args?.policy && typeof args.policy === "object" && !Array.isArray(args.policy)) patch.policy = args.policy;
|
|
26099
26530
|
if (args?.coordinator && typeof args.coordinator === "object" && !Array.isArray(args.coordinator)) patch.coordinator = args.coordinator;
|
|
26531
|
+
if (args?.meshHost && typeof args.meshHost === "object" && !Array.isArray(args.meshHost)) patch.meshHost = args.meshHost;
|
|
26100
26532
|
if (!Object.keys(patch).length) return { success: false, error: "No updates provided" };
|
|
26101
26533
|
const mesh = updateMesh2(meshId, patch);
|
|
26102
26534
|
if (!mesh) return { success: false, error: "Mesh not found" };
|
|
@@ -26107,6 +26539,215 @@ var DaemonCommandRouter = class {
|
|
|
26107
26539
|
return { success: false, error: e.message };
|
|
26108
26540
|
}
|
|
26109
26541
|
}
|
|
26542
|
+
case "get_mesh_host_pairing": {
|
|
26543
|
+
const meshId = typeof args?.meshId === "string" ? args.meshId.trim() : "";
|
|
26544
|
+
if (!meshId) return { success: false, error: "meshId required" };
|
|
26545
|
+
const meshRecord = await this.getMeshForCommand(meshId, args?.inlineMesh, { preferInline: true });
|
|
26546
|
+
const mesh = meshRecord?.mesh;
|
|
26547
|
+
if (!mesh) return { success: false, error: "Mesh not found" };
|
|
26548
|
+
const meshHost = resolveMeshHostStatus(mesh);
|
|
26549
|
+
const pairingStatus = meshHost.pairing?.status || "not_configured";
|
|
26550
|
+
return {
|
|
26551
|
+
success: true,
|
|
26552
|
+
code: pairingStatus === "not_configured" ? "mesh_host_pairing_not_configured" : "mesh_host_pairing_pending",
|
|
26553
|
+
meshId,
|
|
26554
|
+
hostAddress: meshHost.hostAddress,
|
|
26555
|
+
meshHost,
|
|
26556
|
+
manualPairing: {
|
|
26557
|
+
status: pairingStatus,
|
|
26558
|
+
joinImplemented: true,
|
|
26559
|
+
protocol: "standalone_command_direct_v1",
|
|
26560
|
+
description: "Standalone manual pairing can save address/token metadata, apply a host join over direct standalone command HTTP or injected mesh command dispatch, and check persisted status. P2P signaling remains outside this slice."
|
|
26561
|
+
}
|
|
26562
|
+
};
|
|
26563
|
+
}
|
|
26564
|
+
case "configure_mesh_host_pairing": {
|
|
26565
|
+
const meshId = typeof args?.meshId === "string" ? args.meshId.trim() : "";
|
|
26566
|
+
const hostAddress = typeof args?.hostAddress === "string" ? args.hostAddress.trim() : "";
|
|
26567
|
+
const token = typeof args?.token === "string" ? args.token.trim() : "";
|
|
26568
|
+
if (!meshId) return { success: false, error: "meshId required" };
|
|
26569
|
+
if (!hostAddress || !token) return { success: false, error: "hostAddress and token required" };
|
|
26570
|
+
try {
|
|
26571
|
+
const { configureMeshHostPairing: configureMeshHostPairing2 } = await Promise.resolve().then(() => (init_mesh_config(), mesh_config_exports));
|
|
26572
|
+
const configured = configureMeshHostPairing2(meshId, { hostAddress, token });
|
|
26573
|
+
if (!configured) return { success: false, error: "Mesh not found" };
|
|
26574
|
+
this.inlineMeshCache.set(meshId, configured.mesh);
|
|
26575
|
+
const meshHost = resolveMeshHostStatus(configured.mesh);
|
|
26576
|
+
return {
|
|
26577
|
+
success: true,
|
|
26578
|
+
code: "mesh_host_pairing_pending",
|
|
26579
|
+
meshId,
|
|
26580
|
+
hostAddress: configured.hostAddress,
|
|
26581
|
+
meshHost,
|
|
26582
|
+
manualPairing: {
|
|
26583
|
+
status: meshHost.pairing?.status || "pairing",
|
|
26584
|
+
joinImplemented: true,
|
|
26585
|
+
protocol: "standalone_command_direct_v1",
|
|
26586
|
+
description: "Manual Mesh Host pairing config was saved locally. Use join_mesh_host_pairing to apply it to the host. Raw token was not persisted."
|
|
26587
|
+
}
|
|
26588
|
+
};
|
|
26589
|
+
} catch (e) {
|
|
26590
|
+
return { success: false, code: "mesh_host_pairing_invalid", meshId, hostAddress, error: e.message };
|
|
26591
|
+
}
|
|
26592
|
+
}
|
|
26593
|
+
case "create_mesh_host_pairing_token": {
|
|
26594
|
+
const meshId = typeof args?.meshId === "string" ? args.meshId.trim() : "";
|
|
26595
|
+
if (!meshId) return { success: false, error: "meshId required" };
|
|
26596
|
+
try {
|
|
26597
|
+
const { createMeshHostPairingToken: createMeshHostPairingToken2 } = await Promise.resolve().then(() => (init_mesh_config(), mesh_config_exports));
|
|
26598
|
+
const created = createMeshHostPairingToken2(meshId, {
|
|
26599
|
+
token: typeof args?.token === "string" ? args.token : void 0,
|
|
26600
|
+
expiresAt: typeof args?.expiresAt === "string" ? args.expiresAt : void 0
|
|
26601
|
+
});
|
|
26602
|
+
if (!created) return { success: false, error: "Mesh not found" };
|
|
26603
|
+
this.inlineMeshCache.set(meshId, created.mesh);
|
|
26604
|
+
this.invalidateAggregateMeshStatus(meshId);
|
|
26605
|
+
return {
|
|
26606
|
+
success: true,
|
|
26607
|
+
code: "mesh_host_pairing_token_created",
|
|
26608
|
+
meshId,
|
|
26609
|
+
token: created.token,
|
|
26610
|
+
tokenId: created.tokenId,
|
|
26611
|
+
expiresAt: created.expiresAt,
|
|
26612
|
+
meshHost: resolveMeshHostStatus(created.mesh),
|
|
26613
|
+
warning: "Raw token is returned once and is not persisted; share it with member daemons over a trusted channel."
|
|
26614
|
+
};
|
|
26615
|
+
} catch (e) {
|
|
26616
|
+
return { success: false, code: "mesh_host_pairing_token_invalid", meshId, error: e.message };
|
|
26617
|
+
}
|
|
26618
|
+
}
|
|
26619
|
+
case "apply_mesh_host_join": {
|
|
26620
|
+
const meshId = typeof args?.meshId === "string" ? args.meshId.trim() : "";
|
|
26621
|
+
const token = typeof args?.token === "string" ? args.token.trim() : "";
|
|
26622
|
+
const memberNode = args?.memberNode && typeof args.memberNode === "object" && !Array.isArray(args.memberNode) ? args.memberNode : null;
|
|
26623
|
+
if (!meshId) return { success: false, error: "meshId required" };
|
|
26624
|
+
if (!token || !memberNode) return { success: false, error: "token and memberNode required" };
|
|
26625
|
+
try {
|
|
26626
|
+
const { applyMeshHostJoinRequest: applyMeshHostJoinRequest2 } = await Promise.resolve().then(() => (init_mesh_config(), mesh_config_exports));
|
|
26627
|
+
const applied = applyMeshHostJoinRequest2(meshId, {
|
|
26628
|
+
token,
|
|
26629
|
+
memberNode,
|
|
26630
|
+
memberMeshId: typeof args?.memberMeshId === "string" ? args.memberMeshId : void 0
|
|
26631
|
+
});
|
|
26632
|
+
if (!applied) return { success: false, error: "Mesh not found" };
|
|
26633
|
+
if (!applied.accepted) {
|
|
26634
|
+
return {
|
|
26635
|
+
success: false,
|
|
26636
|
+
code: "mesh_host_join_rejected",
|
|
26637
|
+
meshId,
|
|
26638
|
+
tokenId: applied.tokenId,
|
|
26639
|
+
meshHost: applied.meshHost ? resolveMeshHostStatus({ meshHost: applied.meshHost }) : void 0,
|
|
26640
|
+
error: applied.reason
|
|
26641
|
+
};
|
|
26642
|
+
}
|
|
26643
|
+
this.inlineMeshCache.set(meshId, applied.mesh);
|
|
26644
|
+
this.invalidateAggregateMeshStatus(meshId);
|
|
26645
|
+
try {
|
|
26646
|
+
const { appendLedgerEntry: appendLedgerEntry2 } = await Promise.resolve().then(() => (init_mesh_ledger(), mesh_ledger_exports));
|
|
26647
|
+
appendLedgerEntry2(meshId, {
|
|
26648
|
+
kind: "node_joined",
|
|
26649
|
+
nodeId: applied.node.id,
|
|
26650
|
+
payload: { role: "member", tokenId: applied.tokenId, workspace: applied.node.workspace }
|
|
26651
|
+
});
|
|
26652
|
+
} catch {
|
|
26653
|
+
}
|
|
26654
|
+
return {
|
|
26655
|
+
success: true,
|
|
26656
|
+
code: "mesh_host_join_accepted",
|
|
26657
|
+
meshId,
|
|
26658
|
+
node: applied.node,
|
|
26659
|
+
tokenId: applied.tokenId,
|
|
26660
|
+
meshHost: resolveMeshHostStatus(applied.mesh)
|
|
26661
|
+
};
|
|
26662
|
+
} catch (e) {
|
|
26663
|
+
return { success: false, code: "mesh_host_join_failed", meshId, error: e.message };
|
|
26664
|
+
}
|
|
26665
|
+
}
|
|
26666
|
+
case "join_mesh_host_pairing": {
|
|
26667
|
+
const meshId = typeof args?.meshId === "string" ? args.meshId.trim() : "";
|
|
26668
|
+
const token = typeof args?.token === "string" ? args.token.trim() : "";
|
|
26669
|
+
if (!meshId) return { success: false, error: "meshId required" };
|
|
26670
|
+
if (!token) return { success: false, error: "token required because raw pairing tokens are not persisted" };
|
|
26671
|
+
const meshRecord = await this.getMeshForCommand(meshId, args?.inlineMesh, { preferInline: true });
|
|
26672
|
+
const mesh = meshRecord?.mesh;
|
|
26673
|
+
if (!mesh) return { success: false, error: "Mesh not found" };
|
|
26674
|
+
const meshHost = resolveMeshHostStatus(mesh);
|
|
26675
|
+
if (meshHost.role !== "member") {
|
|
26676
|
+
return { success: false, code: "mesh_host_join_not_member", meshId, meshHost, error: "join_mesh_host_pairing must run from a member daemon configured with a Mesh Host address/token." };
|
|
26677
|
+
}
|
|
26678
|
+
try {
|
|
26679
|
+
const { tokenIdForManualPairing: tokenIdForManualPairing2, markMeshHostPairingJoined: markMeshHostPairingJoined2 } = await Promise.resolve().then(() => (init_mesh_config(), mesh_config_exports));
|
|
26680
|
+
const tokenId = tokenIdForManualPairing2(token);
|
|
26681
|
+
if (meshHost.pairing?.tokenId && meshHost.pairing.tokenId !== tokenId) {
|
|
26682
|
+
return { success: false, code: "mesh_host_join_rejected", meshId, tokenId, meshHost, error: "invalid pairing token" };
|
|
26683
|
+
}
|
|
26684
|
+
const memberNode = buildMemberJoinNode(mesh, args, this.deps.statusInstanceId);
|
|
26685
|
+
if (!memberNode) return { success: false, error: "member node metadata unavailable" };
|
|
26686
|
+
const hostMeshId = typeof args?.hostMeshId === "string" && args.hostMeshId.trim() ? args.hostMeshId.trim() : meshId;
|
|
26687
|
+
const hostDaemonId = typeof args?.hostDaemonId === "string" && args.hostDaemonId.trim() ? args.hostDaemonId.trim() : meshHost.hostDaemonId;
|
|
26688
|
+
let hostResult;
|
|
26689
|
+
let transport;
|
|
26690
|
+
if (hostDaemonId && this.deps.dispatchMeshCommand) {
|
|
26691
|
+
transport = "mesh_command_dispatch";
|
|
26692
|
+
hostResult = await this.deps.dispatchMeshCommand(hostDaemonId, "apply_mesh_host_join", {
|
|
26693
|
+
meshId: hostMeshId,
|
|
26694
|
+
token,
|
|
26695
|
+
memberMeshId: meshId,
|
|
26696
|
+
memberNode
|
|
26697
|
+
});
|
|
26698
|
+
} else if (meshHost.hostAddress) {
|
|
26699
|
+
transport = "standalone_http_command";
|
|
26700
|
+
const commandUrl = normalizeStandaloneHostCommandUrl(meshHost.hostAddress);
|
|
26701
|
+
const response = await fetch(commandUrl, {
|
|
26702
|
+
method: "POST",
|
|
26703
|
+
headers: { "Content-Type": "application/json" },
|
|
26704
|
+
body: JSON.stringify({ type: "apply_mesh_host_join", payload: { meshId: hostMeshId, token, memberMeshId: meshId, memberNode } })
|
|
26705
|
+
});
|
|
26706
|
+
hostResult = await response.json().catch(() => ({ success: false, error: `Host returned HTTP ${response.status}` }));
|
|
26707
|
+
if (!response.ok && hostResult?.success !== false) hostResult = { success: false, error: `Host returned HTTP ${response.status}` };
|
|
26708
|
+
} else {
|
|
26709
|
+
return {
|
|
26710
|
+
success: false,
|
|
26711
|
+
code: "mesh_host_join_transport_unavailable",
|
|
26712
|
+
meshId,
|
|
26713
|
+
meshHost,
|
|
26714
|
+
error: "No hostDaemonId dispatch path or hostAddress HTTP command path is available. P2P signaling join is not implemented in this slice."
|
|
26715
|
+
};
|
|
26716
|
+
}
|
|
26717
|
+
if (!hostResult?.success) {
|
|
26718
|
+
return { success: false, code: hostResult?.code || "mesh_host_join_rejected", meshId, meshHost, transport, error: hostResult?.error || "Mesh Host rejected join request", hostResult };
|
|
26719
|
+
}
|
|
26720
|
+
const joined = meshRecord.inline ? null : markMeshHostPairingJoined2(meshId, {
|
|
26721
|
+
tokenId: hostResult.tokenId || tokenId,
|
|
26722
|
+
hostDaemonId: hostResult.meshHost?.hostDaemonId || hostDaemonId,
|
|
26723
|
+
hostNodeId: hostResult.meshHost?.hostNodeId,
|
|
26724
|
+
joinedAt: hostResult.meshHost?.pairing?.joinedAt
|
|
26725
|
+
});
|
|
26726
|
+
if (joined) {
|
|
26727
|
+
this.inlineMeshCache.set(meshId, joined.mesh);
|
|
26728
|
+
this.invalidateAggregateMeshStatus(meshId);
|
|
26729
|
+
}
|
|
26730
|
+
return {
|
|
26731
|
+
success: true,
|
|
26732
|
+
code: "mesh_host_join_applied",
|
|
26733
|
+
meshId,
|
|
26734
|
+
hostMeshId,
|
|
26735
|
+
transport,
|
|
26736
|
+
node: hostResult.node,
|
|
26737
|
+
tokenId: hostResult.tokenId || tokenId,
|
|
26738
|
+
meshHost: joined ? resolveMeshHostStatus(joined.mesh) : { ...meshHost, pairing: { ...meshHost.pairing || {}, status: "paired", tokenId: hostResult.tokenId || tokenId } },
|
|
26739
|
+
hostResult,
|
|
26740
|
+
manualPairing: {
|
|
26741
|
+
status: "paired",
|
|
26742
|
+
joinImplemented: true,
|
|
26743
|
+
protocol: "standalone_command_direct_v1",
|
|
26744
|
+
description: "Mesh Host accepted the join and local member pairing status was marked paired. P2P runtime signaling remains outside this slice."
|
|
26745
|
+
}
|
|
26746
|
+
};
|
|
26747
|
+
} catch (e) {
|
|
26748
|
+
return { success: false, code: "mesh_host_join_failed", meshId, meshHost, error: e.message };
|
|
26749
|
+
}
|
|
26750
|
+
}
|
|
26110
26751
|
case "delete_mesh": {
|
|
26111
26752
|
const meshId = typeof args?.meshId === "string" ? args.meshId.trim() : "";
|
|
26112
26753
|
if (!meshId) return { success: false, error: "meshId required" };
|
|
@@ -26189,6 +26830,8 @@ var DaemonCommandRouter = class {
|
|
|
26189
26830
|
const meshId = typeof args?.meshId === "string" ? args.meshId.trim() : "";
|
|
26190
26831
|
const taskId = typeof args?.taskId === "string" ? args.taskId.trim() : "";
|
|
26191
26832
|
if (!meshId || !taskId) return { success: false, error: "meshId and taskId required" };
|
|
26833
|
+
const ownerFailure = await this.requireMeshHostMutationOwner(meshId, args?.inlineMesh, "queue cancellation");
|
|
26834
|
+
if (ownerFailure) return ownerFailure;
|
|
26192
26835
|
try {
|
|
26193
26836
|
const { cancelTask: cancelTask2 } = await Promise.resolve().then(() => (init_mesh_work_queue(), mesh_work_queue_exports));
|
|
26194
26837
|
const reason = typeof args?.reason === "string" ? args.reason : void 0;
|
|
@@ -26203,6 +26846,8 @@ var DaemonCommandRouter = class {
|
|
|
26203
26846
|
const meshId = typeof args?.meshId === "string" ? args.meshId.trim() : "";
|
|
26204
26847
|
const taskId = typeof args?.taskId === "string" ? args.taskId.trim() : "";
|
|
26205
26848
|
if (!meshId || !taskId) return { success: false, error: "meshId and taskId required" };
|
|
26849
|
+
const ownerFailure = await this.requireMeshHostMutationOwner(meshId, args?.inlineMesh, "queue requeue");
|
|
26850
|
+
if (ownerFailure) return ownerFailure;
|
|
26206
26851
|
try {
|
|
26207
26852
|
const { requeueTask: requeueTask2 } = await Promise.resolve().then(() => (init_mesh_work_queue(), mesh_work_queue_exports));
|
|
26208
26853
|
const task = requeueTask2(meshId, taskId, {
|
|
@@ -26223,6 +26868,8 @@ var DaemonCommandRouter = class {
|
|
|
26223
26868
|
const workspace = typeof args?.workspace === "string" ? args.workspace.trim() : "";
|
|
26224
26869
|
if (!meshId) return { success: false, error: "meshId required" };
|
|
26225
26870
|
if (!workspace) return { success: false, error: "workspace required" };
|
|
26871
|
+
const ownerFailure = await this.requireMeshHostMutationOwner(meshId, args?.inlineMesh, "node addition");
|
|
26872
|
+
if (ownerFailure) return ownerFailure;
|
|
26226
26873
|
try {
|
|
26227
26874
|
const { addNode: addNode3 } = await Promise.resolve().then(() => (init_mesh_config(), mesh_config_exports));
|
|
26228
26875
|
const providerPriority = Array.isArray(args?.providerPriority) ? args.providerPriority.map((type) => typeof type === "string" ? type.trim() : "").filter(Boolean) : [];
|
|
@@ -26231,7 +26878,8 @@ var DaemonCommandRouter = class {
|
|
|
26231
26878
|
...readOnly ? { readOnly: true } : {},
|
|
26232
26879
|
...providerPriority.length ? { providerPriority } : {}
|
|
26233
26880
|
};
|
|
26234
|
-
const
|
|
26881
|
+
const role = normalizeMeshDaemonRole(args?.role);
|
|
26882
|
+
const node = addNode3(meshId, { workspace, ...policy ? { policy } : {}, ...role ? { role } : {} });
|
|
26235
26883
|
if (!node) return { success: false, error: "Mesh not found" };
|
|
26236
26884
|
return { success: true, node };
|
|
26237
26885
|
} catch (e) {
|
|
@@ -26242,6 +26890,8 @@ var DaemonCommandRouter = class {
|
|
|
26242
26890
|
const meshId = typeof args?.meshId === "string" ? args.meshId.trim() : "";
|
|
26243
26891
|
const nodeId = typeof args?.nodeId === "string" ? args.nodeId.trim() : "";
|
|
26244
26892
|
if (!meshId || !nodeId) return { success: false, error: "meshId and nodeId required" };
|
|
26893
|
+
const ownerFailure = await this.requireMeshHostMutationOwner(meshId, args?.inlineMesh, "node update");
|
|
26894
|
+
if (ownerFailure) return ownerFailure;
|
|
26245
26895
|
try {
|
|
26246
26896
|
const { updateNode: updateNode2 } = await Promise.resolve().then(() => (init_mesh_config(), mesh_config_exports));
|
|
26247
26897
|
const policy = args?.policy && typeof args.policy === "object" && !Array.isArray(args.policy) ? { ...args.policy } : {};
|
|
@@ -26265,6 +26915,8 @@ var DaemonCommandRouter = class {
|
|
|
26265
26915
|
const meshId = typeof args?.meshId === "string" ? args.meshId.trim() : "";
|
|
26266
26916
|
const nodeId = typeof args?.nodeId === "string" ? args.nodeId.trim() : "";
|
|
26267
26917
|
if (!meshId || !nodeId) return { success: false, error: "meshId and nodeId required" };
|
|
26918
|
+
const ownerFailure = await this.requireMeshHostMutationOwner(meshId, args?.inlineMesh, "node removal");
|
|
26919
|
+
if (ownerFailure) return ownerFailure;
|
|
26268
26920
|
try {
|
|
26269
26921
|
const meshRecord = await this.getMeshForCommand(meshId, args?.inlineMesh);
|
|
26270
26922
|
const mesh = meshRecord?.mesh;
|
|
@@ -26287,6 +26939,49 @@ var DaemonCommandRouter = class {
|
|
|
26287
26939
|
return { success: false, error: e.message };
|
|
26288
26940
|
}
|
|
26289
26941
|
}
|
|
26942
|
+
case "get_mesh_refine_config_schema": {
|
|
26943
|
+
return {
|
|
26944
|
+
success: true,
|
|
26945
|
+
schema: MESH_REFINE_CONFIG_SCHEMA,
|
|
26946
|
+
locations: MESH_REFINE_CONFIG_LOCATIONS,
|
|
26947
|
+
sourceOfTruth: "repo mesh/refine config",
|
|
26948
|
+
heuristicRole: "suggestions_only_not_execution_path"
|
|
26949
|
+
};
|
|
26950
|
+
}
|
|
26951
|
+
case "validate_mesh_refine_config": {
|
|
26952
|
+
const workspace = typeof args?.workspace === "string" ? args.workspace : process.cwd();
|
|
26953
|
+
const mesh = args?.inlineMesh || {};
|
|
26954
|
+
const loaded = args?.config !== void 0 ? { config: args.config, source: "inline", sourceType: "mesh_policy" } : loadMeshRefineConfig(mesh, workspace);
|
|
26955
|
+
const validation = loaded.config ? validateMeshRefineConfig(loaded.config, loaded.source) : { valid: false, errors: [loaded.error || "repo mesh/refine config unavailable"], commands: [], rejectedCommands: [] };
|
|
26956
|
+
return { success: validation.valid, ...loaded, ...validation };
|
|
26957
|
+
}
|
|
26958
|
+
case "suggest_mesh_refine_config": {
|
|
26959
|
+
const workspace = typeof args?.workspace === "string" ? args.workspace : process.cwd();
|
|
26960
|
+
const mesh = args?.inlineMesh || {};
|
|
26961
|
+
return {
|
|
26962
|
+
success: true,
|
|
26963
|
+
...suggestMeshRefineConfig(mesh, workspace),
|
|
26964
|
+
note: "Suggestions are heuristic scaffold only; Refinery will not execute them until saved into repo mesh/refine config."
|
|
26965
|
+
};
|
|
26966
|
+
}
|
|
26967
|
+
case "plan_mesh_refine_node": {
|
|
26968
|
+
const meshId = typeof args?.meshId === "string" ? args.meshId.trim() : "";
|
|
26969
|
+
const nodeId = typeof args?.nodeId === "string" ? args.nodeId.trim() : "";
|
|
26970
|
+
if (!meshId || !nodeId) return { success: false, error: "meshId and nodeId required" };
|
|
26971
|
+
const meshRecord = await this.getMeshForCommand(meshId, args?.inlineMesh);
|
|
26972
|
+
const mesh = meshRecord?.mesh;
|
|
26973
|
+
const node = mesh?.nodes?.find((n) => n.id === nodeId || n.nodeId === nodeId);
|
|
26974
|
+
if (!node?.workspace) return { success: false, error: `Node '${nodeId}' workspace not found` };
|
|
26975
|
+
return {
|
|
26976
|
+
success: true,
|
|
26977
|
+
dryRun: true,
|
|
26978
|
+
nodeId,
|
|
26979
|
+
workspace: node.workspace,
|
|
26980
|
+
validationPlan: buildMeshRefineValidationPlan(mesh, node.workspace),
|
|
26981
|
+
mergeWillRun: false,
|
|
26982
|
+
cleanupWillRun: false
|
|
26983
|
+
};
|
|
26984
|
+
}
|
|
26290
26985
|
case "refine_mesh_node": {
|
|
26291
26986
|
const meshId = typeof args?.meshId === "string" ? args.meshId.trim() : "";
|
|
26292
26987
|
const nodeId = typeof args?.nodeId === "string" ? args.nodeId.trim() : "";
|
|
@@ -26572,6 +27267,8 @@ var DaemonCommandRouter = class {
|
|
|
26572
27267
|
if (!meshId) return { success: false, error: "meshId required" };
|
|
26573
27268
|
if (!sourceNodeId) return { success: false, error: "sourceNodeId required" };
|
|
26574
27269
|
if (!branch) return { success: false, error: "branch required" };
|
|
27270
|
+
const ownerFailure = await this.requireMeshHostMutationOwner(meshId, args?.inlineMesh, "worktree clone");
|
|
27271
|
+
if (ownerFailure) return ownerFailure;
|
|
26575
27272
|
try {
|
|
26576
27273
|
const meshRecord = await this.getMeshForCommand(meshId, args?.inlineMesh);
|
|
26577
27274
|
const mesh = meshRecord?.mesh;
|
|
@@ -26653,6 +27350,8 @@ var DaemonCommandRouter = class {
|
|
|
26653
27350
|
case "trigger_mesh_queue": {
|
|
26654
27351
|
const meshId = typeof args?.meshId === "string" ? args.meshId.trim() : "";
|
|
26655
27352
|
if (!meshId) return { success: false, error: "meshId required" };
|
|
27353
|
+
const ownerFailure = await this.requireMeshHostMutationOwner(meshId, args?.inlineMesh, "queue trigger");
|
|
27354
|
+
if (ownerFailure) return ownerFailure;
|
|
26656
27355
|
try {
|
|
26657
27356
|
const { triggerMeshQueue: triggerMeshQueue2 } = await Promise.resolve().then(() => (init_mesh_events(), mesh_events_exports));
|
|
26658
27357
|
if (meshId) {
|
|
@@ -26679,6 +27378,15 @@ var DaemonCommandRouter = class {
|
|
|
26679
27378
|
mesh = getMesh3(meshId);
|
|
26680
27379
|
}
|
|
26681
27380
|
if (!mesh) return { success: false, error: "Mesh not found" };
|
|
27381
|
+
const meshHost = resolveMeshHostStatus(mesh);
|
|
27382
|
+
if (!meshHost.canOwnCoordinator) {
|
|
27383
|
+
return {
|
|
27384
|
+
success: false,
|
|
27385
|
+
...buildMeshHostRequiredFailure(mesh, "coordinator launch"),
|
|
27386
|
+
meshId,
|
|
27387
|
+
cliType
|
|
27388
|
+
};
|
|
27389
|
+
}
|
|
26682
27390
|
if (!Array.isArray(mesh.nodes) || mesh.nodes.length === 0) return { success: false, error: "No nodes in mesh" };
|
|
26683
27391
|
const requestedCoordinatorNodeId = typeof args?.coordinatorNodeId === "string" ? args.coordinatorNodeId.trim() : "";
|
|
26684
27392
|
const preferredCoordinatorNodeId = requestedCoordinatorNodeId || (typeof mesh.coordinator?.preferredNodeId === "string" ? mesh.coordinator.preferredNodeId.trim() : "");
|
|
@@ -26861,7 +27569,7 @@ ${block}`);
|
|
|
26861
27569
|
workspace
|
|
26862
27570
|
};
|
|
26863
27571
|
}
|
|
26864
|
-
const { existsSync:
|
|
27572
|
+
const { existsSync: existsSync27, readFileSync: readFileSync19, writeFileSync: writeFileSync15, copyFileSync: copyFileSync4, mkdirSync: mkdirSync17 } = await import("fs");
|
|
26865
27573
|
const { dirname: dirname9 } = await import("path");
|
|
26866
27574
|
const mcpConfigPath = coordinatorSetup.configPath;
|
|
26867
27575
|
const hermesManualFallback = cliType === "hermes-cli" && configFormat === "hermes_config_yaml" ? createHermesManualMeshCoordinatorSetup(meshId, workspace) : null;
|
|
@@ -26904,14 +27612,14 @@ ${block}`);
|
|
|
26904
27612
|
if (hermesManualFallback) return returnManualFallback(message);
|
|
26905
27613
|
return { success: false, code: "mesh_coordinator_config_write_failed", error: message, meshId, cliType, workspace };
|
|
26906
27614
|
}
|
|
26907
|
-
const hadExistingMcpConfig =
|
|
27615
|
+
const hadExistingMcpConfig = existsSync27(mcpConfigPath);
|
|
26908
27616
|
let existingMcpConfig = hermesBaseConfig?.config || {};
|
|
26909
27617
|
if (hermesBaseConfig) {
|
|
26910
27618
|
copyHermesCoordinatorCredentialFiles(hermesBaseConfig.sourceHome, dirname9(mcpConfigPath));
|
|
26911
27619
|
}
|
|
26912
27620
|
if (hadExistingMcpConfig) {
|
|
26913
27621
|
try {
|
|
26914
|
-
const parsedExistingMcpConfig = parseMeshCoordinatorMcpConfig(
|
|
27622
|
+
const parsedExistingMcpConfig = parseMeshCoordinatorMcpConfig(readFileSync19(mcpConfigPath, "utf-8"), configFormat);
|
|
26915
27623
|
const existingCoordinatorConfig = hermesManualFallback ? stripHermesCoordinatorTempModelProviderOverrides(parsedExistingMcpConfig) : parsedExistingMcpConfig;
|
|
26916
27624
|
existingMcpConfig = { ...existingMcpConfig, ...existingCoordinatorConfig };
|
|
26917
27625
|
copyFileSync4(mcpConfigPath, mcpConfigPath + ".backup");
|
|
@@ -27001,6 +27709,7 @@ ${block}`);
|
|
|
27001
27709
|
const meshRecord = await this.getMeshForCommand(meshId, args?.inlineMesh, { preferInline: true });
|
|
27002
27710
|
const mesh = meshRecord?.mesh;
|
|
27003
27711
|
if (!mesh) return { success: false, error: "Mesh not found" };
|
|
27712
|
+
const meshHost = resolveMeshHostStatus(mesh);
|
|
27004
27713
|
const refreshRequested = args?.refresh === true || args?.forceRefresh === true;
|
|
27005
27714
|
const hadAggregateCache = this.aggregateMeshStatusCache.has(meshId);
|
|
27006
27715
|
if (!refreshRequested) {
|
|
@@ -27096,6 +27805,7 @@ ${block}`);
|
|
|
27096
27805
|
repoRoot: node.repoRoot,
|
|
27097
27806
|
isLocalWorktree: node.isLocalWorktree,
|
|
27098
27807
|
worktreeBranch: node.worktreeBranch,
|
|
27808
|
+
role: normalizeMeshDaemonRole(node.role) || (meshHost.hostNodeId && nodeId === meshHost.hostNodeId ? "host" : void 0),
|
|
27099
27809
|
daemonId,
|
|
27100
27810
|
machineId: node.machineId,
|
|
27101
27811
|
machineStatus: node.machineStatus,
|
|
@@ -27274,9 +27984,17 @@ ${block}`);
|
|
|
27274
27984
|
repoIdentity: mesh.repoIdentity,
|
|
27275
27985
|
defaultBranch: mesh.defaultBranch,
|
|
27276
27986
|
refreshedAt,
|
|
27987
|
+
meshHost,
|
|
27277
27988
|
sourceOfTruth: {
|
|
27278
27989
|
membership: meshRecord?.source === "inline_cache" ? "coordinator_inline_mesh_cache" : meshRecord?.source === "local_config" ? "local_mesh_config" : "inline_bootstrap_snapshot",
|
|
27279
27990
|
coordinatorOwnsLiveTruth: directTruthSatisfied,
|
|
27991
|
+
meshHost: {
|
|
27992
|
+
owner: "mesh_host_daemon",
|
|
27993
|
+
localRole: meshHost.role,
|
|
27994
|
+
hostDaemonId: meshHost.hostDaemonId,
|
|
27995
|
+
hostNodeId: meshHost.hostNodeId,
|
|
27996
|
+
hostAddress: meshHost.hostAddress
|
|
27997
|
+
},
|
|
27280
27998
|
...requireDirectPeerTruth ? {
|
|
27281
27999
|
currentStatus: directTruthSatisfied ? "live_git_and_session_probes" : "direct_peer_truth_unavailable",
|
|
27282
28000
|
directPeerTruth: {
|
|
@@ -35364,6 +36082,8 @@ export {
|
|
|
35364
36082
|
InMemoryGitSnapshotStore,
|
|
35365
36083
|
LOG,
|
|
35366
36084
|
MAX_LEDGER_SLICE_LIMIT,
|
|
36085
|
+
MESH_REFINE_CONFIG_LOCATIONS,
|
|
36086
|
+
MESH_REFINE_CONFIG_SCHEMA,
|
|
35367
36087
|
MIN_GIT_WORKSPACE_POLL_INTERVAL_MS,
|
|
35368
36088
|
MIN_MACHINE_RUNTIME_SUBSCRIPTION_INTERVAL_MS,
|
|
35369
36089
|
MIN_SESSION_HOST_DIAGNOSTICS_SUBSCRIPTION_INTERVAL_MS,
|
|
@@ -35386,6 +36106,7 @@ export {
|
|
|
35386
36106
|
buildChatTailDeliverySignature,
|
|
35387
36107
|
buildCoordinatorSystemPrompt,
|
|
35388
36108
|
buildMachineInfo,
|
|
36109
|
+
buildMeshHostRequiredFailure,
|
|
35389
36110
|
buildMeshLedgerReconciliationEvidence,
|
|
35390
36111
|
buildMeshLedgerReplicaEvidence,
|
|
35391
36112
|
buildP2pRelayFailurePayload,
|
|
@@ -35411,6 +36132,7 @@ export {
|
|
|
35411
36132
|
connectCdpManager,
|
|
35412
36133
|
createDebugTraceStore,
|
|
35413
36134
|
createDefaultGitCommandServices,
|
|
36135
|
+
createDefaultMeshHostMetadata,
|
|
35414
36136
|
createGitCompactSummary,
|
|
35415
36137
|
createGitSnapshotStore,
|
|
35416
36138
|
createGitWorkspaceMonitor,
|
|
@@ -35474,6 +36196,7 @@ export {
|
|
|
35474
36196
|
isInternalChatMessage,
|
|
35475
36197
|
isManagedStatusWaiting,
|
|
35476
36198
|
isManagedStatusWorking,
|
|
36199
|
+
isMeshHostOwner,
|
|
35477
36200
|
isP2pRelayTransportFailure,
|
|
35478
36201
|
isPathInside,
|
|
35479
36202
|
isSessionHostLiveRuntime,
|
|
@@ -35487,6 +36210,7 @@ export {
|
|
|
35487
36210
|
listMeshes,
|
|
35488
36211
|
listWorktrees,
|
|
35489
36212
|
loadConfig,
|
|
36213
|
+
loadMeshRefineConfig,
|
|
35490
36214
|
loadState,
|
|
35491
36215
|
logCommand,
|
|
35492
36216
|
markSetupComplete,
|
|
@@ -35500,6 +36224,7 @@ export {
|
|
|
35500
36224
|
normalizeGitWorkspaceSubscriptionParams,
|
|
35501
36225
|
normalizeInputEnvelope,
|
|
35502
36226
|
normalizeManagedStatus,
|
|
36227
|
+
normalizeMeshDaemonRole,
|
|
35503
36228
|
normalizeMessageParts,
|
|
35504
36229
|
normalizeRepoIdentity,
|
|
35505
36230
|
normalizeSessionModalFields,
|
|
@@ -35520,6 +36245,7 @@ export {
|
|
|
35520
36245
|
removeNode,
|
|
35521
36246
|
removeWorktree,
|
|
35522
36247
|
requeueTask,
|
|
36248
|
+
requireMeshHostQueueOwner,
|
|
35523
36249
|
resetConfig,
|
|
35524
36250
|
resetDebugRuntimeConfig,
|
|
35525
36251
|
resetState,
|
|
@@ -35527,6 +36253,8 @@ export {
|
|
|
35527
36253
|
resolveCurrentGlobalInstallSurface,
|
|
35528
36254
|
resolveDebugRuntimeConfig,
|
|
35529
36255
|
resolveGitRepository,
|
|
36256
|
+
resolveMeshHostStatus,
|
|
36257
|
+
resolveMeshRefineValidationPlan,
|
|
35530
36258
|
resolveSessionHostAppName,
|
|
35531
36259
|
resolveSessionHostAppNameResolution,
|
|
35532
36260
|
resolveWorktreePath,
|
|
@@ -35542,6 +36270,7 @@ export {
|
|
|
35542
36270
|
shutdownDaemonComponents,
|
|
35543
36271
|
spawnDetachedDaemonUpgradeHelper,
|
|
35544
36272
|
startDaemonDevSupport,
|
|
36273
|
+
suggestMeshRefineConfig,
|
|
35545
36274
|
summarizeGitStatus,
|
|
35546
36275
|
syncMeshes,
|
|
35547
36276
|
triggerMeshQueue,
|
|
@@ -35550,6 +36279,7 @@ export {
|
|
|
35550
36279
|
updateNode,
|
|
35551
36280
|
updateSessionTaskStatus,
|
|
35552
36281
|
updateTaskStatus,
|
|
35553
|
-
upsertSavedProviderSession
|
|
36282
|
+
upsertSavedProviderSession,
|
|
36283
|
+
validateMeshRefineConfig
|
|
35554
36284
|
};
|
|
35555
36285
|
//# sourceMappingURL=index.mjs.map
|