@adhdev/daemon-standalone 0.9.82-rc.365 → 0.9.82-rc.366
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/index.js +1924 -1752
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
- package/vendor/mcp-server/index.js +7 -0
- package/vendor/mcp-server/index.js.map +1 -1
package/dist/index.js
CHANGED
|
@@ -30036,10 +30036,10 @@ var require_dist3 = __commonJS({
|
|
|
30036
30036
|
}
|
|
30037
30037
|
function getDaemonBuildInfo() {
|
|
30038
30038
|
if (cached2) return cached2;
|
|
30039
|
-
const commit = readInjected(true ? "
|
|
30040
|
-
const commitShort = readInjected(true ? "
|
|
30041
|
-
const version2 = readInjected(true ? "0.9.82-rc.
|
|
30042
|
-
const builtAt = readInjected(true ? "2026-06-
|
|
30039
|
+
const commit = readInjected(true ? "c2224ab0c9d05e85b4cbf88e4fc696f3733ec397" : void 0) ?? "unknown";
|
|
30040
|
+
const commitShort = readInjected(true ? "c2224ab0" : void 0) ?? (commit !== "unknown" ? commit.slice(0, 7) : "unknown");
|
|
30041
|
+
const version2 = readInjected(true ? "0.9.82-rc.366" : void 0) ?? readInjected(typeof process !== "undefined" ? process.env?.ADHDEV_PKG_VERSION : void 0) ?? "unknown";
|
|
30042
|
+
const builtAt = readInjected(true ? "2026-06-24T02:23:02.144Z" : void 0);
|
|
30043
30043
|
cached2 = builtAt ? { commit, commitShort, version: version2, builtAt } : { commit, commitShort, version: version2 };
|
|
30044
30044
|
return cached2;
|
|
30045
30045
|
}
|
|
@@ -37002,8 +37002,8 @@ ${rendered}`, "utf-8");
|
|
|
37002
37002
|
const remaining = (existing.slice(0, openIdx) + existing.slice(closeIdx + CLOSE.length)).replace(/^\s*\n+/, "").replace(/\n+\s*$/, "");
|
|
37003
37003
|
if (!remaining.trim()) {
|
|
37004
37004
|
try {
|
|
37005
|
-
const
|
|
37006
|
-
|
|
37005
|
+
const fs35 = require("fs");
|
|
37006
|
+
fs35.unlinkSync(filePath);
|
|
37007
37007
|
} catch {
|
|
37008
37008
|
}
|
|
37009
37009
|
} else {
|
|
@@ -39448,9 +39448,9 @@ Next step: ${nextStep}`;
|
|
|
39448
39448
|
for (const ext of exes) {
|
|
39449
39449
|
const fullPath = path11.join(p, trimmed + ext);
|
|
39450
39450
|
try {
|
|
39451
|
-
const
|
|
39452
|
-
if (
|
|
39453
|
-
const stat2 =
|
|
39451
|
+
const fs35 = require("fs");
|
|
39452
|
+
if (fs35.existsSync(fullPath)) {
|
|
39453
|
+
const stat2 = fs35.statSync(fullPath);
|
|
39454
39454
|
if (stat2.isFile() && (isWin || stat2.mode & 73)) {
|
|
39455
39455
|
return fullPath;
|
|
39456
39456
|
}
|
|
@@ -39464,12 +39464,12 @@ Next step: ${nextStep}`;
|
|
|
39464
39464
|
function isScriptBinary(binaryPath) {
|
|
39465
39465
|
if (!path11.isAbsolute(binaryPath)) return false;
|
|
39466
39466
|
try {
|
|
39467
|
-
const
|
|
39468
|
-
const resolved =
|
|
39467
|
+
const fs35 = require("fs");
|
|
39468
|
+
const resolved = fs35.realpathSync(binaryPath);
|
|
39469
39469
|
const head = Buffer.alloc(8);
|
|
39470
|
-
const fd =
|
|
39471
|
-
|
|
39472
|
-
|
|
39470
|
+
const fd = fs35.openSync(resolved, "r");
|
|
39471
|
+
fs35.readSync(fd, head, 0, 8, 0);
|
|
39472
|
+
fs35.closeSync(fd);
|
|
39473
39473
|
let i = 0;
|
|
39474
39474
|
if (head[0] === 239 && head[1] === 187 && head[2] === 191) i = 3;
|
|
39475
39475
|
return head[i] === 35 && head[i + 1] === 33;
|
|
@@ -39480,12 +39480,12 @@ Next step: ${nextStep}`;
|
|
|
39480
39480
|
function looksLikeMachOOrElf(filePath) {
|
|
39481
39481
|
if (!path11.isAbsolute(filePath)) return false;
|
|
39482
39482
|
try {
|
|
39483
|
-
const
|
|
39484
|
-
const resolved =
|
|
39483
|
+
const fs35 = require("fs");
|
|
39484
|
+
const resolved = fs35.realpathSync(filePath);
|
|
39485
39485
|
const buf = Buffer.alloc(8);
|
|
39486
|
-
const fd =
|
|
39487
|
-
|
|
39488
|
-
|
|
39486
|
+
const fd = fs35.openSync(resolved, "r");
|
|
39487
|
+
fs35.readSync(fd, buf, 0, 8, 0);
|
|
39488
|
+
fs35.closeSync(fd);
|
|
39489
39489
|
let i = 0;
|
|
39490
39490
|
if (buf[0] === 239 && buf[1] === 187 && buf[2] === 191) i = 3;
|
|
39491
39491
|
const b = buf.subarray(i);
|
|
@@ -43282,6 +43282,13 @@ ${cleanBody}`;
|
|
|
43282
43282
|
nodeId: task.assignedNodeId,
|
|
43283
43283
|
sessionId: task.assignedSessionId
|
|
43284
43284
|
}));
|
|
43285
|
+
const autoLaunchPending = autoLaunchStarted || afterQueue.some((task) => {
|
|
43286
|
+
if (task.status !== "pending") return false;
|
|
43287
|
+
const al = task.autoLaunch;
|
|
43288
|
+
if (!al || al.status !== "started" && al.status !== "completed") return false;
|
|
43289
|
+
const launchedAtMs = Date.parse(al.updatedAt);
|
|
43290
|
+
return Number.isFinite(launchedAtMs) && Date.now() - launchedAtMs < AUTO_LAUNCH_AWAIT_CLAIM_MS;
|
|
43291
|
+
});
|
|
43285
43292
|
return {
|
|
43286
43293
|
success: true,
|
|
43287
43294
|
meshId,
|
|
@@ -43295,7 +43302,11 @@ ${cleanBody}`;
|
|
|
43295
43302
|
remoteIdleSessionsChecked,
|
|
43296
43303
|
skippedSessions,
|
|
43297
43304
|
autoLaunchStarted,
|
|
43298
|
-
...
|
|
43305
|
+
...autoLaunchPending ? { autoLaunchPending: true } : {},
|
|
43306
|
+
// Only report "no idle session, go launch one" when nothing is already on its way.
|
|
43307
|
+
// A pending auto-launch (this tick or a prior still-converging one) means a session
|
|
43308
|
+
// WILL claim shortly, so it is not a no-session-available situation.
|
|
43309
|
+
...pendingAfter > 0 && newlyAssignedTasks.length === 0 && localIdleSessionsChecked === 0 && remoteIdleSessionsChecked === 0 && !autoLaunchPending ? { noIdleMeshSessionAvailable: true } : {}
|
|
43299
43310
|
};
|
|
43300
43311
|
}
|
|
43301
43312
|
async function maybeAutoFastForwardIdleNode(components, args) {
|
|
@@ -46274,8 +46285,8 @@ ${cleanBody}`;
|
|
|
46274
46285
|
let cwd = options.cwd;
|
|
46275
46286
|
if (cwd) {
|
|
46276
46287
|
try {
|
|
46277
|
-
const
|
|
46278
|
-
const stat2 =
|
|
46288
|
+
const fs35 = require("fs");
|
|
46289
|
+
const stat2 = fs35.statSync(cwd);
|
|
46279
46290
|
if (!stat2.isDirectory()) cwd = os14.homedir();
|
|
46280
46291
|
} catch {
|
|
46281
46292
|
cwd = os14.homedir();
|
|
@@ -62051,7 +62062,7 @@ ${effect.notification.body || ""}`.trim();
|
|
|
62051
62062
|
return { success: false, error: "invalid type" };
|
|
62052
62063
|
}
|
|
62053
62064
|
const https = require("https");
|
|
62054
|
-
const
|
|
62065
|
+
const fs35 = require("fs");
|
|
62055
62066
|
const path422 = require("path");
|
|
62056
62067
|
const crypto6 = require("crypto");
|
|
62057
62068
|
const REGISTRY = "https://api.adhf.dev/api/v1/registry";
|
|
@@ -62095,7 +62106,7 @@ ${effect.notification.body || ""}`.trim();
|
|
|
62095
62106
|
if (!targetDir.startsWith(installRootResolved + path422.sep)) {
|
|
62096
62107
|
return { success: false, error: "install path escaped upstream root" };
|
|
62097
62108
|
}
|
|
62098
|
-
|
|
62109
|
+
fs35.mkdirSync(targetDir, { recursive: true });
|
|
62099
62110
|
let manifestProbe = {};
|
|
62100
62111
|
try {
|
|
62101
62112
|
manifestProbe = JSON.parse(manifestBody);
|
|
@@ -62120,7 +62131,7 @@ ${formatManifestValidationIssues2(validation.issues)}`,
|
|
|
62120
62131
|
}
|
|
62121
62132
|
const targetFile = isV1 ? "provider.v1.json" : "provider.json";
|
|
62122
62133
|
const targetPath = path422.join(targetDir, targetFile);
|
|
62123
|
-
|
|
62134
|
+
fs35.writeFileSync(targetPath, manifestBody, "utf-8");
|
|
62124
62135
|
const manifestJson = JSON.parse(manifestBody);
|
|
62125
62136
|
const scriptFetch = await this.fetchProviderSources(
|
|
62126
62137
|
manifestJson,
|
|
@@ -62190,7 +62201,7 @@ ${formatManifestValidationIssues2(validation.issues)}`,
|
|
|
62190
62201
|
const repo = source.repo;
|
|
62191
62202
|
const ref = source.ref;
|
|
62192
62203
|
const https = require("https");
|
|
62193
|
-
const
|
|
62204
|
+
const fs35 = require("fs");
|
|
62194
62205
|
const path422 = require("path");
|
|
62195
62206
|
function fetchJson(url2, timeoutMs) {
|
|
62196
62207
|
return new Promise((resolve24, reject) => {
|
|
@@ -62274,8 +62285,8 @@ ${formatManifestValidationIssues2(validation.issues)}`,
|
|
|
62274
62285
|
const relInside = entry.path.startsWith(sharedDirRel + "/") ? entry.path.slice(sharedDirRel.length + 1) : entry.path;
|
|
62275
62286
|
const outPath = path422.resolve(path422.join(sharedTargetDir, relInside));
|
|
62276
62287
|
if (!outPath.startsWith(path422.resolve(sharedTargetDir) + path422.sep)) continue;
|
|
62277
|
-
|
|
62278
|
-
|
|
62288
|
+
fs35.mkdirSync(path422.dirname(outPath), { recursive: true });
|
|
62289
|
+
fs35.writeFileSync(outPath, body);
|
|
62279
62290
|
fetchedCount++;
|
|
62280
62291
|
} catch (e) {
|
|
62281
62292
|
errors.push(`fetch shared ${entry.path}: ${e?.message ?? e}`);
|
|
@@ -62313,8 +62324,8 @@ ${formatManifestValidationIssues2(validation.issues)}`,
|
|
|
62313
62324
|
errors.push(`refusing to write outside targetDir: ${entry.path}`);
|
|
62314
62325
|
continue;
|
|
62315
62326
|
}
|
|
62316
|
-
|
|
62317
|
-
|
|
62327
|
+
fs35.mkdirSync(path422.dirname(outPath), { recursive: true });
|
|
62328
|
+
fs35.writeFileSync(outPath, body);
|
|
62318
62329
|
fetchedCount++;
|
|
62319
62330
|
} catch (e) {
|
|
62320
62331
|
errors.push(`fetch ${entry.path}: ${e?.message ?? e}`);
|
|
@@ -62342,7 +62353,7 @@ ${formatManifestValidationIssues2(validation.issues)}`,
|
|
|
62342
62353
|
if (!["cli", "ide", "extension", "acp"].includes(category)) {
|
|
62343
62354
|
return { success: false, error: `unknown category: ${category}` };
|
|
62344
62355
|
}
|
|
62345
|
-
const
|
|
62356
|
+
const fs35 = require("fs");
|
|
62346
62357
|
const path422 = require("path");
|
|
62347
62358
|
try {
|
|
62348
62359
|
const installRoot = this.getUpstreamInstallRoot();
|
|
@@ -62351,10 +62362,10 @@ ${formatManifestValidationIssues2(validation.issues)}`,
|
|
|
62351
62362
|
if (!targetDir.startsWith(installRootResolved + path422.sep)) {
|
|
62352
62363
|
return { success: false, error: "refusing to delete outside upstream root" };
|
|
62353
62364
|
}
|
|
62354
|
-
if (!
|
|
62365
|
+
if (!fs35.existsSync(targetDir)) {
|
|
62355
62366
|
return { success: false, error: "not installed" };
|
|
62356
62367
|
}
|
|
62357
|
-
|
|
62368
|
+
fs35.rmSync(targetDir, { recursive: true, force: true });
|
|
62358
62369
|
if (this._ctx.providerLoader) {
|
|
62359
62370
|
this._ctx.providerLoader.reload();
|
|
62360
62371
|
this._ctx.providerLoader.registerToDetector();
|
|
@@ -62370,28 +62381,28 @@ ${formatManifestValidationIssues2(validation.issues)}`,
|
|
|
62370
62381
|
* the UI and by the update checker.
|
|
62371
62382
|
*/
|
|
62372
62383
|
handleListInstalledProviders(_args) {
|
|
62373
|
-
const
|
|
62384
|
+
const fs35 = require("fs");
|
|
62374
62385
|
const path422 = require("path");
|
|
62375
62386
|
const installRoot = this.getUpstreamInstallRoot();
|
|
62376
|
-
if (!
|
|
62387
|
+
if (!fs35.existsSync(installRoot)) return { success: true, providers: [] };
|
|
62377
62388
|
const CATEGORIES = ["cli", "ide", "extension", "acp"];
|
|
62378
62389
|
const items = [];
|
|
62379
62390
|
for (const category of CATEGORIES) {
|
|
62380
62391
|
const categoryDir = path422.join(installRoot, category);
|
|
62381
|
-
if (!
|
|
62392
|
+
if (!fs35.existsSync(categoryDir)) continue;
|
|
62382
62393
|
let entries;
|
|
62383
62394
|
try {
|
|
62384
|
-
entries =
|
|
62395
|
+
entries = fs35.readdirSync(categoryDir);
|
|
62385
62396
|
} catch {
|
|
62386
62397
|
continue;
|
|
62387
62398
|
}
|
|
62388
62399
|
for (const type of entries) {
|
|
62389
62400
|
const v1Path = path422.join(categoryDir, type, "provider.v1.json");
|
|
62390
62401
|
const v0Path = path422.join(categoryDir, type, "provider.json");
|
|
62391
|
-
const manifestPath =
|
|
62402
|
+
const manifestPath = fs35.existsSync(v1Path) ? v1Path : fs35.existsSync(v0Path) ? v0Path : null;
|
|
62392
62403
|
if (!manifestPath) continue;
|
|
62393
62404
|
try {
|
|
62394
|
-
const m = JSON.parse(
|
|
62405
|
+
const m = JSON.parse(fs35.readFileSync(manifestPath, "utf-8"));
|
|
62395
62406
|
items.push({
|
|
62396
62407
|
type,
|
|
62397
62408
|
category,
|
|
@@ -62502,7 +62513,7 @@ ${formatManifestValidationIssues2(validation.issues)}`,
|
|
|
62502
62513
|
if (!/^@[a-z0-9_-]+$/i.test(requestedName)) {
|
|
62503
62514
|
return { success: false, error: "name must match @[a-z0-9_-]+" };
|
|
62504
62515
|
}
|
|
62505
|
-
const
|
|
62516
|
+
const fs35 = require("fs");
|
|
62506
62517
|
const path422 = require("path");
|
|
62507
62518
|
const { spawnSync: spawnSync2 } = require("child_process");
|
|
62508
62519
|
const file2 = ext.loadExternalSources();
|
|
@@ -62513,8 +62524,8 @@ ${formatManifestValidationIssues2(validation.issues)}`,
|
|
|
62513
62524
|
return { success: false, error: `source url+ref already registered (use a different name to track another ref)` };
|
|
62514
62525
|
}
|
|
62515
62526
|
const sourceDir = path422.join(ext.externalRoot(), requestedName);
|
|
62516
|
-
if (!
|
|
62517
|
-
if (
|
|
62527
|
+
if (!fs35.existsSync(ext.externalRoot())) fs35.mkdirSync(ext.externalRoot(), { recursive: true });
|
|
62528
|
+
if (fs35.existsSync(sourceDir)) {
|
|
62518
62529
|
return { success: false, error: `directory already exists: ${sourceDir} (rename or remove first)` };
|
|
62519
62530
|
}
|
|
62520
62531
|
const clone2 = spawnSync2("git", ["clone", "--depth=1", "--branch", ref, "--", url2, sourceDir], {
|
|
@@ -62524,7 +62535,7 @@ ${formatManifestValidationIssues2(validation.issues)}`,
|
|
|
62524
62535
|
});
|
|
62525
62536
|
if (clone2.status !== 0) {
|
|
62526
62537
|
try {
|
|
62527
|
-
|
|
62538
|
+
fs35.rmSync(sourceDir, { recursive: true, force: true });
|
|
62528
62539
|
} catch {
|
|
62529
62540
|
}
|
|
62530
62541
|
return { success: false, error: `git clone failed: ${(clone2.stderr || clone2.stdout || "").trim() || "unknown error"}` };
|
|
@@ -62568,15 +62579,15 @@ ${formatManifestValidationIssues2(validation.issues)}`,
|
|
|
62568
62579
|
const name = typeof args?.name === "string" ? args.name.trim() : "";
|
|
62569
62580
|
if (!name) return { success: false, error: "name is required" };
|
|
62570
62581
|
const ext = (init_external_sources(), __toCommonJS2(external_sources_exports));
|
|
62571
|
-
const
|
|
62582
|
+
const fs35 = require("fs");
|
|
62572
62583
|
const path422 = require("path");
|
|
62573
62584
|
const file2 = ext.loadExternalSources();
|
|
62574
62585
|
const match = file2.sources.find((s2) => s2.name === name);
|
|
62575
62586
|
if (!match) return { success: false, error: `source "${name}" not registered` };
|
|
62576
62587
|
const sourceDir = path422.join(ext.externalRoot(), name);
|
|
62577
|
-
if (
|
|
62588
|
+
if (fs35.existsSync(sourceDir)) {
|
|
62578
62589
|
try {
|
|
62579
|
-
|
|
62590
|
+
fs35.rmSync(sourceDir, { recursive: true, force: true });
|
|
62580
62591
|
} catch (e) {
|
|
62581
62592
|
return { success: false, error: `failed to delete ${sourceDir}: ${e?.message || e}` };
|
|
62582
62593
|
}
|
|
@@ -63345,14 +63356,14 @@ ${formatManifestValidationIssues2(validation.issues)}`,
|
|
|
63345
63356
|
};
|
|
63346
63357
|
var coordinatorPromptHandlers = {
|
|
63347
63358
|
list_coordinator_prompts: async (_ctx, _args) => {
|
|
63348
|
-
const
|
|
63359
|
+
const fs35 = await import("fs");
|
|
63349
63360
|
const path422 = await import("path");
|
|
63350
63361
|
const os30 = await import("os");
|
|
63351
63362
|
const dir = path422.join(os30.homedir(), ".adhdev", "coordinator-prompts");
|
|
63352
63363
|
const entries = {};
|
|
63353
63364
|
try {
|
|
63354
|
-
if (
|
|
63355
|
-
for (const name of
|
|
63365
|
+
if (fs35.existsSync(dir)) {
|
|
63366
|
+
for (const name of fs35.readdirSync(dir)) {
|
|
63356
63367
|
const matchOverride = name.match(/^([a-zA-Z0-9_.-]+)\.md$/);
|
|
63357
63368
|
const matchAppend = name.match(/^([a-zA-Z0-9_.-]+)\.append\.md$/);
|
|
63358
63369
|
const m = matchAppend || matchOverride;
|
|
@@ -63362,7 +63373,7 @@ ${formatManifestValidationIssues2(validation.issues)}`,
|
|
|
63362
63373
|
const full = path422.join(dir, name);
|
|
63363
63374
|
let content = "";
|
|
63364
63375
|
try {
|
|
63365
|
-
content =
|
|
63376
|
+
content = fs35.readFileSync(full, "utf8");
|
|
63366
63377
|
} catch {
|
|
63367
63378
|
}
|
|
63368
63379
|
if (!entries[key]) entries[key] = { override: "", append: "" };
|
|
@@ -63376,7 +63387,7 @@ ${formatManifestValidationIssues2(validation.issues)}`,
|
|
|
63376
63387
|
return { success: true, dir, entries };
|
|
63377
63388
|
},
|
|
63378
63389
|
write_coordinator_prompt: async (_ctx, args) => {
|
|
63379
|
-
const
|
|
63390
|
+
const fs35 = await import("fs");
|
|
63380
63391
|
const path422 = await import("path");
|
|
63381
63392
|
const os30 = await import("os");
|
|
63382
63393
|
const key = typeof args?.key === "string" ? args.key.trim() : "";
|
|
@@ -63389,11 +63400,11 @@ ${formatManifestValidationIssues2(validation.issues)}`,
|
|
|
63389
63400
|
const filename = kind === "append" ? `${key}.append.md` : `${key}.md`;
|
|
63390
63401
|
const full = path422.join(dir, filename);
|
|
63391
63402
|
try {
|
|
63392
|
-
|
|
63403
|
+
fs35.mkdirSync(dir, { recursive: true });
|
|
63393
63404
|
if (content.trim()) {
|
|
63394
|
-
|
|
63395
|
-
} else if (
|
|
63396
|
-
|
|
63405
|
+
fs35.writeFileSync(full, content, { encoding: "utf8", mode: 384 });
|
|
63406
|
+
} else if (fs35.existsSync(full)) {
|
|
63407
|
+
fs35.unlinkSync(full);
|
|
63397
63408
|
}
|
|
63398
63409
|
return { success: true, path: full, kind, key };
|
|
63399
63410
|
} catch (error48) {
|
|
@@ -71349,7 +71360,17 @@ Run 'adhdev doctor' for detailed diagnostics.`
|
|
|
71349
71360
|
continue;
|
|
71350
71361
|
}
|
|
71351
71362
|
const restoredSettings = { ...this.providerLoader.getSettings(normalizedType) };
|
|
71352
|
-
|
|
71363
|
+
let coordinatorEntry = getCoordinatorForSession(record2.runtimeId);
|
|
71364
|
+
if (!coordinatorEntry?.meshId && record2.workspace) {
|
|
71365
|
+
const workspaceCoordinators = listCoordinatorsForWorkspace(record2.workspace).filter((e) => e.meshId && (!e.cliType || e.cliType === record2.cliType));
|
|
71366
|
+
if (workspaceCoordinators.length === 1) {
|
|
71367
|
+
coordinatorEntry = workspaceCoordinators[0];
|
|
71368
|
+
LOG2.info(
|
|
71369
|
+
"CLI",
|
|
71370
|
+
`\u21BB Rebound coordinator mark by workspace for ${record2.runtimeKey || record2.runtimeId} (mesh ${coordinatorEntry.meshId} @ ${record2.workspace}); registry key did not match runtimeId`
|
|
71371
|
+
);
|
|
71372
|
+
}
|
|
71373
|
+
}
|
|
71353
71374
|
if (coordinatorEntry?.meshId) {
|
|
71354
71375
|
restoredSettings.meshCoordinatorFor = coordinatorEntry.meshId;
|
|
71355
71376
|
}
|
|
@@ -74236,7 +74257,7 @@ Run 'adhdev doctor' for detailed diagnostics.`
|
|
|
74236
74257
|
}
|
|
74237
74258
|
if (providerDir) {
|
|
74238
74259
|
try {
|
|
74239
|
-
const
|
|
74260
|
+
const fs35 = require("fs");
|
|
74240
74261
|
const path422 = require("path");
|
|
74241
74262
|
const candidates = [];
|
|
74242
74263
|
if (Array.isArray(base.compatibility)) {
|
|
@@ -74248,13 +74269,13 @@ Run 'adhdev doctor' for detailed diagnostics.`
|
|
|
74248
74269
|
}
|
|
74249
74270
|
candidates.push(path422.join(providerDir, "specs", "default.json"));
|
|
74250
74271
|
candidates.push(path422.join(providerDir, "spec.json"));
|
|
74251
|
-
const specPath = candidates.find((p) =>
|
|
74272
|
+
const specPath = candidates.find((p) => fs35.existsSync(p));
|
|
74252
74273
|
if (specPath) {
|
|
74253
74274
|
resolved._resolvedSpecPath = specPath;
|
|
74254
74275
|
let specControls;
|
|
74255
74276
|
let nh;
|
|
74256
74277
|
try {
|
|
74257
|
-
const rawSpec = JSON.parse(
|
|
74278
|
+
const rawSpec = JSON.parse(fs35.readFileSync(specPath, "utf8"));
|
|
74258
74279
|
specControls = rawSpec.control_bar;
|
|
74259
74280
|
nh = rawSpec.native_history;
|
|
74260
74281
|
} catch {
|
|
@@ -74286,7 +74307,7 @@ Run 'adhdev doctor' for detailed diagnostics.`
|
|
|
74286
74307
|
reader = (input) => executeNativeHistory(nh, input);
|
|
74287
74308
|
} else if (nh.override_path) {
|
|
74288
74309
|
const overrideFile = path422.resolve(providerDir, nh.override_path);
|
|
74289
|
-
if (
|
|
74310
|
+
if (fs35.existsSync(overrideFile)) {
|
|
74290
74311
|
try {
|
|
74291
74312
|
registerProviderScriptRootSafely(path422.dirname(path422.dirname(providerDir)));
|
|
74292
74313
|
delete require.cache[require.resolve(overrideFile)];
|
|
@@ -74833,8 +74854,8 @@ Run 'adhdev doctor' for detailed diagnostics.`
|
|
|
74833
74854
|
}
|
|
74834
74855
|
}
|
|
74835
74856
|
writeConfig(config2) {
|
|
74836
|
-
const { saveConfig:
|
|
74837
|
-
|
|
74857
|
+
const { saveConfig: saveConfig2 } = (init_config(), __toCommonJS2(config_exports));
|
|
74858
|
+
saveConfig2(config2);
|
|
74838
74859
|
}
|
|
74839
74860
|
getPlatformVersionCommand(versionCommand) {
|
|
74840
74861
|
if (!versionCommand) return void 0;
|
|
@@ -75467,7 +75488,7 @@ ${formatManifestValidationIssues2(validation2.issues)}`);
|
|
|
75467
75488
|
}
|
|
75468
75489
|
} else if (plat === "win32") {
|
|
75469
75490
|
try {
|
|
75470
|
-
const
|
|
75491
|
+
const fs35 = require("fs");
|
|
75471
75492
|
const appNameMap = getMacAppIdentifiers();
|
|
75472
75493
|
const appName = appNameMap[ideId];
|
|
75473
75494
|
if (appName) {
|
|
@@ -75476,8 +75497,8 @@ ${formatManifestValidationIssues2(validation2.issues)}`);
|
|
|
75476
75497
|
appName,
|
|
75477
75498
|
"storage.json"
|
|
75478
75499
|
);
|
|
75479
|
-
if (
|
|
75480
|
-
const data = JSON.parse(
|
|
75500
|
+
if (fs35.existsSync(storagePath)) {
|
|
75501
|
+
const data = JSON.parse(fs35.readFileSync(storagePath, "utf-8"));
|
|
75481
75502
|
const workspaces = data?.openedPathsList?.workspaces3 || data?.openedPathsList?.entries || [];
|
|
75482
75503
|
if (workspaces.length > 0) {
|
|
75483
75504
|
const recent = workspaces[0];
|
|
@@ -76971,12 +76992,1039 @@ ${formatManifestValidationIssues2(validation2.issues)}`);
|
|
|
76971
76992
|
...fastForwardHandlers
|
|
76972
76993
|
})
|
|
76973
76994
|
);
|
|
76995
|
+
init_mesh_events();
|
|
76996
|
+
var meshEventsHandlers = {
|
|
76997
|
+
mesh_forward_event: async (ctx, args) => {
|
|
76998
|
+
return handleMeshForwardEvent({ instanceManager: ctx.deps.instanceManager }, args);
|
|
76999
|
+
},
|
|
77000
|
+
get_pending_mesh_events: async (_ctx, args) => {
|
|
77001
|
+
const meshId = typeof args?.meshId === "string" ? args.meshId.trim() : "";
|
|
77002
|
+
const coordinatorDaemonId = typeof args?.coordinatorDaemonId === "string" && args.coordinatorDaemonId.trim() ? args.coordinatorDaemonId.trim() : void 0;
|
|
77003
|
+
const events = drainPendingMeshCoordinatorEvents(meshId || void 0, coordinatorDaemonId);
|
|
77004
|
+
return { success: true, events };
|
|
77005
|
+
},
|
|
77006
|
+
interactive_prompt_response: async (ctx, args) => {
|
|
77007
|
+
const sessionId = typeof args?.targetSessionId === "string" && args.targetSessionId.trim() ? args.targetSessionId.trim() : typeof args?.sessionId === "string" && args.sessionId.trim() ? args.sessionId.trim() : "";
|
|
77008
|
+
if (!sessionId) return { success: false, error: "targetSessionId required" };
|
|
77009
|
+
const response = normalizeInteractivePromptResponse2(args?.response ?? args);
|
|
77010
|
+
const instance = ctx.deps.instanceManager.getInstance(sessionId);
|
|
77011
|
+
if (!instance) return { success: false, error: `No running instance for session ${sessionId}` };
|
|
77012
|
+
ctx.deps.instanceManager.sendEvent(sessionId, "interactive_prompt_response", response);
|
|
77013
|
+
return { success: true };
|
|
77014
|
+
}
|
|
77015
|
+
};
|
|
77016
|
+
var import_path12 = require("path");
|
|
77017
|
+
var fs26 = __toESM2(require("fs"));
|
|
77018
|
+
init_logger();
|
|
77019
|
+
init_mesh_host_ownership();
|
|
77020
|
+
init_coordinator_registry();
|
|
77021
|
+
init_mesh_coordinator();
|
|
77022
|
+
init_dist();
|
|
77023
|
+
var meshCoordinatorLaunchHandlers = {
|
|
77024
|
+
launch_mesh_coordinator: async (ctx, args) => {
|
|
77025
|
+
const meshId = typeof args?.meshId === "string" ? args.meshId.trim() : "";
|
|
77026
|
+
let cliType = typeof args?.cliType === "string" ? args.cliType.trim() : "";
|
|
77027
|
+
const extraSystemPrompt = typeof args?.extraSystemPrompt === "string" ? args.extraSystemPrompt.trim() : "";
|
|
77028
|
+
if (!meshId) return { success: false, error: "meshId required" };
|
|
77029
|
+
try {
|
|
77030
|
+
const { buildCoordinatorSystemPrompt: buildCoordinatorSystemPrompt2 } = await Promise.resolve().then(() => (init_coordinator_prompt(), coordinator_prompt_exports));
|
|
77031
|
+
const { buildMissionPromptSection: buildMissionPromptSection2 } = await Promise.resolve().then(() => (init_mesh_missions(), mesh_missions_exports));
|
|
77032
|
+
const buildMissionSectionBestEffort = (id) => {
|
|
77033
|
+
try {
|
|
77034
|
+
return buildMissionPromptSection2(id);
|
|
77035
|
+
} catch {
|
|
77036
|
+
return "";
|
|
77037
|
+
}
|
|
77038
|
+
};
|
|
77039
|
+
let mesh;
|
|
77040
|
+
if (args?.inlineMesh && typeof args.inlineMesh === "object") {
|
|
77041
|
+
mesh = args.inlineMesh;
|
|
77042
|
+
ctx.inlineMeshCache.set(meshId, mesh);
|
|
77043
|
+
} else {
|
|
77044
|
+
const { getMesh: getMesh2 } = await Promise.resolve().then(() => (init_mesh_config(), mesh_config_exports));
|
|
77045
|
+
mesh = getMesh2(meshId);
|
|
77046
|
+
}
|
|
77047
|
+
if (!mesh) return { success: false, error: "Mesh not found" };
|
|
77048
|
+
const meshHost = resolveMeshHostStatus(mesh);
|
|
77049
|
+
if (!meshHost.canOwnCoordinator) {
|
|
77050
|
+
return {
|
|
77051
|
+
success: false,
|
|
77052
|
+
...buildMeshHostRequiredFailure(mesh, "coordinator launch"),
|
|
77053
|
+
meshId,
|
|
77054
|
+
cliType
|
|
77055
|
+
};
|
|
77056
|
+
}
|
|
77057
|
+
if (!Array.isArray(mesh.nodes) || mesh.nodes.length === 0) return { success: false, error: "No nodes in mesh" };
|
|
77058
|
+
const requestedCoordinatorNodeId = typeof args?.coordinatorNodeId === "string" ? args.coordinatorNodeId.trim() : "";
|
|
77059
|
+
const preferredCoordinatorNodeId = requestedCoordinatorNodeId || (typeof mesh.coordinator?.preferredNodeId === "string" ? mesh.coordinator.preferredNodeId.trim() : "");
|
|
77060
|
+
const coordinatorNode = preferredCoordinatorNodeId ? mesh.nodes.find((node) => node?.id === preferredCoordinatorNodeId || node?.nodeId === preferredCoordinatorNodeId) : mesh.nodes[0];
|
|
77061
|
+
if (!coordinatorNode) {
|
|
77062
|
+
return {
|
|
77063
|
+
success: false,
|
|
77064
|
+
code: "mesh_coordinator_node_not_found",
|
|
77065
|
+
error: `Coordinator node ${preferredCoordinatorNodeId} was not found in mesh`,
|
|
77066
|
+
meshId,
|
|
77067
|
+
cliType
|
|
77068
|
+
};
|
|
77069
|
+
}
|
|
77070
|
+
const sessionHostRecords = ctx.deps.sessionHostControl?.listSessions ? await ctx.deps.sessionHostControl.listSessions().catch(() => []) : [];
|
|
77071
|
+
const liveMeshSessions = partitionSessionHostRecords(Array.isArray(sessionHostRecords) ? sessionHostRecords : []).liveRuntimes;
|
|
77072
|
+
const workspace = readLiveMeshNodeWorkspace({
|
|
77073
|
+
meshId,
|
|
77074
|
+
nodeId: String(normalizeMeshNodeId(coordinatorNode) || preferredCoordinatorNodeId || ""),
|
|
77075
|
+
liveSessionRecords: liveMeshSessions,
|
|
77076
|
+
allowCoordinatorSession: true
|
|
77077
|
+
}) || (typeof coordinatorNode.workspace === "string" ? coordinatorNode.workspace.trim() : "");
|
|
77078
|
+
if (!workspace) return { success: false, error: "Coordinator node workspace required", meshId, cliType };
|
|
77079
|
+
if (!cliType) {
|
|
77080
|
+
const resolved = await resolveProviderTypeFromPriority({
|
|
77081
|
+
nodeId: String(normalizeMeshNodeId(coordinatorNode) || preferredCoordinatorNodeId || "coordinator"),
|
|
77082
|
+
providerPriority: readProviderPriorityFromPolicy(coordinatorNode.policy),
|
|
77083
|
+
providerLoader: ctx.deps.providerLoader,
|
|
77084
|
+
onStatusChange: ctx.deps.onStatusChange
|
|
77085
|
+
});
|
|
77086
|
+
if (!resolved.providerType) {
|
|
77087
|
+
return {
|
|
77088
|
+
success: false,
|
|
77089
|
+
code: "mesh_coordinator_provider_priority_unusable",
|
|
77090
|
+
error: resolved.error || "No usable provider found from node providerPriority",
|
|
77091
|
+
meshId,
|
|
77092
|
+
cliType,
|
|
77093
|
+
workspace
|
|
77094
|
+
};
|
|
77095
|
+
}
|
|
77096
|
+
cliType = resolved.providerType;
|
|
77097
|
+
}
|
|
77098
|
+
const providerMeta = ctx.deps.providerLoader.resolve?.(cliType) || ctx.deps.providerLoader.getMeta(cliType);
|
|
77099
|
+
const coordinatorSetup = resolveMeshCoordinatorSetup({
|
|
77100
|
+
provider: providerMeta,
|
|
77101
|
+
cliType,
|
|
77102
|
+
meshId,
|
|
77103
|
+
workspace
|
|
77104
|
+
});
|
|
77105
|
+
if (coordinatorSetup.kind === "unsupported") {
|
|
77106
|
+
return {
|
|
77107
|
+
success: false,
|
|
77108
|
+
code: "mesh_coordinator_unsupported",
|
|
77109
|
+
error: coordinatorSetup.reason,
|
|
77110
|
+
meshId,
|
|
77111
|
+
cliType,
|
|
77112
|
+
workspace
|
|
77113
|
+
};
|
|
77114
|
+
}
|
|
77115
|
+
if (coordinatorSetup.kind === "manual") {
|
|
77116
|
+
return {
|
|
77117
|
+
success: false,
|
|
77118
|
+
code: "mesh_coordinator_manual_mcp_setup_required",
|
|
77119
|
+
error: coordinatorSetup.instructions,
|
|
77120
|
+
meshId,
|
|
77121
|
+
cliType,
|
|
77122
|
+
workspace,
|
|
77123
|
+
meshCoordinatorSetup: coordinatorSetup
|
|
77124
|
+
};
|
|
77125
|
+
}
|
|
77126
|
+
if (coordinatorSetup.kind === "cli_command") {
|
|
77127
|
+
let cliCmdSystemPrompt = "";
|
|
77128
|
+
try {
|
|
77129
|
+
cliCmdSystemPrompt = buildCoordinatorSystemPrompt2({ mesh, coordinatorCliType: cliType, userInstruction: extraSystemPrompt || void 0, missionSection: buildMissionSectionBestEffort(mesh.id) });
|
|
77130
|
+
} catch (error48) {
|
|
77131
|
+
const message = error48?.message || String(error48);
|
|
77132
|
+
LOG2.error("MeshCoordinator", `Failed to build coordinator prompt: ${message}`);
|
|
77133
|
+
return {
|
|
77134
|
+
success: false,
|
|
77135
|
+
code: "mesh_coordinator_prompt_failed",
|
|
77136
|
+
error: `Failed to build Repo Mesh coordinator prompt: ${message}`,
|
|
77137
|
+
meshId,
|
|
77138
|
+
cliType,
|
|
77139
|
+
workspace
|
|
77140
|
+
};
|
|
77141
|
+
}
|
|
77142
|
+
let mcpRegistrationOk = false;
|
|
77143
|
+
let mcpRegistrationFailure = null;
|
|
77144
|
+
try {
|
|
77145
|
+
const { buildMeshCoordinatorRegistrationPlan: buildMeshCoordinatorRegistrationPlan2, execUnderPty: execUnderPty2 } = await Promise.resolve().then(() => (init_mesh_coordinator(), mesh_coordinator_exports));
|
|
77146
|
+
const registrationPlan = buildMeshCoordinatorRegistrationPlan2(
|
|
77147
|
+
cliType,
|
|
77148
|
+
coordinatorSetup.serverName,
|
|
77149
|
+
coordinatorSetup.command
|
|
77150
|
+
);
|
|
77151
|
+
for (const step of registrationPlan) {
|
|
77152
|
+
const renderedCommand = [step.command, ...step.args].join(" ");
|
|
77153
|
+
LOG2.info("MeshCoordinator", `Running MCP ${step.label} (pty): ${renderedCommand}`);
|
|
77154
|
+
const ptyResult = await execUnderPty2(step.command, step.args, { cwd: workspace, timeoutMs: 2e4 });
|
|
77155
|
+
if (ptyResult.exitCode === 0 && !ptyResult.timedOut) {
|
|
77156
|
+
if (step.required) mcpRegistrationOk = true;
|
|
77157
|
+
continue;
|
|
77158
|
+
}
|
|
77159
|
+
LOG2.warn("MeshCoordinator", `MCP ${step.label} failed exit=${ptyResult.exitCode} signal=${ptyResult.signal} timedOut=${ptyResult.timedOut} \u2014 output:
|
|
77160
|
+
${ptyResult.output.slice(-2e3)}`);
|
|
77161
|
+
if (step.required) {
|
|
77162
|
+
mcpRegistrationFailure = {
|
|
77163
|
+
command: renderedCommand,
|
|
77164
|
+
output: ptyResult.output.slice(-2e3),
|
|
77165
|
+
exitCode: ptyResult.exitCode,
|
|
77166
|
+
signal: ptyResult.signal,
|
|
77167
|
+
timedOut: ptyResult.timedOut
|
|
77168
|
+
};
|
|
77169
|
+
break;
|
|
77170
|
+
}
|
|
77171
|
+
}
|
|
77172
|
+
} catch (error48) {
|
|
77173
|
+
LOG2.warn("MeshCoordinator", `MCP registration command failed: ${error48?.message || error48}`);
|
|
77174
|
+
mcpRegistrationFailure = {
|
|
77175
|
+
command: coordinatorSetup.command,
|
|
77176
|
+
output: error48?.message || String(error48),
|
|
77177
|
+
exitCode: null,
|
|
77178
|
+
signal: null,
|
|
77179
|
+
timedOut: false
|
|
77180
|
+
};
|
|
77181
|
+
}
|
|
77182
|
+
if (!mcpRegistrationOk) {
|
|
77183
|
+
return {
|
|
77184
|
+
success: false,
|
|
77185
|
+
code: "mesh_coordinator_mcp_registration_failed",
|
|
77186
|
+
error: `Could not register ${coordinatorSetup.serverName}; coordinator session was not launched`,
|
|
77187
|
+
meshId,
|
|
77188
|
+
cliType,
|
|
77189
|
+
workspace,
|
|
77190
|
+
registration: mcpRegistrationFailure
|
|
77191
|
+
};
|
|
77192
|
+
}
|
|
77193
|
+
if (cliType === "codex-cli") {
|
|
77194
|
+
const repoMcpConfigPath = (0, import_path12.join)(workspace, ".mcp.json");
|
|
77195
|
+
if (fs26.existsSync(repoMcpConfigPath)) {
|
|
77196
|
+
try {
|
|
77197
|
+
const repoMcpConfig = parseMeshCoordinatorMcpConfig(
|
|
77198
|
+
fs26.readFileSync(repoMcpConfigPath, "utf-8"),
|
|
77199
|
+
"claude_mcp_json"
|
|
77200
|
+
);
|
|
77201
|
+
const existingServers2 = repoMcpConfig.mcpServers;
|
|
77202
|
+
if (existingServers2 && typeof existingServers2 === "object" && !Array.isArray(existingServers2) && existingServers2[coordinatorSetup.serverName]) {
|
|
77203
|
+
fs26.writeFileSync(repoMcpConfigPath, serializeMeshCoordinatorMcpConfig({
|
|
77204
|
+
...repoMcpConfig,
|
|
77205
|
+
mcpServers: {
|
|
77206
|
+
...existingServers2,
|
|
77207
|
+
[coordinatorSetup.serverName]: coordinatorSetup.mcpServer
|
|
77208
|
+
}
|
|
77209
|
+
}, "claude_mcp_json"), "utf-8");
|
|
77210
|
+
LOG2.info("MeshCoordinator", `Refreshed repo-local ${repoMcpConfigPath} entry for ${coordinatorSetup.serverName}`);
|
|
77211
|
+
}
|
|
77212
|
+
} catch (error48) {
|
|
77213
|
+
return {
|
|
77214
|
+
success: false,
|
|
77215
|
+
code: "mesh_coordinator_config_write_failed",
|
|
77216
|
+
error: `Could not refresh repo-local MCP config: ${error48?.message || error48}`,
|
|
77217
|
+
meshId,
|
|
77218
|
+
cliType,
|
|
77219
|
+
workspace
|
|
77220
|
+
};
|
|
77221
|
+
}
|
|
77222
|
+
}
|
|
77223
|
+
}
|
|
77224
|
+
const cliCmdArgs = [];
|
|
77225
|
+
const cliCmdEnv = {};
|
|
77226
|
+
let cliCmdContextFilePath;
|
|
77227
|
+
if (cliCmdSystemPrompt) {
|
|
77228
|
+
const { applyMeshCoordinatorSystemPromptInjection: applyMeshCoordinatorSystemPromptInjection2 } = await Promise.resolve().then(() => (init_mesh_coordinator(), mesh_coordinator_exports));
|
|
77229
|
+
const effect = applyMeshCoordinatorSystemPromptInjection2(
|
|
77230
|
+
cliCmdSystemPrompt,
|
|
77231
|
+
providerMeta?.meshCoordinator?.systemPromptInjection,
|
|
77232
|
+
{ cliArgs: cliCmdArgs, launchEnv: cliCmdEnv, workspace, cliType }
|
|
77233
|
+
);
|
|
77234
|
+
cliCmdContextFilePath = effect.contextFilePath;
|
|
77235
|
+
}
|
|
77236
|
+
const cliCmdLaunch = await ctx.deps.cliManager.handleCliCommand("launch_cli", {
|
|
77237
|
+
cliType,
|
|
77238
|
+
dir: workspace,
|
|
77239
|
+
cliArgs: cliCmdArgs.length > 0 ? cliCmdArgs : void 0,
|
|
77240
|
+
env: Object.keys(cliCmdEnv).length > 0 ? cliCmdEnv : void 0,
|
|
77241
|
+
settings: { meshCoordinatorFor: meshId }
|
|
77242
|
+
});
|
|
77243
|
+
if (cliCmdLaunch?.success && cliCmdContextFilePath) {
|
|
77244
|
+
const stripPath = cliCmdContextFilePath;
|
|
77245
|
+
setTimeout(() => {
|
|
77246
|
+
void Promise.resolve().then(() => (init_mesh_coordinator(), mesh_coordinator_exports)).then(({ stripCoordinatorWrapperFile: stripCoordinatorWrapperFile2 }) => {
|
|
77247
|
+
stripCoordinatorWrapperFile2(stripPath);
|
|
77248
|
+
LOG2.info("MeshCoordinator", `Stripped wrapper from ${stripPath} after launch settle (cli_command)`);
|
|
77249
|
+
}).catch(() => {
|
|
77250
|
+
});
|
|
77251
|
+
}, 5e3);
|
|
77252
|
+
}
|
|
77253
|
+
if (!cliCmdLaunch?.success) {
|
|
77254
|
+
return { success: false, error: cliCmdLaunch?.error || "Failed to launch CLI session" };
|
|
77255
|
+
}
|
|
77256
|
+
LOG2.info("MeshCoordinator", `Launched ${cliType} coordinator (cli_command) for mesh ${meshId}`);
|
|
77257
|
+
const cliCmdSessionId = cliCmdLaunch.sessionId || cliCmdLaunch.id;
|
|
77258
|
+
if (cliCmdSessionId) {
|
|
77259
|
+
const cliCmdInjectionDecl = providerMeta?.meshCoordinator?.systemPromptInjection;
|
|
77260
|
+
registerMeshCoordinator({
|
|
77261
|
+
meshId,
|
|
77262
|
+
sessionId: cliCmdSessionId,
|
|
77263
|
+
workspace,
|
|
77264
|
+
startedAt: Date.now(),
|
|
77265
|
+
cliType,
|
|
77266
|
+
systemPrompt: cliCmdSystemPrompt || void 0,
|
|
77267
|
+
extraSystemPrompt: extraSystemPrompt || void 0,
|
|
77268
|
+
injection: cliCmdInjectionDecl ? {
|
|
77269
|
+
mode: cliCmdInjectionDecl.mode,
|
|
77270
|
+
target: "flag" in cliCmdInjectionDecl ? cliCmdInjectionDecl.flag : "name" in cliCmdInjectionDecl ? cliCmdInjectionDecl.name : "path" in cliCmdInjectionDecl ? cliCmdInjectionDecl.path : void 0
|
|
77271
|
+
} : void 0
|
|
77272
|
+
});
|
|
77273
|
+
}
|
|
77274
|
+
try {
|
|
77275
|
+
const { appendLedgerEntry: appendLedgerEntry2 } = await Promise.resolve().then(() => (init_mesh_ledger(), mesh_ledger_exports));
|
|
77276
|
+
appendLedgerEntry2(meshId, {
|
|
77277
|
+
kind: "coordinator_started",
|
|
77278
|
+
sessionId: cliCmdSessionId,
|
|
77279
|
+
providerType: cliType,
|
|
77280
|
+
payload: { workspace }
|
|
77281
|
+
});
|
|
77282
|
+
} catch {
|
|
77283
|
+
}
|
|
77284
|
+
return {
|
|
77285
|
+
success: true,
|
|
77286
|
+
meshId,
|
|
77287
|
+
cliType,
|
|
77288
|
+
workspace,
|
|
77289
|
+
sessionId: cliCmdSessionId,
|
|
77290
|
+
mcpRegistered: mcpRegistrationOk
|
|
77291
|
+
};
|
|
77292
|
+
}
|
|
77293
|
+
const configFormat = coordinatorSetup.configFormat;
|
|
77294
|
+
if (configFormat !== "claude_mcp_json" && configFormat !== "hermes_config_yaml") {
|
|
77295
|
+
return {
|
|
77296
|
+
success: false,
|
|
77297
|
+
code: "mesh_coordinator_unsupported",
|
|
77298
|
+
error: `Unsupported auto-import MCP config format: ${String(coordinatorSetup.configFormat)}`,
|
|
77299
|
+
meshId,
|
|
77300
|
+
cliType,
|
|
77301
|
+
workspace
|
|
77302
|
+
};
|
|
77303
|
+
}
|
|
77304
|
+
let systemPrompt = "";
|
|
77305
|
+
try {
|
|
77306
|
+
systemPrompt = buildCoordinatorSystemPrompt2({ mesh, coordinatorCliType: cliType, userInstruction: extraSystemPrompt || void 0, missionSection: buildMissionSectionBestEffort(mesh.id) });
|
|
77307
|
+
} catch (error48) {
|
|
77308
|
+
const message = error48?.message || String(error48);
|
|
77309
|
+
LOG2.error("MeshCoordinator", `Failed to build coordinator prompt: ${message}`);
|
|
77310
|
+
return {
|
|
77311
|
+
success: false,
|
|
77312
|
+
code: "mesh_coordinator_prompt_failed",
|
|
77313
|
+
error: `Failed to build Repo Mesh coordinator prompt: ${message}`,
|
|
77314
|
+
meshId,
|
|
77315
|
+
cliType,
|
|
77316
|
+
workspace
|
|
77317
|
+
};
|
|
77318
|
+
}
|
|
77319
|
+
const { existsSync: existsSync49, readFileSync: readFileSync39, writeFileSync: writeFileSync24, copyFileSync: copyFileSync4, mkdirSync: mkdirSync21 } = await import("fs");
|
|
77320
|
+
const { dirname: dirname17 } = await import("path");
|
|
77321
|
+
const mcpConfigPath = coordinatorSetup.configPath;
|
|
77322
|
+
const hermesManualFallback = cliType === "hermes-cli" && configFormat === "hermes_config_yaml" ? createHermesManualMeshCoordinatorSetup(meshId, workspace) : null;
|
|
77323
|
+
let hermesBaseConfig = null;
|
|
77324
|
+
if (hermesManualFallback) {
|
|
77325
|
+
try {
|
|
77326
|
+
hermesBaseConfig = loadHermesCoordinatorBaseConfig(mcpConfigPath);
|
|
77327
|
+
} catch (error48) {
|
|
77328
|
+
const message = `Failed to parse Hermes base config for automatic coordinator setup: ${error48?.message || error48}`;
|
|
77329
|
+
LOG2.error("MeshCoordinator", message);
|
|
77330
|
+
return { success: false, code: "mesh_coordinator_config_parse_failed", error: message, meshId, cliType, workspace };
|
|
77331
|
+
}
|
|
77332
|
+
}
|
|
77333
|
+
const returnManualFallback = (message) => ({
|
|
77334
|
+
success: false,
|
|
77335
|
+
code: "mesh_coordinator_manual_mcp_setup_required",
|
|
77336
|
+
error: message,
|
|
77337
|
+
meshId,
|
|
77338
|
+
cliType,
|
|
77339
|
+
workspace,
|
|
77340
|
+
meshCoordinatorSetup: hermesManualFallback
|
|
77341
|
+
});
|
|
77342
|
+
const mcpServerEntry = {
|
|
77343
|
+
command: coordinatorSetup.mcpServer.command,
|
|
77344
|
+
args: coordinatorSetup.mcpServer.args
|
|
77345
|
+
};
|
|
77346
|
+
if (args?.inlineMesh) {
|
|
77347
|
+
const modeArgIndex = coordinatorSetup.mcpServer.args.findIndex((value) => value === "--mode");
|
|
77348
|
+
const mcpTransport = modeArgIndex >= 0 ? coordinatorSetup.mcpServer.args[modeArgIndex + 1] : "ipc";
|
|
77349
|
+
mcpServerEntry.env = {
|
|
77350
|
+
ADHDEV_INLINE_MESH: JSON.stringify(mesh),
|
|
77351
|
+
ADHDEV_MCP_TRANSPORT: mcpTransport === "local" ? "local" : "ipc"
|
|
77352
|
+
};
|
|
77353
|
+
}
|
|
77354
|
+
try {
|
|
77355
|
+
mkdirSync21(dirname17(mcpConfigPath), { recursive: true });
|
|
77356
|
+
} catch (error48) {
|
|
77357
|
+
const message = `Could not prepare MCP config path for automatic setup: ${error48?.message || error48}`;
|
|
77358
|
+
LOG2.error("MeshCoordinator", message);
|
|
77359
|
+
if (hermesManualFallback) return returnManualFallback(message);
|
|
77360
|
+
return { success: false, code: "mesh_coordinator_config_write_failed", error: message, meshId, cliType, workspace };
|
|
77361
|
+
}
|
|
77362
|
+
const hadExistingMcpConfig = existsSync49(mcpConfigPath);
|
|
77363
|
+
let existingMcpConfig = hermesBaseConfig?.config || {};
|
|
77364
|
+
if (hermesBaseConfig) {
|
|
77365
|
+
copyHermesCoordinatorCredentialFiles(hermesBaseConfig.sourceHome, dirname17(mcpConfigPath));
|
|
77366
|
+
}
|
|
77367
|
+
if (hadExistingMcpConfig) {
|
|
77368
|
+
try {
|
|
77369
|
+
const parsedExistingMcpConfig = parseMeshCoordinatorMcpConfig(readFileSync39(mcpConfigPath, "utf-8"), configFormat);
|
|
77370
|
+
const existingCoordinatorConfig = hermesManualFallback ? stripHermesCoordinatorTempModelProviderOverrides(parsedExistingMcpConfig) : parsedExistingMcpConfig;
|
|
77371
|
+
existingMcpConfig = { ...existingMcpConfig, ...existingCoordinatorConfig };
|
|
77372
|
+
copyFileSync4(mcpConfigPath, mcpConfigPath + ".backup");
|
|
77373
|
+
} catch (error48) {
|
|
77374
|
+
LOG2.error("MeshCoordinator", `Failed to parse existing MCP config ${mcpConfigPath}: ${error48?.message || error48}`);
|
|
77375
|
+
return {
|
|
77376
|
+
success: false,
|
|
77377
|
+
code: "mesh_coordinator_config_parse_failed",
|
|
77378
|
+
error: `Failed to parse existing MCP config at ${mcpConfigPath}`
|
|
77379
|
+
};
|
|
77380
|
+
}
|
|
77381
|
+
}
|
|
77382
|
+
const mcpServersKey = getMcpServersKey(configFormat);
|
|
77383
|
+
const existingServers = existingMcpConfig[mcpServersKey];
|
|
77384
|
+
const mcpConfig = {
|
|
77385
|
+
...existingMcpConfig,
|
|
77386
|
+
[mcpServersKey]: {
|
|
77387
|
+
...existingServers && typeof existingServers === "object" && !Array.isArray(existingServers) ? existingServers : {},
|
|
77388
|
+
[coordinatorSetup.serverName]: mcpServerEntry
|
|
77389
|
+
}
|
|
77390
|
+
};
|
|
77391
|
+
try {
|
|
77392
|
+
writeFileSync24(mcpConfigPath, serializeMeshCoordinatorMcpConfig(mcpConfig, configFormat), "utf-8");
|
|
77393
|
+
} catch (error48) {
|
|
77394
|
+
const message = `Could not write MCP config for automatic setup: ${error48?.message || error48}`;
|
|
77395
|
+
LOG2.error("MeshCoordinator", message);
|
|
77396
|
+
if (hermesManualFallback) return returnManualFallback(message);
|
|
77397
|
+
return { success: false, code: "mesh_coordinator_config_write_failed", error: message, meshId, cliType, workspace };
|
|
77398
|
+
}
|
|
77399
|
+
LOG2.info("MeshCoordinator", `Wrote ${mcpConfigPath} with ${coordinatorSetup.serverName} server`);
|
|
77400
|
+
const cliArgs = [];
|
|
77401
|
+
const launchEnv = {};
|
|
77402
|
+
if (configFormat === "hermes_config_yaml") {
|
|
77403
|
+
launchEnv.HERMES_HOME = dirname17(mcpConfigPath);
|
|
77404
|
+
launchEnv.HERMES_IGNORE_USER_CONFIG = "";
|
|
77405
|
+
}
|
|
77406
|
+
let autoImportContextFilePath;
|
|
77407
|
+
if (systemPrompt) {
|
|
77408
|
+
const { applyMeshCoordinatorSystemPromptInjection: applyMeshCoordinatorSystemPromptInjection2 } = await Promise.resolve().then(() => (init_mesh_coordinator(), mesh_coordinator_exports));
|
|
77409
|
+
const effect = applyMeshCoordinatorSystemPromptInjection2(
|
|
77410
|
+
systemPrompt,
|
|
77411
|
+
providerMeta?.meshCoordinator?.systemPromptInjection,
|
|
77412
|
+
{ cliArgs, launchEnv, workspace, cliType }
|
|
77413
|
+
);
|
|
77414
|
+
autoImportContextFilePath = effect.contextFilePath;
|
|
77415
|
+
}
|
|
77416
|
+
if (cliType === "claude-cli") {
|
|
77417
|
+
cliArgs.push("--mcp-config", coordinatorSetup.configPath);
|
|
77418
|
+
}
|
|
77419
|
+
const launchResult = await ctx.deps.cliManager.handleCliCommand("launch_cli", {
|
|
77420
|
+
cliType,
|
|
77421
|
+
dir: workspace,
|
|
77422
|
+
cliArgs: cliArgs.length > 0 ? cliArgs : void 0,
|
|
77423
|
+
env: Object.keys(launchEnv).length > 0 ? launchEnv : void 0,
|
|
77424
|
+
settings: {
|
|
77425
|
+
meshCoordinatorFor: meshId
|
|
77426
|
+
}
|
|
77427
|
+
});
|
|
77428
|
+
if (launchResult?.success && autoImportContextFilePath) {
|
|
77429
|
+
const stripPath = autoImportContextFilePath;
|
|
77430
|
+
setTimeout(() => {
|
|
77431
|
+
void Promise.resolve().then(() => (init_mesh_coordinator(), mesh_coordinator_exports)).then(({ stripCoordinatorWrapperFile: stripCoordinatorWrapperFile2 }) => {
|
|
77432
|
+
stripCoordinatorWrapperFile2(stripPath);
|
|
77433
|
+
LOG2.info("MeshCoordinator", `Stripped wrapper from ${stripPath} after launch settle (auto_import)`);
|
|
77434
|
+
}).catch(() => {
|
|
77435
|
+
});
|
|
77436
|
+
}, 5e3);
|
|
77437
|
+
}
|
|
77438
|
+
if (!launchResult?.success) {
|
|
77439
|
+
return { success: false, error: launchResult?.error || "Failed to launch CLI session" };
|
|
77440
|
+
}
|
|
77441
|
+
LOG2.info("MeshCoordinator", `Launched ${cliType} coordinator for mesh ${meshId} in ${workspace}`);
|
|
77442
|
+
const launchSessionId = launchResult.sessionId || launchResult.id;
|
|
77443
|
+
if (launchSessionId) {
|
|
77444
|
+
const autoImportInjectionDecl = providerMeta?.meshCoordinator?.systemPromptInjection;
|
|
77445
|
+
registerMeshCoordinator({
|
|
77446
|
+
meshId,
|
|
77447
|
+
sessionId: launchSessionId,
|
|
77448
|
+
workspace,
|
|
77449
|
+
startedAt: Date.now(),
|
|
77450
|
+
cliType,
|
|
77451
|
+
systemPrompt: systemPrompt || void 0,
|
|
77452
|
+
extraSystemPrompt: extraSystemPrompt || void 0,
|
|
77453
|
+
mcpConfigPath,
|
|
77454
|
+
injection: autoImportInjectionDecl ? {
|
|
77455
|
+
mode: autoImportInjectionDecl.mode,
|
|
77456
|
+
target: "flag" in autoImportInjectionDecl ? autoImportInjectionDecl.flag : "name" in autoImportInjectionDecl ? autoImportInjectionDecl.name : "path" in autoImportInjectionDecl ? autoImportInjectionDecl.path : void 0
|
|
77457
|
+
} : void 0
|
|
77458
|
+
});
|
|
77459
|
+
}
|
|
77460
|
+
try {
|
|
77461
|
+
const { appendLedgerEntry: appendLedgerEntry2 } = await Promise.resolve().then(() => (init_mesh_ledger(), mesh_ledger_exports));
|
|
77462
|
+
appendLedgerEntry2(meshId, {
|
|
77463
|
+
kind: "coordinator_started",
|
|
77464
|
+
sessionId: launchSessionId,
|
|
77465
|
+
providerType: cliType,
|
|
77466
|
+
payload: { workspace }
|
|
77467
|
+
});
|
|
77468
|
+
} catch {
|
|
77469
|
+
}
|
|
77470
|
+
return {
|
|
77471
|
+
success: true,
|
|
77472
|
+
meshId,
|
|
77473
|
+
cliType,
|
|
77474
|
+
workspace,
|
|
77475
|
+
sessionId: launchSessionId,
|
|
77476
|
+
mcpConfigWritten: true
|
|
77477
|
+
};
|
|
77478
|
+
} catch (e) {
|
|
77479
|
+
LOG2.error("MeshCoordinator", `Failed: ${e.message}`);
|
|
77480
|
+
return { success: false, error: e.message };
|
|
77481
|
+
}
|
|
77482
|
+
}
|
|
77483
|
+
};
|
|
77484
|
+
var fs27 = __toESM2(require("fs"));
|
|
77485
|
+
var import_os3 = require("os");
|
|
76974
77486
|
init_config();
|
|
77487
|
+
init_git_status();
|
|
77488
|
+
init_dist();
|
|
77489
|
+
init_mesh_events();
|
|
77490
|
+
init_mesh_routing();
|
|
77491
|
+
init_mesh_host_ownership();
|
|
77492
|
+
var import_node_child_process4 = require("child_process");
|
|
77493
|
+
var import_node_fs4 = require("fs");
|
|
77494
|
+
var import_node_path2 = require("path");
|
|
77495
|
+
var PREVIEW_DEPLOY_RECORD = ".adhdev/preview-deploy.json";
|
|
77496
|
+
function runGit2(repoRoot, args) {
|
|
77497
|
+
try {
|
|
77498
|
+
return (0, import_node_child_process4.execFileSync)("git", args, {
|
|
77499
|
+
cwd: repoRoot,
|
|
77500
|
+
encoding: "utf8",
|
|
77501
|
+
stdio: ["ignore", "pipe", "ignore"],
|
|
77502
|
+
timeout: 5e3
|
|
77503
|
+
}).trim();
|
|
77504
|
+
} catch {
|
|
77505
|
+
return "";
|
|
77506
|
+
}
|
|
77507
|
+
}
|
|
77508
|
+
function readRecord5(repoRoot) {
|
|
77509
|
+
const path422 = (0, import_node_path2.resolve)(repoRoot, PREVIEW_DEPLOY_RECORD);
|
|
77510
|
+
if (!(0, import_node_fs4.existsSync)(path422)) return null;
|
|
77511
|
+
try {
|
|
77512
|
+
const parsed = JSON.parse((0, import_node_fs4.readFileSync)(path422, "utf8"));
|
|
77513
|
+
return parsed && typeof parsed === "object" && !Array.isArray(parsed) ? parsed : null;
|
|
77514
|
+
} catch {
|
|
77515
|
+
return null;
|
|
77516
|
+
}
|
|
77517
|
+
}
|
|
77518
|
+
function normalizeCommit(value) {
|
|
77519
|
+
return typeof value === "string" && /^[0-9a-f]{7,40}$/i.test(value.trim()) ? value.trim() : null;
|
|
77520
|
+
}
|
|
77521
|
+
function readTargetFreshness(record2, currentCommit) {
|
|
77522
|
+
const targets = record2?.targets && typeof record2.targets === "object" && !Array.isArray(record2.targets) ? record2.targets : {};
|
|
77523
|
+
const result = {};
|
|
77524
|
+
for (const targetName of ["npm", "server", "web"]) {
|
|
77525
|
+
const targetRecord = targets[targetName] && typeof targets[targetName] === "object" && !Array.isArray(targets[targetName]) ? targets[targetName] : {};
|
|
77526
|
+
const commit = normalizeCommit(targetRecord.commit);
|
|
77527
|
+
result[targetName] = {
|
|
77528
|
+
commit,
|
|
77529
|
+
deployedAt: typeof targetRecord.deployedAt === "string" ? targetRecord.deployedAt : void 0,
|
|
77530
|
+
status: commit && currentCommit ? commit === currentCommit ? "fresh" : "stale" : "unknown"
|
|
77531
|
+
};
|
|
77532
|
+
}
|
|
77533
|
+
return result;
|
|
77534
|
+
}
|
|
77535
|
+
function readCurrentMainCommit(repoRoot) {
|
|
77536
|
+
const originMain = runGit2(repoRoot, ["rev-parse", "--verify", "origin/main^{commit}"]);
|
|
77537
|
+
if (originMain) {
|
|
77538
|
+
return { currentMainCommit: originMain, currentMainCommitSource: "origin/main" };
|
|
77539
|
+
}
|
|
77540
|
+
const head = runGit2(repoRoot, ["rev-parse", "--verify", "HEAD"]);
|
|
77541
|
+
if (head) {
|
|
77542
|
+
return { currentMainCommit: head, currentMainCommitSource: "HEAD" };
|
|
77543
|
+
}
|
|
77544
|
+
return { currentMainCommit: null, currentMainCommitSource: "unknown" };
|
|
77545
|
+
}
|
|
77546
|
+
function buildPreviewFreshness(repoRoot) {
|
|
77547
|
+
const current = readCurrentMainCommit(repoRoot);
|
|
77548
|
+
const record2 = readRecord5(repoRoot);
|
|
77549
|
+
const lastPreviewCommit = normalizeCommit(record2?.lastPreviewCommit);
|
|
77550
|
+
const targets = readTargetFreshness(record2, current.currentMainCommit);
|
|
77551
|
+
let status = "unknown";
|
|
77552
|
+
let nextAction = "Run npm run deploy:preview from the current main commit, then smoke preview.";
|
|
77553
|
+
if (lastPreviewCommit && current.currentMainCommit) {
|
|
77554
|
+
status = lastPreviewCommit === current.currentMainCommit ? "fresh" : "stale";
|
|
77555
|
+
nextAction = status === "fresh" ? "No preview deploy action needed." : "Run npm run deploy:preview from origin/main, then smoke preview.";
|
|
77556
|
+
} else if (!current.currentMainCommit) {
|
|
77557
|
+
nextAction = "Resolve the current main commit before judging preview freshness.";
|
|
77558
|
+
}
|
|
77559
|
+
return {
|
|
77560
|
+
status,
|
|
77561
|
+
lastPreviewCommit,
|
|
77562
|
+
currentMainCommit: current.currentMainCommit,
|
|
77563
|
+
currentMainCommitSource: current.currentMainCommitSource,
|
|
77564
|
+
recordPath: PREVIEW_DEPLOY_RECORD,
|
|
77565
|
+
lastDeployedAt: typeof record2?.updatedAt === "string" ? record2.updatedAt : void 0,
|
|
77566
|
+
lastTarget: typeof record2?.target === "string" ? record2.target : void 0,
|
|
77567
|
+
previewVersion: typeof record2?.previewVersion === "string" ? record2.previewVersion : void 0,
|
|
77568
|
+
targets,
|
|
77569
|
+
nextAction
|
|
77570
|
+
};
|
|
77571
|
+
}
|
|
77572
|
+
init_mesh_refine_status();
|
|
77573
|
+
var meshStatusHandlers = {
|
|
77574
|
+
mesh_status: async (ctx, args) => {
|
|
77575
|
+
const meshId = typeof args?.meshId === "string" ? args.meshId.trim() : "";
|
|
77576
|
+
if (!meshId) return { success: false, error: "meshId required" };
|
|
77577
|
+
try {
|
|
77578
|
+
const meshRecord = await ctx.getMeshForCommand(meshId, args?.inlineMesh, { preferInline: true });
|
|
77579
|
+
const mesh = meshRecord?.mesh;
|
|
77580
|
+
if (!mesh) return { success: false, error: "Mesh not found" };
|
|
77581
|
+
const meshHost = resolveMeshHostStatus(mesh);
|
|
77582
|
+
const refreshRequested = args?.refresh === true || args?.forceRefresh === true;
|
|
77583
|
+
const verboseMissions = args?.verbose === true || args?.compact === false;
|
|
77584
|
+
const peekScope = typeof args?.coordinatorDaemonId === "string" && args.coordinatorDaemonId.trim() ? args.coordinatorDaemonId.trim() : ctx.deps.statusInstanceId || void 0;
|
|
77585
|
+
const pendingCoordinatorEventCount = getPendingMeshCoordinatorEvents(meshId, peekScope).length;
|
|
77586
|
+
const hadAggregateCache = ctx.aggregateMeshStatusCache.has(meshId);
|
|
77587
|
+
if (!refreshRequested && !verboseMissions && pendingCoordinatorEventCount === 0) {
|
|
77588
|
+
const cachedStatus = ctx.getCachedAggregateMeshStatus(meshId, mesh, { requireDirectPeerTruth: args?.requireDirectPeerTruth === true });
|
|
77589
|
+
if (cachedStatus) {
|
|
77590
|
+
logRepoMeshStatusDebug("return_cached", {
|
|
77591
|
+
meshId,
|
|
77592
|
+
command: "mesh_status",
|
|
77593
|
+
refreshRequested,
|
|
77594
|
+
summary: summarizeRepoMeshStatusDebug(cachedStatus)
|
|
77595
|
+
});
|
|
77596
|
+
return cachedStatus;
|
|
77597
|
+
}
|
|
77598
|
+
}
|
|
77599
|
+
const refreshReason = refreshRequested ? "explicit_refresh" : pendingCoordinatorEventCount > 0 ? "pending_coordinator_events" : hadAggregateCache ? "stale_pending_cache_refresh" : "cold_cache_miss";
|
|
77600
|
+
const { getMeshQueueStats: getMeshQueueStats2, getQueue: getQueue2 } = await Promise.resolve().then(() => (init_mesh_work_queue(), mesh_work_queue_exports));
|
|
77601
|
+
const queue = getQueue2(meshId);
|
|
77602
|
+
const queueSummary = getMeshQueueStats2(meshId);
|
|
77603
|
+
const { readLedgerEntries: readLedgerEntries2, getLedgerSummary: getLedgerSummary2 } = await Promise.resolve().then(() => (init_mesh_ledger(), mesh_ledger_exports));
|
|
77604
|
+
const ledgerEntries = readLedgerEntries2(meshId, { tail: 20 });
|
|
77605
|
+
const asyncRefineLedgerEntries = readLedgerEntries2(meshId, { tail: 100 });
|
|
77606
|
+
const ledgerSummary = getLedgerSummary2(meshId);
|
|
77607
|
+
const sessionHostRecords = ctx.deps.sessionHostControl?.listSessions ? await ctx.deps.sessionHostControl.listSessions().catch(() => []) : [];
|
|
77608
|
+
const liveMeshSessions = partitionSessionHostRecords(Array.isArray(sessionHostRecords) ? sessionHostRecords : []).liveRuntimes;
|
|
77609
|
+
const localMachineId = loadConfig2().machineId || "";
|
|
77610
|
+
const requireDirectPeerTruth = args?.requireDirectPeerTruth === true;
|
|
77611
|
+
const meshGitProbeCache = ctx.meshGitProbeCache;
|
|
77612
|
+
const directTruth = requireDirectPeerTruth ? await hydrateInlineMeshDirectTruth({
|
|
77613
|
+
mesh,
|
|
77614
|
+
meshSource: meshRecord.source,
|
|
77615
|
+
dispatchMeshCommand: ctx.deps.dispatchMeshCommand,
|
|
77616
|
+
getMeshPeerConnectionStatus: ctx.deps.getMeshPeerConnectionStatus,
|
|
77617
|
+
statusInstanceId: ctx.deps.statusInstanceId,
|
|
77618
|
+
localMachineId,
|
|
77619
|
+
// Standing-state model: only an explicit refresh fans
|
|
77620
|
+
// out a blocking peer git probe. Default loads return
|
|
77621
|
+
// held truth so one slow peer can't block the graph.
|
|
77622
|
+
probeRemotePeers: refreshRequested,
|
|
77623
|
+
probeCache: meshGitProbeCache
|
|
77624
|
+
}) : {
|
|
77625
|
+
directEvidenceCount: 0,
|
|
77626
|
+
localConfirmedCount: 0,
|
|
77627
|
+
peerAttemptedCount: 0,
|
|
77628
|
+
peerConfirmedCount: 0,
|
|
77629
|
+
standingEvidenceCount: 0,
|
|
77630
|
+
unavailableNodeIds: [],
|
|
77631
|
+
deadNodeIds: []
|
|
77632
|
+
};
|
|
77633
|
+
const passivePeerTruthNotAttempted = requireDirectPeerTruth && !refreshRequested && directTruth.directEvidenceCount > 0 && directTruth.peerAttemptedCount === 0;
|
|
77634
|
+
const effectiveDirectTruth = passivePeerTruthNotAttempted ? { ...directTruth, unavailableNodeIds: [] } : directTruth;
|
|
77635
|
+
const unavailableDirectTruthNodeIds = new Set(effectiveDirectTruth.unavailableNodeIds);
|
|
77636
|
+
const unavailableNodesAreOnlyRemovedWorktrees = unavailableDirectTruthNodeIds.size > 0 && Array.isArray(mesh.nodes) && mesh.nodes.filter((node) => unavailableDirectTruthNodeIds.has(normalizeMeshNodeId(node) ?? "")).every((node) => node?.isLocalWorktree === true);
|
|
77637
|
+
const directTruthSatisfied = !requireDirectPeerTruth || !refreshRequested || effectiveDirectTruth.directEvidenceCount > 0 && (effectiveDirectTruth.unavailableNodeIds.length === 0 || unavailableNodesAreOnlyRemovedWorktrees);
|
|
77638
|
+
if (requireDirectPeerTruth && refreshRequested && !directTruthSatisfied) {
|
|
77639
|
+
const failureResult = {
|
|
77640
|
+
success: false,
|
|
77641
|
+
code: "mesh_direct_peer_truth_unavailable",
|
|
77642
|
+
error: "Selected coordinator could not confirm direct mesh truth yet. Bootstrap inventory stays unavailable until direct mesh_status probes succeed.",
|
|
77643
|
+
sourceOfTruth: {
|
|
77644
|
+
membership: meshRecord.source === "inline_cache" ? "coordinator_inline_mesh_cache" : meshRecord.source === "local_config" ? "local_mesh_config" : "inline_bootstrap_snapshot",
|
|
77645
|
+
coordinatorOwnsLiveTruth: false,
|
|
77646
|
+
currentStatus: "direct_peer_truth_unavailable",
|
|
77647
|
+
directPeerTruth: {
|
|
77648
|
+
required: true,
|
|
77649
|
+
satisfied: false,
|
|
77650
|
+
directEvidenceCount: directTruth.directEvidenceCount,
|
|
77651
|
+
localConfirmedCount: directTruth.localConfirmedCount,
|
|
77652
|
+
peerAttemptedCount: directTruth.peerAttemptedCount,
|
|
77653
|
+
peerConfirmedCount: directTruth.peerConfirmedCount,
|
|
77654
|
+
unavailableNodeIds: directTruth.unavailableNodeIds
|
|
77655
|
+
}
|
|
77656
|
+
}
|
|
77657
|
+
};
|
|
77658
|
+
logRepoMeshStatusDebug("direct_truth_unavailable", {
|
|
77659
|
+
meshId,
|
|
77660
|
+
command: "mesh_status",
|
|
77661
|
+
refreshRequested,
|
|
77662
|
+
meshSource: meshRecord.source,
|
|
77663
|
+
directTruth
|
|
77664
|
+
});
|
|
77665
|
+
return failureResult;
|
|
77666
|
+
}
|
|
77667
|
+
const directTruthUnavailableNodeIds = new Set(effectiveDirectTruth.unavailableNodeIds);
|
|
77668
|
+
const coordinatorHostname = (0, import_os3.hostname)();
|
|
77669
|
+
const selectedCoordinatorNodeId = readStringValue(
|
|
77670
|
+
mesh.coordinator?.preferredNodeId,
|
|
77671
|
+
normalizeMeshNodeId(mesh.nodes?.[0])
|
|
77672
|
+
);
|
|
77673
|
+
const inlineCoordinatorNodeId = meshRecord?.inline && Array.isArray(mesh.nodes) ? selectedCoordinatorNodeId : void 0;
|
|
77674
|
+
const refreshedAt = (/* @__PURE__ */ new Date()).toISOString();
|
|
77675
|
+
const nodeStatuses = [];
|
|
77676
|
+
for (const [nodeIndex, node] of (mesh.nodes || []).entries()) {
|
|
77677
|
+
const nodeId = normalizeMeshNodeId(node) ?? "";
|
|
77678
|
+
const daemonId = readStringValue(node.daemonId);
|
|
77679
|
+
const nodeMachineId = readMeshNodeMachineId(node);
|
|
77680
|
+
const nodeHostname = readMeshNodeHostname(node);
|
|
77681
|
+
const providerPriority = readProviderPriorityFromPolicy(node.policy);
|
|
77682
|
+
const configuredCoordinatorNode = Boolean(
|
|
77683
|
+
nodeId && selectedCoordinatorNodeId && nodeId === selectedCoordinatorNodeId
|
|
77684
|
+
);
|
|
77685
|
+
const sparseConfiguredCoordinatorNode = configuredCoordinatorNode && !daemonId && !nodeMachineId && !nodeHostname;
|
|
77686
|
+
const isSelfNode = Boolean(
|
|
77687
|
+
nodeId && inlineCoordinatorNodeId && nodeId === inlineCoordinatorNodeId
|
|
77688
|
+
) || Boolean(
|
|
77689
|
+
daemonId && (daemonIdsEquivalent(daemonId, localMachineId) || daemonIdsEquivalent(daemonId, ctx.deps.statusInstanceId))
|
|
77690
|
+
) || Boolean(meshRecord?.inline && nodeIndex === 0) || sparseConfiguredCoordinatorNode;
|
|
77691
|
+
const machineIdentity = buildMeshNodeMachineIdentity(node, {
|
|
77692
|
+
localMachineId,
|
|
77693
|
+
localDaemonId: ctx.deps.statusInstanceId,
|
|
77694
|
+
coordinatorHostname,
|
|
77695
|
+
isSelfNode
|
|
77696
|
+
});
|
|
77697
|
+
const status = {
|
|
77698
|
+
nodeId,
|
|
77699
|
+
machineLabel: buildMeshNodeDisplayLabel(node, nodeId, providerPriority),
|
|
77700
|
+
labelSource: readStringValue(node.machineLabel, node.machine_label, node.machineNickname, node.machine_nickname, node.alias) ? "explicit_metadata" : "workspace_host_provider_context",
|
|
77701
|
+
workspace: node.workspace,
|
|
77702
|
+
repoRoot: node.repoRoot,
|
|
77703
|
+
isLocalWorktree: node.isLocalWorktree,
|
|
77704
|
+
worktreeBranch: node.worktreeBranch,
|
|
77705
|
+
role: normalizeMeshDaemonRole(node.role) || (meshHost.hostNodeId && nodeId === meshHost.hostNodeId ? "host" : void 0),
|
|
77706
|
+
daemonId,
|
|
77707
|
+
machineId: nodeMachineId || node.machineId,
|
|
77708
|
+
machine: machineIdentity,
|
|
77709
|
+
machineStatus: node.machineStatus,
|
|
77710
|
+
health: "unknown",
|
|
77711
|
+
providers: node.providers || [],
|
|
77712
|
+
providerPriority,
|
|
77713
|
+
activeSessions: [],
|
|
77714
|
+
activeSessionDetails: [],
|
|
77715
|
+
launchReady: false
|
|
77716
|
+
};
|
|
77717
|
+
if (isSelfNode) {
|
|
77718
|
+
status.connection = {
|
|
77719
|
+
perspective: "selected_coordinator",
|
|
77720
|
+
source: "mesh_peer_status",
|
|
77721
|
+
state: "self",
|
|
77722
|
+
transport: "local",
|
|
77723
|
+
reported: true,
|
|
77724
|
+
reason: "Selected coordinator daemon",
|
|
77725
|
+
lastStateChangeAt: refreshedAt
|
|
77726
|
+
};
|
|
77727
|
+
} else if (daemonId) {
|
|
77728
|
+
const connection = ctx.deps.getMeshPeerConnectionStatus?.(daemonId);
|
|
77729
|
+
status.connection = connection ?? {
|
|
77730
|
+
perspective: "selected_coordinator",
|
|
77731
|
+
source: "not_reported",
|
|
77732
|
+
state: "unknown",
|
|
77733
|
+
transport: "unknown",
|
|
77734
|
+
reported: false,
|
|
77735
|
+
reason: "No live mesh peer telemetry reported by the selected coordinator yet."
|
|
77736
|
+
};
|
|
77737
|
+
} else {
|
|
77738
|
+
status.connection = {
|
|
77739
|
+
perspective: "selected_coordinator",
|
|
77740
|
+
source: "not_reported",
|
|
77741
|
+
state: "unknown",
|
|
77742
|
+
transport: "unknown",
|
|
77743
|
+
reported: false,
|
|
77744
|
+
reason: "Node has no daemon id, so mesh transport cannot be reported from the selected coordinator."
|
|
77745
|
+
};
|
|
77746
|
+
}
|
|
77747
|
+
const matchedLiveSessionRecords = collectLiveMeshSessionRecords({
|
|
77748
|
+
meshId,
|
|
77749
|
+
node,
|
|
77750
|
+
nodeId,
|
|
77751
|
+
liveSessionRecords: liveMeshSessions,
|
|
77752
|
+
allowCoordinatorSession: nodeId === selectedCoordinatorNodeId
|
|
77753
|
+
});
|
|
77754
|
+
const workspace = readLiveMeshNodeWorkspace({
|
|
77755
|
+
meshId,
|
|
77756
|
+
nodeId,
|
|
77757
|
+
liveSessionRecords: matchedLiveSessionRecords,
|
|
77758
|
+
allowCoordinatorSession: nodeId === selectedCoordinatorNodeId
|
|
77759
|
+
}) || (typeof node.workspace === "string" ? node.workspace : "");
|
|
77760
|
+
status.workspace = workspace || node.workspace;
|
|
77761
|
+
if (matchedLiveSessionRecords.length > 0) {
|
|
77762
|
+
const sessionIds = matchedLiveSessionRecords.map((record2) => typeof record2?.sessionId === "string" ? record2.sessionId : "").filter(Boolean);
|
|
77763
|
+
const providerTypes = matchedLiveSessionRecords.map((record2) => readStringValue(record2?.providerType)).filter(Boolean);
|
|
77764
|
+
status.activeSessions = sessionIds;
|
|
77765
|
+
status.activeSessionDetails = matchedLiveSessionRecords.map(summarizeMeshSessionRecord);
|
|
77766
|
+
if (providerTypes.length > 0) {
|
|
77767
|
+
status.providers = Array.from(/* @__PURE__ */ new Set([...Array.isArray(status.providers) ? status.providers : [], ...providerTypes]));
|
|
77768
|
+
}
|
|
77769
|
+
}
|
|
77770
|
+
if (workspace) {
|
|
77771
|
+
if (!fs27.existsSync(workspace)) {
|
|
77772
|
+
const inlineTransitGit = buildInlineMeshTransitGitStatus(node);
|
|
77773
|
+
let remoteProbeApplied = false;
|
|
77774
|
+
if (inlineTransitGit) {
|
|
77775
|
+
status.git = inlineTransitGit;
|
|
77776
|
+
status.health = inlineTransitGit.isGitRepo ? deriveMeshNodeHealthFromGit(inlineTransitGit) : "degraded";
|
|
77777
|
+
const connection = readObjectRecord(status.connection);
|
|
77778
|
+
const connectionState = readStringValue(connection.state);
|
|
77779
|
+
const connectionReported = readBooleanValue(connection.reported) ?? false;
|
|
77780
|
+
if (!connectionReported || connectionState === "unknown") {
|
|
77781
|
+
status.connection = buildLivePeerGitConnection(connection, refreshedAt);
|
|
77782
|
+
}
|
|
77783
|
+
remoteProbeApplied = true;
|
|
77784
|
+
} else if (refreshRequested && !isSelfNode && daemonId && ctx.deps.dispatchMeshCommand && !directTruthUnavailableNodeIds.has(nodeId)) {
|
|
77785
|
+
const runNodeProbe = () => probeRemoteMeshGitStatusWithRetry({
|
|
77786
|
+
dispatchMeshCommand: ctx.deps.dispatchMeshCommand,
|
|
77787
|
+
daemonId,
|
|
77788
|
+
workspace,
|
|
77789
|
+
timeoutMs: MESH_DIRECT_PROBE_TIMEOUT_MS,
|
|
77790
|
+
retryTimeoutMs: MESH_DIRECT_PROBE_RETRY_TIMEOUT_MS,
|
|
77791
|
+
getConnection: ctx.deps.getMeshPeerConnectionStatus,
|
|
77792
|
+
onConnection: (connection) => {
|
|
77793
|
+
status.connection = connection;
|
|
77794
|
+
}
|
|
77795
|
+
});
|
|
77796
|
+
const remoteGit = await meshGitProbeCache.probe(daemonId, workspace, runNodeProbe);
|
|
77797
|
+
if (remoteGit) {
|
|
77798
|
+
status.git = remoteGit;
|
|
77799
|
+
status.health = remoteGit.isGitRepo ? deriveMeshNodeHealthFromGit(remoteGit) : "degraded";
|
|
77800
|
+
const connection = readObjectRecord(status.connection);
|
|
77801
|
+
const connectionState = readStringValue(connection.state);
|
|
77802
|
+
const connectionReported = readBooleanValue(connection.reported) ?? false;
|
|
77803
|
+
if (!connectionReported || connectionState === "unknown") {
|
|
77804
|
+
status.connection = buildLivePeerGitConnection(connection, refreshedAt);
|
|
77805
|
+
}
|
|
77806
|
+
const reporter = recordInlineMeshDirectGitTruth(node, remoteGit, "selected_coordinator_mesh_p2p_git");
|
|
77807
|
+
persistNodeReporterPlatform(meshRecord.source, mesh, nodeId, reporter);
|
|
77808
|
+
remoteProbeApplied = true;
|
|
77809
|
+
}
|
|
77810
|
+
}
|
|
77811
|
+
if (!remoteProbeApplied) {
|
|
77812
|
+
const connectionState = readStringValue(status.connection?.state);
|
|
77813
|
+
const pendingPeerGitProbe = !inlineTransitGit && !isSelfNode && !!daemonId && (readStringValue(status.machineStatus) === "online" || readStringValue(status.health) === "online" || connectionState === "connecting" || connectionState === "connected" || connectionState === "unknown");
|
|
77814
|
+
if (pendingPeerGitProbe) {
|
|
77815
|
+
status.gitProbePending = true;
|
|
77816
|
+
status.health = "unknown";
|
|
77817
|
+
}
|
|
77818
|
+
if (applyCachedInlineMeshNodeStatus(
|
|
77819
|
+
status,
|
|
77820
|
+
node,
|
|
77821
|
+
pendingPeerGitProbe ? { skipGit: true, skipError: true, skipHealth: true } : void 0
|
|
77822
|
+
)) {
|
|
77823
|
+
applyInlineMeshBranchConvergence(mesh, node, status);
|
|
77824
|
+
finalizeMeshNodeStatus({ status, node, daemonId, isSelfNode });
|
|
77825
|
+
nodeStatuses.push(status);
|
|
77826
|
+
continue;
|
|
77827
|
+
}
|
|
77828
|
+
if (meshRecord?.source === "inline_cache" && !isSelfNode) {
|
|
77829
|
+
applyInlineMeshBranchConvergence(mesh, node, status);
|
|
77830
|
+
finalizeMeshNodeStatus({ status, node, daemonId, isSelfNode });
|
|
77831
|
+
nodeStatuses.push(status);
|
|
77832
|
+
continue;
|
|
77833
|
+
}
|
|
77834
|
+
}
|
|
77835
|
+
} else {
|
|
77836
|
+
try {
|
|
77837
|
+
const gitStatus = await getGitRepoStatus(workspace, { timeoutMs: 1e4, refreshUpstream: true });
|
|
77838
|
+
status.git = gitStatus;
|
|
77839
|
+
const reporter = recordInlineMeshDirectGitTruth(node, gitStatus, "selected_coordinator_local_git");
|
|
77840
|
+
persistNodeReporterPlatform(meshRecord.source, mesh, nodeId, reporter);
|
|
77841
|
+
if (gitStatus.isGitRepo) {
|
|
77842
|
+
status.health = deriveMeshNodeHealthFromGit(gitStatus);
|
|
77843
|
+
} else {
|
|
77844
|
+
status.health = "degraded";
|
|
77845
|
+
if (gitStatus.error && !status.error) status.error = gitStatus.error;
|
|
77846
|
+
}
|
|
77847
|
+
} catch {
|
|
77848
|
+
if (!applyCachedInlineMeshNodeStatus(status, node)) {
|
|
77849
|
+
status.health = "degraded";
|
|
77850
|
+
}
|
|
77851
|
+
}
|
|
77852
|
+
}
|
|
77853
|
+
} else {
|
|
77854
|
+
applyCachedInlineMeshNodeStatus(status, node);
|
|
77855
|
+
}
|
|
77856
|
+
applyInlineMeshBranchConvergence(mesh, node, status);
|
|
77857
|
+
finalizeMeshNodeStatus({ status, node, daemonId, isSelfNode });
|
|
77858
|
+
nodeStatuses.push(status);
|
|
77859
|
+
}
|
|
77860
|
+
const callerCoordinatorDaemonId = typeof args?.coordinatorDaemonId === "string" && args.coordinatorDaemonId.trim() ? args.coordinatorDaemonId.trim() : ctx.deps.statusInstanceId || void 0;
|
|
77861
|
+
const pendingCoordinatorEvents = getPendingMeshCoordinatorEvents(meshId, callerCoordinatorDaemonId);
|
|
77862
|
+
const unroutableDeliveries = getRecentUnroutableDeliveries();
|
|
77863
|
+
const previewFreshness = (() => {
|
|
77864
|
+
const localRepoRoot = nodeStatuses.map((node) => readStringValue(node?.git?.repoRoot, node?.repoRoot, node?.workspace)).find((candidate) => !!candidate && fs27.existsSync(candidate));
|
|
77865
|
+
return localRepoRoot ? buildPreviewFreshness(localRepoRoot) : void 0;
|
|
77866
|
+
})();
|
|
77867
|
+
const asyncRefineJobs = buildMeshAsyncRefineJobs({
|
|
77868
|
+
meshId,
|
|
77869
|
+
ledgerEntries: asyncRefineLedgerEntries,
|
|
77870
|
+
pendingEvents: [...pendingCoordinatorEvents]
|
|
77871
|
+
});
|
|
77872
|
+
const historicalSessions = buildHistoricalMeshSessions({
|
|
77873
|
+
meshId,
|
|
77874
|
+
nodes: mesh.nodes || [],
|
|
77875
|
+
liveSessionRecords: liveMeshSessions
|
|
77876
|
+
});
|
|
77877
|
+
const { getMeshStatusMissionSummaries: getMeshStatusMissionSummaries2 } = await Promise.resolve().then(() => (init_mesh_missions(), mesh_missions_exports));
|
|
77878
|
+
const missions = getMeshStatusMissionSummaries2(meshId, { verbose: verboseMissions, withStats: true });
|
|
77879
|
+
const statusResult = {
|
|
77880
|
+
success: true,
|
|
77881
|
+
meshId: mesh.id,
|
|
77882
|
+
meshName: mesh.name,
|
|
77883
|
+
repoIdentity: mesh.repoIdentity,
|
|
77884
|
+
defaultBranch: mesh.defaultBranch,
|
|
77885
|
+
refreshedAt,
|
|
77886
|
+
meshHost,
|
|
77887
|
+
sourceOfTruth: {
|
|
77888
|
+
membership: meshRecord?.source === "inline_cache" ? "coordinator_inline_mesh_cache" : meshRecord?.source === "local_config" ? "local_mesh_config" : "inline_bootstrap_snapshot",
|
|
77889
|
+
coordinatorOwnsLiveTruth: directTruthSatisfied,
|
|
77890
|
+
meshHost: {
|
|
77891
|
+
owner: "mesh_host_daemon",
|
|
77892
|
+
localRole: meshHost.role,
|
|
77893
|
+
hostDaemonId: meshHost.hostDaemonId,
|
|
77894
|
+
hostNodeId: meshHost.hostNodeId,
|
|
77895
|
+
hostAddress: meshHost.hostAddress
|
|
77896
|
+
},
|
|
77897
|
+
...requireDirectPeerTruth ? {
|
|
77898
|
+
currentStatus: directTruthSatisfied ? "live_git_and_session_probes" : "direct_peer_truth_unavailable",
|
|
77899
|
+
directPeerTruth: {
|
|
77900
|
+
required: true,
|
|
77901
|
+
satisfied: directTruthSatisfied,
|
|
77902
|
+
directEvidenceCount: effectiveDirectTruth.directEvidenceCount,
|
|
77903
|
+
localConfirmedCount: effectiveDirectTruth.localConfirmedCount,
|
|
77904
|
+
peerAttemptedCount: effectiveDirectTruth.peerAttemptedCount,
|
|
77905
|
+
peerConfirmedCount: effectiveDirectTruth.peerConfirmedCount,
|
|
77906
|
+
unavailableNodeIds: effectiveDirectTruth.unavailableNodeIds,
|
|
77907
|
+
partialNodeFailures: effectiveDirectTruth.unavailableNodeIds
|
|
77908
|
+
}
|
|
77909
|
+
} : {},
|
|
77910
|
+
historicalEvidenceOnly: ["recoveryHints", "ledger.summary", "queue.summary", "historicalSessions"]
|
|
77911
|
+
},
|
|
77912
|
+
branchConvergenceSummary: summarizeInlineMeshBranchConvergence(nodeStatuses),
|
|
77913
|
+
...previewFreshness ? { previewFreshness, deployFreshness: previewFreshness } : {},
|
|
77914
|
+
nodes: nodeStatuses,
|
|
77915
|
+
queue: { tasks: queue, summary: queueSummary },
|
|
77916
|
+
ledger: { entries: ledgerEntries, summary: ledgerSummary },
|
|
77917
|
+
...missions.length > 0 ? { missions } : {},
|
|
77918
|
+
...asyncRefineJobs.length > 0 ? { asyncRefineJobs } : {},
|
|
77919
|
+
...historicalSessions ? { historicalSessions } : {},
|
|
77920
|
+
...pendingCoordinatorEvents.length > 0 ? { pendingCoordinatorEvents } : {},
|
|
77921
|
+
...unroutableDeliveries.length > 0 ? { unroutableDeliveries } : {},
|
|
77922
|
+
activeRefineJobs: Array.from(ctx.runningRefineJobs.values()).filter((job) => job.meshId === meshId).map((job) => ({
|
|
77923
|
+
jobId: job.jobId,
|
|
77924
|
+
nodeId: job.targetNodeId,
|
|
77925
|
+
workspace: job.workspace,
|
|
77926
|
+
startedAt: job.startedAt,
|
|
77927
|
+
status: job.status,
|
|
77928
|
+
targetCoordinatorDaemonId: job.targetCoordinatorDaemonId
|
|
77929
|
+
}))
|
|
77930
|
+
};
|
|
77931
|
+
const { pendingCoordinatorEvents: _pendingCoordinatorEvents, unroutableDeliveries: _unroutableDeliveries, ...cacheableStatusResult } = statusResult;
|
|
77932
|
+
const rememberedStatus = verboseMissions ? cacheableStatusResult : ctx.rememberAggregateMeshStatus(meshId, cacheableStatusResult, refreshReason);
|
|
77933
|
+
const returnedStatus = {
|
|
77934
|
+
...rememberedStatus,
|
|
77935
|
+
...pendingCoordinatorEvents.length > 0 ? { pendingCoordinatorEvents } : {},
|
|
77936
|
+
...unroutableDeliveries.length > 0 ? { unroutableDeliveries } : {}
|
|
77937
|
+
};
|
|
77938
|
+
logRepoMeshStatusDebug("return_live", {
|
|
77939
|
+
meshId,
|
|
77940
|
+
command: "mesh_status",
|
|
77941
|
+
refreshRequested,
|
|
77942
|
+
refreshReason,
|
|
77943
|
+
meshSource: meshRecord.source,
|
|
77944
|
+
directTruth,
|
|
77945
|
+
summary: summarizeRepoMeshStatusDebug(returnedStatus)
|
|
77946
|
+
});
|
|
77947
|
+
return returnedStatus;
|
|
77948
|
+
} catch (e) {
|
|
77949
|
+
return { success: false, error: e.message };
|
|
77950
|
+
}
|
|
77951
|
+
},
|
|
77952
|
+
get_mesh_review_inbox: async (ctx, args) => {
|
|
77953
|
+
const meshId = typeof args?.meshId === "string" ? args.meshId.trim() : "";
|
|
77954
|
+
if (!meshId) return { success: false, error: "meshId required" };
|
|
77955
|
+
try {
|
|
77956
|
+
const { deriveMeshReviewInboxItems: deriveMeshReviewInboxItems2 } = await Promise.resolve().then(() => (init_mesh_review_inbox(), mesh_review_inbox_exports));
|
|
77957
|
+
const { readLedgerEntries: readLedgerEntries2 } = await Promise.resolve().then(() => (init_mesh_ledger(), mesh_ledger_exports));
|
|
77958
|
+
const { getGitDiffSummary: getGitDiffSummary2 } = await Promise.resolve().then(() => (init_git_diff(), git_diff_exports));
|
|
77959
|
+
const { existsSync: existsSync49 } = await import("fs");
|
|
77960
|
+
const meshRecord = await ctx.getMeshForCommand(meshId, args?.inlineMesh, { preferInline: true });
|
|
77961
|
+
const mesh = meshRecord?.mesh;
|
|
77962
|
+
if (!mesh) return { success: false, error: "Mesh not found" };
|
|
77963
|
+
const inlineNodes = args?.inlineMesh && Array.isArray(args.inlineMesh?.nodes) ? args.inlineMesh.nodes : null;
|
|
77964
|
+
let cachedStatus = !inlineNodes ? ctx.getCachedAggregateMeshStatus(meshId, mesh, {}) : null;
|
|
77965
|
+
if (!cachedStatus && !inlineNodes) {
|
|
77966
|
+
const freshStatus = await ctx.execute("mesh_status", {
|
|
77967
|
+
meshId,
|
|
77968
|
+
inlineMesh: args?.inlineMesh,
|
|
77969
|
+
refresh: true
|
|
77970
|
+
}, "get_mesh_review_inbox");
|
|
77971
|
+
cachedStatus = freshStatus?.success !== false ? freshStatus : null;
|
|
77972
|
+
}
|
|
77973
|
+
const nodeStatuses = inlineNodes ? inlineNodes : Array.isArray(cachedStatus?.nodes) ? cachedStatus.nodes : Array.isArray(mesh.nodes) ? mesh.nodes : [];
|
|
77974
|
+
const ledgerEntries = readLedgerEntries2(meshId, { tail: 300 });
|
|
77975
|
+
const derivation = deriveMeshReviewInboxItems2({ nodes: nodeStatuses, ledgerEntries });
|
|
77976
|
+
for (const item of derivation.items) {
|
|
77977
|
+
const workspace = item.workspace;
|
|
77978
|
+
if (!workspace || !existsSync49(workspace)) continue;
|
|
77979
|
+
const baseRef = item.defaultBranch ? `origin/${item.defaultBranch}` : "origin/main";
|
|
77980
|
+
try {
|
|
77981
|
+
const diffResult = await getGitDiffSummary2(workspace, { baseRef, maxFiles: 100 });
|
|
77982
|
+
if (diffResult.isGitRepo) {
|
|
77983
|
+
item.diffSummary = {
|
|
77984
|
+
baseRef,
|
|
77985
|
+
files: diffResult.files.map((f) => ({
|
|
77986
|
+
path: f.path,
|
|
77987
|
+
status: f.status,
|
|
77988
|
+
insertions: f.insertions,
|
|
77989
|
+
deletions: f.deletions,
|
|
77990
|
+
binary: f.binary,
|
|
77991
|
+
oldPath: f.oldPath
|
|
77992
|
+
})),
|
|
77993
|
+
totalFiles: diffResult.files.length,
|
|
77994
|
+
totalInsertions: diffResult.totalInsertions,
|
|
77995
|
+
totalDeletions: diffResult.totalDeletions,
|
|
77996
|
+
truncated: diffResult.truncated,
|
|
77997
|
+
...diffResult.error ? { error: diffResult.error } : {}
|
|
77998
|
+
};
|
|
77999
|
+
}
|
|
78000
|
+
} catch {
|
|
78001
|
+
item.diffSummary = null;
|
|
78002
|
+
}
|
|
78003
|
+
}
|
|
78004
|
+
return {
|
|
78005
|
+
success: true,
|
|
78006
|
+
meshId,
|
|
78007
|
+
inbox: derivation.items,
|
|
78008
|
+
remoteNodesExcluded: derivation.remoteNodesExcluded,
|
|
78009
|
+
excludedRemoteNodeIds: derivation.excludedRemoteNodeIds
|
|
78010
|
+
};
|
|
78011
|
+
} catch (e) {
|
|
78012
|
+
return { success: false, error: e.message };
|
|
78013
|
+
}
|
|
78014
|
+
}
|
|
78015
|
+
};
|
|
78016
|
+
var highFamilyRegistry = new Map(
|
|
78017
|
+
Object.entries({
|
|
78018
|
+
...meshEventsHandlers,
|
|
78019
|
+
...meshCoordinatorLaunchHandlers,
|
|
78020
|
+
...meshStatusHandlers
|
|
78021
|
+
})
|
|
78022
|
+
);
|
|
76975
78023
|
init_cli_detector();
|
|
76976
78024
|
init_git_status();
|
|
76977
78025
|
init_dist();
|
|
76978
78026
|
init_logger();
|
|
76979
|
-
var
|
|
78027
|
+
var fs28 = __toESM2(require("fs"));
|
|
76980
78028
|
var path36 = __toESM2(require("path"));
|
|
76981
78029
|
var os27 = __toESM2(require("os"));
|
|
76982
78030
|
var ADHDEV_HOME2 = process.env.ADHDEV_CONFIG_DIR && process.env.ADHDEV_CONFIG_DIR.trim() ? process.env.ADHDEV_CONFIG_DIR.trim() : path36.join(os27.homedir(), ".adhdev");
|
|
@@ -76984,7 +78032,7 @@ ${formatManifestValidationIssues2(validation2.issues)}`);
|
|
|
76984
78032
|
var MAX_FILE_SIZE = 5 * 1024 * 1024;
|
|
76985
78033
|
var MAX_DAYS = 7;
|
|
76986
78034
|
try {
|
|
76987
|
-
|
|
78035
|
+
fs28.mkdirSync(LOG_DIR2, { recursive: true });
|
|
76988
78036
|
} catch {
|
|
76989
78037
|
}
|
|
76990
78038
|
var SENSITIVE_KEYS = /* @__PURE__ */ new Set([
|
|
@@ -77030,7 +78078,7 @@ ${formatManifestValidationIssues2(validation2.issues)}`);
|
|
|
77030
78078
|
}
|
|
77031
78079
|
function cleanOldFiles() {
|
|
77032
78080
|
try {
|
|
77033
|
-
const files =
|
|
78081
|
+
const files = fs28.readdirSync(LOG_DIR2).filter((f) => f.startsWith("commands-") && f.endsWith(".jsonl"));
|
|
77034
78082
|
const cutoff = /* @__PURE__ */ new Date();
|
|
77035
78083
|
cutoff.setDate(cutoff.getDate() - MAX_DAYS);
|
|
77036
78084
|
const cutoffStr = cutoff.toISOString().slice(0, 10);
|
|
@@ -77038,7 +78086,7 @@ ${formatManifestValidationIssues2(validation2.issues)}`);
|
|
|
77038
78086
|
const dateMatch = file2.match(/commands-(\d{4}-\d{2}-\d{2})/);
|
|
77039
78087
|
if (dateMatch && dateMatch[1] < cutoffStr) {
|
|
77040
78088
|
try {
|
|
77041
|
-
|
|
78089
|
+
fs28.unlinkSync(path36.join(LOG_DIR2, file2));
|
|
77042
78090
|
} catch {
|
|
77043
78091
|
}
|
|
77044
78092
|
}
|
|
@@ -77048,14 +78096,14 @@ ${formatManifestValidationIssues2(validation2.issues)}`);
|
|
|
77048
78096
|
}
|
|
77049
78097
|
function checkSize() {
|
|
77050
78098
|
try {
|
|
77051
|
-
const stat2 =
|
|
78099
|
+
const stat2 = fs28.statSync(currentFile);
|
|
77052
78100
|
if (stat2.size > MAX_FILE_SIZE) {
|
|
77053
78101
|
const backup = currentFile.replace(".jsonl", ".1.jsonl");
|
|
77054
78102
|
try {
|
|
77055
|
-
|
|
78103
|
+
fs28.unlinkSync(backup);
|
|
77056
78104
|
} catch {
|
|
77057
78105
|
}
|
|
77058
|
-
|
|
78106
|
+
fs28.renameSync(currentFile, backup);
|
|
77059
78107
|
}
|
|
77060
78108
|
} catch {
|
|
77061
78109
|
}
|
|
@@ -77088,14 +78136,14 @@ ${formatManifestValidationIssues2(validation2.issues)}`);
|
|
|
77088
78136
|
...entry.error ? { err: entry.error } : {},
|
|
77089
78137
|
...entry.durationMs !== void 0 ? { ms: entry.durationMs } : {}
|
|
77090
78138
|
});
|
|
77091
|
-
|
|
78139
|
+
fs28.appendFileSync(currentFile, line + "\n");
|
|
77092
78140
|
} catch {
|
|
77093
78141
|
}
|
|
77094
78142
|
}
|
|
77095
78143
|
function getRecentCommands(count = 50) {
|
|
77096
78144
|
try {
|
|
77097
|
-
if (!
|
|
77098
|
-
const content =
|
|
78145
|
+
if (!fs28.existsSync(currentFile)) return [];
|
|
78146
|
+
const content = fs28.readFileSync(currentFile, "utf-8");
|
|
77099
78147
|
const lines = content.trim().split("\n").filter(Boolean);
|
|
77100
78148
|
return lines.slice(-count).map((line) => {
|
|
77101
78149
|
try {
|
|
@@ -77120,14 +78168,11 @@ ${formatManifestValidationIssues2(validation2.issues)}`);
|
|
|
77120
78168
|
}
|
|
77121
78169
|
cleanOldFiles();
|
|
77122
78170
|
var yaml4 = __toESM2(require_js_yaml());
|
|
77123
|
-
init_mesh_coordinator();
|
|
77124
|
-
init_coordinator_registry();
|
|
77125
78171
|
init_mesh_events();
|
|
77126
|
-
init_mesh_routing();
|
|
77127
78172
|
init_mesh_host_ownership();
|
|
77128
|
-
var
|
|
78173
|
+
var import_node_child_process5 = require("child_process");
|
|
77129
78174
|
var import_node_util4 = require("util");
|
|
77130
|
-
var execFileAsync3 = (0, import_node_util4.promisify)(
|
|
78175
|
+
var execFileAsync3 = (0, import_node_util4.promisify)(import_node_child_process5.execFile);
|
|
77131
78176
|
var MAX_CHANGED_FILES2 = 500;
|
|
77132
78177
|
function topLevel(path422) {
|
|
77133
78178
|
const slash = path422.indexOf("/");
|
|
@@ -77210,92 +78255,11 @@ ${formatManifestValidationIssues2(validation2.issues)}`);
|
|
|
77210
78255
|
}
|
|
77211
78256
|
return { order: ranked.map((a) => a.nodeId), changeAreas: areaById, rationale };
|
|
77212
78257
|
}
|
|
77213
|
-
var import_node_child_process5 = require("child_process");
|
|
77214
|
-
var import_node_fs4 = require("fs");
|
|
77215
|
-
var import_node_path2 = require("path");
|
|
77216
|
-
var PREVIEW_DEPLOY_RECORD = ".adhdev/preview-deploy.json";
|
|
77217
|
-
function runGit2(repoRoot, args) {
|
|
77218
|
-
try {
|
|
77219
|
-
return (0, import_node_child_process5.execFileSync)("git", args, {
|
|
77220
|
-
cwd: repoRoot,
|
|
77221
|
-
encoding: "utf8",
|
|
77222
|
-
stdio: ["ignore", "pipe", "ignore"],
|
|
77223
|
-
timeout: 5e3
|
|
77224
|
-
}).trim();
|
|
77225
|
-
} catch {
|
|
77226
|
-
return "";
|
|
77227
|
-
}
|
|
77228
|
-
}
|
|
77229
|
-
function readRecord5(repoRoot) {
|
|
77230
|
-
const path422 = (0, import_node_path2.resolve)(repoRoot, PREVIEW_DEPLOY_RECORD);
|
|
77231
|
-
if (!(0, import_node_fs4.existsSync)(path422)) return null;
|
|
77232
|
-
try {
|
|
77233
|
-
const parsed = JSON.parse((0, import_node_fs4.readFileSync)(path422, "utf8"));
|
|
77234
|
-
return parsed && typeof parsed === "object" && !Array.isArray(parsed) ? parsed : null;
|
|
77235
|
-
} catch {
|
|
77236
|
-
return null;
|
|
77237
|
-
}
|
|
77238
|
-
}
|
|
77239
|
-
function normalizeCommit(value) {
|
|
77240
|
-
return typeof value === "string" && /^[0-9a-f]{7,40}$/i.test(value.trim()) ? value.trim() : null;
|
|
77241
|
-
}
|
|
77242
|
-
function readTargetFreshness(record2, currentCommit) {
|
|
77243
|
-
const targets = record2?.targets && typeof record2.targets === "object" && !Array.isArray(record2.targets) ? record2.targets : {};
|
|
77244
|
-
const result = {};
|
|
77245
|
-
for (const targetName of ["npm", "server", "web"]) {
|
|
77246
|
-
const targetRecord = targets[targetName] && typeof targets[targetName] === "object" && !Array.isArray(targets[targetName]) ? targets[targetName] : {};
|
|
77247
|
-
const commit = normalizeCommit(targetRecord.commit);
|
|
77248
|
-
result[targetName] = {
|
|
77249
|
-
commit,
|
|
77250
|
-
deployedAt: typeof targetRecord.deployedAt === "string" ? targetRecord.deployedAt : void 0,
|
|
77251
|
-
status: commit && currentCommit ? commit === currentCommit ? "fresh" : "stale" : "unknown"
|
|
77252
|
-
};
|
|
77253
|
-
}
|
|
77254
|
-
return result;
|
|
77255
|
-
}
|
|
77256
|
-
function readCurrentMainCommit(repoRoot) {
|
|
77257
|
-
const originMain = runGit2(repoRoot, ["rev-parse", "--verify", "origin/main^{commit}"]);
|
|
77258
|
-
if (originMain) {
|
|
77259
|
-
return { currentMainCommit: originMain, currentMainCommitSource: "origin/main" };
|
|
77260
|
-
}
|
|
77261
|
-
const head = runGit2(repoRoot, ["rev-parse", "--verify", "HEAD"]);
|
|
77262
|
-
if (head) {
|
|
77263
|
-
return { currentMainCommit: head, currentMainCommitSource: "HEAD" };
|
|
77264
|
-
}
|
|
77265
|
-
return { currentMainCommit: null, currentMainCommitSource: "unknown" };
|
|
77266
|
-
}
|
|
77267
|
-
function buildPreviewFreshness(repoRoot) {
|
|
77268
|
-
const current = readCurrentMainCommit(repoRoot);
|
|
77269
|
-
const record2 = readRecord5(repoRoot);
|
|
77270
|
-
const lastPreviewCommit = normalizeCommit(record2?.lastPreviewCommit);
|
|
77271
|
-
const targets = readTargetFreshness(record2, current.currentMainCommit);
|
|
77272
|
-
let status = "unknown";
|
|
77273
|
-
let nextAction = "Run npm run deploy:preview from the current main commit, then smoke preview.";
|
|
77274
|
-
if (lastPreviewCommit && current.currentMainCommit) {
|
|
77275
|
-
status = lastPreviewCommit === current.currentMainCommit ? "fresh" : "stale";
|
|
77276
|
-
nextAction = status === "fresh" ? "No preview deploy action needed." : "Run npm run deploy:preview from origin/main, then smoke preview.";
|
|
77277
|
-
} else if (!current.currentMainCommit) {
|
|
77278
|
-
nextAction = "Resolve the current main commit before judging preview freshness.";
|
|
77279
|
-
}
|
|
77280
|
-
return {
|
|
77281
|
-
status,
|
|
77282
|
-
lastPreviewCommit,
|
|
77283
|
-
currentMainCommit: current.currentMainCommit,
|
|
77284
|
-
currentMainCommitSource: current.currentMainCommitSource,
|
|
77285
|
-
recordPath: PREVIEW_DEPLOY_RECORD,
|
|
77286
|
-
lastDeployedAt: typeof record2?.updatedAt === "string" ? record2.updatedAt : void 0,
|
|
77287
|
-
lastTarget: typeof record2?.target === "string" ? record2.target : void 0,
|
|
77288
|
-
previewVersion: typeof record2?.previewVersion === "string" ? record2.previewVersion : void 0,
|
|
77289
|
-
targets,
|
|
77290
|
-
nextAction
|
|
77291
|
-
};
|
|
77292
|
-
}
|
|
77293
|
-
init_mesh_refine_status();
|
|
77294
78258
|
init_mesh_work_queue();
|
|
77295
78259
|
init_repo_mesh_types();
|
|
77296
|
-
var
|
|
77297
|
-
var
|
|
77298
|
-
var
|
|
78260
|
+
var import_os4 = require("os");
|
|
78261
|
+
var import_path13 = require("path");
|
|
78262
|
+
var fs29 = __toESM2(require("fs"));
|
|
77299
78263
|
var import_node_child_process6 = require("child_process");
|
|
77300
78264
|
init_resolve_executable();
|
|
77301
78265
|
function readProviderPriorityFromPolicy(policy) {
|
|
@@ -77643,7 +78607,7 @@ ${formatManifestValidationIssues2(validation2.issues)}`);
|
|
|
77643
78607
|
if (node?.isLocalWorktree !== true) return false;
|
|
77644
78608
|
const workspace = readStringValue(node?.workspace);
|
|
77645
78609
|
if (!workspace) return false;
|
|
77646
|
-
return !
|
|
78610
|
+
return !fs29.existsSync(workspace);
|
|
77647
78611
|
}
|
|
77648
78612
|
function foldMeshNodeIdentityToCanonical(node) {
|
|
77649
78613
|
if (!node || typeof node !== "object" || Array.isArray(node)) return node;
|
|
@@ -77891,7 +78855,7 @@ ${formatManifestValidationIssues2(validation2.issues)}`);
|
|
|
77891
78855
|
const followUps = nodes.filter((node) => {
|
|
77892
78856
|
if (readObjectRecord(node.branchConvergence).needsConvergence !== true) return false;
|
|
77893
78857
|
const workspace = typeof node.workspace === "string" ? node.workspace : "";
|
|
77894
|
-
if (workspace && !
|
|
78858
|
+
if (workspace && !fs29.existsSync(workspace)) return false;
|
|
77895
78859
|
return true;
|
|
77896
78860
|
}).map((node) => {
|
|
77897
78861
|
const convergence = readObjectRecord(node.branchConvergence);
|
|
@@ -78199,7 +79163,7 @@ ${formatManifestValidationIssues2(validation2.issues)}`);
|
|
|
78199
79163
|
if (!isSelfNode && daemonId) unavailableNodeIds.push(nodeId);
|
|
78200
79164
|
continue;
|
|
78201
79165
|
}
|
|
78202
|
-
if (
|
|
79166
|
+
if (fs29.existsSync(workspace)) {
|
|
78203
79167
|
try {
|
|
78204
79168
|
const localGit = await getGitRepoStatus(workspace, { timeoutMs: 1e4, refreshUpstream: true });
|
|
78205
79169
|
if (localGit?.isGitRepo) {
|
|
@@ -78307,7 +79271,7 @@ ${formatManifestValidationIssues2(validation2.issues)}`);
|
|
|
78307
79271
|
}
|
|
78308
79272
|
function collectLiveMeshSessionRecords(args) {
|
|
78309
79273
|
const nodeWorkspace = readStringValue(args.node?.workspace);
|
|
78310
|
-
const nodeIsMissingLocalWorktree = args.node?.isLocalWorktree === true && !!nodeWorkspace && !
|
|
79274
|
+
const nodeIsMissingLocalWorktree = args.node?.isLocalWorktree === true && !!nodeWorkspace && !fs29.existsSync(nodeWorkspace);
|
|
78311
79275
|
const matches = args.liveSessionRecords.filter((record2) => {
|
|
78312
79276
|
const recordNodeId = readStringValue(record2?.meta?.meshNodeId);
|
|
78313
79277
|
if (recordNodeId && recordNodeId !== args.nodeId) return false;
|
|
@@ -78334,7 +79298,7 @@ ${formatManifestValidationIssues2(validation2.issues)}`);
|
|
|
78334
79298
|
const workspace = readStringValue(node?.workspace);
|
|
78335
79299
|
if (nodeId) liveNodeIds.add(nodeId);
|
|
78336
79300
|
if (workspace) liveWorkspaces.add(workspace);
|
|
78337
|
-
if (nodeId && node?.isLocalWorktree === true && workspace && !
|
|
79301
|
+
if (nodeId && node?.isLocalWorktree === true && workspace && !fs29.existsSync(workspace)) {
|
|
78338
79302
|
missingLocalWorktreeNodeIds.add(nodeId);
|
|
78339
79303
|
}
|
|
78340
79304
|
}
|
|
@@ -78770,7 +79734,7 @@ ${mergeTreeErr?.stderr || ""}`;
|
|
|
78770
79734
|
if (!baseCommit || !branchCommit) return false;
|
|
78771
79735
|
if (baseCommit === branchCommit) return true;
|
|
78772
79736
|
try {
|
|
78773
|
-
if (!
|
|
79737
|
+
if (!fs29.existsSync(submoduleRepoPath)) return false;
|
|
78774
79738
|
(0, import_node_child_process6.execFileSync)("git", ["cat-file", "-e", `${baseCommit}^{commit}`], { cwd: submoduleRepoPath, stdio: "ignore" });
|
|
78775
79739
|
(0, import_node_child_process6.execFileSync)("git", ["cat-file", "-e", `${branchCommit}^{commit}`], { cwd: submoduleRepoPath, stdio: "ignore" });
|
|
78776
79740
|
(0, import_node_child_process6.execFileSync)("git", ["merge-base", "--is-ancestor", baseCommit, branchCommit], { cwd: submoduleRepoPath, stdio: "ignore" });
|
|
@@ -78809,14 +79773,14 @@ ${mergeTreeErr?.stderr || ""}`;
|
|
|
78809
79773
|
const baseCommit = readTreeObject(repoRoot, baseHead, path422);
|
|
78810
79774
|
const branchCommit = readTreeObject(repoRoot, branchHead, path422);
|
|
78811
79775
|
if (!baseCommit || !branchCommit) return false;
|
|
78812
|
-
return isSubmoduleFastForward((0,
|
|
79776
|
+
return isSubmoduleFastForward((0, import_path13.resolve)(repoRoot, path422), baseCommit, branchCommit);
|
|
78813
79777
|
});
|
|
78814
79778
|
}
|
|
78815
79779
|
function evaluateGitlinkTrivialFastForward(repoRoot, baseHead, branchHead) {
|
|
78816
79780
|
const changedGitlinks = readChangedGitlinkPaths(repoRoot, baseHead, branchHead).map((path422) => {
|
|
78817
79781
|
const baseCommit = readTreeObject(repoRoot, baseHead, path422);
|
|
78818
79782
|
const branchCommit = readTreeObject(repoRoot, branchHead, path422);
|
|
78819
|
-
const submoduleRepoPath = (0,
|
|
79783
|
+
const submoduleRepoPath = (0, import_path13.resolve)(repoRoot, path422);
|
|
78820
79784
|
const fastForward = !!baseCommit && !!branchCommit && isSubmoduleFastForward(submoduleRepoPath, baseCommit, branchCommit);
|
|
78821
79785
|
return { path: path422, baseCommit, branchCommit, fastForward };
|
|
78822
79786
|
});
|
|
@@ -78871,7 +79835,7 @@ ${mergeTreeErr?.stderr || ""}`;
|
|
|
78871
79835
|
if (!tree) return void 0;
|
|
78872
79836
|
const updates = paths.map((path422) => `160000 commit ${placeholderCommit} ${path422}`).join("\n");
|
|
78873
79837
|
if (!updates) return tree;
|
|
78874
|
-
const tmpIndex = (0,
|
|
79838
|
+
const tmpIndex = (0, import_path13.join)(resolveGitDir(repoRoot), `adhdev-refine-eq-${commitish.slice(0, 12)}.index`);
|
|
78875
79839
|
const env2 = { ...process.env, GIT_INDEX_FILE: tmpIndex };
|
|
78876
79840
|
try {
|
|
78877
79841
|
(0, import_node_child_process6.execFileSync)("git", ["read-tree", tree], { cwd: repoRoot, env: env2, stdio: "ignore" });
|
|
@@ -78887,7 +79851,7 @@ ${mergeTreeErr?.stderr || ""}`;
|
|
|
78887
79851
|
return newTree || void 0;
|
|
78888
79852
|
} finally {
|
|
78889
79853
|
try {
|
|
78890
|
-
|
|
79854
|
+
fs29.rmSync(tmpIndex, { force: true });
|
|
78891
79855
|
} catch {
|
|
78892
79856
|
}
|
|
78893
79857
|
}
|
|
@@ -78946,7 +79910,7 @@ ${mergeTreeErr?.stderr || ""}`;
|
|
|
78946
79910
|
if (!contentTree) return void 0;
|
|
78947
79911
|
const updates = branchGitlinks.map((entry) => `160000 commit ${entry.branchCommit} ${entry.path}`).join("\n");
|
|
78948
79912
|
if (!updates) return contentTree;
|
|
78949
|
-
const tmpIndex = (0,
|
|
79913
|
+
const tmpIndex = (0, import_path13.join)(resolveGitDir(repoRoot), `adhdev-refine-ff-${baseHead.slice(0, 12)}-${branchHead.slice(0, 12)}.index`);
|
|
78950
79914
|
const env2 = { ...process.env, GIT_INDEX_FILE: tmpIndex };
|
|
78951
79915
|
try {
|
|
78952
79916
|
(0, import_node_child_process6.execFileSync)("git", ["read-tree", contentTree], { cwd: repoRoot, env: env2, stdio: "ignore" });
|
|
@@ -78962,7 +79926,7 @@ ${mergeTreeErr?.stderr || ""}`;
|
|
|
78962
79926
|
return newTree || void 0;
|
|
78963
79927
|
} finally {
|
|
78964
79928
|
try {
|
|
78965
|
-
|
|
79929
|
+
fs29.rmSync(tmpIndex, { force: true });
|
|
78966
79930
|
} catch {
|
|
78967
79931
|
}
|
|
78968
79932
|
}
|
|
@@ -79068,7 +80032,7 @@ ${mergeTreeErr?.stderr || ""}`;
|
|
|
79068
80032
|
return { stdout: String(stdout || ""), stderr: String(stderr || ""), refspec };
|
|
79069
80033
|
};
|
|
79070
80034
|
const importCommitFromWorktreeSubmodule = async (submodulePath, worktreeSubmodulePath, commit) => {
|
|
79071
|
-
if (!
|
|
80035
|
+
if (!fs29.existsSync(worktreeSubmodulePath)) return false;
|
|
79072
80036
|
try {
|
|
79073
80037
|
await runGit3(worktreeSubmodulePath, ["cat-file", "-e", `${commit}^{commit}`]);
|
|
79074
80038
|
} catch {
|
|
@@ -79084,14 +80048,14 @@ ${mergeTreeErr?.stderr || ""}`;
|
|
|
79084
80048
|
return match ? { commit: match[1], path: match[2] } : null;
|
|
79085
80049
|
}).filter((entry) => !!entry);
|
|
79086
80050
|
for (const gitlink of gitlinks) {
|
|
79087
|
-
const submodulePath = (0,
|
|
80051
|
+
const submodulePath = (0, import_path13.resolve)(repoRoot, gitlink.path);
|
|
79088
80052
|
const entry = {
|
|
79089
80053
|
path: gitlink.path,
|
|
79090
80054
|
commit: gitlink.commit,
|
|
79091
80055
|
reachable: false
|
|
79092
80056
|
};
|
|
79093
80057
|
try {
|
|
79094
|
-
if (!
|
|
80058
|
+
if (!fs29.existsSync(submodulePath)) {
|
|
79095
80059
|
entry.error = `Submodule checkout missing at ${gitlink.path}`;
|
|
79096
80060
|
entry.publishRequired = true;
|
|
79097
80061
|
if (options.allowAutoPublishSubmoduleMainCommits === true) {
|
|
@@ -79112,7 +80076,7 @@ ${mergeTreeErr?.stderr || ""}`;
|
|
|
79112
80076
|
try {
|
|
79113
80077
|
const imported = await importCommitFromWorktreeSubmodule(
|
|
79114
80078
|
submodulePath,
|
|
79115
|
-
(0,
|
|
80079
|
+
(0, import_path13.resolve)(options.worktreeRoot, gitlink.path),
|
|
79116
80080
|
gitlink.commit
|
|
79117
80081
|
);
|
|
79118
80082
|
if (imported) {
|
|
@@ -79324,19 +80288,19 @@ ${mergeTreeErr?.stderr || ""}`;
|
|
|
79324
80288
|
...extras
|
|
79325
80289
|
});
|
|
79326
80290
|
const isPackageManagerValidation = (candidate) => {
|
|
79327
|
-
const command = (0,
|
|
80291
|
+
const command = (0, import_path13.basename)(candidate.command).replace(/\.(?:cmd|exe)$/i, "");
|
|
79328
80292
|
return ["npm", "pnpm", "yarn", "bun"].includes(command) && candidate.args.some((arg) => arg === "run" || arg === "test" || arg === "exec");
|
|
79329
80293
|
};
|
|
79330
80294
|
const dependenciesLikelyMissing = (cwd) => {
|
|
79331
|
-
if (!
|
|
79332
|
-
if (
|
|
79333
|
-
return ["package-lock.json", "npm-shrinkwrap.json", "pnpm-lock.yaml", "yarn.lock", "bun.lockb", "bun.lock"].some((lock) =>
|
|
80295
|
+
if (!fs29.existsSync((0, import_path13.join)(cwd, "package.json"))) return false;
|
|
80296
|
+
if (fs29.existsSync((0, import_path13.join)(cwd, "node_modules"))) return false;
|
|
80297
|
+
return ["package-lock.json", "npm-shrinkwrap.json", "pnpm-lock.yaml", "yarn.lock", "bun.lockb", "bun.lock"].some((lock) => fs29.existsSync((0, import_path13.join)(cwd, lock)));
|
|
79334
80298
|
};
|
|
79335
80299
|
if (runLegacyBootstrapCommands) {
|
|
79336
80300
|
summary.bootstrap = { stage: "legacy" };
|
|
79337
80301
|
for (const candidate of selection.bootstrapCommands) {
|
|
79338
80302
|
const startedAt = Date.now();
|
|
79339
|
-
const cwd = candidate.cwd ? (0,
|
|
80303
|
+
const cwd = candidate.cwd ? (0, import_path13.resolve)(workspace, candidate.cwd) : workspace;
|
|
79340
80304
|
const timeout = candidate.timeoutMs || REFINE_VALIDATION_TIMEOUT_MS;
|
|
79341
80305
|
const resolvedCommand = resolveWin32Executable(candidate.command);
|
|
79342
80306
|
try {
|
|
@@ -79366,7 +80330,7 @@ ${mergeTreeErr?.stderr || ""}`;
|
|
|
79366
80330
|
}
|
|
79367
80331
|
for (const candidate of selection.commands) {
|
|
79368
80332
|
const startedAt = Date.now();
|
|
79369
|
-
const cwd = candidate.cwd ? (0,
|
|
80333
|
+
const cwd = candidate.cwd ? (0, import_path13.resolve)(workspace, candidate.cwd) : workspace;
|
|
79370
80334
|
const timeout = candidate.timeoutMs || REFINE_VALIDATION_TIMEOUT_MS;
|
|
79371
80335
|
const bootstrapProvidedDependencies = summary.bootstrap?.stage === "cached" || summary.bootstrap?.stage === "ran" || summary.bootstrap?.stage === "legacy";
|
|
79372
80336
|
if (!bootstrapProvidedDependencies && isPackageManagerValidation(candidate) && dependenciesLikelyMissing(cwd)) {
|
|
@@ -79435,14 +80399,14 @@ ${mergeTreeErr?.stderr || ""}`;
|
|
|
79435
80399
|
}
|
|
79436
80400
|
function resolveHermesUserHome() {
|
|
79437
80401
|
const explicitHome = process.env.HERMES_HOME?.trim();
|
|
79438
|
-
return explicitHome || (0,
|
|
80402
|
+
return explicitHome || (0, import_path13.join)((0, import_os4.homedir)(), ".hermes");
|
|
79439
80403
|
}
|
|
79440
80404
|
function loadHermesCoordinatorBaseConfig(targetConfigPath) {
|
|
79441
80405
|
const sourceHome = resolveHermesUserHome();
|
|
79442
|
-
const sourceConfigPath = (0,
|
|
79443
|
-
if (!
|
|
79444
|
-
if ((0,
|
|
79445
|
-
const parsed = parseMeshCoordinatorMcpConfig(
|
|
80406
|
+
const sourceConfigPath = (0, import_path13.join)(sourceHome, "config.yaml");
|
|
80407
|
+
if (!fs29.existsSync(sourceConfigPath)) return { config: {}, sourceHome, sourceConfigPath };
|
|
80408
|
+
if ((0, import_path13.resolve)(sourceConfigPath) === (0, import_path13.resolve)(targetConfigPath)) return { config: {}, sourceHome, sourceConfigPath };
|
|
80409
|
+
const parsed = parseMeshCoordinatorMcpConfig(fs29.readFileSync(sourceConfigPath, "utf-8"), "hermes_config_yaml");
|
|
79446
80410
|
const { mcp_servers: _mcpServers, ...baseConfig } = parsed;
|
|
79447
80411
|
return { config: baseConfig, sourceHome, sourceConfigPath };
|
|
79448
80412
|
}
|
|
@@ -79475,13 +80439,13 @@ ${mergeTreeErr?.stderr || ""}`;
|
|
|
79475
80439
|
return sanitized;
|
|
79476
80440
|
}
|
|
79477
80441
|
function copyHermesCoordinatorCredentialFiles(sourceHome, targetHome) {
|
|
79478
|
-
if ((0,
|
|
80442
|
+
if ((0, import_path13.resolve)(sourceHome) === (0, import_path13.resolve)(targetHome)) return;
|
|
79479
80443
|
for (const fileName of [".env", "auth.json"]) {
|
|
79480
|
-
const sourcePath = (0,
|
|
79481
|
-
const targetPath = (0,
|
|
79482
|
-
if (!
|
|
80444
|
+
const sourcePath = (0, import_path13.join)(sourceHome, fileName);
|
|
80445
|
+
const targetPath = (0, import_path13.join)(targetHome, fileName);
|
|
80446
|
+
if (!fs29.existsSync(sourcePath)) continue;
|
|
79483
80447
|
try {
|
|
79484
|
-
|
|
80448
|
+
fs29.copyFileSync(sourcePath, targetPath);
|
|
79485
80449
|
} catch (error48) {
|
|
79486
80450
|
LOG2.warn("MeshCoordinator", `Could not copy Hermes ${fileName} into isolated coordinator home: ${error48?.message || error48}`);
|
|
79487
80451
|
}
|
|
@@ -79873,6 +80837,29 @@ ${mergeTreeErr?.stderr || ""}`;
|
|
|
79873
80837
|
};
|
|
79874
80838
|
return ctx;
|
|
79875
80839
|
}
|
|
80840
|
+
/**
|
|
80841
|
+
* Build the HighFamilyContext handed to RF-ROUTER HIGH family handlers. Binds
|
|
80842
|
+
* the router-private collaborators those handlers need (mesh resolution, the
|
|
80843
|
+
* aggregate-status memory cache + its bound read/write helpers, the
|
|
80844
|
+
* running-refine-job table, inline-mesh + git-probe caches, and the router's
|
|
80845
|
+
* own `execute` for the get_mesh_review_inbox mesh_status re-entry). HIGH
|
|
80846
|
+
* handlers reach more router-owned state than MED, but the binding shape is
|
|
80847
|
+
* the same: bound methods + direct field references, none reachable from
|
|
80848
|
+
* `deps`.
|
|
80849
|
+
*/
|
|
80850
|
+
buildHighFamilyContext() {
|
|
80851
|
+
return {
|
|
80852
|
+
deps: this.deps,
|
|
80853
|
+
getMeshForCommand: this.getMeshForCommand.bind(this),
|
|
80854
|
+
getCachedAggregateMeshStatus: this.getCachedAggregateMeshStatus.bind(this),
|
|
80855
|
+
rememberAggregateMeshStatus: this.rememberAggregateMeshStatus.bind(this),
|
|
80856
|
+
execute: this.execute.bind(this),
|
|
80857
|
+
aggregateMeshStatusCache: this.aggregateMeshStatusCache,
|
|
80858
|
+
runningRefineJobs: this.runningRefineJobs,
|
|
80859
|
+
inlineMeshCache: this.inlineMeshCache,
|
|
80860
|
+
meshGitProbeCache: this.meshGitProbeCache
|
|
80861
|
+
};
|
|
80862
|
+
}
|
|
79876
80863
|
async requireMeshHostMutationOwner(meshId, inlineMesh, operation) {
|
|
79877
80864
|
const meshRecord = await this.getMeshForCommand(meshId, inlineMesh, { preferInline: true });
|
|
79878
80865
|
const mesh = meshRecord?.mesh;
|
|
@@ -79930,7 +80917,7 @@ ${mergeTreeErr?.stderr || ""}`;
|
|
|
79930
80917
|
const nodeId = readInlineMeshNodeId(node);
|
|
79931
80918
|
if (!nodeId || !tombstones.has(nodeId)) return true;
|
|
79932
80919
|
const workspace = readStringValue(node?.workspace);
|
|
79933
|
-
if (workspace &&
|
|
80920
|
+
if (workspace && fs29.existsSync(workspace)) {
|
|
79934
80921
|
tombstones.delete(nodeId);
|
|
79935
80922
|
return true;
|
|
79936
80923
|
}
|
|
@@ -79965,14 +80952,14 @@ ${mergeTreeErr?.stderr || ""}`;
|
|
|
79965
80952
|
* to give handles time to release, and reports whether residue remains.
|
|
79966
80953
|
*/
|
|
79967
80954
|
async bestEffortRemoveWorktreeDir(dir) {
|
|
79968
|
-
if (!dir || !
|
|
80955
|
+
if (!dir || !fs29.existsSync(dir)) return { removed: true, residue: false };
|
|
79969
80956
|
const sleep3 = (ms) => new Promise((resolve24) => setTimeout(resolve24, ms));
|
|
79970
80957
|
const ABSORB = /* @__PURE__ */ new Set(["EINVAL", "EPERM", "EBUSY", "ENOTEMPTY", "EACCES", "EMFILE", "ENFILE"]);
|
|
79971
80958
|
let lastErr;
|
|
79972
80959
|
for (let attempt = 0; attempt < 4; attempt++) {
|
|
79973
80960
|
try {
|
|
79974
|
-
|
|
79975
|
-
if (!
|
|
80961
|
+
fs29.rmSync(dir, { recursive: true, force: true, maxRetries: 3, retryDelay: 100 });
|
|
80962
|
+
if (!fs29.existsSync(dir)) return { removed: true, residue: false };
|
|
79976
80963
|
lastErr = new Error("directory still present after rmSync");
|
|
79977
80964
|
} catch (e) {
|
|
79978
80965
|
lastErr = e;
|
|
@@ -79983,7 +80970,7 @@ ${mergeTreeErr?.stderr || ""}`;
|
|
|
79983
80970
|
}
|
|
79984
80971
|
await sleep3(150 * (attempt + 1));
|
|
79985
80972
|
}
|
|
79986
|
-
return
|
|
80973
|
+
return fs29.existsSync(dir) ? { removed: false, residue: true, error: String(lastErr?.message || lastErr || "unknown rm error") } : { removed: true, residue: false };
|
|
79987
80974
|
}
|
|
79988
80975
|
async cleanupLocalWorktreeNode(args) {
|
|
79989
80976
|
const workspace = typeof args.node?.workspace === "string" ? args.node.workspace.trim() : "";
|
|
@@ -79995,13 +80982,13 @@ ${mergeTreeErr?.stderr || ""}`;
|
|
|
79995
80982
|
recoveryHint: "Inspect the mesh node record before removing it, or remove stale metadata manually only after confirming no managed worktree remains."
|
|
79996
80983
|
};
|
|
79997
80984
|
}
|
|
79998
|
-
const worktreeExists =
|
|
80985
|
+
const worktreeExists = fs29.existsSync(workspace);
|
|
79999
80986
|
const sourceNode = args.node?.clonedFromNodeId ? args.mesh?.nodes?.find((n) => meshNodeIdMatches(n, args.node.clonedFromNodeId)) : args.mesh?.nodes?.find((n) => !n.isLocalWorktree);
|
|
80000
80987
|
const repoRoot = typeof sourceNode?.repoRoot === "string" && sourceNode.repoRoot.trim() ? sourceNode.repoRoot.trim() : typeof sourceNode?.workspace === "string" && sourceNode.workspace.trim() ? sourceNode.workspace.trim() : "";
|
|
80001
80988
|
if (!worktreeExists) {
|
|
80002
80989
|
return { success: true, skipped: true, removedPath: workspace, repoRoot: repoRoot || void 0, reason: "worktree_path_missing" };
|
|
80003
80990
|
}
|
|
80004
|
-
if (!repoRoot || !
|
|
80991
|
+
if (!repoRoot || !fs29.existsSync(repoRoot)) {
|
|
80005
80992
|
return {
|
|
80006
80993
|
success: false,
|
|
80007
80994
|
code: "mesh_worktree_cleanup_missing_source_repo",
|
|
@@ -80019,9 +81006,9 @@ ${mergeTreeErr?.stderr || ""}`;
|
|
|
80019
81006
|
}
|
|
80020
81007
|
const { resolveWorktreePath: resolveWorktreePath2, listWorktrees: listWorktrees2, removeWorktree: removeWorktree2 } = await Promise.resolve().then(() => (init_git_worktree(), git_worktree_exports));
|
|
80021
81008
|
const normalizePath = (value) => {
|
|
80022
|
-
const resolved = (0,
|
|
81009
|
+
const resolved = (0, import_path13.resolve)(value);
|
|
80023
81010
|
try {
|
|
80024
|
-
return
|
|
81011
|
+
return fs29.realpathSync(resolved);
|
|
80025
81012
|
} catch {
|
|
80026
81013
|
return resolved;
|
|
80027
81014
|
}
|
|
@@ -80616,196 +81603,242 @@ ${mergeTreeErr?.stderr || ""}`;
|
|
|
80616
81603
|
LOG2.warn("Mesh", `[Refinery] resumePendingRefineJobsOnStartup failed: ${e?.message || e}`);
|
|
80617
81604
|
}
|
|
80618
81605
|
}
|
|
81606
|
+
/**
|
|
81607
|
+
* Synchronous refinery for a single worktree node — the gate pipeline that
|
|
81608
|
+
* validates, preflights (patch-equivalence / submodule-reachability /
|
|
81609
|
+
* no-op), merges, aligns submodules, cleans up the worktree node and
|
|
81610
|
+
* (optionally) pushes. The body is a flat sequence of stage methods; each
|
|
81611
|
+
* stage either returns a terminal CommandRouterResult (gate failure or a
|
|
81612
|
+
* successful already-merged short-circuit) or `continue` with the extended
|
|
81613
|
+
* context. Behavior — stage order, every early-exit, and every result shape —
|
|
81614
|
+
* is identical to the previous single inlined body.
|
|
81615
|
+
*/
|
|
80619
81616
|
async executeMeshRefineNodeSynchronously(meshId, nodeId, args) {
|
|
80620
81617
|
const refineStages = [];
|
|
80621
81618
|
try {
|
|
80622
|
-
const
|
|
80623
|
-
|
|
80624
|
-
const
|
|
80625
|
-
|
|
80626
|
-
if (
|
|
80627
|
-
|
|
80628
|
-
|
|
80629
|
-
const
|
|
80630
|
-
|
|
80631
|
-
|
|
80632
|
-
|
|
80633
|
-
const
|
|
80634
|
-
|
|
80635
|
-
|
|
80636
|
-
|
|
80637
|
-
|
|
80638
|
-
|
|
80639
|
-
|
|
80640
|
-
|
|
80641
|
-
|
|
80642
|
-
|
|
80643
|
-
|
|
80644
|
-
|
|
80645
|
-
|
|
80646
|
-
|
|
80647
|
-
|
|
80648
|
-
|
|
80649
|
-
|
|
80650
|
-
|
|
80651
|
-
|
|
80652
|
-
|
|
80653
|
-
|
|
80654
|
-
|
|
80655
|
-
|
|
80656
|
-
|
|
80657
|
-
|
|
80658
|
-
|
|
80659
|
-
|
|
80660
|
-
|
|
80661
|
-
|
|
80662
|
-
|
|
80663
|
-
|
|
80664
|
-
|
|
80665
|
-
|
|
80666
|
-
|
|
80667
|
-
|
|
80668
|
-
})
|
|
80669
|
-
|
|
81619
|
+
const resolved = await this.refineResolveRefsStage(meshId, nodeId, args, refineStages);
|
|
81620
|
+
if (resolved.kind === "terminal") return resolved.result;
|
|
81621
|
+
const ctx = resolved.ctx;
|
|
81622
|
+
const validation = await this.refineValidationStage(ctx);
|
|
81623
|
+
if (validation.kind === "terminal") return validation.result;
|
|
81624
|
+
const patchEquivalence = await this.refinePatchEquivalenceStage(ctx);
|
|
81625
|
+
if (patchEquivalence.kind === "terminal") return patchEquivalence.result;
|
|
81626
|
+
const submoduleReachability = await this.refineSubmoduleReachabilityStage(ctx);
|
|
81627
|
+
if (submoduleReachability.kind === "terminal") return submoduleReachability.result;
|
|
81628
|
+
const effectiveDiff = await this.refineEffectiveDiffStage(ctx);
|
|
81629
|
+
if (effectiveDiff.kind === "terminal") return effectiveDiff.result;
|
|
81630
|
+
const merge2 = await this.refineMergeAndFinalizeStage(ctx);
|
|
81631
|
+
return merge2.result;
|
|
81632
|
+
} catch (e) {
|
|
81633
|
+
return { success: false, error: e.message, refineStages };
|
|
81634
|
+
}
|
|
81635
|
+
}
|
|
81636
|
+
/**
|
|
81637
|
+
* resolve_refs stage: resolve the mesh / worktree node / source node /
|
|
81638
|
+
* repoRoot, then the worktree branch, base branch, fetched base head and
|
|
81639
|
+
* branch head. Seeds the RefineContext consumed by every later stage.
|
|
81640
|
+
*/
|
|
81641
|
+
async refineResolveRefsStage(meshId, nodeId, args, refineStages) {
|
|
81642
|
+
const meshRecord = await this.getMeshForCommand(meshId, args?.inlineMesh, { preferInline: true });
|
|
81643
|
+
const mesh = meshRecord?.mesh;
|
|
81644
|
+
const node = mesh?.nodes?.find((n) => meshNodeIdMatches(n, nodeId));
|
|
81645
|
+
if (!node) return { kind: "terminal", result: { success: false, error: `Node '${nodeId}' not found in mesh`, refineStages } };
|
|
81646
|
+
if (!node.isLocalWorktree || !node.workspace) {
|
|
81647
|
+
return { kind: "terminal", result: { success: false, error: `Refinery requires a local worktree node`, refineStages } };
|
|
81648
|
+
}
|
|
81649
|
+
const sourceNode = node.clonedFromNodeId ? mesh?.nodes.find((n) => meshNodeIdMatches(n, node.clonedFromNodeId)) : mesh?.nodes.find((n) => !n.isLocalWorktree);
|
|
81650
|
+
const repoRoot = sourceNode?.repoRoot || sourceNode?.workspace;
|
|
81651
|
+
if (!repoRoot) return { kind: "terminal", result: { success: false, error: "Source node repoRoot not found", refineStages } };
|
|
81652
|
+
const { execFile: execFile5 } = await import("child_process");
|
|
81653
|
+
const { promisify: promisify8 } = await import("util");
|
|
81654
|
+
const execFileAsync4 = promisify8(execFile5);
|
|
81655
|
+
const resolveStarted = Date.now();
|
|
81656
|
+
const { stdout: branchStdout } = await execFileAsync4("git", ["branch", "--show-current"], { cwd: node.workspace, encoding: "utf8" });
|
|
81657
|
+
const branch = branchStdout.trim();
|
|
81658
|
+
if (!branch) return { kind: "terminal", result: { success: false, error: "Could not determine branch of the worktree node", refineStages } };
|
|
81659
|
+
const { stdout: baseBranchStdout } = await execFileAsync4("git", ["branch", "--show-current"], { cwd: repoRoot, encoding: "utf8" });
|
|
81660
|
+
const baseBranch = baseBranchStdout.trim();
|
|
81661
|
+
let fetchWarning;
|
|
81662
|
+
try {
|
|
81663
|
+
await execFileAsync4("git", ["fetch", "origin", baseBranch], { cwd: repoRoot, encoding: "utf8" });
|
|
81664
|
+
} catch (e) {
|
|
81665
|
+
fetchWarning = `git fetch origin ${baseBranch} failed (proceeding with local HEAD): ${e?.message}`;
|
|
81666
|
+
}
|
|
81667
|
+
let baseHeadRaw;
|
|
81668
|
+
try {
|
|
81669
|
+
const { stdout } = await execFileAsync4("git", ["rev-parse", `origin/${baseBranch}`], { cwd: repoRoot, encoding: "utf8" });
|
|
81670
|
+
baseHeadRaw = stdout.trim();
|
|
81671
|
+
} catch {
|
|
81672
|
+
const { stdout: localHead } = await execFileAsync4("git", ["rev-parse", "HEAD"], { cwd: repoRoot, encoding: "utf8" });
|
|
81673
|
+
baseHeadRaw = localHead.trim();
|
|
81674
|
+
}
|
|
81675
|
+
const { stdout: branchHeadStdout } = await execFileAsync4("git", ["rev-parse", branch], { cwd: node.workspace, encoding: "utf8" });
|
|
81676
|
+
const baseHead = baseHeadRaw;
|
|
81677
|
+
const branchHead = branchHeadStdout.trim();
|
|
81678
|
+
recordMeshRefineStage(refineStages, "resolve_refs", "passed", resolveStarted, { branch, baseBranch, baseHead, branchHead, ...fetchWarning ? { fetchWarning } : {} });
|
|
81679
|
+
return {
|
|
81680
|
+
kind: "continue",
|
|
81681
|
+
ctx: {
|
|
81682
|
+
meshId,
|
|
81683
|
+
nodeId,
|
|
81684
|
+
args,
|
|
80670
81685
|
refineStages,
|
|
80671
|
-
|
|
80672
|
-
|
|
80673
|
-
|
|
80674
|
-
|
|
80675
|
-
|
|
80676
|
-
|
|
80677
|
-
|
|
80678
|
-
|
|
80679
|
-
|
|
80680
|
-
|
|
80681
|
-
|
|
80682
|
-
|
|
80683
|
-
|
|
80684
|
-
|
|
80685
|
-
|
|
80686
|
-
|
|
80687
|
-
|
|
81686
|
+
execFileAsync: execFileAsync4,
|
|
81687
|
+
mesh,
|
|
81688
|
+
node,
|
|
81689
|
+
sourceNode,
|
|
81690
|
+
repoRoot,
|
|
81691
|
+
branch,
|
|
81692
|
+
baseBranch,
|
|
81693
|
+
baseHead,
|
|
81694
|
+
branchHead,
|
|
81695
|
+
validationSummary: void 0,
|
|
81696
|
+
patchEquivalence: void 0,
|
|
81697
|
+
submoduleReachability: void 0
|
|
81698
|
+
}
|
|
81699
|
+
};
|
|
81700
|
+
}
|
|
81701
|
+
/**
|
|
81702
|
+
* validation stage: run the refinery validation gate (typecheck / test /
|
|
81703
|
+
* lint / build per node config) and block on failure or when no allowlisted
|
|
81704
|
+
* command was available. On pass, stores the summary on the context.
|
|
81705
|
+
*/
|
|
81706
|
+
async refineValidationStage(ctx) {
|
|
81707
|
+
const { mesh, node, branch, baseBranch, refineStages } = ctx;
|
|
81708
|
+
const validationStarted = Date.now();
|
|
81709
|
+
const validationSummary = await runMeshRefineValidationGate(mesh, node.workspace, {
|
|
81710
|
+
// M2-2: consume the node's persisted bootstrap state; persist re-runs.
|
|
81711
|
+
persistedBootstrapState: node.worktreeBootstrap,
|
|
81712
|
+
onBootstrapStateChange: (state) => {
|
|
81713
|
+
node.worktreeBootstrap = state;
|
|
81714
|
+
void Promise.resolve().then(() => (init_mesh_config(), mesh_config_exports)).then(({ updateNode: updateNode2 }) => updateNode2(mesh.id, node.id, { worktreeBootstrap: state })).catch(() => {
|
|
81715
|
+
});
|
|
81716
|
+
}
|
|
81717
|
+
});
|
|
81718
|
+
ctx.validationSummary = validationSummary;
|
|
81719
|
+
recordMeshRefineStage(
|
|
81720
|
+
refineStages,
|
|
81721
|
+
"validation",
|
|
81722
|
+
validationSummary.status === "passed" ? "passed" : validationSummary.status === "failed" ? "failed" : "skipped",
|
|
81723
|
+
validationStarted,
|
|
81724
|
+
{ validationStatus: validationSummary.status, commandsRun: validationSummary.commandsRun.length }
|
|
81725
|
+
);
|
|
81726
|
+
if (validationSummary.status === "failed") {
|
|
81727
|
+
const firstFailedCmd = Array.isArray(validationSummary.commandsRun) ? validationSummary.commandsRun.find((c) => c.success === false) : void 0;
|
|
81728
|
+
const buildValidationFailedError = () => {
|
|
81729
|
+
const base = validationSummary.failureCode === "missing_dependencies" ? "Refinery validation dependencies are missing; merge/refine was not attempted. Configure validation.bootstrapCommands if Refinery should bootstrap dependencies before validation." : validationSummary.failureCode === "dependency_bootstrap_failed" ? "Refinery dependency/bootstrap command failed; merge/refine was not attempted." : validationSummary.failureCode === "spawn_resolution_failed" ? validationSummary.spawnResolutionError || "Refinery validation command could not be spawned (executable not found); merge/refine was not attempted." : "Refinery validation gate failed; merge/refine was not attempted.";
|
|
81730
|
+
if (!firstFailedCmd) return base;
|
|
81731
|
+
const cmdName = typeof firstFailedCmd.displayCommand === "string" ? firstFailedCmd.displayCommand : typeof firstFailedCmd.command === "string" ? [firstFailedCmd.command, ...Array.isArray(firstFailedCmd.args) ? firstFailedCmd.args : []].join(" ").trim() : typeof firstFailedCmd.cmd === "string" ? firstFailedCmd.cmd : "";
|
|
81732
|
+
const rawOutput = [firstFailedCmd.stdout, firstFailedCmd.stderr, firstFailedCmd.output].filter((s2) => typeof s2 === "string" && s2.length > 0).join("\n");
|
|
81733
|
+
const tail = rawOutput.length > 800 ? rawOutput.slice(-800) : rawOutput;
|
|
81734
|
+
return [
|
|
81735
|
+
base,
|
|
81736
|
+
cmdName ? `First failing command: ${cmdName}` : "",
|
|
81737
|
+
tail ? `Output (tail):
|
|
80688
81738
|
${tail}` : ""
|
|
80689
|
-
|
|
80690
|
-
|
|
80691
|
-
|
|
80692
|
-
|
|
80693
|
-
|
|
80694
|
-
|
|
80695
|
-
|
|
81739
|
+
].filter(Boolean).join("\n");
|
|
81740
|
+
};
|
|
81741
|
+
return { kind: "terminal", result: {
|
|
81742
|
+
success: false,
|
|
81743
|
+
code: validationSummary.failureCode || "validation_failed",
|
|
81744
|
+
convergenceStatus: "blocked_review",
|
|
81745
|
+
error: buildValidationFailedError(),
|
|
81746
|
+
branch,
|
|
81747
|
+
into: baseBranch,
|
|
81748
|
+
validationSummary,
|
|
81749
|
+
refineStages,
|
|
81750
|
+
finalBranchConvergenceState: {
|
|
80696
81751
|
branch,
|
|
80697
|
-
|
|
80698
|
-
|
|
80699
|
-
|
|
80700
|
-
|
|
80701
|
-
|
|
80702
|
-
|
|
80703
|
-
|
|
80704
|
-
|
|
80705
|
-
|
|
80706
|
-
|
|
80707
|
-
|
|
80708
|
-
|
|
80709
|
-
|
|
80710
|
-
|
|
80711
|
-
|
|
80712
|
-
|
|
80713
|
-
|
|
80714
|
-
|
|
80715
|
-
|
|
81752
|
+
baseBranch,
|
|
81753
|
+
merged: false,
|
|
81754
|
+
removed: false,
|
|
81755
|
+
validation: "failed",
|
|
81756
|
+
status: "blocked_review"
|
|
81757
|
+
}
|
|
81758
|
+
} };
|
|
81759
|
+
}
|
|
81760
|
+
if (validationSummary.status === "skipped") {
|
|
81761
|
+
return { kind: "terminal", result: {
|
|
81762
|
+
success: false,
|
|
81763
|
+
code: "validation_unavailable",
|
|
81764
|
+
convergenceStatus: "blocked_review",
|
|
81765
|
+
error: "Refinery validation gate is required but no allowlisted validation command was available; merge/refine was not attempted.",
|
|
81766
|
+
branch,
|
|
81767
|
+
into: baseBranch,
|
|
81768
|
+
validationSummary,
|
|
81769
|
+
refineStages,
|
|
81770
|
+
finalBranchConvergenceState: {
|
|
80716
81771
|
branch,
|
|
80717
|
-
|
|
80718
|
-
|
|
80719
|
-
|
|
80720
|
-
|
|
80721
|
-
|
|
80722
|
-
|
|
80723
|
-
|
|
80724
|
-
|
|
80725
|
-
|
|
80726
|
-
|
|
80727
|
-
|
|
80728
|
-
|
|
81772
|
+
baseBranch,
|
|
81773
|
+
merged: false,
|
|
81774
|
+
removed: false,
|
|
81775
|
+
validation: "unavailable",
|
|
81776
|
+
status: "blocked_review"
|
|
81777
|
+
}
|
|
81778
|
+
} };
|
|
81779
|
+
}
|
|
81780
|
+
return { kind: "continue", ctx };
|
|
81781
|
+
}
|
|
81782
|
+
/**
|
|
81783
|
+
* patch_equivalence stage: preflight that the worktree branch's cumulative
|
|
81784
|
+
* patch is equivalent to base+branch. On a "behind base" branch, auto-rebase
|
|
81785
|
+
* once and re-check; on an empty merge-tree with real branch changes, treat as
|
|
81786
|
+
* already-merged-via-another-path and short-circuit to cleanup. Mutates the
|
|
81787
|
+
* context's branchHead (after rebase) and patchEquivalence (rebased gate).
|
|
81788
|
+
*/
|
|
81789
|
+
async refinePatchEquivalenceStage(ctx) {
|
|
81790
|
+
const { meshId, nodeId, args, repoRoot, baseHead, node, branch, baseBranch, validationSummary, refineStages, execFileAsync: execFileAsync4 } = ctx;
|
|
81791
|
+
let branchHead = ctx.branchHead;
|
|
81792
|
+
const patchEquivalenceStarted = Date.now();
|
|
81793
|
+
let patchEquivalence = await runMeshRefinePatchEquivalenceGate(repoRoot, baseHead, branchHead);
|
|
81794
|
+
recordMeshRefineStage(refineStages, "patch_equivalence", patchEquivalence.status, patchEquivalenceStarted, {
|
|
81795
|
+
equivalent: patchEquivalence.equivalent,
|
|
81796
|
+
expectedPatchId: patchEquivalence.expectedPatchId,
|
|
81797
|
+
actualPatchId: patchEquivalence.actualPatchId,
|
|
81798
|
+
error: patchEquivalence.error,
|
|
81799
|
+
actionableHint: patchEquivalence.actionableHint
|
|
81800
|
+
});
|
|
81801
|
+
if (!patchEquivalence.equivalent) {
|
|
81802
|
+
let didAutoRebase = false;
|
|
81803
|
+
let isBehindBase = false;
|
|
81804
|
+
try {
|
|
81805
|
+
(0, import_node_child_process6.execFileSync)("git", ["merge-base", "--is-ancestor", branchHead, baseHead], {
|
|
81806
|
+
cwd: node.workspace,
|
|
81807
|
+
stdio: "ignore"
|
|
81808
|
+
});
|
|
81809
|
+
isBehindBase = true;
|
|
81810
|
+
} catch {
|
|
80729
81811
|
}
|
|
80730
|
-
|
|
80731
|
-
|
|
80732
|
-
recordMeshRefineStage(refineStages, "patch_equivalence", patchEquivalence.status, patchEquivalenceStarted, {
|
|
80733
|
-
equivalent: patchEquivalence.equivalent,
|
|
80734
|
-
expectedPatchId: patchEquivalence.expectedPatchId,
|
|
80735
|
-
actualPatchId: patchEquivalence.actualPatchId,
|
|
80736
|
-
error: patchEquivalence.error,
|
|
80737
|
-
actionableHint: patchEquivalence.actionableHint
|
|
80738
|
-
});
|
|
80739
|
-
if (!patchEquivalence.equivalent) {
|
|
80740
|
-
let didAutoRebase = false;
|
|
80741
|
-
let isBehindBase = false;
|
|
81812
|
+
if (isBehindBase) {
|
|
81813
|
+
const autoRebaseStarted = Date.now();
|
|
80742
81814
|
try {
|
|
80743
|
-
(0, import_node_child_process6.execFileSync)("git", ["
|
|
81815
|
+
(0, import_node_child_process6.execFileSync)("git", ["rebase", baseHead], {
|
|
80744
81816
|
cwd: node.workspace,
|
|
80745
|
-
stdio: "ignore"
|
|
81817
|
+
stdio: ["ignore", "pipe", "pipe"]
|
|
80746
81818
|
});
|
|
80747
|
-
|
|
80748
|
-
|
|
80749
|
-
|
|
80750
|
-
|
|
80751
|
-
|
|
80752
|
-
|
|
80753
|
-
|
|
80754
|
-
|
|
80755
|
-
|
|
80756
|
-
|
|
80757
|
-
|
|
80758
|
-
|
|
80759
|
-
|
|
80760
|
-
|
|
80761
|
-
|
|
80762
|
-
expectedPatchId: rebasedPatchEquivalence.expectedPatchId,
|
|
80763
|
-
actualPatchId: rebasedPatchEquivalence.actualPatchId,
|
|
80764
|
-
error: rebasedPatchEquivalence.error,
|
|
80765
|
-
rebasedBranchHead: branchHead
|
|
80766
|
-
});
|
|
80767
|
-
if (rebasedPatchEquivalence.equivalent) {
|
|
80768
|
-
patchEquivalence = rebasedPatchEquivalence;
|
|
80769
|
-
didAutoRebase = true;
|
|
80770
|
-
} else {
|
|
80771
|
-
return {
|
|
80772
|
-
success: false,
|
|
80773
|
-
code: "needs_rebase",
|
|
80774
|
-
convergenceStatus: "blocked_review",
|
|
80775
|
-
error: "Branch was rebased onto base but patch equivalence still failed; manual intervention required.",
|
|
80776
|
-
branch,
|
|
80777
|
-
into: baseBranch,
|
|
80778
|
-
validationSummary,
|
|
80779
|
-
patchEquivalence: rebasedPatchEquivalence,
|
|
80780
|
-
refineStages,
|
|
80781
|
-
finalBranchConvergenceState: {
|
|
80782
|
-
branch,
|
|
80783
|
-
baseBranch,
|
|
80784
|
-
merged: false,
|
|
80785
|
-
removed: false,
|
|
80786
|
-
validation: "passed",
|
|
80787
|
-
patchEquivalence: "failed",
|
|
80788
|
-
status: "blocked_review"
|
|
80789
|
-
}
|
|
80790
|
-
};
|
|
80791
|
-
}
|
|
80792
|
-
} catch (rebaseErr) {
|
|
80793
|
-
try {
|
|
80794
|
-
(0, import_node_child_process6.execFileSync)("git", ["rebase", "--abort"], { cwd: node.workspace, stdio: "ignore" });
|
|
80795
|
-
} catch {
|
|
80796
|
-
}
|
|
80797
|
-
recordMeshRefineStage(refineStages, "patch_equivalence_after_auto_rebase", "failed", autoRebaseStarted, {
|
|
80798
|
-
error: rebaseErr?.message || String(rebaseErr)
|
|
80799
|
-
});
|
|
80800
|
-
return {
|
|
81819
|
+
const { stdout: rebasedHeadStdout } = await execFileAsync4("git", ["rev-parse", "HEAD"], { cwd: node.workspace, encoding: "utf8" });
|
|
81820
|
+
branchHead = rebasedHeadStdout.trim();
|
|
81821
|
+
const rebasedPatchEquivalence = await runMeshRefinePatchEquivalenceGate(repoRoot, baseHead, branchHead);
|
|
81822
|
+
recordMeshRefineStage(refineStages, "patch_equivalence_after_auto_rebase", rebasedPatchEquivalence.status, autoRebaseStarted, {
|
|
81823
|
+
equivalent: rebasedPatchEquivalence.equivalent,
|
|
81824
|
+
expectedPatchId: rebasedPatchEquivalence.expectedPatchId,
|
|
81825
|
+
actualPatchId: rebasedPatchEquivalence.actualPatchId,
|
|
81826
|
+
error: rebasedPatchEquivalence.error,
|
|
81827
|
+
rebasedBranchHead: branchHead
|
|
81828
|
+
});
|
|
81829
|
+
if (rebasedPatchEquivalence.equivalent) {
|
|
81830
|
+
patchEquivalence = rebasedPatchEquivalence;
|
|
81831
|
+
didAutoRebase = true;
|
|
81832
|
+
} else {
|
|
81833
|
+
return { kind: "terminal", result: {
|
|
80801
81834
|
success: false,
|
|
80802
|
-
code: "
|
|
81835
|
+
code: "needs_rebase",
|
|
80803
81836
|
convergenceStatus: "blocked_review",
|
|
80804
|
-
error: "Branch
|
|
81837
|
+
error: "Branch was rebased onto base but patch equivalence still failed; manual intervention required.",
|
|
80805
81838
|
branch,
|
|
80806
81839
|
into: baseBranch,
|
|
80807
81840
|
validationSummary,
|
|
80808
|
-
patchEquivalence,
|
|
81841
|
+
patchEquivalence: rebasedPatchEquivalence,
|
|
80809
81842
|
refineStages,
|
|
80810
81843
|
finalBranchConvergenceState: {
|
|
80811
81844
|
branch,
|
|
@@ -80816,16 +81849,21 @@ ${tail}` : ""
|
|
|
80816
81849
|
patchEquivalence: "failed",
|
|
80817
81850
|
status: "blocked_review"
|
|
80818
81851
|
}
|
|
80819
|
-
};
|
|
81852
|
+
} };
|
|
80820
81853
|
}
|
|
80821
|
-
}
|
|
80822
|
-
|
|
80823
|
-
|
|
80824
|
-
|
|
81854
|
+
} catch (rebaseErr) {
|
|
81855
|
+
try {
|
|
81856
|
+
(0, import_node_child_process6.execFileSync)("git", ["rebase", "--abort"], { cwd: node.workspace, stdio: "ignore" });
|
|
81857
|
+
} catch {
|
|
81858
|
+
}
|
|
81859
|
+
recordMeshRefineStage(refineStages, "patch_equivalence_after_auto_rebase", "failed", autoRebaseStarted, {
|
|
81860
|
+
error: rebaseErr?.message || String(rebaseErr)
|
|
81861
|
+
});
|
|
81862
|
+
return { kind: "terminal", result: {
|
|
80825
81863
|
success: false,
|
|
80826
|
-
code: "
|
|
81864
|
+
code: "needs_rebase_with_conflicts",
|
|
80827
81865
|
convergenceStatus: "blocked_review",
|
|
80828
|
-
error: "
|
|
81866
|
+
error: "Branch is behind base and auto-rebase failed due to conflicts; resolve conflicts manually and retry.",
|
|
80829
81867
|
branch,
|
|
80830
81868
|
into: baseBranch,
|
|
80831
81869
|
validationSummary,
|
|
@@ -80840,146 +81878,20 @@ ${tail}` : ""
|
|
|
80840
81878
|
patchEquivalence: "failed",
|
|
80841
81879
|
status: "blocked_review"
|
|
80842
81880
|
}
|
|
80843
|
-
};
|
|
80844
|
-
}
|
|
80845
|
-
if (!didAutoRebase && alreadyMergedViaOtherPath) {
|
|
80846
|
-
recordMeshRefineStage(refineStages, "merge", "skipped", Date.now(), {
|
|
80847
|
-
reason: "already_merged_via_other_path",
|
|
80848
|
-
note: "actualPatchId is empty; branch content is already present in base via a different commit path"
|
|
80849
|
-
});
|
|
80850
|
-
const cleanupStarted2 = Date.now();
|
|
80851
|
-
const removeResult2 = await this.execute("remove_mesh_node", {
|
|
80852
|
-
meshId,
|
|
80853
|
-
nodeId,
|
|
80854
|
-
sessionCleanupMode: "preserve",
|
|
80855
|
-
inlineMesh: args?.inlineMesh
|
|
80856
|
-
});
|
|
80857
|
-
recordMeshRefineStage(refineStages, "cleanup", removeResult2?.success === false ? "failed" : "passed", cleanupStarted2, {
|
|
80858
|
-
removed: removeResult2?.removed,
|
|
80859
|
-
code: removeResult2?.code,
|
|
80860
|
-
error: removeResult2?.error
|
|
80861
|
-
});
|
|
80862
|
-
try {
|
|
80863
|
-
const { appendLedgerEntry: appendLedgerEntry2 } = await Promise.resolve().then(() => (init_mesh_ledger(), mesh_ledger_exports));
|
|
80864
|
-
appendLedgerEntry2(meshId, {
|
|
80865
|
-
kind: "node_removed",
|
|
80866
|
-
nodeId,
|
|
80867
|
-
payload: { alreadyMergedViaOtherPath: true, branch, into: baseBranch, validationSummary, patchEquivalence }
|
|
80868
|
-
});
|
|
80869
|
-
} catch {
|
|
80870
|
-
}
|
|
80871
|
-
return {
|
|
80872
|
-
success: removeResult2?.success !== false,
|
|
80873
|
-
code: "already_merged",
|
|
80874
|
-
merged: false,
|
|
80875
|
-
alreadyMergedViaOtherPath: true,
|
|
80876
|
-
branch,
|
|
80877
|
-
into: baseBranch,
|
|
80878
|
-
removeResult: removeResult2,
|
|
80879
|
-
validationSummary,
|
|
80880
|
-
patchEquivalence,
|
|
80881
|
-
refineStages,
|
|
80882
|
-
finalBranchConvergenceState: {
|
|
80883
|
-
branch: baseBranch,
|
|
80884
|
-
mergedBranch: branch,
|
|
80885
|
-
baseBranch,
|
|
80886
|
-
merged: false,
|
|
80887
|
-
alreadyMergedViaOtherPath: true,
|
|
80888
|
-
removed: removeResult2?.success !== false,
|
|
80889
|
-
validation: "passed",
|
|
80890
|
-
patchEquivalence: "already_merged",
|
|
80891
|
-
status: removeResult2?.success === false ? "merged_cleanup_failed" : "merged_to_main"
|
|
80892
|
-
}
|
|
80893
|
-
};
|
|
81881
|
+
} };
|
|
80894
81882
|
}
|
|
80895
81883
|
}
|
|
80896
|
-
const
|
|
80897
|
-
|
|
80898
|
-
|
|
80899
|
-
allowAutoPublishSubmoduleMainCommits: autoPublishSubmoduleMainCommits.enabled,
|
|
80900
|
-
autoPublishPolicySource: autoPublishSubmoduleMainCommits.source,
|
|
80901
|
-
worktreeRoot: node.workspace
|
|
80902
|
-
});
|
|
80903
|
-
recordMeshRefineStage(refineStages, "submodule_reachability", submoduleReachability.status, submoduleReachabilityStarted, {
|
|
80904
|
-
checked: submoduleReachability.checked,
|
|
80905
|
-
autoPublishAllowed: submoduleReachability.autoPublishAllowed,
|
|
80906
|
-
autoPublishPolicySource: submoduleReachability.autoPublishPolicySource,
|
|
80907
|
-
autoPublished: submoduleReachability.entries.filter((entry) => entry.autoPublishAttempted).map((entry) => ({
|
|
80908
|
-
path: entry.path,
|
|
80909
|
-
commit: entry.commit,
|
|
80910
|
-
remote: entry.remote,
|
|
80911
|
-
remoteUrl: entry.remoteUrl,
|
|
80912
|
-
remoteMainBranch: entry.remoteMainBranch,
|
|
80913
|
-
refspec: entry.autoPublishRefspec,
|
|
80914
|
-
succeeded: entry.autoPublishSucceeded,
|
|
80915
|
-
verified: entry.autoPublishVerified,
|
|
80916
|
-
remoteMainReachable: entry.remoteMainReachable,
|
|
80917
|
-
error: entry.error
|
|
80918
|
-
})),
|
|
80919
|
-
autoPublishSkipped: submoduleReachability.entries.filter((entry) => entry.autoPublishAllowed === true && entry.autoPublishAttempted !== true).map((entry) => ({
|
|
80920
|
-
path: entry.path,
|
|
80921
|
-
commit: entry.commit,
|
|
80922
|
-
remote: entry.remote,
|
|
80923
|
-
remoteUrl: entry.remoteUrl,
|
|
80924
|
-
remoteMainBranch: entry.remoteMainBranch,
|
|
80925
|
-
reason: entry.autoPublishSkippedReason || entry.error || "auto-publish was allowed but no publish attempt was possible"
|
|
80926
|
-
})),
|
|
80927
|
-
unreachable: submoduleReachability.unreachable.map((entry) => ({
|
|
80928
|
-
path: entry.path,
|
|
80929
|
-
commit: entry.commit,
|
|
80930
|
-
publishRequired: entry.publishRequired === true,
|
|
80931
|
-
autoPublishAllowed: entry.autoPublishAllowed,
|
|
80932
|
-
autoPublishAttempted: entry.autoPublishAttempted,
|
|
80933
|
-
autoPublishSucceeded: entry.autoPublishSucceeded,
|
|
80934
|
-
autoPublishVerified: entry.autoPublishVerified,
|
|
80935
|
-
autoPublishRefspec: entry.autoPublishRefspec,
|
|
80936
|
-
autoPublishSkippedReason: entry.autoPublishSkippedReason,
|
|
80937
|
-
remote: entry.remote,
|
|
80938
|
-
remoteUrl: entry.remoteUrl,
|
|
80939
|
-
remoteReachable: entry.remoteReachable,
|
|
80940
|
-
remoteMainBranch: entry.remoteMainBranch,
|
|
80941
|
-
remoteMainReachable: entry.remoteMainReachable,
|
|
80942
|
-
error: entry.error
|
|
80943
|
-
})),
|
|
80944
|
-
error: submoduleReachability.error
|
|
80945
|
-
});
|
|
80946
|
-
if (submoduleReachability.status === "failed") {
|
|
80947
|
-
const nextStep = buildSubmodulePublishRequiredNextStep(submoduleReachability.unreachable);
|
|
80948
|
-
return {
|
|
81884
|
+
const alreadyMergedViaOtherPath = !patchEquivalence.actualPatchId && !!patchEquivalence.expectedPatchId;
|
|
81885
|
+
if (!didAutoRebase && !alreadyMergedViaOtherPath) {
|
|
81886
|
+
return { kind: "terminal", result: {
|
|
80949
81887
|
success: false,
|
|
80950
|
-
code: "
|
|
81888
|
+
code: "patch_equivalence_failed",
|
|
80951
81889
|
convergenceStatus: "blocked_review",
|
|
80952
|
-
|
|
80953
|
-
blockedReason: "submodule_publish_required",
|
|
80954
|
-
error: "Refinery submodule reachability preflight failed because one or more submodule gitlink commits are not reachable from their configured remote main branch; merge/refine cleanup was not attempted.",
|
|
80955
|
-
nextStep,
|
|
80956
|
-
nextSteps: [
|
|
80957
|
-
"Ask the user for explicit approval before pushing or publishing any submodule commit.",
|
|
80958
|
-
"Push/publish each unreachable submodule commit to the configured submodule remote main branch shown in the evidence.",
|
|
80959
|
-
"Rerun mesh_refine_node after remote reachability is confirmed.",
|
|
80960
|
-
"Do not merge the root branch until every submodule gitlink commit is reachable from submodule origin/main."
|
|
80961
|
-
],
|
|
80962
|
-
unreachableSubmoduleCommits: submoduleReachability.unreachable.map((entry) => ({
|
|
80963
|
-
path: entry.path,
|
|
80964
|
-
commit: entry.commit,
|
|
80965
|
-
remote: entry.remote,
|
|
80966
|
-
remoteUrl: entry.remoteUrl,
|
|
80967
|
-
remoteReachable: entry.remoteReachable,
|
|
80968
|
-
remoteMainBranch: entry.remoteMainBranch,
|
|
80969
|
-
remoteMainReachable: entry.remoteMainReachable,
|
|
80970
|
-
autoPublishAllowed: entry.autoPublishAllowed,
|
|
80971
|
-
autoPublishAttempted: entry.autoPublishAttempted,
|
|
80972
|
-
autoPublishSucceeded: entry.autoPublishSucceeded,
|
|
80973
|
-
autoPublishVerified: entry.autoPublishVerified,
|
|
80974
|
-
autoPublishRefspec: entry.autoPublishRefspec,
|
|
80975
|
-
autoPublishSkippedReason: entry.autoPublishSkippedReason,
|
|
80976
|
-
error: entry.error
|
|
80977
|
-
})),
|
|
81890
|
+
error: "Refinery patch-equivalence preflight failed; merge/refine was not attempted.",
|
|
80978
81891
|
branch,
|
|
80979
81892
|
into: baseBranch,
|
|
80980
81893
|
validationSummary,
|
|
80981
81894
|
patchEquivalence,
|
|
80982
|
-
submoduleReachability,
|
|
80983
81895
|
refineStages,
|
|
80984
81896
|
finalBranchConvergenceState: {
|
|
80985
81897
|
branch,
|
|
@@ -80987,232 +81899,378 @@ ${tail}` : ""
|
|
|
80987
81899
|
merged: false,
|
|
80988
81900
|
removed: false,
|
|
80989
81901
|
validation: "passed",
|
|
80990
|
-
patchEquivalence: "
|
|
80991
|
-
|
|
80992
|
-
status: "blocked_review",
|
|
80993
|
-
reason: "submodule_publish_required",
|
|
80994
|
-
nextStep
|
|
80995
|
-
}
|
|
80996
|
-
};
|
|
80997
|
-
}
|
|
80998
|
-
const effectiveDiffStarted = Date.now();
|
|
80999
|
-
const effectiveDiff = await runMeshRefineEffectiveDiffGate(repoRoot, baseHead, branchHead);
|
|
81000
|
-
recordMeshRefineStage(refineStages, "effective_diff", effectiveDiff.status, effectiveDiffStarted, {
|
|
81001
|
-
hasEffectiveDiff: effectiveDiff.hasEffectiveDiff,
|
|
81002
|
-
changedPaths: effectiveDiff.changedPaths,
|
|
81003
|
-
submoduleHints: effectiveDiff.submoduleHints,
|
|
81004
|
-
...effectiveDiff.error ? { error: effectiveDiff.error } : {}
|
|
81005
|
-
});
|
|
81006
|
-
if (effectiveDiff.status === "failed" && !effectiveDiff.hasEffectiveDiff) {
|
|
81007
|
-
const hintLines = (effectiveDiff.submoduleHints || []).map((h) => ` - ${h.path}: ${h.reason}`);
|
|
81008
|
-
const message = [
|
|
81009
|
-
`Refinery no-op guard: branch '${branch}' has no effective root-tree diff against '${baseBranch}' (${baseHead.slice(0, 12)}); nothing would merge.`,
|
|
81010
|
-
"This usually means a submodule (e.g. oss) has commits but the root branch never committed the gitlink (pointer) bump, so the merge would be a silent no-op while the real change never reaches main.",
|
|
81011
|
-
hintLines.length ? `Submodules with uncommitted pointer bumps:
|
|
81012
|
-
${hintLines.join("\n")}` : "",
|
|
81013
|
-
`Fix: commit the submodule pointer bump on '${branch}' (git add <submodule-path> && git commit), then re-run refine.`
|
|
81014
|
-
].filter(Boolean).join("\n");
|
|
81015
|
-
return {
|
|
81016
|
-
success: false,
|
|
81017
|
-
code: "no_effective_diff",
|
|
81018
|
-
convergenceStatus: "blocked_review",
|
|
81019
|
-
error: message,
|
|
81020
|
-
branch,
|
|
81021
|
-
into: baseBranch,
|
|
81022
|
-
validationSummary,
|
|
81023
|
-
patchEquivalence,
|
|
81024
|
-
effectiveDiff,
|
|
81025
|
-
refineStages,
|
|
81026
|
-
finalBranchConvergenceState: {
|
|
81027
|
-
branch,
|
|
81028
|
-
baseBranch,
|
|
81029
|
-
merged: false,
|
|
81030
|
-
removed: false,
|
|
81031
|
-
validation: "passed",
|
|
81032
|
-
patchEquivalence: "passed",
|
|
81033
|
-
effectiveDiff: "no_effective_diff",
|
|
81034
|
-
status: "blocked_review",
|
|
81035
|
-
reason: "no_effective_diff",
|
|
81036
|
-
...effectiveDiff.submoduleHints?.length ? { submoduleHints: effectiveDiff.submoduleHints } : {}
|
|
81902
|
+
patchEquivalence: "failed",
|
|
81903
|
+
status: "blocked_review"
|
|
81037
81904
|
}
|
|
81038
|
-
};
|
|
81905
|
+
} };
|
|
81039
81906
|
}
|
|
81040
|
-
|
|
81041
|
-
|
|
81042
|
-
|
|
81043
|
-
|
|
81044
|
-
mergeResult = {
|
|
81045
|
-
stdout: truncateValidationOutput(result.stdout),
|
|
81046
|
-
stderr: truncateValidationOutput(result.stderr),
|
|
81047
|
-
durationMs: Date.now() - mergeStarted
|
|
81048
|
-
};
|
|
81049
|
-
recordMeshRefineStage(refineStages, "merge", "passed", mergeStarted, mergeResult);
|
|
81050
|
-
} catch (e) {
|
|
81051
|
-
recordMeshRefineStage(refineStages, "merge", "failed", mergeStarted, {
|
|
81052
|
-
error: e?.message || String(e),
|
|
81053
|
-
stdout: truncateValidationOutput(e?.stdout),
|
|
81054
|
-
stderr: truncateValidationOutput(e?.stderr)
|
|
81907
|
+
if (!didAutoRebase && alreadyMergedViaOtherPath) {
|
|
81908
|
+
recordMeshRefineStage(refineStages, "merge", "skipped", Date.now(), {
|
|
81909
|
+
reason: "already_merged_via_other_path",
|
|
81910
|
+
note: "actualPatchId is empty; branch content is already present in base via a different commit path"
|
|
81055
81911
|
});
|
|
81056
|
-
|
|
81057
|
-
|
|
81058
|
-
|
|
81059
|
-
|
|
81060
|
-
|
|
81061
|
-
|
|
81062
|
-
finalBranchConvergenceState: {
|
|
81063
|
-
branch,
|
|
81064
|
-
baseBranch,
|
|
81065
|
-
merged: false,
|
|
81066
|
-
removed: false,
|
|
81067
|
-
validation: "passed",
|
|
81068
|
-
patchEquivalence: "passed",
|
|
81069
|
-
status: "not_mergeable"
|
|
81070
|
-
}
|
|
81071
|
-
};
|
|
81072
|
-
}
|
|
81073
|
-
const submoduleAlignmentStarted = Date.now();
|
|
81074
|
-
const submoduleAlignment = await alignRefinerySubmodulesAfterMerge(repoRoot, baseHead, "HEAD", {
|
|
81075
|
-
submoduleIgnorePaths: Array.isArray(sourceNode?.policy?.submoduleIgnorePaths) ? sourceNode.policy.submoduleIgnorePaths.filter((value) => typeof value === "string") : void 0
|
|
81076
|
-
});
|
|
81077
|
-
if (submoduleAlignment.status !== "skipped") {
|
|
81078
|
-
recordMeshRefineStage(refineStages, "submodule_alignment", submoduleAlignment.status, submoduleAlignmentStarted, {
|
|
81079
|
-
changedGitlinkPaths: submoduleAlignment.changedGitlinkPaths,
|
|
81080
|
-
outOfSyncPaths: submoduleAlignment.outOfSyncPaths,
|
|
81081
|
-
updatedPaths: submoduleAlignment.updatedPaths,
|
|
81082
|
-
verifiedPaths: submoduleAlignment.verifiedPaths,
|
|
81083
|
-
command: submoduleAlignment.command,
|
|
81084
|
-
error: submoduleAlignment.error
|
|
81912
|
+
const cleanupStarted = Date.now();
|
|
81913
|
+
const removeResult = await this.execute("remove_mesh_node", {
|
|
81914
|
+
meshId,
|
|
81915
|
+
nodeId,
|
|
81916
|
+
sessionCleanupMode: "preserve",
|
|
81917
|
+
inlineMesh: args?.inlineMesh
|
|
81085
81918
|
});
|
|
81086
|
-
|
|
81087
|
-
|
|
81088
|
-
|
|
81089
|
-
|
|
81090
|
-
|
|
81091
|
-
|
|
81092
|
-
|
|
81919
|
+
recordMeshRefineStage(refineStages, "cleanup", removeResult?.success === false ? "failed" : "passed", cleanupStarted, {
|
|
81920
|
+
removed: removeResult?.removed,
|
|
81921
|
+
code: removeResult?.code,
|
|
81922
|
+
error: removeResult?.error
|
|
81923
|
+
});
|
|
81924
|
+
try {
|
|
81925
|
+
const { appendLedgerEntry: appendLedgerEntry2 } = await Promise.resolve().then(() => (init_mesh_ledger(), mesh_ledger_exports));
|
|
81926
|
+
appendLedgerEntry2(meshId, {
|
|
81927
|
+
kind: "node_removed",
|
|
81928
|
+
nodeId,
|
|
81929
|
+
payload: { alreadyMergedViaOtherPath: true, branch, into: baseBranch, validationSummary, patchEquivalence }
|
|
81930
|
+
});
|
|
81931
|
+
} catch {
|
|
81932
|
+
}
|
|
81933
|
+
return { kind: "terminal", result: {
|
|
81934
|
+
success: removeResult?.success !== false,
|
|
81935
|
+
code: "already_merged",
|
|
81936
|
+
merged: false,
|
|
81937
|
+
alreadyMergedViaOtherPath: true,
|
|
81093
81938
|
branch,
|
|
81094
81939
|
into: baseBranch,
|
|
81940
|
+
removeResult,
|
|
81095
81941
|
validationSummary,
|
|
81096
81942
|
patchEquivalence,
|
|
81097
|
-
submoduleReachability,
|
|
81098
|
-
submoduleAlignment,
|
|
81099
|
-
mergeResult,
|
|
81100
81943
|
refineStages,
|
|
81101
81944
|
finalBranchConvergenceState: {
|
|
81102
81945
|
branch: baseBranch,
|
|
81103
81946
|
mergedBranch: branch,
|
|
81104
81947
|
baseBranch,
|
|
81105
|
-
merged:
|
|
81106
|
-
|
|
81948
|
+
merged: false,
|
|
81949
|
+
alreadyMergedViaOtherPath: true,
|
|
81950
|
+
removed: removeResult?.success !== false,
|
|
81107
81951
|
validation: "passed",
|
|
81108
|
-
patchEquivalence: "
|
|
81109
|
-
|
|
81110
|
-
submoduleAlignment: "failed",
|
|
81111
|
-
status: "post_merge_alignment_failed",
|
|
81112
|
-
nextStep: submoduleAlignment.command || "Run git submodule update --init --recursive for the reported path(s), then re-check base workspace status."
|
|
81952
|
+
patchEquivalence: "already_merged",
|
|
81953
|
+
status: removeResult?.success === false ? "merged_cleanup_failed" : "merged_to_main"
|
|
81113
81954
|
}
|
|
81114
|
-
};
|
|
81955
|
+
} };
|
|
81115
81956
|
}
|
|
81116
|
-
|
|
81117
|
-
|
|
81118
|
-
|
|
81119
|
-
|
|
81120
|
-
|
|
81121
|
-
|
|
81122
|
-
|
|
81123
|
-
|
|
81124
|
-
|
|
81125
|
-
|
|
81126
|
-
|
|
81127
|
-
|
|
81128
|
-
|
|
81129
|
-
|
|
81130
|
-
|
|
81131
|
-
|
|
81132
|
-
|
|
81133
|
-
|
|
81134
|
-
|
|
81957
|
+
}
|
|
81958
|
+
ctx.branchHead = branchHead;
|
|
81959
|
+
ctx.patchEquivalence = patchEquivalence;
|
|
81960
|
+
return { kind: "continue", ctx };
|
|
81961
|
+
}
|
|
81962
|
+
/**
|
|
81963
|
+
* submodule_reachability stage: verify every submodule gitlink commit that
|
|
81964
|
+
* would land via the merge is reachable from its configured remote main
|
|
81965
|
+
* branch (optionally auto-publishing when policy allows). Blocks the merge
|
|
81966
|
+
* when any commit is unreachable. Stores the result on the context.
|
|
81967
|
+
*/
|
|
81968
|
+
async refineSubmoduleReachabilityStage(ctx) {
|
|
81969
|
+
const { mesh, node, repoRoot, branch, baseBranch, branchHead, validationSummary, patchEquivalence, refineStages } = ctx;
|
|
81970
|
+
const submoduleReachabilityStarted = Date.now();
|
|
81971
|
+
const autoPublishSubmoduleMainCommits = resolveRefineryAutoPublishSubmoduleMainCommits(mesh, node.workspace);
|
|
81972
|
+
const submoduleReachability = await runMeshRefineSubmoduleReachabilityGate(repoRoot, patchEquivalence.mergedTree || branchHead, {
|
|
81973
|
+
allowAutoPublishSubmoduleMainCommits: autoPublishSubmoduleMainCommits.enabled,
|
|
81974
|
+
autoPublishPolicySource: autoPublishSubmoduleMainCommits.source,
|
|
81975
|
+
worktreeRoot: node.workspace
|
|
81976
|
+
});
|
|
81977
|
+
recordMeshRefineStage(refineStages, "submodule_reachability", submoduleReachability.status, submoduleReachabilityStarted, {
|
|
81978
|
+
checked: submoduleReachability.checked,
|
|
81979
|
+
autoPublishAllowed: submoduleReachability.autoPublishAllowed,
|
|
81980
|
+
autoPublishPolicySource: submoduleReachability.autoPublishPolicySource,
|
|
81981
|
+
autoPublished: submoduleReachability.entries.filter((entry) => entry.autoPublishAttempted).map((entry) => ({
|
|
81982
|
+
path: entry.path,
|
|
81983
|
+
commit: entry.commit,
|
|
81984
|
+
remote: entry.remote,
|
|
81985
|
+
remoteUrl: entry.remoteUrl,
|
|
81986
|
+
remoteMainBranch: entry.remoteMainBranch,
|
|
81987
|
+
refspec: entry.autoPublishRefspec,
|
|
81988
|
+
succeeded: entry.autoPublishSucceeded,
|
|
81989
|
+
verified: entry.autoPublishVerified,
|
|
81990
|
+
remoteMainReachable: entry.remoteMainReachable,
|
|
81991
|
+
error: entry.error
|
|
81992
|
+
})),
|
|
81993
|
+
autoPublishSkipped: submoduleReachability.entries.filter((entry) => entry.autoPublishAllowed === true && entry.autoPublishAttempted !== true).map((entry) => ({
|
|
81994
|
+
path: entry.path,
|
|
81995
|
+
commit: entry.commit,
|
|
81996
|
+
remote: entry.remote,
|
|
81997
|
+
remoteUrl: entry.remoteUrl,
|
|
81998
|
+
remoteMainBranch: entry.remoteMainBranch,
|
|
81999
|
+
reason: entry.autoPublishSkippedReason || entry.error || "auto-publish was allowed but no publish attempt was possible"
|
|
82000
|
+
})),
|
|
82001
|
+
unreachable: submoduleReachability.unreachable.map((entry) => ({
|
|
82002
|
+
path: entry.path,
|
|
82003
|
+
commit: entry.commit,
|
|
82004
|
+
publishRequired: entry.publishRequired === true,
|
|
82005
|
+
autoPublishAllowed: entry.autoPublishAllowed,
|
|
82006
|
+
autoPublishAttempted: entry.autoPublishAttempted,
|
|
82007
|
+
autoPublishSucceeded: entry.autoPublishSucceeded,
|
|
82008
|
+
autoPublishVerified: entry.autoPublishVerified,
|
|
82009
|
+
autoPublishRefspec: entry.autoPublishRefspec,
|
|
82010
|
+
autoPublishSkippedReason: entry.autoPublishSkippedReason,
|
|
82011
|
+
remote: entry.remote,
|
|
82012
|
+
remoteUrl: entry.remoteUrl,
|
|
82013
|
+
remoteReachable: entry.remoteReachable,
|
|
82014
|
+
remoteMainBranch: entry.remoteMainBranch,
|
|
82015
|
+
remoteMainReachable: entry.remoteMainReachable,
|
|
82016
|
+
error: entry.error
|
|
82017
|
+
})),
|
|
82018
|
+
error: submoduleReachability.error
|
|
82019
|
+
});
|
|
82020
|
+
if (submoduleReachability.status === "failed") {
|
|
82021
|
+
const nextStep = buildSubmodulePublishRequiredNextStep(submoduleReachability.unreachable);
|
|
82022
|
+
return { kind: "terminal", result: {
|
|
82023
|
+
success: false,
|
|
82024
|
+
code: "submodule_reachability_failed",
|
|
82025
|
+
convergenceStatus: "blocked_review",
|
|
82026
|
+
publishRequired: true,
|
|
82027
|
+
blockedReason: "submodule_publish_required",
|
|
82028
|
+
error: "Refinery submodule reachability preflight failed because one or more submodule gitlink commits are not reachable from their configured remote main branch; merge/refine cleanup was not attempted.",
|
|
82029
|
+
nextStep,
|
|
82030
|
+
nextSteps: [
|
|
82031
|
+
"Ask the user for explicit approval before pushing or publishing any submodule commit.",
|
|
82032
|
+
"Push/publish each unreachable submodule commit to the configured submodule remote main branch shown in the evidence.",
|
|
82033
|
+
"Rerun mesh_refine_node after remote reachability is confirmed.",
|
|
82034
|
+
"Do not merge the root branch until every submodule gitlink commit is reachable from submodule origin/main."
|
|
82035
|
+
],
|
|
82036
|
+
unreachableSubmoduleCommits: submoduleReachability.unreachable.map((entry) => ({
|
|
82037
|
+
path: entry.path,
|
|
82038
|
+
commit: entry.commit,
|
|
82039
|
+
remote: entry.remote,
|
|
82040
|
+
remoteUrl: entry.remoteUrl,
|
|
82041
|
+
remoteReachable: entry.remoteReachable,
|
|
82042
|
+
remoteMainBranch: entry.remoteMainBranch,
|
|
82043
|
+
remoteMainReachable: entry.remoteMainReachable,
|
|
82044
|
+
autoPublishAllowed: entry.autoPublishAllowed,
|
|
82045
|
+
autoPublishAttempted: entry.autoPublishAttempted,
|
|
82046
|
+
autoPublishSucceeded: entry.autoPublishSucceeded,
|
|
82047
|
+
autoPublishVerified: entry.autoPublishVerified,
|
|
82048
|
+
autoPublishRefspec: entry.autoPublishRefspec,
|
|
82049
|
+
autoPublishSkippedReason: entry.autoPublishSkippedReason,
|
|
82050
|
+
error: entry.error
|
|
82051
|
+
})),
|
|
82052
|
+
branch,
|
|
82053
|
+
into: baseBranch,
|
|
82054
|
+
validationSummary,
|
|
82055
|
+
patchEquivalence,
|
|
82056
|
+
submoduleReachability,
|
|
82057
|
+
refineStages,
|
|
82058
|
+
finalBranchConvergenceState: {
|
|
82059
|
+
branch,
|
|
82060
|
+
baseBranch,
|
|
82061
|
+
merged: false,
|
|
82062
|
+
removed: false,
|
|
82063
|
+
validation: "passed",
|
|
82064
|
+
patchEquivalence: "passed",
|
|
82065
|
+
submoduleReachability: "failed",
|
|
82066
|
+
status: "blocked_review",
|
|
82067
|
+
reason: "submodule_publish_required",
|
|
82068
|
+
nextStep
|
|
81135
82069
|
}
|
|
81136
|
-
}
|
|
81137
|
-
|
|
81138
|
-
|
|
81139
|
-
|
|
81140
|
-
|
|
81141
|
-
|
|
81142
|
-
|
|
82070
|
+
} };
|
|
82071
|
+
}
|
|
82072
|
+
ctx.submoduleReachability = submoduleReachability;
|
|
82073
|
+
return { kind: "continue", ctx };
|
|
82074
|
+
}
|
|
82075
|
+
/**
|
|
82076
|
+
* effective_diff stage (no-op guard): block a silent no-op merge where the
|
|
82077
|
+
* branch produces no effective root-tree diff against base — typically a
|
|
82078
|
+
* submodule that has commits but whose root-level gitlink (pointer) bump was
|
|
82079
|
+
* never committed, so the merge would land nothing real on main.
|
|
82080
|
+
*/
|
|
82081
|
+
async refineEffectiveDiffStage(ctx) {
|
|
82082
|
+
const { repoRoot, baseHead, branchHead, branch, baseBranch, validationSummary, patchEquivalence, refineStages } = ctx;
|
|
82083
|
+
const effectiveDiffStarted = Date.now();
|
|
82084
|
+
const effectiveDiff = await runMeshRefineEffectiveDiffGate(repoRoot, baseHead, branchHead);
|
|
82085
|
+
recordMeshRefineStage(refineStages, "effective_diff", effectiveDiff.status, effectiveDiffStarted, {
|
|
82086
|
+
hasEffectiveDiff: effectiveDiff.hasEffectiveDiff,
|
|
82087
|
+
changedPaths: effectiveDiff.changedPaths,
|
|
82088
|
+
submoduleHints: effectiveDiff.submoduleHints,
|
|
82089
|
+
...effectiveDiff.error ? { error: effectiveDiff.error } : {}
|
|
82090
|
+
});
|
|
82091
|
+
if (effectiveDiff.status === "failed" && !effectiveDiff.hasEffectiveDiff) {
|
|
82092
|
+
const hintLines = (effectiveDiff.submoduleHints || []).map((h) => ` - ${h.path}: ${h.reason}`);
|
|
82093
|
+
const message = [
|
|
82094
|
+
`Refinery no-op guard: branch '${branch}' has no effective root-tree diff against '${baseBranch}' (${baseHead.slice(0, 12)}); nothing would merge.`,
|
|
82095
|
+
"This usually means a submodule (e.g. oss) has commits but the root branch never committed the gitlink (pointer) bump, so the merge would be a silent no-op while the real change never reaches main.",
|
|
82096
|
+
hintLines.length ? `Submodules with uncommitted pointer bumps:
|
|
82097
|
+
${hintLines.join("\n")}` : "",
|
|
82098
|
+
`Fix: commit the submodule pointer bump on '${branch}' (git add <submodule-path> && git commit), then re-run refine.`
|
|
82099
|
+
].filter(Boolean).join("\n");
|
|
82100
|
+
return { kind: "terminal", result: {
|
|
82101
|
+
success: false,
|
|
82102
|
+
code: "no_effective_diff",
|
|
82103
|
+
convergenceStatus: "blocked_review",
|
|
82104
|
+
error: message,
|
|
82105
|
+
branch,
|
|
82106
|
+
into: baseBranch,
|
|
82107
|
+
validationSummary,
|
|
82108
|
+
patchEquivalence,
|
|
82109
|
+
effectiveDiff,
|
|
82110
|
+
refineStages,
|
|
82111
|
+
finalBranchConvergenceState: {
|
|
82112
|
+
branch,
|
|
82113
|
+
baseBranch,
|
|
82114
|
+
merged: false,
|
|
82115
|
+
removed: false,
|
|
82116
|
+
validation: "passed",
|
|
82117
|
+
patchEquivalence: "passed",
|
|
82118
|
+
effectiveDiff: "no_effective_diff",
|
|
82119
|
+
status: "blocked_review",
|
|
82120
|
+
reason: "no_effective_diff",
|
|
82121
|
+
...effectiveDiff.submoduleHints?.length ? { submoduleHints: effectiveDiff.submoduleHints } : {}
|
|
82122
|
+
}
|
|
82123
|
+
} };
|
|
82124
|
+
}
|
|
82125
|
+
return { kind: "continue", ctx };
|
|
82126
|
+
}
|
|
82127
|
+
/**
|
|
82128
|
+
* merge + finalize stage: perform the --no-ff merge, align submodule
|
|
82129
|
+
* checkouts after merge, clean up (remove) the worktree node per policy,
|
|
82130
|
+
* append the refinery ledger entry, and (unless approval is required) push the
|
|
82131
|
+
* base branch. Always terminal — produces the final CommandRouterResult.
|
|
82132
|
+
*/
|
|
82133
|
+
async refineMergeAndFinalizeStage(ctx) {
|
|
82134
|
+
const { meshId, nodeId, args, repoRoot, baseHead, node, branch, baseBranch, sourceNode, validationSummary, patchEquivalence, submoduleReachability, mesh, refineStages, execFileAsync: execFileAsync4 } = ctx;
|
|
82135
|
+
let mergeResult;
|
|
82136
|
+
const mergeStarted = Date.now();
|
|
82137
|
+
try {
|
|
82138
|
+
const result = await execFileAsync4("git", ["merge", "--no-ff", branch, "-m", `Auto-merge branch '${branch}' via Refinery`], { cwd: repoRoot, encoding: "utf8" });
|
|
82139
|
+
mergeResult = {
|
|
82140
|
+
stdout: truncateValidationOutput(result.stdout),
|
|
82141
|
+
stderr: truncateValidationOutput(result.stderr),
|
|
82142
|
+
durationMs: Date.now() - mergeStarted
|
|
82143
|
+
};
|
|
82144
|
+
recordMeshRefineStage(refineStages, "merge", "passed", mergeStarted, mergeResult);
|
|
82145
|
+
} catch (e) {
|
|
82146
|
+
recordMeshRefineStage(refineStages, "merge", "failed", mergeStarted, {
|
|
82147
|
+
error: e?.message || String(e),
|
|
82148
|
+
stdout: truncateValidationOutput(e?.stdout),
|
|
82149
|
+
stderr: truncateValidationOutput(e?.stderr)
|
|
81143
82150
|
});
|
|
81144
|
-
|
|
81145
|
-
|
|
81146
|
-
|
|
81147
|
-
|
|
82151
|
+
return { kind: "terminal", result: {
|
|
82152
|
+
success: false,
|
|
82153
|
+
error: `Merge failed (conflicts?): ${e.message}`,
|
|
82154
|
+
validationSummary,
|
|
82155
|
+
patchEquivalence,
|
|
82156
|
+
refineStages,
|
|
82157
|
+
finalBranchConvergenceState: {
|
|
82158
|
+
branch,
|
|
82159
|
+
baseBranch,
|
|
82160
|
+
merged: false,
|
|
82161
|
+
removed: false,
|
|
82162
|
+
validation: "passed",
|
|
82163
|
+
patchEquivalence: "passed",
|
|
82164
|
+
status: "not_mergeable"
|
|
82165
|
+
}
|
|
82166
|
+
} };
|
|
82167
|
+
}
|
|
82168
|
+
const submoduleAlignmentStarted = Date.now();
|
|
82169
|
+
const submoduleAlignment = await alignRefinerySubmodulesAfterMerge(repoRoot, baseHead, "HEAD", {
|
|
82170
|
+
submoduleIgnorePaths: Array.isArray(sourceNode?.policy?.submoduleIgnorePaths) ? sourceNode.policy.submoduleIgnorePaths.filter((value) => typeof value === "string") : void 0
|
|
82171
|
+
});
|
|
82172
|
+
if (submoduleAlignment.status !== "skipped") {
|
|
82173
|
+
recordMeshRefineStage(refineStages, "submodule_alignment", submoduleAlignment.status, submoduleAlignmentStarted, {
|
|
82174
|
+
changedGitlinkPaths: submoduleAlignment.changedGitlinkPaths,
|
|
82175
|
+
outOfSyncPaths: submoduleAlignment.outOfSyncPaths,
|
|
82176
|
+
updatedPaths: submoduleAlignment.updatedPaths,
|
|
82177
|
+
verifiedPaths: submoduleAlignment.verifiedPaths,
|
|
82178
|
+
command: submoduleAlignment.command,
|
|
82179
|
+
error: submoduleAlignment.error
|
|
81148
82180
|
});
|
|
81149
|
-
|
|
81150
|
-
|
|
81151
|
-
|
|
81152
|
-
|
|
81153
|
-
|
|
81154
|
-
|
|
81155
|
-
nodeId,
|
|
81156
|
-
payload: { refined: true, mergedBranch: branch, into: baseBranch, validationSummary, patchEquivalence, submoduleReachability, submoduleAlignment }
|
|
81157
|
-
});
|
|
81158
|
-
recordMeshRefineStage(refineStages, "ledger", "passed", ledgerStarted);
|
|
81159
|
-
} catch (e) {
|
|
81160
|
-
ledgerError = e?.message || String(e);
|
|
81161
|
-
recordMeshRefineStage(refineStages, "ledger", "failed", ledgerStarted, { error: ledgerError });
|
|
81162
|
-
}
|
|
81163
|
-
const finalBranchConvergenceState = {
|
|
81164
|
-
branch: baseBranch,
|
|
81165
|
-
mergedBranch: branch,
|
|
81166
|
-
baseBranch,
|
|
82181
|
+
}
|
|
82182
|
+
if (submoduleAlignment.status === "failed") {
|
|
82183
|
+
return { kind: "terminal", result: {
|
|
82184
|
+
success: false,
|
|
82185
|
+
code: "post_merge_submodule_alignment_failed",
|
|
82186
|
+
error: "Refinery merge completed but post-merge submodule checkout alignment failed; run the reported git submodule update command and re-check base workspace status.",
|
|
81167
82187
|
merged: true,
|
|
81168
|
-
|
|
81169
|
-
|
|
81170
|
-
|
|
81171
|
-
|
|
81172
|
-
|
|
81173
|
-
|
|
81174
|
-
|
|
81175
|
-
|
|
81176
|
-
|
|
81177
|
-
|
|
81178
|
-
|
|
82188
|
+
branch,
|
|
82189
|
+
into: baseBranch,
|
|
82190
|
+
validationSummary,
|
|
82191
|
+
patchEquivalence,
|
|
82192
|
+
submoduleReachability,
|
|
82193
|
+
submoduleAlignment,
|
|
82194
|
+
mergeResult,
|
|
82195
|
+
refineStages,
|
|
82196
|
+
finalBranchConvergenceState: {
|
|
82197
|
+
branch: baseBranch,
|
|
82198
|
+
mergedBranch: branch,
|
|
82199
|
+
baseBranch,
|
|
81179
82200
|
merged: true,
|
|
81180
|
-
|
|
81181
|
-
|
|
81182
|
-
|
|
81183
|
-
|
|
81184
|
-
|
|
81185
|
-
|
|
81186
|
-
submoduleAlignment,
|
|
81187
|
-
|
|
81188
|
-
|
|
81189
|
-
|
|
81190
|
-
|
|
81191
|
-
|
|
81192
|
-
|
|
81193
|
-
|
|
81194
|
-
|
|
81195
|
-
|
|
81196
|
-
|
|
81197
|
-
|
|
81198
|
-
|
|
81199
|
-
|
|
81200
|
-
|
|
81201
|
-
|
|
81202
|
-
|
|
81203
|
-
|
|
81204
|
-
|
|
81205
|
-
|
|
81206
|
-
|
|
81207
|
-
|
|
81208
|
-
|
|
81209
|
-
durationMs: Date.now() - pushStarted
|
|
81210
|
-
};
|
|
81211
|
-
recordMeshRefineStage(refineStages, "push", "failed", pushStarted, pushResult);
|
|
81212
|
-
}
|
|
82201
|
+
removed: false,
|
|
82202
|
+
validation: "passed",
|
|
82203
|
+
patchEquivalence: "passed",
|
|
82204
|
+
submoduleReachability: "passed",
|
|
82205
|
+
submoduleAlignment: "failed",
|
|
82206
|
+
status: "post_merge_alignment_failed",
|
|
82207
|
+
nextStep: submoduleAlignment.command || "Run git submodule update --init --recursive for the reported path(s), then re-check base workspace status."
|
|
82208
|
+
}
|
|
82209
|
+
} };
|
|
82210
|
+
}
|
|
82211
|
+
const cleanupStarted = Date.now();
|
|
82212
|
+
const refineSessionCleanupMode = this.normalizeMeshSessionCleanupMode(
|
|
82213
|
+
mesh?.policy?.sessionCleanupOnNodeRemove
|
|
82214
|
+
);
|
|
82215
|
+
let refineSessionIds;
|
|
82216
|
+
if (refineSessionCleanupMode !== "preserve" && this.deps.sessionHostControl) {
|
|
82217
|
+
try {
|
|
82218
|
+
const liveSessions = await this.deps.sessionHostControl.listSessions();
|
|
82219
|
+
const workspace = typeof node.workspace === "string" ? node.workspace : "";
|
|
82220
|
+
refineSessionIds = liveSessions.filter((record2) => {
|
|
82221
|
+
const sid = typeof record2?.sessionId === "string" ? record2.sessionId : "";
|
|
82222
|
+
if (!sid) return false;
|
|
82223
|
+
if (readStringValue(record2?.meta?.meshCoordinatorFor) === meshId) return false;
|
|
82224
|
+
const boundToNode = readStringValue(record2?.meta?.meshNodeId) === nodeId;
|
|
82225
|
+
const matchedByWorkspace = !!workspace && record2?.workspace === workspace;
|
|
82226
|
+
return boundToNode || matchedByWorkspace;
|
|
82227
|
+
}).map((record2) => String(record2.sessionId));
|
|
82228
|
+
} catch {
|
|
82229
|
+
refineSessionIds = void 0;
|
|
81213
82230
|
}
|
|
81214
|
-
|
|
81215
|
-
|
|
82231
|
+
}
|
|
82232
|
+
const removeResult = await this.execute("remove_mesh_node", {
|
|
82233
|
+
meshId,
|
|
82234
|
+
nodeId,
|
|
82235
|
+
sessionCleanupMode: refineSessionCleanupMode,
|
|
82236
|
+
...refineSessionIds && refineSessionIds.length > 0 ? { sessionIds: refineSessionIds } : {},
|
|
82237
|
+
inlineMesh: args?.inlineMesh
|
|
82238
|
+
});
|
|
82239
|
+
recordMeshRefineStage(refineStages, "cleanup", removeResult?.success === false ? "failed" : "passed", cleanupStarted, {
|
|
82240
|
+
removed: removeResult?.removed,
|
|
82241
|
+
code: removeResult?.code,
|
|
82242
|
+
error: removeResult?.error
|
|
82243
|
+
});
|
|
82244
|
+
let ledgerError;
|
|
82245
|
+
const ledgerStarted = Date.now();
|
|
82246
|
+
try {
|
|
82247
|
+
const { appendLedgerEntry: appendLedgerEntry2 } = await Promise.resolve().then(() => (init_mesh_ledger(), mesh_ledger_exports));
|
|
82248
|
+
appendLedgerEntry2(meshId, {
|
|
82249
|
+
kind: "node_removed",
|
|
82250
|
+
nodeId,
|
|
82251
|
+
payload: { refined: true, mergedBranch: branch, into: baseBranch, validationSummary, patchEquivalence, submoduleReachability, submoduleAlignment }
|
|
82252
|
+
});
|
|
82253
|
+
recordMeshRefineStage(refineStages, "ledger", "passed", ledgerStarted);
|
|
82254
|
+
} catch (e) {
|
|
82255
|
+
ledgerError = e?.message || String(e);
|
|
82256
|
+
recordMeshRefineStage(refineStages, "ledger", "failed", ledgerStarted, { error: ledgerError });
|
|
82257
|
+
}
|
|
82258
|
+
const finalBranchConvergenceState = {
|
|
82259
|
+
branch: baseBranch,
|
|
82260
|
+
mergedBranch: branch,
|
|
82261
|
+
baseBranch,
|
|
82262
|
+
merged: true,
|
|
82263
|
+
removed: removeResult?.success !== false,
|
|
82264
|
+
validation: "passed",
|
|
82265
|
+
patchEquivalence: "passed",
|
|
82266
|
+
submoduleAlignment: submoduleAlignment.status,
|
|
82267
|
+
status: removeResult?.success === false ? "merged_cleanup_failed" : "merged"
|
|
82268
|
+
};
|
|
82269
|
+
if (removeResult?.success === false) {
|
|
82270
|
+
return { kind: "terminal", result: {
|
|
82271
|
+
success: false,
|
|
82272
|
+
code: "cleanup_failed",
|
|
82273
|
+
error: "Refinery merge completed but worktree cleanup failed; manual cleanup/retry is required.",
|
|
81216
82274
|
merged: true,
|
|
81217
82275
|
branch,
|
|
81218
82276
|
into: baseBranch,
|
|
@@ -81224,17 +82282,51 @@ ${hintLines.join("\n")}` : "",
|
|
|
81224
82282
|
mergeResult,
|
|
81225
82283
|
refineStages,
|
|
81226
82284
|
...ledgerError ? { ledgerError } : {},
|
|
81227
|
-
finalBranchConvergenceState
|
|
81228
|
-
|
|
81229
|
-
...pushResult ? { pushResult } : {
|
|
81230
|
-
pushReady: true,
|
|
81231
|
-
pushCommand: `git push origin ${baseBranch}`,
|
|
81232
|
-
pushNote: "requireApprovalForPush is enabled \u2014 run the push command or obtain user approval before pushing."
|
|
81233
|
-
}
|
|
81234
|
-
};
|
|
81235
|
-
} catch (e) {
|
|
81236
|
-
return { success: false, error: e.message, refineStages };
|
|
82285
|
+
finalBranchConvergenceState
|
|
82286
|
+
} };
|
|
81237
82287
|
}
|
|
82288
|
+
const requireApprovalForPush = mesh?.policy?.requireApprovalForPush ?? DEFAULT_MESH_POLICY.requireApprovalForPush;
|
|
82289
|
+
let pushResult;
|
|
82290
|
+
if (!requireApprovalForPush) {
|
|
82291
|
+
const pushStarted = Date.now();
|
|
82292
|
+
try {
|
|
82293
|
+
await execFileAsync4("git", ["push", "origin", baseBranch], { cwd: repoRoot, encoding: "utf8" });
|
|
82294
|
+
pushResult = { pushed: true, remote: "origin", branch: baseBranch, durationMs: Date.now() - pushStarted };
|
|
82295
|
+
recordMeshRefineStage(refineStages, "push", "passed", pushStarted, pushResult);
|
|
82296
|
+
finalBranchConvergenceState.status = "merged_pushed";
|
|
82297
|
+
} catch (e) {
|
|
82298
|
+
pushResult = {
|
|
82299
|
+
pushed: false,
|
|
82300
|
+
remote: "origin",
|
|
82301
|
+
branch: baseBranch,
|
|
82302
|
+
error: e?.message || String(e),
|
|
82303
|
+
stderr: e?.stderr,
|
|
82304
|
+
durationMs: Date.now() - pushStarted
|
|
82305
|
+
};
|
|
82306
|
+
recordMeshRefineStage(refineStages, "push", "failed", pushStarted, pushResult);
|
|
82307
|
+
}
|
|
82308
|
+
}
|
|
82309
|
+
return { kind: "terminal", result: {
|
|
82310
|
+
success: true,
|
|
82311
|
+
merged: true,
|
|
82312
|
+
branch,
|
|
82313
|
+
into: baseBranch,
|
|
82314
|
+
removeResult,
|
|
82315
|
+
validationSummary,
|
|
82316
|
+
patchEquivalence,
|
|
82317
|
+
submoduleReachability,
|
|
82318
|
+
submoduleAlignment,
|
|
82319
|
+
mergeResult,
|
|
82320
|
+
refineStages,
|
|
82321
|
+
...ledgerError ? { ledgerError } : {},
|
|
82322
|
+
finalBranchConvergenceState,
|
|
82323
|
+
// Push outcome or readiness info for coordinator.
|
|
82324
|
+
...pushResult ? { pushResult } : {
|
|
82325
|
+
pushReady: true,
|
|
82326
|
+
pushCommand: `git push origin ${baseBranch}`,
|
|
82327
|
+
pushNote: "requireApprovalForPush is enabled \u2014 run the push command or obtain user approval before pushing."
|
|
82328
|
+
}
|
|
82329
|
+
} };
|
|
81238
82330
|
}
|
|
81239
82331
|
/**
|
|
81240
82332
|
* Batch refinery: converge multiple sibling worktree nodes onto the base branch
|
|
@@ -81792,929 +82884,9 @@ ${hintLines.join("\n")}` : "",
|
|
|
81792
82884
|
if (medFamilyHandler) {
|
|
81793
82885
|
return await medFamilyHandler(this.buildMedFamilyContext(), args);
|
|
81794
82886
|
}
|
|
81795
|
-
|
|
81796
|
-
|
|
81797
|
-
|
|
81798
|
-
return handleMeshForwardEvent({ instanceManager: this.deps.instanceManager }, args);
|
|
81799
|
-
}
|
|
81800
|
-
case "get_pending_mesh_events": {
|
|
81801
|
-
const meshId = typeof args?.meshId === "string" ? args.meshId.trim() : "";
|
|
81802
|
-
const coordinatorDaemonId = typeof args?.coordinatorDaemonId === "string" && args.coordinatorDaemonId.trim() ? args.coordinatorDaemonId.trim() : void 0;
|
|
81803
|
-
const events = drainPendingMeshCoordinatorEvents(meshId || void 0, coordinatorDaemonId);
|
|
81804
|
-
return { success: true, events };
|
|
81805
|
-
}
|
|
81806
|
-
case "interactive_prompt_response": {
|
|
81807
|
-
const sessionId = typeof args?.targetSessionId === "string" && args.targetSessionId.trim() ? args.targetSessionId.trim() : typeof args?.sessionId === "string" && args.sessionId.trim() ? args.sessionId.trim() : "";
|
|
81808
|
-
if (!sessionId) return { success: false, error: "targetSessionId required" };
|
|
81809
|
-
const response = normalizeInteractivePromptResponse2(args?.response ?? args);
|
|
81810
|
-
const instance = this.deps.instanceManager.getInstance(sessionId);
|
|
81811
|
-
if (!instance) return { success: false, error: `No running instance for session ${sessionId}` };
|
|
81812
|
-
this.deps.instanceManager.sendEvent(sessionId, "interactive_prompt_response", response);
|
|
81813
|
-
return { success: true };
|
|
81814
|
-
}
|
|
81815
|
-
// ─── Mesh Coordinator Launch ───
|
|
81816
|
-
case "launch_mesh_coordinator": {
|
|
81817
|
-
const meshId = typeof args?.meshId === "string" ? args.meshId.trim() : "";
|
|
81818
|
-
let cliType = typeof args?.cliType === "string" ? args.cliType.trim() : "";
|
|
81819
|
-
const extraSystemPrompt = typeof args?.extraSystemPrompt === "string" ? args.extraSystemPrompt.trim() : "";
|
|
81820
|
-
if (!meshId) return { success: false, error: "meshId required" };
|
|
81821
|
-
try {
|
|
81822
|
-
const { buildCoordinatorSystemPrompt: buildCoordinatorSystemPrompt2 } = await Promise.resolve().then(() => (init_coordinator_prompt(), coordinator_prompt_exports));
|
|
81823
|
-
const { buildMissionPromptSection: buildMissionPromptSection2 } = await Promise.resolve().then(() => (init_mesh_missions(), mesh_missions_exports));
|
|
81824
|
-
const buildMissionSectionBestEffort = (id) => {
|
|
81825
|
-
try {
|
|
81826
|
-
return buildMissionPromptSection2(id);
|
|
81827
|
-
} catch {
|
|
81828
|
-
return "";
|
|
81829
|
-
}
|
|
81830
|
-
};
|
|
81831
|
-
let mesh;
|
|
81832
|
-
if (args?.inlineMesh && typeof args.inlineMesh === "object") {
|
|
81833
|
-
mesh = args.inlineMesh;
|
|
81834
|
-
this.inlineMeshCache.set(meshId, mesh);
|
|
81835
|
-
} else {
|
|
81836
|
-
const { getMesh: getMesh2 } = await Promise.resolve().then(() => (init_mesh_config(), mesh_config_exports));
|
|
81837
|
-
mesh = getMesh2(meshId);
|
|
81838
|
-
}
|
|
81839
|
-
if (!mesh) return { success: false, error: "Mesh not found" };
|
|
81840
|
-
const meshHost = resolveMeshHostStatus(mesh);
|
|
81841
|
-
if (!meshHost.canOwnCoordinator) {
|
|
81842
|
-
return {
|
|
81843
|
-
success: false,
|
|
81844
|
-
...buildMeshHostRequiredFailure(mesh, "coordinator launch"),
|
|
81845
|
-
meshId,
|
|
81846
|
-
cliType
|
|
81847
|
-
};
|
|
81848
|
-
}
|
|
81849
|
-
if (!Array.isArray(mesh.nodes) || mesh.nodes.length === 0) return { success: false, error: "No nodes in mesh" };
|
|
81850
|
-
const requestedCoordinatorNodeId = typeof args?.coordinatorNodeId === "string" ? args.coordinatorNodeId.trim() : "";
|
|
81851
|
-
const preferredCoordinatorNodeId = requestedCoordinatorNodeId || (typeof mesh.coordinator?.preferredNodeId === "string" ? mesh.coordinator.preferredNodeId.trim() : "");
|
|
81852
|
-
const coordinatorNode = preferredCoordinatorNodeId ? mesh.nodes.find((node) => node?.id === preferredCoordinatorNodeId || node?.nodeId === preferredCoordinatorNodeId) : mesh.nodes[0];
|
|
81853
|
-
if (!coordinatorNode) {
|
|
81854
|
-
return {
|
|
81855
|
-
success: false,
|
|
81856
|
-
code: "mesh_coordinator_node_not_found",
|
|
81857
|
-
error: `Coordinator node ${preferredCoordinatorNodeId} was not found in mesh`,
|
|
81858
|
-
meshId,
|
|
81859
|
-
cliType
|
|
81860
|
-
};
|
|
81861
|
-
}
|
|
81862
|
-
const sessionHostRecords = this.deps.sessionHostControl?.listSessions ? await this.deps.sessionHostControl.listSessions().catch(() => []) : [];
|
|
81863
|
-
const liveMeshSessions = partitionSessionHostRecords(Array.isArray(sessionHostRecords) ? sessionHostRecords : []).liveRuntimes;
|
|
81864
|
-
const workspace = readLiveMeshNodeWorkspace({
|
|
81865
|
-
meshId,
|
|
81866
|
-
nodeId: String(normalizeMeshNodeId(coordinatorNode) || preferredCoordinatorNodeId || ""),
|
|
81867
|
-
liveSessionRecords: liveMeshSessions,
|
|
81868
|
-
allowCoordinatorSession: true
|
|
81869
|
-
}) || (typeof coordinatorNode.workspace === "string" ? coordinatorNode.workspace.trim() : "");
|
|
81870
|
-
if (!workspace) return { success: false, error: "Coordinator node workspace required", meshId, cliType };
|
|
81871
|
-
if (!cliType) {
|
|
81872
|
-
const resolved = await resolveProviderTypeFromPriority({
|
|
81873
|
-
nodeId: String(normalizeMeshNodeId(coordinatorNode) || preferredCoordinatorNodeId || "coordinator"),
|
|
81874
|
-
providerPriority: readProviderPriorityFromPolicy(coordinatorNode.policy),
|
|
81875
|
-
providerLoader: this.deps.providerLoader,
|
|
81876
|
-
onStatusChange: this.deps.onStatusChange
|
|
81877
|
-
});
|
|
81878
|
-
if (!resolved.providerType) {
|
|
81879
|
-
return {
|
|
81880
|
-
success: false,
|
|
81881
|
-
code: "mesh_coordinator_provider_priority_unusable",
|
|
81882
|
-
error: resolved.error || "No usable provider found from node providerPriority",
|
|
81883
|
-
meshId,
|
|
81884
|
-
cliType,
|
|
81885
|
-
workspace
|
|
81886
|
-
};
|
|
81887
|
-
}
|
|
81888
|
-
cliType = resolved.providerType;
|
|
81889
|
-
}
|
|
81890
|
-
const providerMeta = this.deps.providerLoader.resolve?.(cliType) || this.deps.providerLoader.getMeta(cliType);
|
|
81891
|
-
const coordinatorSetup = resolveMeshCoordinatorSetup({
|
|
81892
|
-
provider: providerMeta,
|
|
81893
|
-
cliType,
|
|
81894
|
-
meshId,
|
|
81895
|
-
workspace
|
|
81896
|
-
});
|
|
81897
|
-
if (coordinatorSetup.kind === "unsupported") {
|
|
81898
|
-
return {
|
|
81899
|
-
success: false,
|
|
81900
|
-
code: "mesh_coordinator_unsupported",
|
|
81901
|
-
error: coordinatorSetup.reason,
|
|
81902
|
-
meshId,
|
|
81903
|
-
cliType,
|
|
81904
|
-
workspace
|
|
81905
|
-
};
|
|
81906
|
-
}
|
|
81907
|
-
if (coordinatorSetup.kind === "manual") {
|
|
81908
|
-
return {
|
|
81909
|
-
success: false,
|
|
81910
|
-
code: "mesh_coordinator_manual_mcp_setup_required",
|
|
81911
|
-
error: coordinatorSetup.instructions,
|
|
81912
|
-
meshId,
|
|
81913
|
-
cliType,
|
|
81914
|
-
workspace,
|
|
81915
|
-
meshCoordinatorSetup: coordinatorSetup
|
|
81916
|
-
};
|
|
81917
|
-
}
|
|
81918
|
-
if (coordinatorSetup.kind === "cli_command") {
|
|
81919
|
-
let cliCmdSystemPrompt = "";
|
|
81920
|
-
try {
|
|
81921
|
-
cliCmdSystemPrompt = buildCoordinatorSystemPrompt2({ mesh, coordinatorCliType: cliType, userInstruction: extraSystemPrompt || void 0, missionSection: buildMissionSectionBestEffort(mesh.id) });
|
|
81922
|
-
} catch (error48) {
|
|
81923
|
-
const message = error48?.message || String(error48);
|
|
81924
|
-
LOG2.error("MeshCoordinator", `Failed to build coordinator prompt: ${message}`);
|
|
81925
|
-
return {
|
|
81926
|
-
success: false,
|
|
81927
|
-
code: "mesh_coordinator_prompt_failed",
|
|
81928
|
-
error: `Failed to build Repo Mesh coordinator prompt: ${message}`,
|
|
81929
|
-
meshId,
|
|
81930
|
-
cliType,
|
|
81931
|
-
workspace
|
|
81932
|
-
};
|
|
81933
|
-
}
|
|
81934
|
-
let mcpRegistrationOk = false;
|
|
81935
|
-
let mcpRegistrationFailure = null;
|
|
81936
|
-
try {
|
|
81937
|
-
const { buildMeshCoordinatorRegistrationPlan: buildMeshCoordinatorRegistrationPlan2, execUnderPty: execUnderPty2 } = await Promise.resolve().then(() => (init_mesh_coordinator(), mesh_coordinator_exports));
|
|
81938
|
-
const registrationPlan = buildMeshCoordinatorRegistrationPlan2(
|
|
81939
|
-
cliType,
|
|
81940
|
-
coordinatorSetup.serverName,
|
|
81941
|
-
coordinatorSetup.command
|
|
81942
|
-
);
|
|
81943
|
-
for (const step of registrationPlan) {
|
|
81944
|
-
const renderedCommand = [step.command, ...step.args].join(" ");
|
|
81945
|
-
LOG2.info("MeshCoordinator", `Running MCP ${step.label} (pty): ${renderedCommand}`);
|
|
81946
|
-
const ptyResult = await execUnderPty2(step.command, step.args, { cwd: workspace, timeoutMs: 2e4 });
|
|
81947
|
-
if (ptyResult.exitCode === 0 && !ptyResult.timedOut) {
|
|
81948
|
-
if (step.required) mcpRegistrationOk = true;
|
|
81949
|
-
continue;
|
|
81950
|
-
}
|
|
81951
|
-
LOG2.warn("MeshCoordinator", `MCP ${step.label} failed exit=${ptyResult.exitCode} signal=${ptyResult.signal} timedOut=${ptyResult.timedOut} \u2014 output:
|
|
81952
|
-
${ptyResult.output.slice(-2e3)}`);
|
|
81953
|
-
if (step.required) {
|
|
81954
|
-
mcpRegistrationFailure = {
|
|
81955
|
-
command: renderedCommand,
|
|
81956
|
-
output: ptyResult.output.slice(-2e3),
|
|
81957
|
-
exitCode: ptyResult.exitCode,
|
|
81958
|
-
signal: ptyResult.signal,
|
|
81959
|
-
timedOut: ptyResult.timedOut
|
|
81960
|
-
};
|
|
81961
|
-
break;
|
|
81962
|
-
}
|
|
81963
|
-
}
|
|
81964
|
-
} catch (error48) {
|
|
81965
|
-
LOG2.warn("MeshCoordinator", `MCP registration command failed: ${error48?.message || error48}`);
|
|
81966
|
-
mcpRegistrationFailure = {
|
|
81967
|
-
command: coordinatorSetup.command,
|
|
81968
|
-
output: error48?.message || String(error48),
|
|
81969
|
-
exitCode: null,
|
|
81970
|
-
signal: null,
|
|
81971
|
-
timedOut: false
|
|
81972
|
-
};
|
|
81973
|
-
}
|
|
81974
|
-
if (!mcpRegistrationOk) {
|
|
81975
|
-
return {
|
|
81976
|
-
success: false,
|
|
81977
|
-
code: "mesh_coordinator_mcp_registration_failed",
|
|
81978
|
-
error: `Could not register ${coordinatorSetup.serverName}; coordinator session was not launched`,
|
|
81979
|
-
meshId,
|
|
81980
|
-
cliType,
|
|
81981
|
-
workspace,
|
|
81982
|
-
registration: mcpRegistrationFailure
|
|
81983
|
-
};
|
|
81984
|
-
}
|
|
81985
|
-
if (cliType === "codex-cli") {
|
|
81986
|
-
const repoMcpConfigPath = (0, import_path12.join)(workspace, ".mcp.json");
|
|
81987
|
-
if (fs27.existsSync(repoMcpConfigPath)) {
|
|
81988
|
-
try {
|
|
81989
|
-
const repoMcpConfig = parseMeshCoordinatorMcpConfig(
|
|
81990
|
-
fs27.readFileSync(repoMcpConfigPath, "utf-8"),
|
|
81991
|
-
"claude_mcp_json"
|
|
81992
|
-
);
|
|
81993
|
-
const existingServers2 = repoMcpConfig.mcpServers;
|
|
81994
|
-
if (existingServers2 && typeof existingServers2 === "object" && !Array.isArray(existingServers2) && existingServers2[coordinatorSetup.serverName]) {
|
|
81995
|
-
fs27.writeFileSync(repoMcpConfigPath, serializeMeshCoordinatorMcpConfig({
|
|
81996
|
-
...repoMcpConfig,
|
|
81997
|
-
mcpServers: {
|
|
81998
|
-
...existingServers2,
|
|
81999
|
-
[coordinatorSetup.serverName]: coordinatorSetup.mcpServer
|
|
82000
|
-
}
|
|
82001
|
-
}, "claude_mcp_json"), "utf-8");
|
|
82002
|
-
LOG2.info("MeshCoordinator", `Refreshed repo-local ${repoMcpConfigPath} entry for ${coordinatorSetup.serverName}`);
|
|
82003
|
-
}
|
|
82004
|
-
} catch (error48) {
|
|
82005
|
-
return {
|
|
82006
|
-
success: false,
|
|
82007
|
-
code: "mesh_coordinator_config_write_failed",
|
|
82008
|
-
error: `Could not refresh repo-local MCP config: ${error48?.message || error48}`,
|
|
82009
|
-
meshId,
|
|
82010
|
-
cliType,
|
|
82011
|
-
workspace
|
|
82012
|
-
};
|
|
82013
|
-
}
|
|
82014
|
-
}
|
|
82015
|
-
}
|
|
82016
|
-
const cliCmdArgs = [];
|
|
82017
|
-
const cliCmdEnv = {};
|
|
82018
|
-
let cliCmdContextFilePath;
|
|
82019
|
-
if (cliCmdSystemPrompt) {
|
|
82020
|
-
const { applyMeshCoordinatorSystemPromptInjection: applyMeshCoordinatorSystemPromptInjection2 } = await Promise.resolve().then(() => (init_mesh_coordinator(), mesh_coordinator_exports));
|
|
82021
|
-
const effect = applyMeshCoordinatorSystemPromptInjection2(
|
|
82022
|
-
cliCmdSystemPrompt,
|
|
82023
|
-
providerMeta?.meshCoordinator?.systemPromptInjection,
|
|
82024
|
-
{ cliArgs: cliCmdArgs, launchEnv: cliCmdEnv, workspace, cliType }
|
|
82025
|
-
);
|
|
82026
|
-
cliCmdContextFilePath = effect.contextFilePath;
|
|
82027
|
-
}
|
|
82028
|
-
const cliCmdLaunch = await this.deps.cliManager.handleCliCommand("launch_cli", {
|
|
82029
|
-
cliType,
|
|
82030
|
-
dir: workspace,
|
|
82031
|
-
cliArgs: cliCmdArgs.length > 0 ? cliCmdArgs : void 0,
|
|
82032
|
-
env: Object.keys(cliCmdEnv).length > 0 ? cliCmdEnv : void 0,
|
|
82033
|
-
settings: { meshCoordinatorFor: meshId }
|
|
82034
|
-
});
|
|
82035
|
-
if (cliCmdLaunch?.success && cliCmdContextFilePath) {
|
|
82036
|
-
const stripPath = cliCmdContextFilePath;
|
|
82037
|
-
setTimeout(() => {
|
|
82038
|
-
void Promise.resolve().then(() => (init_mesh_coordinator(), mesh_coordinator_exports)).then(({ stripCoordinatorWrapperFile: stripCoordinatorWrapperFile2 }) => {
|
|
82039
|
-
stripCoordinatorWrapperFile2(stripPath);
|
|
82040
|
-
LOG2.info("MeshCoordinator", `Stripped wrapper from ${stripPath} after launch settle (cli_command)`);
|
|
82041
|
-
}).catch(() => {
|
|
82042
|
-
});
|
|
82043
|
-
}, 5e3);
|
|
82044
|
-
}
|
|
82045
|
-
if (!cliCmdLaunch?.success) {
|
|
82046
|
-
return { success: false, error: cliCmdLaunch?.error || "Failed to launch CLI session" };
|
|
82047
|
-
}
|
|
82048
|
-
LOG2.info("MeshCoordinator", `Launched ${cliType} coordinator (cli_command) for mesh ${meshId}`);
|
|
82049
|
-
const cliCmdSessionId = cliCmdLaunch.sessionId || cliCmdLaunch.id;
|
|
82050
|
-
if (cliCmdSessionId) {
|
|
82051
|
-
const cliCmdInjectionDecl = providerMeta?.meshCoordinator?.systemPromptInjection;
|
|
82052
|
-
registerMeshCoordinator({
|
|
82053
|
-
meshId,
|
|
82054
|
-
sessionId: cliCmdSessionId,
|
|
82055
|
-
workspace,
|
|
82056
|
-
startedAt: Date.now(),
|
|
82057
|
-
cliType,
|
|
82058
|
-
systemPrompt: cliCmdSystemPrompt || void 0,
|
|
82059
|
-
extraSystemPrompt: extraSystemPrompt || void 0,
|
|
82060
|
-
injection: cliCmdInjectionDecl ? {
|
|
82061
|
-
mode: cliCmdInjectionDecl.mode,
|
|
82062
|
-
target: "flag" in cliCmdInjectionDecl ? cliCmdInjectionDecl.flag : "name" in cliCmdInjectionDecl ? cliCmdInjectionDecl.name : "path" in cliCmdInjectionDecl ? cliCmdInjectionDecl.path : void 0
|
|
82063
|
-
} : void 0
|
|
82064
|
-
});
|
|
82065
|
-
}
|
|
82066
|
-
try {
|
|
82067
|
-
const { appendLedgerEntry: appendLedgerEntry2 } = await Promise.resolve().then(() => (init_mesh_ledger(), mesh_ledger_exports));
|
|
82068
|
-
appendLedgerEntry2(meshId, {
|
|
82069
|
-
kind: "coordinator_started",
|
|
82070
|
-
sessionId: cliCmdSessionId,
|
|
82071
|
-
providerType: cliType,
|
|
82072
|
-
payload: { workspace }
|
|
82073
|
-
});
|
|
82074
|
-
} catch {
|
|
82075
|
-
}
|
|
82076
|
-
return {
|
|
82077
|
-
success: true,
|
|
82078
|
-
meshId,
|
|
82079
|
-
cliType,
|
|
82080
|
-
workspace,
|
|
82081
|
-
sessionId: cliCmdSessionId,
|
|
82082
|
-
mcpRegistered: mcpRegistrationOk
|
|
82083
|
-
};
|
|
82084
|
-
}
|
|
82085
|
-
const configFormat = coordinatorSetup.configFormat;
|
|
82086
|
-
if (configFormat !== "claude_mcp_json" && configFormat !== "hermes_config_yaml") {
|
|
82087
|
-
return {
|
|
82088
|
-
success: false,
|
|
82089
|
-
code: "mesh_coordinator_unsupported",
|
|
82090
|
-
error: `Unsupported auto-import MCP config format: ${String(coordinatorSetup.configFormat)}`,
|
|
82091
|
-
meshId,
|
|
82092
|
-
cliType,
|
|
82093
|
-
workspace
|
|
82094
|
-
};
|
|
82095
|
-
}
|
|
82096
|
-
let systemPrompt = "";
|
|
82097
|
-
try {
|
|
82098
|
-
systemPrompt = buildCoordinatorSystemPrompt2({ mesh, coordinatorCliType: cliType, userInstruction: extraSystemPrompt || void 0, missionSection: buildMissionSectionBestEffort(mesh.id) });
|
|
82099
|
-
} catch (error48) {
|
|
82100
|
-
const message = error48?.message || String(error48);
|
|
82101
|
-
LOG2.error("MeshCoordinator", `Failed to build coordinator prompt: ${message}`);
|
|
82102
|
-
return {
|
|
82103
|
-
success: false,
|
|
82104
|
-
code: "mesh_coordinator_prompt_failed",
|
|
82105
|
-
error: `Failed to build Repo Mesh coordinator prompt: ${message}`,
|
|
82106
|
-
meshId,
|
|
82107
|
-
cliType,
|
|
82108
|
-
workspace
|
|
82109
|
-
};
|
|
82110
|
-
}
|
|
82111
|
-
const { existsSync: existsSync47, readFileSync: readFileSync38, writeFileSync: writeFileSync24, copyFileSync: copyFileSync4, mkdirSync: mkdirSync21 } = await import("fs");
|
|
82112
|
-
const { dirname: dirname17 } = await import("path");
|
|
82113
|
-
const mcpConfigPath = coordinatorSetup.configPath;
|
|
82114
|
-
const hermesManualFallback = cliType === "hermes-cli" && configFormat === "hermes_config_yaml" ? createHermesManualMeshCoordinatorSetup(meshId, workspace) : null;
|
|
82115
|
-
let hermesBaseConfig = null;
|
|
82116
|
-
if (hermesManualFallback) {
|
|
82117
|
-
try {
|
|
82118
|
-
hermesBaseConfig = loadHermesCoordinatorBaseConfig(mcpConfigPath);
|
|
82119
|
-
} catch (error48) {
|
|
82120
|
-
const message = `Failed to parse Hermes base config for automatic coordinator setup: ${error48?.message || error48}`;
|
|
82121
|
-
LOG2.error("MeshCoordinator", message);
|
|
82122
|
-
return { success: false, code: "mesh_coordinator_config_parse_failed", error: message, meshId, cliType, workspace };
|
|
82123
|
-
}
|
|
82124
|
-
}
|
|
82125
|
-
const returnManualFallback = (message) => ({
|
|
82126
|
-
success: false,
|
|
82127
|
-
code: "mesh_coordinator_manual_mcp_setup_required",
|
|
82128
|
-
error: message,
|
|
82129
|
-
meshId,
|
|
82130
|
-
cliType,
|
|
82131
|
-
workspace,
|
|
82132
|
-
meshCoordinatorSetup: hermesManualFallback
|
|
82133
|
-
});
|
|
82134
|
-
const mcpServerEntry = {
|
|
82135
|
-
command: coordinatorSetup.mcpServer.command,
|
|
82136
|
-
args: coordinatorSetup.mcpServer.args
|
|
82137
|
-
};
|
|
82138
|
-
if (args?.inlineMesh) {
|
|
82139
|
-
const modeArgIndex = coordinatorSetup.mcpServer.args.findIndex((value) => value === "--mode");
|
|
82140
|
-
const mcpTransport = modeArgIndex >= 0 ? coordinatorSetup.mcpServer.args[modeArgIndex + 1] : "ipc";
|
|
82141
|
-
mcpServerEntry.env = {
|
|
82142
|
-
ADHDEV_INLINE_MESH: JSON.stringify(mesh),
|
|
82143
|
-
ADHDEV_MCP_TRANSPORT: mcpTransport === "local" ? "local" : "ipc"
|
|
82144
|
-
};
|
|
82145
|
-
}
|
|
82146
|
-
try {
|
|
82147
|
-
mkdirSync21(dirname17(mcpConfigPath), { recursive: true });
|
|
82148
|
-
} catch (error48) {
|
|
82149
|
-
const message = `Could not prepare MCP config path for automatic setup: ${error48?.message || error48}`;
|
|
82150
|
-
LOG2.error("MeshCoordinator", message);
|
|
82151
|
-
if (hermesManualFallback) return returnManualFallback(message);
|
|
82152
|
-
return { success: false, code: "mesh_coordinator_config_write_failed", error: message, meshId, cliType, workspace };
|
|
82153
|
-
}
|
|
82154
|
-
const hadExistingMcpConfig = existsSync47(mcpConfigPath);
|
|
82155
|
-
let existingMcpConfig = hermesBaseConfig?.config || {};
|
|
82156
|
-
if (hermesBaseConfig) {
|
|
82157
|
-
copyHermesCoordinatorCredentialFiles(hermesBaseConfig.sourceHome, dirname17(mcpConfigPath));
|
|
82158
|
-
}
|
|
82159
|
-
if (hadExistingMcpConfig) {
|
|
82160
|
-
try {
|
|
82161
|
-
const parsedExistingMcpConfig = parseMeshCoordinatorMcpConfig(readFileSync38(mcpConfigPath, "utf-8"), configFormat);
|
|
82162
|
-
const existingCoordinatorConfig = hermesManualFallback ? stripHermesCoordinatorTempModelProviderOverrides(parsedExistingMcpConfig) : parsedExistingMcpConfig;
|
|
82163
|
-
existingMcpConfig = { ...existingMcpConfig, ...existingCoordinatorConfig };
|
|
82164
|
-
copyFileSync4(mcpConfigPath, mcpConfigPath + ".backup");
|
|
82165
|
-
} catch (error48) {
|
|
82166
|
-
LOG2.error("MeshCoordinator", `Failed to parse existing MCP config ${mcpConfigPath}: ${error48?.message || error48}`);
|
|
82167
|
-
return {
|
|
82168
|
-
success: false,
|
|
82169
|
-
code: "mesh_coordinator_config_parse_failed",
|
|
82170
|
-
error: `Failed to parse existing MCP config at ${mcpConfigPath}`
|
|
82171
|
-
};
|
|
82172
|
-
}
|
|
82173
|
-
}
|
|
82174
|
-
const mcpServersKey = getMcpServersKey(configFormat);
|
|
82175
|
-
const existingServers = existingMcpConfig[mcpServersKey];
|
|
82176
|
-
const mcpConfig = {
|
|
82177
|
-
...existingMcpConfig,
|
|
82178
|
-
[mcpServersKey]: {
|
|
82179
|
-
...existingServers && typeof existingServers === "object" && !Array.isArray(existingServers) ? existingServers : {},
|
|
82180
|
-
[coordinatorSetup.serverName]: mcpServerEntry
|
|
82181
|
-
}
|
|
82182
|
-
};
|
|
82183
|
-
try {
|
|
82184
|
-
writeFileSync24(mcpConfigPath, serializeMeshCoordinatorMcpConfig(mcpConfig, configFormat), "utf-8");
|
|
82185
|
-
} catch (error48) {
|
|
82186
|
-
const message = `Could not write MCP config for automatic setup: ${error48?.message || error48}`;
|
|
82187
|
-
LOG2.error("MeshCoordinator", message);
|
|
82188
|
-
if (hermesManualFallback) return returnManualFallback(message);
|
|
82189
|
-
return { success: false, code: "mesh_coordinator_config_write_failed", error: message, meshId, cliType, workspace };
|
|
82190
|
-
}
|
|
82191
|
-
LOG2.info("MeshCoordinator", `Wrote ${mcpConfigPath} with ${coordinatorSetup.serverName} server`);
|
|
82192
|
-
const cliArgs = [];
|
|
82193
|
-
const launchEnv = {};
|
|
82194
|
-
if (configFormat === "hermes_config_yaml") {
|
|
82195
|
-
launchEnv.HERMES_HOME = dirname17(mcpConfigPath);
|
|
82196
|
-
launchEnv.HERMES_IGNORE_USER_CONFIG = "";
|
|
82197
|
-
}
|
|
82198
|
-
let autoImportContextFilePath;
|
|
82199
|
-
if (systemPrompt) {
|
|
82200
|
-
const { applyMeshCoordinatorSystemPromptInjection: applyMeshCoordinatorSystemPromptInjection2 } = await Promise.resolve().then(() => (init_mesh_coordinator(), mesh_coordinator_exports));
|
|
82201
|
-
const effect = applyMeshCoordinatorSystemPromptInjection2(
|
|
82202
|
-
systemPrompt,
|
|
82203
|
-
providerMeta?.meshCoordinator?.systemPromptInjection,
|
|
82204
|
-
{ cliArgs, launchEnv, workspace, cliType }
|
|
82205
|
-
);
|
|
82206
|
-
autoImportContextFilePath = effect.contextFilePath;
|
|
82207
|
-
}
|
|
82208
|
-
if (cliType === "claude-cli") {
|
|
82209
|
-
cliArgs.push("--mcp-config", coordinatorSetup.configPath);
|
|
82210
|
-
}
|
|
82211
|
-
const launchResult = await this.deps.cliManager.handleCliCommand("launch_cli", {
|
|
82212
|
-
cliType,
|
|
82213
|
-
dir: workspace,
|
|
82214
|
-
cliArgs: cliArgs.length > 0 ? cliArgs : void 0,
|
|
82215
|
-
env: Object.keys(launchEnv).length > 0 ? launchEnv : void 0,
|
|
82216
|
-
settings: {
|
|
82217
|
-
meshCoordinatorFor: meshId
|
|
82218
|
-
}
|
|
82219
|
-
});
|
|
82220
|
-
if (launchResult?.success && autoImportContextFilePath) {
|
|
82221
|
-
const stripPath = autoImportContextFilePath;
|
|
82222
|
-
setTimeout(() => {
|
|
82223
|
-
void Promise.resolve().then(() => (init_mesh_coordinator(), mesh_coordinator_exports)).then(({ stripCoordinatorWrapperFile: stripCoordinatorWrapperFile2 }) => {
|
|
82224
|
-
stripCoordinatorWrapperFile2(stripPath);
|
|
82225
|
-
LOG2.info("MeshCoordinator", `Stripped wrapper from ${stripPath} after launch settle (auto_import)`);
|
|
82226
|
-
}).catch(() => {
|
|
82227
|
-
});
|
|
82228
|
-
}, 5e3);
|
|
82229
|
-
}
|
|
82230
|
-
if (!launchResult?.success) {
|
|
82231
|
-
return { success: false, error: launchResult?.error || "Failed to launch CLI session" };
|
|
82232
|
-
}
|
|
82233
|
-
LOG2.info("MeshCoordinator", `Launched ${cliType} coordinator for mesh ${meshId} in ${workspace}`);
|
|
82234
|
-
const launchSessionId = launchResult.sessionId || launchResult.id;
|
|
82235
|
-
if (launchSessionId) {
|
|
82236
|
-
const autoImportInjectionDecl = providerMeta?.meshCoordinator?.systemPromptInjection;
|
|
82237
|
-
registerMeshCoordinator({
|
|
82238
|
-
meshId,
|
|
82239
|
-
sessionId: launchSessionId,
|
|
82240
|
-
workspace,
|
|
82241
|
-
startedAt: Date.now(),
|
|
82242
|
-
cliType,
|
|
82243
|
-
systemPrompt: systemPrompt || void 0,
|
|
82244
|
-
extraSystemPrompt: extraSystemPrompt || void 0,
|
|
82245
|
-
mcpConfigPath,
|
|
82246
|
-
injection: autoImportInjectionDecl ? {
|
|
82247
|
-
mode: autoImportInjectionDecl.mode,
|
|
82248
|
-
target: "flag" in autoImportInjectionDecl ? autoImportInjectionDecl.flag : "name" in autoImportInjectionDecl ? autoImportInjectionDecl.name : "path" in autoImportInjectionDecl ? autoImportInjectionDecl.path : void 0
|
|
82249
|
-
} : void 0
|
|
82250
|
-
});
|
|
82251
|
-
}
|
|
82252
|
-
try {
|
|
82253
|
-
const { appendLedgerEntry: appendLedgerEntry2 } = await Promise.resolve().then(() => (init_mesh_ledger(), mesh_ledger_exports));
|
|
82254
|
-
appendLedgerEntry2(meshId, {
|
|
82255
|
-
kind: "coordinator_started",
|
|
82256
|
-
sessionId: launchSessionId,
|
|
82257
|
-
providerType: cliType,
|
|
82258
|
-
payload: { workspace }
|
|
82259
|
-
});
|
|
82260
|
-
} catch {
|
|
82261
|
-
}
|
|
82262
|
-
return {
|
|
82263
|
-
success: true,
|
|
82264
|
-
meshId,
|
|
82265
|
-
cliType,
|
|
82266
|
-
workspace,
|
|
82267
|
-
sessionId: launchSessionId,
|
|
82268
|
-
mcpConfigWritten: true
|
|
82269
|
-
};
|
|
82270
|
-
} catch (e) {
|
|
82271
|
-
LOG2.error("MeshCoordinator", `Failed: ${e.message}`);
|
|
82272
|
-
return { success: false, error: e.message };
|
|
82273
|
-
}
|
|
82274
|
-
}
|
|
82275
|
-
case "mesh_status": {
|
|
82276
|
-
const meshId = typeof args?.meshId === "string" ? args.meshId.trim() : "";
|
|
82277
|
-
if (!meshId) return { success: false, error: "meshId required" };
|
|
82278
|
-
try {
|
|
82279
|
-
const meshRecord = await this.getMeshForCommand(meshId, args?.inlineMesh, { preferInline: true });
|
|
82280
|
-
const mesh = meshRecord?.mesh;
|
|
82281
|
-
if (!mesh) return { success: false, error: "Mesh not found" };
|
|
82282
|
-
const meshHost = resolveMeshHostStatus(mesh);
|
|
82283
|
-
const refreshRequested = args?.refresh === true || args?.forceRefresh === true;
|
|
82284
|
-
const verboseMissions = args?.verbose === true || args?.compact === false;
|
|
82285
|
-
const peekScope = typeof args?.coordinatorDaemonId === "string" && args.coordinatorDaemonId.trim() ? args.coordinatorDaemonId.trim() : this.deps.statusInstanceId || void 0;
|
|
82286
|
-
const pendingCoordinatorEventCount = getPendingMeshCoordinatorEvents(meshId, peekScope).length;
|
|
82287
|
-
const hadAggregateCache = this.aggregateMeshStatusCache.has(meshId);
|
|
82288
|
-
if (!refreshRequested && !verboseMissions && pendingCoordinatorEventCount === 0) {
|
|
82289
|
-
const cachedStatus = this.getCachedAggregateMeshStatus(meshId, mesh, { requireDirectPeerTruth: args?.requireDirectPeerTruth === true });
|
|
82290
|
-
if (cachedStatus) {
|
|
82291
|
-
logRepoMeshStatusDebug("return_cached", {
|
|
82292
|
-
meshId,
|
|
82293
|
-
command: "mesh_status",
|
|
82294
|
-
refreshRequested,
|
|
82295
|
-
summary: summarizeRepoMeshStatusDebug(cachedStatus)
|
|
82296
|
-
});
|
|
82297
|
-
return cachedStatus;
|
|
82298
|
-
}
|
|
82299
|
-
}
|
|
82300
|
-
const refreshReason = refreshRequested ? "explicit_refresh" : pendingCoordinatorEventCount > 0 ? "pending_coordinator_events" : hadAggregateCache ? "stale_pending_cache_refresh" : "cold_cache_miss";
|
|
82301
|
-
const { getMeshQueueStats: getMeshQueueStats2, getQueue: getQueue2 } = await Promise.resolve().then(() => (init_mesh_work_queue(), mesh_work_queue_exports));
|
|
82302
|
-
const queue = getQueue2(meshId);
|
|
82303
|
-
const queueSummary = getMeshQueueStats2(meshId);
|
|
82304
|
-
const { readLedgerEntries: readLedgerEntries2, getLedgerSummary: getLedgerSummary2 } = await Promise.resolve().then(() => (init_mesh_ledger(), mesh_ledger_exports));
|
|
82305
|
-
const ledgerEntries = readLedgerEntries2(meshId, { tail: 20 });
|
|
82306
|
-
const asyncRefineLedgerEntries = readLedgerEntries2(meshId, { tail: 100 });
|
|
82307
|
-
const ledgerSummary = getLedgerSummary2(meshId);
|
|
82308
|
-
const sessionHostRecords = this.deps.sessionHostControl?.listSessions ? await this.deps.sessionHostControl.listSessions().catch(() => []) : [];
|
|
82309
|
-
const liveMeshSessions = partitionSessionHostRecords(Array.isArray(sessionHostRecords) ? sessionHostRecords : []).liveRuntimes;
|
|
82310
|
-
const localMachineId = loadConfig2().machineId || "";
|
|
82311
|
-
const requireDirectPeerTruth = args?.requireDirectPeerTruth === true;
|
|
82312
|
-
const meshGitProbeCache = this.meshGitProbeCache;
|
|
82313
|
-
const directTruth = requireDirectPeerTruth ? await hydrateInlineMeshDirectTruth({
|
|
82314
|
-
mesh,
|
|
82315
|
-
meshSource: meshRecord.source,
|
|
82316
|
-
dispatchMeshCommand: this.deps.dispatchMeshCommand,
|
|
82317
|
-
getMeshPeerConnectionStatus: this.deps.getMeshPeerConnectionStatus,
|
|
82318
|
-
statusInstanceId: this.deps.statusInstanceId,
|
|
82319
|
-
localMachineId,
|
|
82320
|
-
// Standing-state model: only an explicit refresh fans
|
|
82321
|
-
// out a blocking peer git probe. Default loads return
|
|
82322
|
-
// held truth so one slow peer can't block the graph.
|
|
82323
|
-
probeRemotePeers: refreshRequested,
|
|
82324
|
-
probeCache: meshGitProbeCache
|
|
82325
|
-
}) : {
|
|
82326
|
-
directEvidenceCount: 0,
|
|
82327
|
-
localConfirmedCount: 0,
|
|
82328
|
-
peerAttemptedCount: 0,
|
|
82329
|
-
peerConfirmedCount: 0,
|
|
82330
|
-
standingEvidenceCount: 0,
|
|
82331
|
-
unavailableNodeIds: [],
|
|
82332
|
-
deadNodeIds: []
|
|
82333
|
-
};
|
|
82334
|
-
const passivePeerTruthNotAttempted = requireDirectPeerTruth && !refreshRequested && directTruth.directEvidenceCount > 0 && directTruth.peerAttemptedCount === 0;
|
|
82335
|
-
const effectiveDirectTruth = passivePeerTruthNotAttempted ? { ...directTruth, unavailableNodeIds: [] } : directTruth;
|
|
82336
|
-
const unavailableDirectTruthNodeIds = new Set(effectiveDirectTruth.unavailableNodeIds);
|
|
82337
|
-
const unavailableNodesAreOnlyRemovedWorktrees = unavailableDirectTruthNodeIds.size > 0 && Array.isArray(mesh.nodes) && mesh.nodes.filter((node) => unavailableDirectTruthNodeIds.has(normalizeMeshNodeId(node) ?? "")).every((node) => node?.isLocalWorktree === true);
|
|
82338
|
-
const directTruthSatisfied = !requireDirectPeerTruth || !refreshRequested || effectiveDirectTruth.directEvidenceCount > 0 && (effectiveDirectTruth.unavailableNodeIds.length === 0 || unavailableNodesAreOnlyRemovedWorktrees);
|
|
82339
|
-
if (requireDirectPeerTruth && refreshRequested && !directTruthSatisfied) {
|
|
82340
|
-
const failureResult = {
|
|
82341
|
-
success: false,
|
|
82342
|
-
code: "mesh_direct_peer_truth_unavailable",
|
|
82343
|
-
error: "Selected coordinator could not confirm direct mesh truth yet. Bootstrap inventory stays unavailable until direct mesh_status probes succeed.",
|
|
82344
|
-
sourceOfTruth: {
|
|
82345
|
-
membership: meshRecord.source === "inline_cache" ? "coordinator_inline_mesh_cache" : meshRecord.source === "local_config" ? "local_mesh_config" : "inline_bootstrap_snapshot",
|
|
82346
|
-
coordinatorOwnsLiveTruth: false,
|
|
82347
|
-
currentStatus: "direct_peer_truth_unavailable",
|
|
82348
|
-
directPeerTruth: {
|
|
82349
|
-
required: true,
|
|
82350
|
-
satisfied: false,
|
|
82351
|
-
directEvidenceCount: directTruth.directEvidenceCount,
|
|
82352
|
-
localConfirmedCount: directTruth.localConfirmedCount,
|
|
82353
|
-
peerAttemptedCount: directTruth.peerAttemptedCount,
|
|
82354
|
-
peerConfirmedCount: directTruth.peerConfirmedCount,
|
|
82355
|
-
unavailableNodeIds: directTruth.unavailableNodeIds
|
|
82356
|
-
}
|
|
82357
|
-
}
|
|
82358
|
-
};
|
|
82359
|
-
logRepoMeshStatusDebug("direct_truth_unavailable", {
|
|
82360
|
-
meshId,
|
|
82361
|
-
command: "mesh_status",
|
|
82362
|
-
refreshRequested,
|
|
82363
|
-
meshSource: meshRecord.source,
|
|
82364
|
-
directTruth
|
|
82365
|
-
});
|
|
82366
|
-
return failureResult;
|
|
82367
|
-
}
|
|
82368
|
-
const directTruthUnavailableNodeIds = new Set(effectiveDirectTruth.unavailableNodeIds);
|
|
82369
|
-
const coordinatorHostname = (0, import_os3.hostname)();
|
|
82370
|
-
const selectedCoordinatorNodeId = readStringValue(
|
|
82371
|
-
mesh.coordinator?.preferredNodeId,
|
|
82372
|
-
normalizeMeshNodeId(mesh.nodes?.[0])
|
|
82373
|
-
);
|
|
82374
|
-
const inlineCoordinatorNodeId = meshRecord?.inline && Array.isArray(mesh.nodes) ? selectedCoordinatorNodeId : void 0;
|
|
82375
|
-
const refreshedAt = (/* @__PURE__ */ new Date()).toISOString();
|
|
82376
|
-
const nodeStatuses = [];
|
|
82377
|
-
for (const [nodeIndex, node] of (mesh.nodes || []).entries()) {
|
|
82378
|
-
const nodeId = normalizeMeshNodeId(node) ?? "";
|
|
82379
|
-
const daemonId = readStringValue(node.daemonId);
|
|
82380
|
-
const nodeMachineId = readMeshNodeMachineId(node);
|
|
82381
|
-
const nodeHostname = readMeshNodeHostname(node);
|
|
82382
|
-
const providerPriority = readProviderPriorityFromPolicy(node.policy);
|
|
82383
|
-
const configuredCoordinatorNode = Boolean(
|
|
82384
|
-
nodeId && selectedCoordinatorNodeId && nodeId === selectedCoordinatorNodeId
|
|
82385
|
-
);
|
|
82386
|
-
const sparseConfiguredCoordinatorNode = configuredCoordinatorNode && !daemonId && !nodeMachineId && !nodeHostname;
|
|
82387
|
-
const isSelfNode = Boolean(
|
|
82388
|
-
nodeId && inlineCoordinatorNodeId && nodeId === inlineCoordinatorNodeId
|
|
82389
|
-
) || Boolean(
|
|
82390
|
-
daemonId && (daemonIdsEquivalent(daemonId, localMachineId) || daemonIdsEquivalent(daemonId, this.deps.statusInstanceId))
|
|
82391
|
-
) || Boolean(meshRecord?.inline && nodeIndex === 0) || sparseConfiguredCoordinatorNode;
|
|
82392
|
-
const machineIdentity = buildMeshNodeMachineIdentity(node, {
|
|
82393
|
-
localMachineId,
|
|
82394
|
-
localDaemonId: this.deps.statusInstanceId,
|
|
82395
|
-
coordinatorHostname,
|
|
82396
|
-
isSelfNode
|
|
82397
|
-
});
|
|
82398
|
-
const status = {
|
|
82399
|
-
nodeId,
|
|
82400
|
-
machineLabel: buildMeshNodeDisplayLabel(node, nodeId, providerPriority),
|
|
82401
|
-
labelSource: readStringValue(node.machineLabel, node.machine_label, node.machineNickname, node.machine_nickname, node.alias) ? "explicit_metadata" : "workspace_host_provider_context",
|
|
82402
|
-
workspace: node.workspace,
|
|
82403
|
-
repoRoot: node.repoRoot,
|
|
82404
|
-
isLocalWorktree: node.isLocalWorktree,
|
|
82405
|
-
worktreeBranch: node.worktreeBranch,
|
|
82406
|
-
role: normalizeMeshDaemonRole(node.role) || (meshHost.hostNodeId && nodeId === meshHost.hostNodeId ? "host" : void 0),
|
|
82407
|
-
daemonId,
|
|
82408
|
-
machineId: nodeMachineId || node.machineId,
|
|
82409
|
-
machine: machineIdentity,
|
|
82410
|
-
machineStatus: node.machineStatus,
|
|
82411
|
-
health: "unknown",
|
|
82412
|
-
providers: node.providers || [],
|
|
82413
|
-
providerPriority,
|
|
82414
|
-
activeSessions: [],
|
|
82415
|
-
activeSessionDetails: [],
|
|
82416
|
-
launchReady: false
|
|
82417
|
-
};
|
|
82418
|
-
if (isSelfNode) {
|
|
82419
|
-
status.connection = {
|
|
82420
|
-
perspective: "selected_coordinator",
|
|
82421
|
-
source: "mesh_peer_status",
|
|
82422
|
-
state: "self",
|
|
82423
|
-
transport: "local",
|
|
82424
|
-
reported: true,
|
|
82425
|
-
reason: "Selected coordinator daemon",
|
|
82426
|
-
lastStateChangeAt: refreshedAt
|
|
82427
|
-
};
|
|
82428
|
-
} else if (daemonId) {
|
|
82429
|
-
const connection = this.deps.getMeshPeerConnectionStatus?.(daemonId);
|
|
82430
|
-
status.connection = connection ?? {
|
|
82431
|
-
perspective: "selected_coordinator",
|
|
82432
|
-
source: "not_reported",
|
|
82433
|
-
state: "unknown",
|
|
82434
|
-
transport: "unknown",
|
|
82435
|
-
reported: false,
|
|
82436
|
-
reason: "No live mesh peer telemetry reported by the selected coordinator yet."
|
|
82437
|
-
};
|
|
82438
|
-
} else {
|
|
82439
|
-
status.connection = {
|
|
82440
|
-
perspective: "selected_coordinator",
|
|
82441
|
-
source: "not_reported",
|
|
82442
|
-
state: "unknown",
|
|
82443
|
-
transport: "unknown",
|
|
82444
|
-
reported: false,
|
|
82445
|
-
reason: "Node has no daemon id, so mesh transport cannot be reported from the selected coordinator."
|
|
82446
|
-
};
|
|
82447
|
-
}
|
|
82448
|
-
const matchedLiveSessionRecords = collectLiveMeshSessionRecords({
|
|
82449
|
-
meshId,
|
|
82450
|
-
node,
|
|
82451
|
-
nodeId,
|
|
82452
|
-
liveSessionRecords: liveMeshSessions,
|
|
82453
|
-
allowCoordinatorSession: nodeId === selectedCoordinatorNodeId
|
|
82454
|
-
});
|
|
82455
|
-
const workspace = readLiveMeshNodeWorkspace({
|
|
82456
|
-
meshId,
|
|
82457
|
-
nodeId,
|
|
82458
|
-
liveSessionRecords: matchedLiveSessionRecords,
|
|
82459
|
-
allowCoordinatorSession: nodeId === selectedCoordinatorNodeId
|
|
82460
|
-
}) || (typeof node.workspace === "string" ? node.workspace : "");
|
|
82461
|
-
status.workspace = workspace || node.workspace;
|
|
82462
|
-
if (matchedLiveSessionRecords.length > 0) {
|
|
82463
|
-
const sessionIds = matchedLiveSessionRecords.map((record2) => typeof record2?.sessionId === "string" ? record2.sessionId : "").filter(Boolean);
|
|
82464
|
-
const providerTypes = matchedLiveSessionRecords.map((record2) => readStringValue(record2?.providerType)).filter(Boolean);
|
|
82465
|
-
status.activeSessions = sessionIds;
|
|
82466
|
-
status.activeSessionDetails = matchedLiveSessionRecords.map(summarizeMeshSessionRecord);
|
|
82467
|
-
if (providerTypes.length > 0) {
|
|
82468
|
-
status.providers = Array.from(/* @__PURE__ */ new Set([...Array.isArray(status.providers) ? status.providers : [], ...providerTypes]));
|
|
82469
|
-
}
|
|
82470
|
-
}
|
|
82471
|
-
if (workspace) {
|
|
82472
|
-
if (!fs27.existsSync(workspace)) {
|
|
82473
|
-
const inlineTransitGit = buildInlineMeshTransitGitStatus(node);
|
|
82474
|
-
let remoteProbeApplied = false;
|
|
82475
|
-
if (inlineTransitGit) {
|
|
82476
|
-
status.git = inlineTransitGit;
|
|
82477
|
-
status.health = inlineTransitGit.isGitRepo ? deriveMeshNodeHealthFromGit(inlineTransitGit) : "degraded";
|
|
82478
|
-
const connection = readObjectRecord(status.connection);
|
|
82479
|
-
const connectionState = readStringValue(connection.state);
|
|
82480
|
-
const connectionReported = readBooleanValue(connection.reported) ?? false;
|
|
82481
|
-
if (!connectionReported || connectionState === "unknown") {
|
|
82482
|
-
status.connection = buildLivePeerGitConnection(connection, refreshedAt);
|
|
82483
|
-
}
|
|
82484
|
-
remoteProbeApplied = true;
|
|
82485
|
-
} else if (refreshRequested && !isSelfNode && daemonId && this.deps.dispatchMeshCommand && !directTruthUnavailableNodeIds.has(nodeId)) {
|
|
82486
|
-
const runNodeProbe = () => probeRemoteMeshGitStatusWithRetry({
|
|
82487
|
-
dispatchMeshCommand: this.deps.dispatchMeshCommand,
|
|
82488
|
-
daemonId,
|
|
82489
|
-
workspace,
|
|
82490
|
-
timeoutMs: MESH_DIRECT_PROBE_TIMEOUT_MS,
|
|
82491
|
-
retryTimeoutMs: MESH_DIRECT_PROBE_RETRY_TIMEOUT_MS,
|
|
82492
|
-
getConnection: this.deps.getMeshPeerConnectionStatus,
|
|
82493
|
-
onConnection: (connection) => {
|
|
82494
|
-
status.connection = connection;
|
|
82495
|
-
}
|
|
82496
|
-
});
|
|
82497
|
-
const remoteGit = await meshGitProbeCache.probe(daemonId, workspace, runNodeProbe);
|
|
82498
|
-
if (remoteGit) {
|
|
82499
|
-
status.git = remoteGit;
|
|
82500
|
-
status.health = remoteGit.isGitRepo ? deriveMeshNodeHealthFromGit(remoteGit) : "degraded";
|
|
82501
|
-
const connection = readObjectRecord(status.connection);
|
|
82502
|
-
const connectionState = readStringValue(connection.state);
|
|
82503
|
-
const connectionReported = readBooleanValue(connection.reported) ?? false;
|
|
82504
|
-
if (!connectionReported || connectionState === "unknown") {
|
|
82505
|
-
status.connection = buildLivePeerGitConnection(connection, refreshedAt);
|
|
82506
|
-
}
|
|
82507
|
-
const reporter = recordInlineMeshDirectGitTruth(node, remoteGit, "selected_coordinator_mesh_p2p_git");
|
|
82508
|
-
persistNodeReporterPlatform(meshRecord.source, mesh, nodeId, reporter);
|
|
82509
|
-
remoteProbeApplied = true;
|
|
82510
|
-
}
|
|
82511
|
-
}
|
|
82512
|
-
if (!remoteProbeApplied) {
|
|
82513
|
-
const connectionState = readStringValue(status.connection?.state);
|
|
82514
|
-
const pendingPeerGitProbe = !inlineTransitGit && !isSelfNode && !!daemonId && (readStringValue(status.machineStatus) === "online" || readStringValue(status.health) === "online" || connectionState === "connecting" || connectionState === "connected" || connectionState === "unknown");
|
|
82515
|
-
if (pendingPeerGitProbe) {
|
|
82516
|
-
status.gitProbePending = true;
|
|
82517
|
-
status.health = "unknown";
|
|
82518
|
-
}
|
|
82519
|
-
if (applyCachedInlineMeshNodeStatus(
|
|
82520
|
-
status,
|
|
82521
|
-
node,
|
|
82522
|
-
pendingPeerGitProbe ? { skipGit: true, skipError: true, skipHealth: true } : void 0
|
|
82523
|
-
)) {
|
|
82524
|
-
applyInlineMeshBranchConvergence(mesh, node, status);
|
|
82525
|
-
finalizeMeshNodeStatus({ status, node, daemonId, isSelfNode });
|
|
82526
|
-
nodeStatuses.push(status);
|
|
82527
|
-
continue;
|
|
82528
|
-
}
|
|
82529
|
-
if (meshRecord?.source === "inline_cache" && !isSelfNode) {
|
|
82530
|
-
applyInlineMeshBranchConvergence(mesh, node, status);
|
|
82531
|
-
finalizeMeshNodeStatus({ status, node, daemonId, isSelfNode });
|
|
82532
|
-
nodeStatuses.push(status);
|
|
82533
|
-
continue;
|
|
82534
|
-
}
|
|
82535
|
-
}
|
|
82536
|
-
} else {
|
|
82537
|
-
try {
|
|
82538
|
-
const gitStatus = await getGitRepoStatus(workspace, { timeoutMs: 1e4, refreshUpstream: true });
|
|
82539
|
-
status.git = gitStatus;
|
|
82540
|
-
const reporter = recordInlineMeshDirectGitTruth(node, gitStatus, "selected_coordinator_local_git");
|
|
82541
|
-
persistNodeReporterPlatform(meshRecord.source, mesh, nodeId, reporter);
|
|
82542
|
-
if (gitStatus.isGitRepo) {
|
|
82543
|
-
status.health = deriveMeshNodeHealthFromGit(gitStatus);
|
|
82544
|
-
} else {
|
|
82545
|
-
status.health = "degraded";
|
|
82546
|
-
if (gitStatus.error && !status.error) status.error = gitStatus.error;
|
|
82547
|
-
}
|
|
82548
|
-
} catch {
|
|
82549
|
-
if (!applyCachedInlineMeshNodeStatus(status, node)) {
|
|
82550
|
-
status.health = "degraded";
|
|
82551
|
-
}
|
|
82552
|
-
}
|
|
82553
|
-
}
|
|
82554
|
-
} else {
|
|
82555
|
-
applyCachedInlineMeshNodeStatus(status, node);
|
|
82556
|
-
}
|
|
82557
|
-
applyInlineMeshBranchConvergence(mesh, node, status);
|
|
82558
|
-
finalizeMeshNodeStatus({ status, node, daemonId, isSelfNode });
|
|
82559
|
-
nodeStatuses.push(status);
|
|
82560
|
-
}
|
|
82561
|
-
const callerCoordinatorDaemonId = typeof args?.coordinatorDaemonId === "string" && args.coordinatorDaemonId.trim() ? args.coordinatorDaemonId.trim() : this.deps.statusInstanceId || void 0;
|
|
82562
|
-
const pendingCoordinatorEvents = getPendingMeshCoordinatorEvents(meshId, callerCoordinatorDaemonId);
|
|
82563
|
-
const unroutableDeliveries = getRecentUnroutableDeliveries();
|
|
82564
|
-
const previewFreshness = (() => {
|
|
82565
|
-
const localRepoRoot = nodeStatuses.map((node) => readStringValue(node?.git?.repoRoot, node?.repoRoot, node?.workspace)).find((candidate) => !!candidate && fs27.existsSync(candidate));
|
|
82566
|
-
return localRepoRoot ? buildPreviewFreshness(localRepoRoot) : void 0;
|
|
82567
|
-
})();
|
|
82568
|
-
const asyncRefineJobs = buildMeshAsyncRefineJobs({
|
|
82569
|
-
meshId,
|
|
82570
|
-
ledgerEntries: asyncRefineLedgerEntries,
|
|
82571
|
-
pendingEvents: [...pendingCoordinatorEvents]
|
|
82572
|
-
});
|
|
82573
|
-
const historicalSessions = buildHistoricalMeshSessions({
|
|
82574
|
-
meshId,
|
|
82575
|
-
nodes: mesh.nodes || [],
|
|
82576
|
-
liveSessionRecords: liveMeshSessions
|
|
82577
|
-
});
|
|
82578
|
-
const { getMeshStatusMissionSummaries: getMeshStatusMissionSummaries2 } = await Promise.resolve().then(() => (init_mesh_missions(), mesh_missions_exports));
|
|
82579
|
-
const missions = getMeshStatusMissionSummaries2(meshId, { verbose: verboseMissions, withStats: true });
|
|
82580
|
-
const statusResult = {
|
|
82581
|
-
success: true,
|
|
82582
|
-
meshId: mesh.id,
|
|
82583
|
-
meshName: mesh.name,
|
|
82584
|
-
repoIdentity: mesh.repoIdentity,
|
|
82585
|
-
defaultBranch: mesh.defaultBranch,
|
|
82586
|
-
refreshedAt,
|
|
82587
|
-
meshHost,
|
|
82588
|
-
sourceOfTruth: {
|
|
82589
|
-
membership: meshRecord?.source === "inline_cache" ? "coordinator_inline_mesh_cache" : meshRecord?.source === "local_config" ? "local_mesh_config" : "inline_bootstrap_snapshot",
|
|
82590
|
-
coordinatorOwnsLiveTruth: directTruthSatisfied,
|
|
82591
|
-
meshHost: {
|
|
82592
|
-
owner: "mesh_host_daemon",
|
|
82593
|
-
localRole: meshHost.role,
|
|
82594
|
-
hostDaemonId: meshHost.hostDaemonId,
|
|
82595
|
-
hostNodeId: meshHost.hostNodeId,
|
|
82596
|
-
hostAddress: meshHost.hostAddress
|
|
82597
|
-
},
|
|
82598
|
-
...requireDirectPeerTruth ? {
|
|
82599
|
-
currentStatus: directTruthSatisfied ? "live_git_and_session_probes" : "direct_peer_truth_unavailable",
|
|
82600
|
-
directPeerTruth: {
|
|
82601
|
-
required: true,
|
|
82602
|
-
satisfied: directTruthSatisfied,
|
|
82603
|
-
directEvidenceCount: effectiveDirectTruth.directEvidenceCount,
|
|
82604
|
-
localConfirmedCount: effectiveDirectTruth.localConfirmedCount,
|
|
82605
|
-
peerAttemptedCount: effectiveDirectTruth.peerAttemptedCount,
|
|
82606
|
-
peerConfirmedCount: effectiveDirectTruth.peerConfirmedCount,
|
|
82607
|
-
unavailableNodeIds: effectiveDirectTruth.unavailableNodeIds,
|
|
82608
|
-
partialNodeFailures: effectiveDirectTruth.unavailableNodeIds
|
|
82609
|
-
}
|
|
82610
|
-
} : {},
|
|
82611
|
-
historicalEvidenceOnly: ["recoveryHints", "ledger.summary", "queue.summary", "historicalSessions"]
|
|
82612
|
-
},
|
|
82613
|
-
branchConvergenceSummary: summarizeInlineMeshBranchConvergence(nodeStatuses),
|
|
82614
|
-
...previewFreshness ? { previewFreshness, deployFreshness: previewFreshness } : {},
|
|
82615
|
-
nodes: nodeStatuses,
|
|
82616
|
-
queue: { tasks: queue, summary: queueSummary },
|
|
82617
|
-
ledger: { entries: ledgerEntries, summary: ledgerSummary },
|
|
82618
|
-
...missions.length > 0 ? { missions } : {},
|
|
82619
|
-
...asyncRefineJobs.length > 0 ? { asyncRefineJobs } : {},
|
|
82620
|
-
...historicalSessions ? { historicalSessions } : {},
|
|
82621
|
-
...pendingCoordinatorEvents.length > 0 ? { pendingCoordinatorEvents } : {},
|
|
82622
|
-
...unroutableDeliveries.length > 0 ? { unroutableDeliveries } : {},
|
|
82623
|
-
activeRefineJobs: Array.from(this.runningRefineJobs.values()).filter((job) => job.meshId === meshId).map((job) => ({
|
|
82624
|
-
jobId: job.jobId,
|
|
82625
|
-
nodeId: job.targetNodeId,
|
|
82626
|
-
workspace: job.workspace,
|
|
82627
|
-
startedAt: job.startedAt,
|
|
82628
|
-
status: job.status,
|
|
82629
|
-
targetCoordinatorDaemonId: job.targetCoordinatorDaemonId
|
|
82630
|
-
}))
|
|
82631
|
-
};
|
|
82632
|
-
const { pendingCoordinatorEvents: _pendingCoordinatorEvents, unroutableDeliveries: _unroutableDeliveries, ...cacheableStatusResult } = statusResult;
|
|
82633
|
-
const rememberedStatus = verboseMissions ? cacheableStatusResult : this.rememberAggregateMeshStatus(meshId, cacheableStatusResult, refreshReason);
|
|
82634
|
-
const returnedStatus = {
|
|
82635
|
-
...rememberedStatus,
|
|
82636
|
-
...pendingCoordinatorEvents.length > 0 ? { pendingCoordinatorEvents } : {},
|
|
82637
|
-
...unroutableDeliveries.length > 0 ? { unroutableDeliveries } : {}
|
|
82638
|
-
};
|
|
82639
|
-
logRepoMeshStatusDebug("return_live", {
|
|
82640
|
-
meshId,
|
|
82641
|
-
command: "mesh_status",
|
|
82642
|
-
refreshRequested,
|
|
82643
|
-
refreshReason,
|
|
82644
|
-
meshSource: meshRecord.source,
|
|
82645
|
-
directTruth,
|
|
82646
|
-
summary: summarizeRepoMeshStatusDebug(returnedStatus)
|
|
82647
|
-
});
|
|
82648
|
-
return returnedStatus;
|
|
82649
|
-
} catch (e) {
|
|
82650
|
-
return { success: false, error: e.message };
|
|
82651
|
-
}
|
|
82652
|
-
}
|
|
82653
|
-
case "get_mesh_review_inbox": {
|
|
82654
|
-
const meshId = typeof args?.meshId === "string" ? args.meshId.trim() : "";
|
|
82655
|
-
if (!meshId) return { success: false, error: "meshId required" };
|
|
82656
|
-
try {
|
|
82657
|
-
const { deriveMeshReviewInboxItems: deriveMeshReviewInboxItems2 } = await Promise.resolve().then(() => (init_mesh_review_inbox(), mesh_review_inbox_exports));
|
|
82658
|
-
const { readLedgerEntries: readLedgerEntries2 } = await Promise.resolve().then(() => (init_mesh_ledger(), mesh_ledger_exports));
|
|
82659
|
-
const { getGitDiffSummary: getGitDiffSummary2 } = await Promise.resolve().then(() => (init_git_diff(), git_diff_exports));
|
|
82660
|
-
const { existsSync: existsSync47 } = await import("fs");
|
|
82661
|
-
const meshRecord = await this.getMeshForCommand(meshId, args?.inlineMesh, { preferInline: true });
|
|
82662
|
-
const mesh = meshRecord?.mesh;
|
|
82663
|
-
if (!mesh) return { success: false, error: "Mesh not found" };
|
|
82664
|
-
const inlineNodes = args?.inlineMesh && Array.isArray(args.inlineMesh?.nodes) ? args.inlineMesh.nodes : null;
|
|
82665
|
-
let cachedStatus = !inlineNodes ? this.getCachedAggregateMeshStatus(meshId, mesh, {}) : null;
|
|
82666
|
-
if (!cachedStatus && !inlineNodes) {
|
|
82667
|
-
const freshStatus = await this.execute("mesh_status", {
|
|
82668
|
-
meshId,
|
|
82669
|
-
inlineMesh: args?.inlineMesh,
|
|
82670
|
-
refresh: true
|
|
82671
|
-
}, "get_mesh_review_inbox");
|
|
82672
|
-
cachedStatus = freshStatus?.success !== false ? freshStatus : null;
|
|
82673
|
-
}
|
|
82674
|
-
const nodeStatuses = inlineNodes ? inlineNodes : Array.isArray(cachedStatus?.nodes) ? cachedStatus.nodes : Array.isArray(mesh.nodes) ? mesh.nodes : [];
|
|
82675
|
-
const ledgerEntries = readLedgerEntries2(meshId, { tail: 300 });
|
|
82676
|
-
const derivation = deriveMeshReviewInboxItems2({ nodes: nodeStatuses, ledgerEntries });
|
|
82677
|
-
for (const item of derivation.items) {
|
|
82678
|
-
const workspace = item.workspace;
|
|
82679
|
-
if (!workspace || !existsSync47(workspace)) continue;
|
|
82680
|
-
const baseRef = item.defaultBranch ? `origin/${item.defaultBranch}` : "origin/main";
|
|
82681
|
-
try {
|
|
82682
|
-
const diffResult = await getGitDiffSummary2(workspace, { baseRef, maxFiles: 100 });
|
|
82683
|
-
if (diffResult.isGitRepo) {
|
|
82684
|
-
item.diffSummary = {
|
|
82685
|
-
baseRef,
|
|
82686
|
-
files: diffResult.files.map((f) => ({
|
|
82687
|
-
path: f.path,
|
|
82688
|
-
status: f.status,
|
|
82689
|
-
insertions: f.insertions,
|
|
82690
|
-
deletions: f.deletions,
|
|
82691
|
-
binary: f.binary,
|
|
82692
|
-
oldPath: f.oldPath
|
|
82693
|
-
})),
|
|
82694
|
-
totalFiles: diffResult.files.length,
|
|
82695
|
-
totalInsertions: diffResult.totalInsertions,
|
|
82696
|
-
totalDeletions: diffResult.totalDeletions,
|
|
82697
|
-
truncated: diffResult.truncated,
|
|
82698
|
-
...diffResult.error ? { error: diffResult.error } : {}
|
|
82699
|
-
};
|
|
82700
|
-
}
|
|
82701
|
-
} catch {
|
|
82702
|
-
item.diffSummary = null;
|
|
82703
|
-
}
|
|
82704
|
-
}
|
|
82705
|
-
return {
|
|
82706
|
-
success: true,
|
|
82707
|
-
meshId,
|
|
82708
|
-
inbox: derivation.items,
|
|
82709
|
-
remoteNodesExcluded: derivation.remoteNodesExcluded,
|
|
82710
|
-
excludedRemoteNodeIds: derivation.excludedRemoteNodeIds
|
|
82711
|
-
};
|
|
82712
|
-
} catch (e) {
|
|
82713
|
-
return { success: false, error: e.message };
|
|
82714
|
-
}
|
|
82715
|
-
}
|
|
82716
|
-
default:
|
|
82717
|
-
break;
|
|
82887
|
+
const highFamilyHandler = highFamilyRegistry.get(cmd);
|
|
82888
|
+
if (highFamilyHandler) {
|
|
82889
|
+
return await highFamilyHandler(this.buildHighFamilyContext(), args);
|
|
82718
82890
|
}
|
|
82719
82891
|
return null;
|
|
82720
82892
|
}
|
|
@@ -84416,10 +84588,10 @@ ${ptyResult.output.slice(-2e3)}`);
|
|
|
84416
84588
|
};
|
|
84417
84589
|
init_io_contracts();
|
|
84418
84590
|
init_chat_message_normalization();
|
|
84419
|
-
var
|
|
84591
|
+
var fs30 = __toESM2(require("fs"));
|
|
84420
84592
|
var path37 = __toESM2(require("path"));
|
|
84421
84593
|
var os28 = __toESM2(require("os"));
|
|
84422
|
-
var
|
|
84594
|
+
var import_os5 = require("os");
|
|
84423
84595
|
var import_child_process10 = require("child_process");
|
|
84424
84596
|
var ARCHIVE_PATH = path37.join(os28.homedir(), ".adhdev", "version-history.json");
|
|
84425
84597
|
var MAX_ENTRIES_PER_PROVIDER = 20;
|
|
@@ -84430,8 +84602,8 @@ ${ptyResult.output.slice(-2e3)}`);
|
|
|
84430
84602
|
}
|
|
84431
84603
|
load() {
|
|
84432
84604
|
try {
|
|
84433
|
-
if (
|
|
84434
|
-
this.history = JSON.parse(
|
|
84605
|
+
if (fs30.existsSync(ARCHIVE_PATH)) {
|
|
84606
|
+
this.history = JSON.parse(fs30.readFileSync(ARCHIVE_PATH, "utf-8"));
|
|
84435
84607
|
}
|
|
84436
84608
|
} catch {
|
|
84437
84609
|
this.history = {};
|
|
@@ -84446,7 +84618,7 @@ ${ptyResult.output.slice(-2e3)}`);
|
|
|
84446
84618
|
entries.push({
|
|
84447
84619
|
version: version2,
|
|
84448
84620
|
detectedAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
84449
|
-
os: (0,
|
|
84621
|
+
os: (0, import_os5.platform)()
|
|
84450
84622
|
});
|
|
84451
84623
|
if (entries.length > MAX_ENTRIES_PER_PROVIDER) {
|
|
84452
84624
|
this.history[type] = entries.slice(-MAX_ENTRIES_PER_PROVIDER);
|
|
@@ -84468,8 +84640,8 @@ ${ptyResult.output.slice(-2e3)}`);
|
|
|
84468
84640
|
}
|
|
84469
84641
|
save() {
|
|
84470
84642
|
try {
|
|
84471
|
-
|
|
84472
|
-
|
|
84643
|
+
fs30.mkdirSync(path37.dirname(ARCHIVE_PATH), { recursive: true });
|
|
84644
|
+
fs30.writeFileSync(ARCHIVE_PATH, JSON.stringify(this.history, null, 2));
|
|
84473
84645
|
} catch {
|
|
84474
84646
|
}
|
|
84475
84647
|
}
|
|
@@ -84486,7 +84658,7 @@ ${ptyResult.output.slice(-2e3)}`);
|
|
|
84486
84658
|
});
|
|
84487
84659
|
}
|
|
84488
84660
|
function findBinary2(name) {
|
|
84489
|
-
const isWin = (0,
|
|
84661
|
+
const isWin = (0, import_os5.platform)() === "win32";
|
|
84490
84662
|
const paths = (process.env.PATH || "").split(isWin ? ";" : ":");
|
|
84491
84663
|
const exes = isWin ? [".exe", ".cmd", ".bat", ""] : [""];
|
|
84492
84664
|
for (const p of paths) {
|
|
@@ -84494,8 +84666,8 @@ ${ptyResult.output.slice(-2e3)}`);
|
|
|
84494
84666
|
for (const ext of exes) {
|
|
84495
84667
|
const fullPath = path37.join(p, name + ext);
|
|
84496
84668
|
try {
|
|
84497
|
-
if (
|
|
84498
|
-
const stat2 =
|
|
84669
|
+
if (fs30.existsSync(fullPath)) {
|
|
84670
|
+
const stat2 = fs30.statSync(fullPath);
|
|
84499
84671
|
if (stat2.isFile() && (isWin || stat2.mode & 73)) {
|
|
84500
84672
|
return fullPath;
|
|
84501
84673
|
}
|
|
@@ -84542,23 +84714,23 @@ ${ptyResult.output.slice(-2e3)}`);
|
|
|
84542
84714
|
if (p.includes("*")) {
|
|
84543
84715
|
const home = os28.homedir();
|
|
84544
84716
|
const resolved = p.replace(/\*/g, home.split(path37.sep).pop() || "");
|
|
84545
|
-
if (
|
|
84717
|
+
if (fs30.existsSync(resolved)) return resolved;
|
|
84546
84718
|
} else {
|
|
84547
|
-
if (
|
|
84719
|
+
if (fs30.existsSync(p)) return p;
|
|
84548
84720
|
}
|
|
84549
84721
|
}
|
|
84550
84722
|
return null;
|
|
84551
84723
|
}
|
|
84552
84724
|
async function getMacAppVersion(appPath) {
|
|
84553
|
-
if ((0,
|
|
84725
|
+
if ((0, import_os5.platform)() !== "darwin" || !appPath.endsWith(".app")) return null;
|
|
84554
84726
|
const plistPath = path37.join(appPath, "Contents", "Info.plist");
|
|
84555
|
-
if (!
|
|
84727
|
+
if (!fs30.existsSync(plistPath)) return null;
|
|
84556
84728
|
const raw = await runCommand(`/usr/libexec/PlistBuddy -c "Print CFBundleShortVersionString" "${plistPath}"`);
|
|
84557
84729
|
return raw || null;
|
|
84558
84730
|
}
|
|
84559
84731
|
async function detectAllVersions(loader, archive) {
|
|
84560
84732
|
const results = [];
|
|
84561
|
-
const currentOs = (0,
|
|
84733
|
+
const currentOs = (0, import_os5.platform)();
|
|
84562
84734
|
const win32ProcessNames = typeof loader.getWinProcessNames === "function" ? loader.getWinProcessNames() : {};
|
|
84563
84735
|
for (const provider of loader.getAll()) {
|
|
84564
84736
|
const info = {
|
|
@@ -84579,7 +84751,7 @@ ${ptyResult.output.slice(-2e3)}`);
|
|
|
84579
84751
|
let resolvedBin = cliBin;
|
|
84580
84752
|
if (!resolvedBin && appPath && currentOs === "darwin") {
|
|
84581
84753
|
const bundled = path37.join(appPath, "Contents", "Resources", "app", "bin", provider.cli || "");
|
|
84582
|
-
if (provider.cli &&
|
|
84754
|
+
if (provider.cli && fs30.existsSync(bundled)) resolvedBin = bundled;
|
|
84583
84755
|
}
|
|
84584
84756
|
info.installed = !!(appPath || resolvedBin);
|
|
84585
84757
|
info.path = appPath || null;
|
|
@@ -84625,7 +84797,7 @@ ${ptyResult.output.slice(-2e3)}`);
|
|
|
84625
84797
|
return results;
|
|
84626
84798
|
}
|
|
84627
84799
|
var http2 = __toESM2(require("http"));
|
|
84628
|
-
var
|
|
84800
|
+
var fs34 = __toESM2(require("fs"));
|
|
84629
84801
|
var path41 = __toESM2(require("path"));
|
|
84630
84802
|
init_config();
|
|
84631
84803
|
function generateFiles(type, name, category, opts = {}) {
|
|
@@ -84971,7 +85143,7 @@ async (params) => {
|
|
|
84971
85143
|
}
|
|
84972
85144
|
init_logger();
|
|
84973
85145
|
init_builders();
|
|
84974
|
-
var
|
|
85146
|
+
var fs31 = __toESM2(require("fs"));
|
|
84975
85147
|
var path38 = __toESM2(require("path"));
|
|
84976
85148
|
init_logger();
|
|
84977
85149
|
async function handleCdpEvaluate(ctx, req, res) {
|
|
@@ -85152,17 +85324,17 @@ async (params) => {
|
|
|
85152
85324
|
}
|
|
85153
85325
|
let scriptsPath = "";
|
|
85154
85326
|
const directScripts = path38.join(dir, "scripts.js");
|
|
85155
|
-
if (
|
|
85327
|
+
if (fs31.existsSync(directScripts)) {
|
|
85156
85328
|
scriptsPath = directScripts;
|
|
85157
85329
|
} else {
|
|
85158
85330
|
const scriptsDir = path38.join(dir, "scripts");
|
|
85159
|
-
if (
|
|
85160
|
-
const versions =
|
|
85161
|
-
return
|
|
85331
|
+
if (fs31.existsSync(scriptsDir)) {
|
|
85332
|
+
const versions = fs31.readdirSync(scriptsDir).filter((d) => {
|
|
85333
|
+
return fs31.statSync(path38.join(scriptsDir, d)).isDirectory();
|
|
85162
85334
|
}).sort().reverse();
|
|
85163
85335
|
for (const ver of versions) {
|
|
85164
85336
|
const p = path38.join(scriptsDir, ver, "scripts.js");
|
|
85165
|
-
if (
|
|
85337
|
+
if (fs31.existsSync(p)) {
|
|
85166
85338
|
scriptsPath = p;
|
|
85167
85339
|
break;
|
|
85168
85340
|
}
|
|
@@ -85174,7 +85346,7 @@ async (params) => {
|
|
|
85174
85346
|
return;
|
|
85175
85347
|
}
|
|
85176
85348
|
try {
|
|
85177
|
-
const source =
|
|
85349
|
+
const source = fs31.readFileSync(scriptsPath, "utf-8");
|
|
85178
85350
|
const hints = {};
|
|
85179
85351
|
const funcRegex = /module\.exports\.(\w+)\s*=\s*function\s+\w+\s*\(params\)/g;
|
|
85180
85352
|
let match;
|
|
@@ -85987,7 +86159,7 @@ async (params) => {
|
|
|
85987
86159
|
ctx.json(res, 500, { error: `DOM context collection failed: ${e.message}` });
|
|
85988
86160
|
}
|
|
85989
86161
|
}
|
|
85990
|
-
var
|
|
86162
|
+
var fs322 = __toESM2(require("fs"));
|
|
85991
86163
|
var path39 = __toESM2(require("path"));
|
|
85992
86164
|
function slugifyFixtureName(value) {
|
|
85993
86165
|
const normalized = String(value || "").trim().toLowerCase().replace(/[^a-z0-9._-]+/g, "-").replace(/^-+|-+$/g, "");
|
|
@@ -86003,10 +86175,10 @@ async (params) => {
|
|
|
86003
86175
|
function readCliFixture(ctx, type, name) {
|
|
86004
86176
|
const fixtureDir = getCliFixtureDir(ctx, type);
|
|
86005
86177
|
const filePath = path39.join(fixtureDir, `${name}.json`);
|
|
86006
|
-
if (!
|
|
86178
|
+
if (!fs322.existsSync(filePath)) {
|
|
86007
86179
|
throw new Error(`Fixture not found: ${filePath}`);
|
|
86008
86180
|
}
|
|
86009
|
-
return JSON.parse(
|
|
86181
|
+
return JSON.parse(fs322.readFileSync(filePath, "utf-8"));
|
|
86010
86182
|
}
|
|
86011
86183
|
function getExerciseTranscriptText(result) {
|
|
86012
86184
|
const parts = [];
|
|
@@ -86751,7 +86923,7 @@ async (params) => {
|
|
|
86751
86923
|
return;
|
|
86752
86924
|
}
|
|
86753
86925
|
const fixtureDir = getCliFixtureDir(ctx, type);
|
|
86754
|
-
|
|
86926
|
+
fs322.mkdirSync(fixtureDir, { recursive: true });
|
|
86755
86927
|
const name = slugifyFixtureName(String(body?.name || `${type}-${Date.now()}`));
|
|
86756
86928
|
const result = await runCliExerciseInternal(ctx, { ...request, type });
|
|
86757
86929
|
const fixture = {
|
|
@@ -86779,7 +86951,7 @@ async (params) => {
|
|
|
86779
86951
|
notes: typeof body?.notes === "string" ? body.notes : void 0
|
|
86780
86952
|
};
|
|
86781
86953
|
const filePath = path39.join(fixtureDir, `${name}.json`);
|
|
86782
|
-
|
|
86954
|
+
fs322.writeFileSync(filePath, JSON.stringify(fixture, null, 2));
|
|
86783
86955
|
ctx.json(res, 200, {
|
|
86784
86956
|
saved: true,
|
|
86785
86957
|
name,
|
|
@@ -86797,14 +86969,14 @@ async (params) => {
|
|
|
86797
86969
|
async function handleCliFixtureList(ctx, type, _req, res) {
|
|
86798
86970
|
try {
|
|
86799
86971
|
const fixtureDir = getCliFixtureDir(ctx, type);
|
|
86800
|
-
if (!
|
|
86972
|
+
if (!fs322.existsSync(fixtureDir)) {
|
|
86801
86973
|
ctx.json(res, 200, { fixtures: [], count: 0 });
|
|
86802
86974
|
return;
|
|
86803
86975
|
}
|
|
86804
|
-
const fixtures =
|
|
86976
|
+
const fixtures = fs322.readdirSync(fixtureDir).filter((file2) => file2.endsWith(".json")).sort((a, b) => b.localeCompare(a, void 0, { numeric: true, sensitivity: "base" })).map((file2) => {
|
|
86805
86977
|
const fullPath = path39.join(fixtureDir, file2);
|
|
86806
86978
|
try {
|
|
86807
|
-
const raw = JSON.parse(
|
|
86979
|
+
const raw = JSON.parse(fs322.readFileSync(fullPath, "utf-8"));
|
|
86808
86980
|
return {
|
|
86809
86981
|
name: raw.name || file2.replace(/\.json$/i, ""),
|
|
86810
86982
|
path: fullPath,
|
|
@@ -86935,7 +87107,7 @@ async (params) => {
|
|
|
86935
87107
|
ctx.json(res, 500, { error: `Raw send failed: ${e.message}` });
|
|
86936
87108
|
}
|
|
86937
87109
|
}
|
|
86938
|
-
var
|
|
87110
|
+
var fs33 = __toESM2(require("fs"));
|
|
86939
87111
|
var path40 = __toESM2(require("path"));
|
|
86940
87112
|
var os29 = __toESM2(require("os"));
|
|
86941
87113
|
var import_session_host_core8 = require_dist();
|
|
@@ -86984,10 +87156,10 @@ async (params) => {
|
|
|
86984
87156
|
return fallback?.type || null;
|
|
86985
87157
|
}
|
|
86986
87158
|
function getLatestScriptVersionDir(scriptsDir) {
|
|
86987
|
-
if (!
|
|
86988
|
-
const versions =
|
|
87159
|
+
if (!fs33.existsSync(scriptsDir)) return null;
|
|
87160
|
+
const versions = fs33.readdirSync(scriptsDir).filter((d) => {
|
|
86989
87161
|
try {
|
|
86990
|
-
return
|
|
87162
|
+
return fs33.statSync(path40.join(scriptsDir, d)).isDirectory();
|
|
86991
87163
|
} catch {
|
|
86992
87164
|
return false;
|
|
86993
87165
|
}
|
|
@@ -87009,13 +87181,13 @@ async (params) => {
|
|
|
87009
87181
|
if (!sourceDir) {
|
|
87010
87182
|
return { dir: null, reason: `Provider source directory not found for '${type}'` };
|
|
87011
87183
|
}
|
|
87012
|
-
if (!
|
|
87013
|
-
|
|
87014
|
-
|
|
87184
|
+
if (!fs33.existsSync(desiredDir)) {
|
|
87185
|
+
fs33.mkdirSync(path40.dirname(desiredDir), { recursive: true });
|
|
87186
|
+
fs33.cpSync(sourceDir, desiredDir, { recursive: true });
|
|
87015
87187
|
ctx.log(`Auto-implement writable copy created: ${desiredDir}`);
|
|
87016
87188
|
}
|
|
87017
87189
|
const providerJson = path40.join(desiredDir, "provider.json");
|
|
87018
|
-
if (!
|
|
87190
|
+
if (!fs33.existsSync(providerJson)) {
|
|
87019
87191
|
return { dir: null, reason: `provider.json not found in writable provider directory: ${desiredDir}` };
|
|
87020
87192
|
}
|
|
87021
87193
|
return { dir: desiredDir };
|
|
@@ -87023,15 +87195,15 @@ async (params) => {
|
|
|
87023
87195
|
function loadAutoImplReferenceScripts(ctx, referenceType) {
|
|
87024
87196
|
if (!referenceType) return {};
|
|
87025
87197
|
const refDir = ctx.findProviderDir(referenceType);
|
|
87026
|
-
if (!refDir || !
|
|
87198
|
+
if (!refDir || !fs33.existsSync(refDir)) return {};
|
|
87027
87199
|
const referenceScripts = {};
|
|
87028
87200
|
const scriptsDir = path40.join(refDir, "scripts");
|
|
87029
87201
|
const latestDir = getLatestScriptVersionDir(scriptsDir);
|
|
87030
87202
|
if (!latestDir) return referenceScripts;
|
|
87031
|
-
for (const file2 of
|
|
87203
|
+
for (const file2 of fs33.readdirSync(latestDir)) {
|
|
87032
87204
|
if (!file2.endsWith(".js")) continue;
|
|
87033
87205
|
try {
|
|
87034
|
-
referenceScripts[file2] =
|
|
87206
|
+
referenceScripts[file2] = fs33.readFileSync(path40.join(latestDir, file2), "utf-8");
|
|
87035
87207
|
} catch {
|
|
87036
87208
|
}
|
|
87037
87209
|
}
|
|
@@ -87140,15 +87312,15 @@ async (params) => {
|
|
|
87140
87312
|
const referenceScripts = loadAutoImplReferenceScripts(ctx, resolvedReference);
|
|
87141
87313
|
const prompt = buildAutoImplPrompt(ctx, type, provider, providerDir, functions, domContext, referenceScripts, comment, resolvedReference, verification);
|
|
87142
87314
|
const tmpDir = path40.join(os29.tmpdir(), "adhdev-autoimpl");
|
|
87143
|
-
if (!
|
|
87315
|
+
if (!fs33.existsSync(tmpDir)) fs33.mkdirSync(tmpDir, { recursive: true });
|
|
87144
87316
|
const promptFile = path40.join(tmpDir, `prompt-${type}-${Date.now()}.md`);
|
|
87145
|
-
|
|
87317
|
+
fs33.writeFileSync(promptFile, prompt, "utf-8");
|
|
87146
87318
|
ctx.log(`Auto-implement prompt written to ${promptFile} (${prompt.length} chars)`);
|
|
87147
87319
|
const agentProvider = ctx.providerLoader.resolve(agent) || ctx.providerLoader.getMeta(agent);
|
|
87148
87320
|
const spawn4 = agentProvider?.spawn;
|
|
87149
87321
|
if (!spawn4?.command) {
|
|
87150
87322
|
try {
|
|
87151
|
-
|
|
87323
|
+
fs33.unlinkSync(promptFile);
|
|
87152
87324
|
} catch {
|
|
87153
87325
|
}
|
|
87154
87326
|
ctx.json(res, 400, { error: `Agent '${agent}' has no spawn config. Select a CLI provider with a spawn configuration.` });
|
|
@@ -87250,7 +87422,7 @@ async (params) => {
|
|
|
87250
87422
|
} catch {
|
|
87251
87423
|
}
|
|
87252
87424
|
try {
|
|
87253
|
-
|
|
87425
|
+
fs33.unlinkSync(promptFile);
|
|
87254
87426
|
} catch {
|
|
87255
87427
|
}
|
|
87256
87428
|
ctx.log(`Auto-implement (ACP) ${success2 ? "completed" : "failed"}: ${type} (exit: ${code})`);
|
|
@@ -87476,7 +87648,7 @@ async (params) => {
|
|
|
87476
87648
|
}
|
|
87477
87649
|
});
|
|
87478
87650
|
try {
|
|
87479
|
-
|
|
87651
|
+
fs33.unlinkSync(promptFile);
|
|
87480
87652
|
} catch {
|
|
87481
87653
|
}
|
|
87482
87654
|
ctx.log(`Auto-implement ${success2 ? "completed" : "failed"}: ${type} (exit: ${code})${verificationSummary ? ` verify=${verificationSummary.pass ? "pass" : "fail"}` : ""}`);
|
|
@@ -87581,10 +87753,10 @@ async (params) => {
|
|
|
87581
87753
|
lines.push("## \u270F\uFE0F Target Files (EDIT THESE)");
|
|
87582
87754
|
lines.push("These are the ONLY files you are allowed to modify. Replace the TODO stubs with working implementations.");
|
|
87583
87755
|
lines.push("");
|
|
87584
|
-
for (const file2 of
|
|
87756
|
+
for (const file2 of fs33.readdirSync(latestScriptsDir)) {
|
|
87585
87757
|
if (file2.endsWith(".js") && targetFileNames.has(file2)) {
|
|
87586
87758
|
try {
|
|
87587
|
-
const content =
|
|
87759
|
+
const content = fs33.readFileSync(path40.join(latestScriptsDir, file2), "utf-8");
|
|
87588
87760
|
lines.push(`### \`${file2}\` \u270F\uFE0F EDIT`);
|
|
87589
87761
|
lines.push("```javascript");
|
|
87590
87762
|
lines.push(content);
|
|
@@ -87594,14 +87766,14 @@ async (params) => {
|
|
|
87594
87766
|
}
|
|
87595
87767
|
}
|
|
87596
87768
|
}
|
|
87597
|
-
const refFiles =
|
|
87769
|
+
const refFiles = fs33.readdirSync(latestScriptsDir).filter((f) => f.endsWith(".js") && !targetFileNames.has(f));
|
|
87598
87770
|
if (refFiles.length > 0) {
|
|
87599
87771
|
lines.push("## \u{1F512} Other Scripts (REFERENCE ONLY \u2014 DO NOT EDIT)");
|
|
87600
87772
|
lines.push("These files are shown for context only. Do NOT modify them under any circumstances.");
|
|
87601
87773
|
lines.push("");
|
|
87602
87774
|
for (const file2 of refFiles) {
|
|
87603
87775
|
try {
|
|
87604
|
-
const content =
|
|
87776
|
+
const content = fs33.readFileSync(path40.join(latestScriptsDir, file2), "utf-8");
|
|
87605
87777
|
lines.push(`### \`${file2}\` \u{1F512}`);
|
|
87606
87778
|
lines.push("```javascript");
|
|
87607
87779
|
lines.push(content);
|
|
@@ -87646,7 +87818,7 @@ async (params) => {
|
|
|
87646
87818
|
const loadGuide = (name) => {
|
|
87647
87819
|
try {
|
|
87648
87820
|
const p = path40.join(docsDir, name);
|
|
87649
|
-
if (
|
|
87821
|
+
if (fs33.existsSync(p)) return fs33.readFileSync(p, "utf-8");
|
|
87650
87822
|
} catch {
|
|
87651
87823
|
}
|
|
87652
87824
|
return null;
|
|
@@ -87890,11 +88062,11 @@ async (params) => {
|
|
|
87890
88062
|
lines.push("## \u270F\uFE0F Target Files (EDIT THESE)");
|
|
87891
88063
|
lines.push("These are the ONLY files you are allowed to modify. Replace TODO or heuristic-only logic with working PTY-aware implementations.");
|
|
87892
88064
|
lines.push("");
|
|
87893
|
-
for (const file2 of
|
|
88065
|
+
for (const file2 of fs33.readdirSync(latestScriptsDir)) {
|
|
87894
88066
|
if (!file2.endsWith(".js")) continue;
|
|
87895
88067
|
if (!targetFileNames.has(file2)) continue;
|
|
87896
88068
|
try {
|
|
87897
|
-
const content =
|
|
88069
|
+
const content = fs33.readFileSync(path40.join(latestScriptsDir, file2), "utf-8");
|
|
87898
88070
|
lines.push(`### \`${file2}\` \u270F\uFE0F EDIT`);
|
|
87899
88071
|
lines.push("```javascript");
|
|
87900
88072
|
lines.push(content);
|
|
@@ -87903,14 +88075,14 @@ async (params) => {
|
|
|
87903
88075
|
} catch {
|
|
87904
88076
|
}
|
|
87905
88077
|
}
|
|
87906
|
-
const refFiles =
|
|
88078
|
+
const refFiles = fs33.readdirSync(latestScriptsDir).filter((f) => f.endsWith(".js") && !targetFileNames.has(f));
|
|
87907
88079
|
if (refFiles.length > 0) {
|
|
87908
88080
|
lines.push("## \u{1F512} Other Scripts (REFERENCE ONLY \u2014 DO NOT EDIT)");
|
|
87909
88081
|
lines.push("These files are shown for context only. Do NOT modify them under any circumstances.");
|
|
87910
88082
|
lines.push("");
|
|
87911
88083
|
for (const file2 of refFiles) {
|
|
87912
88084
|
try {
|
|
87913
|
-
const content =
|
|
88085
|
+
const content = fs33.readFileSync(path40.join(latestScriptsDir, file2), "utf-8");
|
|
87914
88086
|
lines.push(`### \`${file2}\` \u{1F512}`);
|
|
87915
88087
|
lines.push("```javascript");
|
|
87916
88088
|
lines.push(content);
|
|
@@ -87947,7 +88119,7 @@ async (params) => {
|
|
|
87947
88119
|
const loadGuide = (name) => {
|
|
87948
88120
|
try {
|
|
87949
88121
|
const p = path40.join(docsDir, name);
|
|
87950
|
-
if (
|
|
88122
|
+
if (fs33.existsSync(p)) return fs33.readFileSync(p, "utf-8");
|
|
87951
88123
|
} catch {
|
|
87952
88124
|
}
|
|
87953
88125
|
return null;
|
|
@@ -88685,7 +88857,7 @@ data: ${JSON.stringify(msg.data)}
|
|
|
88685
88857
|
path41.join(process.cwd(), "packages/web-devconsole/dist")
|
|
88686
88858
|
];
|
|
88687
88859
|
for (const dir of candidates) {
|
|
88688
|
-
if (
|
|
88860
|
+
if (fs34.existsSync(path41.join(dir, "index.html"))) return dir;
|
|
88689
88861
|
}
|
|
88690
88862
|
return null;
|
|
88691
88863
|
}
|
|
@@ -88697,7 +88869,7 @@ data: ${JSON.stringify(msg.data)}
|
|
|
88697
88869
|
}
|
|
88698
88870
|
const htmlPath = path41.join(distDir, "index.html");
|
|
88699
88871
|
try {
|
|
88700
|
-
const html =
|
|
88872
|
+
const html = fs34.readFileSync(htmlPath, "utf-8");
|
|
88701
88873
|
res.writeHead(200, { "Content-Type": "text/html; charset=utf-8" });
|
|
88702
88874
|
res.end(html);
|
|
88703
88875
|
} catch (e) {
|
|
@@ -88727,7 +88899,7 @@ data: ${JSON.stringify(msg.data)}
|
|
|
88727
88899
|
return;
|
|
88728
88900
|
}
|
|
88729
88901
|
try {
|
|
88730
|
-
const content =
|
|
88902
|
+
const content = fs34.readFileSync(filePath);
|
|
88731
88903
|
const ext = path41.extname(filePath);
|
|
88732
88904
|
const contentType = _DevServer.MIME_MAP[ext] || "application/octet-stream";
|
|
88733
88905
|
res.writeHead(200, { "Content-Type": contentType, "Cache-Control": "public, max-age=31536000, immutable" });
|
|
@@ -88836,14 +89008,14 @@ data: ${JSON.stringify(msg.data)}
|
|
|
88836
89008
|
const files = [];
|
|
88837
89009
|
const scan = (d, prefix) => {
|
|
88838
89010
|
try {
|
|
88839
|
-
for (const entry of
|
|
89011
|
+
for (const entry of fs34.readdirSync(d, { withFileTypes: true })) {
|
|
88840
89012
|
if (entry.name.startsWith(".") || entry.name.endsWith(".bak")) continue;
|
|
88841
89013
|
const rel = prefix ? `${prefix}/${entry.name}` : entry.name;
|
|
88842
89014
|
if (entry.isDirectory()) {
|
|
88843
89015
|
files.push({ path: rel, size: 0, type: "dir" });
|
|
88844
89016
|
scan(path41.join(d, entry.name), rel);
|
|
88845
89017
|
} else {
|
|
88846
|
-
const stat2 =
|
|
89018
|
+
const stat2 = fs34.statSync(path41.join(d, entry.name));
|
|
88847
89019
|
files.push({ path: rel, size: stat2.size, type: "file" });
|
|
88848
89020
|
}
|
|
88849
89021
|
}
|
|
@@ -88871,11 +89043,11 @@ data: ${JSON.stringify(msg.data)}
|
|
|
88871
89043
|
this.json(res, 403, { error: "Forbidden" });
|
|
88872
89044
|
return;
|
|
88873
89045
|
}
|
|
88874
|
-
if (!
|
|
89046
|
+
if (!fs34.existsSync(fullPath) || fs34.statSync(fullPath).isDirectory()) {
|
|
88875
89047
|
this.json(res, 404, { error: `File not found: ${filePath}` });
|
|
88876
89048
|
return;
|
|
88877
89049
|
}
|
|
88878
|
-
const content =
|
|
89050
|
+
const content = fs34.readFileSync(fullPath, "utf-8");
|
|
88879
89051
|
this.json(res, 200, { type, path: filePath, content, lines: content.split("\n").length });
|
|
88880
89052
|
}
|
|
88881
89053
|
/** POST /api/providers/:type/file — write a file { path, content } */
|
|
@@ -88897,9 +89069,9 @@ data: ${JSON.stringify(msg.data)}
|
|
|
88897
89069
|
return;
|
|
88898
89070
|
}
|
|
88899
89071
|
try {
|
|
88900
|
-
if (
|
|
88901
|
-
|
|
88902
|
-
|
|
89072
|
+
if (fs34.existsSync(fullPath)) fs34.copyFileSync(fullPath, fullPath + ".bak");
|
|
89073
|
+
fs34.mkdirSync(path41.dirname(fullPath), { recursive: true });
|
|
89074
|
+
fs34.writeFileSync(fullPath, content, "utf-8");
|
|
88903
89075
|
this.log(`File saved: ${fullPath} (${content.length} chars)`);
|
|
88904
89076
|
this.providerLoader.reload();
|
|
88905
89077
|
this.json(res, 200, { saved: true, path: filePath, chars: content.length });
|
|
@@ -88916,8 +89088,8 @@ data: ${JSON.stringify(msg.data)}
|
|
|
88916
89088
|
}
|
|
88917
89089
|
for (const name of ["scripts.js", "provider.json"]) {
|
|
88918
89090
|
const p = path41.join(dir, name);
|
|
88919
|
-
if (
|
|
88920
|
-
const source =
|
|
89091
|
+
if (fs34.existsSync(p)) {
|
|
89092
|
+
const source = fs34.readFileSync(p, "utf-8");
|
|
88921
89093
|
this.json(res, 200, { type, path: p, source, lines: source.split("\n").length });
|
|
88922
89094
|
return;
|
|
88923
89095
|
}
|
|
@@ -88936,11 +89108,11 @@ data: ${JSON.stringify(msg.data)}
|
|
|
88936
89108
|
this.json(res, 404, { error: `Provider not found: ${type}` });
|
|
88937
89109
|
return;
|
|
88938
89110
|
}
|
|
88939
|
-
const target =
|
|
89111
|
+
const target = fs34.existsSync(path41.join(dir, "scripts.js")) ? "scripts.js" : "provider.json";
|
|
88940
89112
|
const targetPath = path41.join(dir, target);
|
|
88941
89113
|
try {
|
|
88942
|
-
if (
|
|
88943
|
-
|
|
89114
|
+
if (fs34.existsSync(targetPath)) fs34.copyFileSync(targetPath, targetPath + ".bak");
|
|
89115
|
+
fs34.writeFileSync(targetPath, source, "utf-8");
|
|
88944
89116
|
this.log(`Saved provider: ${targetPath} (${source.length} chars)`);
|
|
88945
89117
|
this.providerLoader.reload();
|
|
88946
89118
|
this.json(res, 200, { saved: true, path: targetPath, chars: source.length });
|
|
@@ -89085,20 +89257,20 @@ data: ${JSON.stringify(msg.data)}
|
|
|
89085
89257
|
let targetDir;
|
|
89086
89258
|
targetDir = this.providerLoader.getUserProviderDir(category, type);
|
|
89087
89259
|
const jsonPath = path41.join(targetDir, "provider.json");
|
|
89088
|
-
if (
|
|
89260
|
+
if (fs34.existsSync(jsonPath)) {
|
|
89089
89261
|
this.json(res, 409, { error: `Provider already exists at ${targetDir}`, path: targetDir });
|
|
89090
89262
|
return;
|
|
89091
89263
|
}
|
|
89092
89264
|
try {
|
|
89093
89265
|
const result = generateFiles(type, name, category, { cdpPorts, cli, processName, installPath, binary, extensionId, version: version2, osPaths, processNames });
|
|
89094
|
-
|
|
89095
|
-
|
|
89266
|
+
fs34.mkdirSync(targetDir, { recursive: true });
|
|
89267
|
+
fs34.writeFileSync(jsonPath, result["provider.json"], "utf-8");
|
|
89096
89268
|
const createdFiles = ["provider.json"];
|
|
89097
89269
|
if (result.files) {
|
|
89098
89270
|
for (const [relPath, content] of Object.entries(result.files)) {
|
|
89099
89271
|
const fullPath = path41.join(targetDir, relPath);
|
|
89100
|
-
|
|
89101
|
-
|
|
89272
|
+
fs34.mkdirSync(path41.dirname(fullPath), { recursive: true });
|
|
89273
|
+
fs34.writeFileSync(fullPath, content, "utf-8");
|
|
89102
89274
|
createdFiles.push(relPath);
|
|
89103
89275
|
}
|
|
89104
89276
|
}
|
|
@@ -89147,10 +89319,10 @@ data: ${JSON.stringify(msg.data)}
|
|
|
89147
89319
|
}
|
|
89148
89320
|
// ─── Phase 2: Auto-Implement Backend ───
|
|
89149
89321
|
getLatestScriptVersionDir(scriptsDir) {
|
|
89150
|
-
if (!
|
|
89151
|
-
const versions =
|
|
89322
|
+
if (!fs34.existsSync(scriptsDir)) return null;
|
|
89323
|
+
const versions = fs34.readdirSync(scriptsDir).filter((d) => {
|
|
89152
89324
|
try {
|
|
89153
|
-
return
|
|
89325
|
+
return fs34.statSync(path41.join(scriptsDir, d)).isDirectory();
|
|
89154
89326
|
} catch {
|
|
89155
89327
|
return false;
|
|
89156
89328
|
}
|
|
@@ -89172,13 +89344,13 @@ data: ${JSON.stringify(msg.data)}
|
|
|
89172
89344
|
if (!sourceDir) {
|
|
89173
89345
|
return { dir: null, reason: `Provider source directory not found for '${type}'` };
|
|
89174
89346
|
}
|
|
89175
|
-
if (!
|
|
89176
|
-
|
|
89177
|
-
|
|
89347
|
+
if (!fs34.existsSync(desiredDir)) {
|
|
89348
|
+
fs34.mkdirSync(path41.dirname(desiredDir), { recursive: true });
|
|
89349
|
+
fs34.cpSync(sourceDir, desiredDir, { recursive: true });
|
|
89178
89350
|
this.log(`Auto-implement writable copy created: ${desiredDir}`);
|
|
89179
89351
|
}
|
|
89180
89352
|
const providerJson = path41.join(desiredDir, "provider.json");
|
|
89181
|
-
if (!
|
|
89353
|
+
if (!fs34.existsSync(providerJson)) {
|
|
89182
89354
|
return { dir: null, reason: `provider.json not found in writable provider directory: ${desiredDir}` };
|
|
89183
89355
|
}
|
|
89184
89356
|
return { dir: desiredDir };
|
|
@@ -89221,10 +89393,10 @@ data: ${JSON.stringify(msg.data)}
|
|
|
89221
89393
|
lines.push("## \u270F\uFE0F Target Files (EDIT THESE)");
|
|
89222
89394
|
lines.push("These are the ONLY files you are allowed to modify. Replace the TODO stubs with working implementations.");
|
|
89223
89395
|
lines.push("");
|
|
89224
|
-
for (const file2 of
|
|
89396
|
+
for (const file2 of fs34.readdirSync(latestScriptsDir)) {
|
|
89225
89397
|
if (file2.endsWith(".js") && targetFileNames.has(file2)) {
|
|
89226
89398
|
try {
|
|
89227
|
-
const content =
|
|
89399
|
+
const content = fs34.readFileSync(path41.join(latestScriptsDir, file2), "utf-8");
|
|
89228
89400
|
lines.push(`### \`${file2}\` \u270F\uFE0F EDIT`);
|
|
89229
89401
|
lines.push("```javascript");
|
|
89230
89402
|
lines.push(content);
|
|
@@ -89234,14 +89406,14 @@ data: ${JSON.stringify(msg.data)}
|
|
|
89234
89406
|
}
|
|
89235
89407
|
}
|
|
89236
89408
|
}
|
|
89237
|
-
const refFiles =
|
|
89409
|
+
const refFiles = fs34.readdirSync(latestScriptsDir).filter((f) => f.endsWith(".js") && !targetFileNames.has(f));
|
|
89238
89410
|
if (refFiles.length > 0) {
|
|
89239
89411
|
lines.push("## \u{1F512} Other Scripts (REFERENCE ONLY \u2014 DO NOT EDIT)");
|
|
89240
89412
|
lines.push("These files are shown for context only. Do NOT modify them under any circumstances.");
|
|
89241
89413
|
lines.push("");
|
|
89242
89414
|
for (const file2 of refFiles) {
|
|
89243
89415
|
try {
|
|
89244
|
-
const content =
|
|
89416
|
+
const content = fs34.readFileSync(path41.join(latestScriptsDir, file2), "utf-8");
|
|
89245
89417
|
lines.push(`### \`${file2}\` \u{1F512}`);
|
|
89246
89418
|
lines.push("```javascript");
|
|
89247
89419
|
lines.push(content);
|
|
@@ -89286,7 +89458,7 @@ data: ${JSON.stringify(msg.data)}
|
|
|
89286
89458
|
const loadGuide = (name) => {
|
|
89287
89459
|
try {
|
|
89288
89460
|
const p = path41.join(docsDir, name);
|
|
89289
|
-
if (
|
|
89461
|
+
if (fs34.existsSync(p)) return fs34.readFileSync(p, "utf-8");
|
|
89290
89462
|
} catch {
|
|
89291
89463
|
}
|
|
89292
89464
|
return null;
|
|
@@ -89467,11 +89639,11 @@ data: ${JSON.stringify(msg.data)}
|
|
|
89467
89639
|
lines.push("## \u270F\uFE0F Target Files (EDIT THESE)");
|
|
89468
89640
|
lines.push("These are the ONLY files you are allowed to modify. Replace TODO or heuristic-only logic with working PTY-aware implementations.");
|
|
89469
89641
|
lines.push("");
|
|
89470
|
-
for (const file2 of
|
|
89642
|
+
for (const file2 of fs34.readdirSync(latestScriptsDir)) {
|
|
89471
89643
|
if (!file2.endsWith(".js")) continue;
|
|
89472
89644
|
if (!targetFileNames.has(file2)) continue;
|
|
89473
89645
|
try {
|
|
89474
|
-
const content =
|
|
89646
|
+
const content = fs34.readFileSync(path41.join(latestScriptsDir, file2), "utf-8");
|
|
89475
89647
|
lines.push(`### \`${file2}\` \u270F\uFE0F EDIT`);
|
|
89476
89648
|
lines.push("```javascript");
|
|
89477
89649
|
lines.push(content);
|
|
@@ -89480,14 +89652,14 @@ data: ${JSON.stringify(msg.data)}
|
|
|
89480
89652
|
} catch {
|
|
89481
89653
|
}
|
|
89482
89654
|
}
|
|
89483
|
-
const refFiles =
|
|
89655
|
+
const refFiles = fs34.readdirSync(latestScriptsDir).filter((f) => f.endsWith(".js") && !targetFileNames.has(f));
|
|
89484
89656
|
if (refFiles.length > 0) {
|
|
89485
89657
|
lines.push("## \u{1F512} Other Scripts (REFERENCE ONLY \u2014 DO NOT EDIT)");
|
|
89486
89658
|
lines.push("These files are shown for context only. Do NOT modify them under any circumstances.");
|
|
89487
89659
|
lines.push("");
|
|
89488
89660
|
for (const file2 of refFiles) {
|
|
89489
89661
|
try {
|
|
89490
|
-
const content =
|
|
89662
|
+
const content = fs34.readFileSync(path41.join(latestScriptsDir, file2), "utf-8");
|
|
89491
89663
|
lines.push(`### \`${file2}\` \u{1F512}`);
|
|
89492
89664
|
lines.push("```javascript");
|
|
89493
89665
|
lines.push(content);
|
|
@@ -89524,7 +89696,7 @@ data: ${JSON.stringify(msg.data)}
|
|
|
89524
89696
|
const loadGuide = (name) => {
|
|
89525
89697
|
try {
|
|
89526
89698
|
const p = path41.join(docsDir, name);
|
|
89527
|
-
if (
|
|
89699
|
+
if (fs34.existsSync(p)) return fs34.readFileSync(p, "utf-8");
|
|
89528
89700
|
} catch {
|
|
89529
89701
|
}
|
|
89530
89702
|
return null;
|
|
@@ -90611,8 +90783,8 @@ data: ${JSON.stringify(msg.data)}
|
|
|
90611
90783
|
const res = await fetch(extension.vsixUrl);
|
|
90612
90784
|
if (res.ok) {
|
|
90613
90785
|
const buffer = Buffer.from(await res.arrayBuffer());
|
|
90614
|
-
const
|
|
90615
|
-
|
|
90786
|
+
const fs35 = await import("fs");
|
|
90787
|
+
fs35.writeFileSync(vsixPath, buffer);
|
|
90616
90788
|
return new Promise((resolve24) => {
|
|
90617
90789
|
const cmd = `"${ide.cliCommand}" --install-extension "${vsixPath}" --force`;
|
|
90618
90790
|
(0, import_child_process11.exec)(cmd, { timeout: 6e4 }, (error48, _stdout, stderr) => {
|