@adhdev/daemon-standalone 1.0.58-rc.2 → 1.0.58-rc.4
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
CHANGED
|
@@ -3591,14 +3591,77 @@ var require_dist = __commonJS({
|
|
|
3591
3591
|
}
|
|
3592
3592
|
};
|
|
3593
3593
|
}
|
|
3594
|
+
var establishedSockets2 = /* @__PURE__ */ new WeakSet();
|
|
3594
3595
|
var SessionHostClient2 = class {
|
|
3595
3596
|
endpoint;
|
|
3596
3597
|
socket = null;
|
|
3597
3598
|
requestWaiters = /* @__PURE__ */ new Map();
|
|
3598
3599
|
eventListeners = /* @__PURE__ */ new Set();
|
|
3600
|
+
disconnectListeners = /* @__PURE__ */ new Set();
|
|
3601
|
+
/** Guards against emitting both an 'error'-path and a 'close'-path disconnect for one socket. */
|
|
3602
|
+
disconnectedSockets = /* @__PURE__ */ new WeakSet();
|
|
3599
3603
|
constructor(options = {}) {
|
|
3600
3604
|
this.endpoint = options.endpoint || getDefaultSessionHostEndpoint2(options.appName || "adhdev");
|
|
3601
3605
|
}
|
|
3606
|
+
/**
|
|
3607
|
+
* Fires when an established connection to the session host goes away.
|
|
3608
|
+
*
|
|
3609
|
+
* Before this existed the client registered only 'data' and 'error' handlers,
|
|
3610
|
+
* so a *clean* FIN — the host process exiting normally, or dying to an
|
|
3611
|
+
* uncaught exception that took the socket down without an error event on our
|
|
3612
|
+
* end — ran nothing at all: `this.socket` stayed non-null pointing at a dead
|
|
3613
|
+
* socket, in-flight waiters hung to their 30s timeout, and no caller was told.
|
|
3614
|
+
* That silence is what let a session-host death present downstream as an
|
|
3615
|
+
* unrelated application-level fault (a missing completion marker) instead of
|
|
3616
|
+
* "the host is gone".
|
|
3617
|
+
*/
|
|
3618
|
+
onDisconnect(listener) {
|
|
3619
|
+
this.disconnectListeners.add(listener);
|
|
3620
|
+
return () => {
|
|
3621
|
+
this.disconnectListeners.delete(listener);
|
|
3622
|
+
};
|
|
3623
|
+
}
|
|
3624
|
+
handleDisconnect(socket, reason, error48) {
|
|
3625
|
+
if (this.disconnectedSockets.has(socket)) return;
|
|
3626
|
+
this.disconnectedSockets.add(socket);
|
|
3627
|
+
const wasEstablished = establishedSockets2.has(socket);
|
|
3628
|
+
if (!wasEstablished) {
|
|
3629
|
+
if (this.socket === socket) this.socket = null;
|
|
3630
|
+
try {
|
|
3631
|
+
socket.destroy();
|
|
3632
|
+
} catch {
|
|
3633
|
+
}
|
|
3634
|
+
const failure2 = error48 || new Error(`Session host connect failed (${this.endpoint.path})`);
|
|
3635
|
+
for (const waiter of this.requestWaiters.values()) waiter.reject(failure2);
|
|
3636
|
+
this.requestWaiters.clear();
|
|
3637
|
+
return;
|
|
3638
|
+
}
|
|
3639
|
+
const pendingRequests = this.requestWaiters.size;
|
|
3640
|
+
const failure = error48 || new Error(`Session host connection ${reason} (${this.endpoint.path})`);
|
|
3641
|
+
for (const waiter of this.requestWaiters.values()) {
|
|
3642
|
+
waiter.reject(failure);
|
|
3643
|
+
}
|
|
3644
|
+
this.requestWaiters.clear();
|
|
3645
|
+
if (this.socket === socket) {
|
|
3646
|
+
this.socket = null;
|
|
3647
|
+
}
|
|
3648
|
+
try {
|
|
3649
|
+
socket.destroy();
|
|
3650
|
+
} catch {
|
|
3651
|
+
}
|
|
3652
|
+
const info = {
|
|
3653
|
+
reason,
|
|
3654
|
+
endpointPath: this.endpoint.path,
|
|
3655
|
+
pendingRequests,
|
|
3656
|
+
error: error48
|
|
3657
|
+
};
|
|
3658
|
+
for (const listener of this.disconnectListeners) {
|
|
3659
|
+
try {
|
|
3660
|
+
listener(info);
|
|
3661
|
+
} catch {
|
|
3662
|
+
}
|
|
3663
|
+
}
|
|
3664
|
+
}
|
|
3602
3665
|
async connect() {
|
|
3603
3666
|
if (this.socket && !this.socket.destroyed) return;
|
|
3604
3667
|
if (this.socket) {
|
|
@@ -3624,20 +3687,19 @@ var require_dist = __commonJS({
|
|
|
3624
3687
|
}
|
|
3625
3688
|
}));
|
|
3626
3689
|
socket.on("error", (error48) => {
|
|
3627
|
-
|
|
3628
|
-
|
|
3629
|
-
|
|
3630
|
-
this.
|
|
3631
|
-
|
|
3632
|
-
|
|
3633
|
-
|
|
3634
|
-
try {
|
|
3635
|
-
socket.destroy();
|
|
3636
|
-
} catch {
|
|
3637
|
-
}
|
|
3690
|
+
this.handleDisconnect(socket, "error", error48);
|
|
3691
|
+
});
|
|
3692
|
+
socket.on("close", () => {
|
|
3693
|
+
this.handleDisconnect(socket, "closed");
|
|
3694
|
+
});
|
|
3695
|
+
socket.on("end", () => {
|
|
3696
|
+
this.handleDisconnect(socket, "ended");
|
|
3638
3697
|
});
|
|
3639
3698
|
await new Promise((resolve3, reject) => {
|
|
3640
|
-
socket.once("connect", () =>
|
|
3699
|
+
socket.once("connect", () => {
|
|
3700
|
+
establishedSockets2.add(socket);
|
|
3701
|
+
resolve3();
|
|
3702
|
+
});
|
|
3641
3703
|
socket.once("error", reject);
|
|
3642
3704
|
});
|
|
3643
3705
|
}
|
|
@@ -3679,6 +3741,7 @@ var require_dist = __commonJS({
|
|
|
3679
3741
|
if (!this.socket) return;
|
|
3680
3742
|
const socket = this.socket;
|
|
3681
3743
|
this.socket = null;
|
|
3744
|
+
this.disconnectedSockets.add(socket);
|
|
3682
3745
|
for (const waiter of this.requestWaiters.values()) {
|
|
3683
3746
|
waiter.reject(new Error("Session host client closed"));
|
|
3684
3747
|
}
|
|
@@ -36768,10 +36831,10 @@ var require_dist3 = __commonJS({
|
|
|
36768
36831
|
}
|
|
36769
36832
|
function getDaemonBuildInfo() {
|
|
36770
36833
|
if (cached2) return cached2;
|
|
36771
|
-
const commit = readInjected(true ? "
|
|
36772
|
-
const commitShort = readInjected(true ? "
|
|
36773
|
-
const version2 = readInjected(true ? "1.0.58-rc.
|
|
36774
|
-
const builtAt = readInjected(true ? "2026-08-
|
|
36834
|
+
const commit = readInjected(true ? "388d6e74b391ae9afd94d860aed141063297dca9" : void 0) ?? "unknown";
|
|
36835
|
+
const commitShort = readInjected(true ? "388d6e74" : void 0) ?? (commit !== "unknown" ? commit.slice(0, 7) : "unknown");
|
|
36836
|
+
const version2 = readInjected(true ? "1.0.58-rc.4" : void 0) ?? readInjected(typeof process !== "undefined" ? process.env?.ADHDEV_PKG_VERSION : void 0) ?? "unknown";
|
|
36837
|
+
const builtAt = readInjected(true ? "2026-08-23T04:11:22.908Z" : void 0);
|
|
36775
36838
|
cached2 = builtAt ? { commit, commitShort, version: version2, builtAt } : { commit, commitShort, version: version2 };
|
|
36776
36839
|
return cached2;
|
|
36777
36840
|
}
|
|
@@ -38186,7 +38249,9 @@ var require_dist3 = __commonJS({
|
|
|
38186
38249
|
}
|
|
38187
38250
|
}
|
|
38188
38251
|
function sizeRotationPath(logFile, generation) {
|
|
38189
|
-
|
|
38252
|
+
const match = logFile.match(/^(.*)(\.[^./\\]+)$/);
|
|
38253
|
+
if (!match) return `${logFile}.${generation}`;
|
|
38254
|
+
return `${match[1]}.${generation}${match[2]}`;
|
|
38190
38255
|
}
|
|
38191
38256
|
function rotateSizeGenerations(logFile, maxGenerations = MAX_SIZE_ROTATION_GENERATIONS) {
|
|
38192
38257
|
if (maxGenerations < 1) return;
|
|
@@ -38205,6 +38270,20 @@ var require_dist3 = __commonJS({
|
|
|
38205
38270
|
}
|
|
38206
38271
|
fs22.renameSync(logFile, sizeRotationPath(logFile, 1));
|
|
38207
38272
|
}
|
|
38273
|
+
function rotateCaptureLogIfNeeded(logPath, maxSize = MAX_CAPTURE_LOG_SIZE, maxGenerations = MAX_CAPTURE_LOG_GENERATIONS) {
|
|
38274
|
+
try {
|
|
38275
|
+
const stat2 = fs22.statSync(logPath);
|
|
38276
|
+
if (stat2.size <= maxSize) return false;
|
|
38277
|
+
} catch {
|
|
38278
|
+
return false;
|
|
38279
|
+
}
|
|
38280
|
+
try {
|
|
38281
|
+
rotateSizeGenerations(logPath, maxGenerations);
|
|
38282
|
+
return true;
|
|
38283
|
+
} catch {
|
|
38284
|
+
return false;
|
|
38285
|
+
}
|
|
38286
|
+
}
|
|
38208
38287
|
function rotateSizeIfNeeded() {
|
|
38209
38288
|
try {
|
|
38210
38289
|
const stat2 = fs22.statSync(currentLogFile);
|
|
@@ -38343,6 +38422,8 @@ var require_dist3 = __commonJS({
|
|
|
38343
38422
|
var currentDate;
|
|
38344
38423
|
var currentLogDir;
|
|
38345
38424
|
var currentLogFile;
|
|
38425
|
+
var MAX_CAPTURE_LOG_SIZE;
|
|
38426
|
+
var MAX_CAPTURE_LOG_GENERATIONS;
|
|
38346
38427
|
var preparedLogDirs;
|
|
38347
38428
|
var writeCount;
|
|
38348
38429
|
var currentLogDirEnv;
|
|
@@ -38371,6 +38452,8 @@ var require_dist3 = __commonJS({
|
|
|
38371
38452
|
currentDate = getDateStr();
|
|
38372
38453
|
currentLogDir = resolveLogDir();
|
|
38373
38454
|
currentLogFile = path32.join(currentLogDir, daemonLogFileName(currentDate));
|
|
38455
|
+
MAX_CAPTURE_LOG_SIZE = 10 * 1024 * 1024;
|
|
38456
|
+
MAX_CAPTURE_LOG_GENERATIONS = 2;
|
|
38374
38457
|
preparedLogDirs = /* @__PURE__ */ new Set();
|
|
38375
38458
|
writeCount = 0;
|
|
38376
38459
|
currentLogDirEnv = process.env.ADHDEV_CONFIG_DIR;
|
|
@@ -44117,25 +44200,75 @@ ${error48.message || ""}`;
|
|
|
44117
44200
|
function getMeshConfigPath() {
|
|
44118
44201
|
return (0, import_path5.join)(getConfigDir2(), "meshes.json");
|
|
44119
44202
|
}
|
|
44120
|
-
function
|
|
44203
|
+
function sleepBlockingMs(ms) {
|
|
44204
|
+
if (ms <= 0) return;
|
|
44205
|
+
Atomics.wait(new Int32Array(new SharedArrayBuffer(4)), 0, 0, ms);
|
|
44206
|
+
}
|
|
44207
|
+
function acquireMeshConfigLock() {
|
|
44208
|
+
const lockPath = `${getMeshConfigPath()}.lock`;
|
|
44209
|
+
const deadline = Date.now() + MESH_CONFIG_LOCK_WAIT_MS;
|
|
44210
|
+
while (Date.now() <= deadline) {
|
|
44211
|
+
try {
|
|
44212
|
+
(0, import_fs5.mkdirSync)(lockPath);
|
|
44213
|
+
return () => {
|
|
44214
|
+
try {
|
|
44215
|
+
(0, import_fs5.rmSync)(lockPath, { recursive: true, force: true });
|
|
44216
|
+
} catch {
|
|
44217
|
+
}
|
|
44218
|
+
};
|
|
44219
|
+
} catch (error48) {
|
|
44220
|
+
if (error48?.code !== "EEXIST") return null;
|
|
44221
|
+
try {
|
|
44222
|
+
const stat2 = (0, import_fs5.statSync)(lockPath);
|
|
44223
|
+
if (Date.now() - stat2.mtimeMs > MESH_CONFIG_LOCK_STALE_MS) {
|
|
44224
|
+
(0, import_fs5.rmSync)(lockPath, { recursive: true, force: true });
|
|
44225
|
+
continue;
|
|
44226
|
+
}
|
|
44227
|
+
} catch {
|
|
44228
|
+
continue;
|
|
44229
|
+
}
|
|
44230
|
+
sleepBlockingMs(MESH_CONFIG_LOCK_POLL_MS);
|
|
44231
|
+
}
|
|
44232
|
+
}
|
|
44233
|
+
return null;
|
|
44234
|
+
}
|
|
44235
|
+
function withMeshConfigWriteLock(fn) {
|
|
44236
|
+
if (meshConfigLockHeldInProcess) return fn();
|
|
44237
|
+
const release2 = acquireMeshConfigLock();
|
|
44238
|
+
if (!release2) return fn();
|
|
44239
|
+
meshConfigLockHeldInProcess = true;
|
|
44240
|
+
try {
|
|
44241
|
+
return fn();
|
|
44242
|
+
} finally {
|
|
44243
|
+
meshConfigLockHeldInProcess = false;
|
|
44244
|
+
release2();
|
|
44245
|
+
}
|
|
44246
|
+
}
|
|
44247
|
+
function readMeshConfigFile() {
|
|
44121
44248
|
const path60 = getMeshConfigPath();
|
|
44122
44249
|
if (!(0, import_fs5.existsSync)(path60)) return { meshes: [] };
|
|
44123
44250
|
try {
|
|
44124
44251
|
const raw = JSON.parse((0, import_fs5.readFileSync)(path60, "utf-8"));
|
|
44125
44252
|
if (!raw || !Array.isArray(raw.meshes)) return { meshes: [] };
|
|
44126
|
-
|
|
44127
|
-
const migrated = migrateLoadedMeshConfig(config2);
|
|
44128
|
-
if (migrated && options.persistMigrations !== false) {
|
|
44129
|
-
try {
|
|
44130
|
-
saveMeshConfig(config2);
|
|
44131
|
-
} catch {
|
|
44132
|
-
}
|
|
44133
|
-
}
|
|
44134
|
-
return config2;
|
|
44253
|
+
return raw;
|
|
44135
44254
|
} catch {
|
|
44136
44255
|
return { meshes: [] };
|
|
44137
44256
|
}
|
|
44138
44257
|
}
|
|
44258
|
+
function loadMeshConfig(options = {}) {
|
|
44259
|
+
const config2 = readMeshConfigFile();
|
|
44260
|
+
const migrated = migrateLoadedMeshConfig(config2);
|
|
44261
|
+
if (migrated && options.persistMigrations !== false) {
|
|
44262
|
+
try {
|
|
44263
|
+
withMeshConfigWriteLock(() => {
|
|
44264
|
+
const fresh = readMeshConfigFile();
|
|
44265
|
+
if (migrateLoadedMeshConfig(fresh)) saveMeshConfig(fresh);
|
|
44266
|
+
});
|
|
44267
|
+
} catch {
|
|
44268
|
+
}
|
|
44269
|
+
}
|
|
44270
|
+
return config2;
|
|
44271
|
+
}
|
|
44139
44272
|
function migrateLoadedMeshConfig(config2) {
|
|
44140
44273
|
let changed = false;
|
|
44141
44274
|
if (foldLegacyTopLevelMeshSetting(config2, "magiKindPanels", "mesh_magi_kind_panel_set({ meshId, task_kind, slots })")) changed = true;
|
|
@@ -44220,7 +44353,9 @@ ${error48.message || ""}`;
|
|
|
44220
44353
|
}
|
|
44221
44354
|
function saveMeshConfig(config2) {
|
|
44222
44355
|
const path60 = getMeshConfigPath();
|
|
44223
|
-
|
|
44356
|
+
const tmpPath = `${path60}.tmp-${process.pid}`;
|
|
44357
|
+
(0, import_fs5.writeFileSync)(tmpPath, JSON.stringify(config2, null, 2), { encoding: "utf-8", mode: 384 });
|
|
44358
|
+
(0, import_fs5.renameSync)(tmpPath, path60);
|
|
44224
44359
|
}
|
|
44225
44360
|
function normalizeRepoIdentity(remoteUrl) {
|
|
44226
44361
|
let identity = remoteUrl.trim().replace(/[?#].*$/, "").replace(/\/+$/, "");
|
|
@@ -44260,7 +44395,10 @@ ${error48.message || ""}`;
|
|
|
44260
44395
|
const normalized = normalizeRepoIdentity(repoIdentity);
|
|
44261
44396
|
return loadMeshConfig().meshes.find((m) => normalizeRepoIdentity(m.repoIdentity) === normalized);
|
|
44262
44397
|
}
|
|
44263
|
-
function createMesh(
|
|
44398
|
+
function createMesh(...args) {
|
|
44399
|
+
return withMeshConfigWriteLock(() => createMeshUnlocked(...args));
|
|
44400
|
+
}
|
|
44401
|
+
function createMeshUnlocked(opts) {
|
|
44264
44402
|
const config2 = loadMeshConfig();
|
|
44265
44403
|
if (config2.meshes.length >= 20) {
|
|
44266
44404
|
throw new Error("Maximum 20 meshes allowed");
|
|
@@ -44289,7 +44427,10 @@ ${error48.message || ""}`;
|
|
|
44289
44427
|
saveMeshConfig(config2);
|
|
44290
44428
|
return mesh;
|
|
44291
44429
|
}
|
|
44292
|
-
function updateMesh(
|
|
44430
|
+
function updateMesh(...args) {
|
|
44431
|
+
return withMeshConfigWriteLock(() => updateMeshUnlocked(...args));
|
|
44432
|
+
}
|
|
44433
|
+
function updateMeshUnlocked(meshId, opts) {
|
|
44293
44434
|
const config2 = loadMeshConfig();
|
|
44294
44435
|
const mesh = config2.meshes.find((m) => m.id === meshId);
|
|
44295
44436
|
if (!mesh) return void 0;
|
|
@@ -44302,7 +44443,10 @@ ${error48.message || ""}`;
|
|
|
44302
44443
|
saveMeshConfig(config2);
|
|
44303
44444
|
return mesh;
|
|
44304
44445
|
}
|
|
44305
|
-
function deleteMesh(
|
|
44446
|
+
function deleteMesh(...args) {
|
|
44447
|
+
return withMeshConfigWriteLock(() => deleteMeshUnlocked(...args));
|
|
44448
|
+
}
|
|
44449
|
+
function deleteMeshUnlocked(meshId) {
|
|
44306
44450
|
const config2 = loadMeshConfig();
|
|
44307
44451
|
const idx = config2.meshes.findIndex((m) => m.id === meshId);
|
|
44308
44452
|
if (idx === -1) return false;
|
|
@@ -44349,7 +44493,10 @@ ${error48.message || ""}`;
|
|
|
44349
44493
|
}
|
|
44350
44494
|
return { ok: true, tokenId: presentedTokenId };
|
|
44351
44495
|
}
|
|
44352
|
-
function configureMeshHostPairing(
|
|
44496
|
+
function configureMeshHostPairing(...args) {
|
|
44497
|
+
return withMeshConfigWriteLock(() => configureMeshHostPairingUnlocked(...args));
|
|
44498
|
+
}
|
|
44499
|
+
function configureMeshHostPairingUnlocked(meshId, opts) {
|
|
44353
44500
|
const hostAddress = normalizeManualHostAddress(opts.hostAddress);
|
|
44354
44501
|
const token = opts.token.trim();
|
|
44355
44502
|
if (!token) throw new Error("token required");
|
|
@@ -44373,7 +44520,10 @@ ${error48.message || ""}`;
|
|
|
44373
44520
|
saveMeshConfig(config2);
|
|
44374
44521
|
return { mesh, meshHost, hostAddress };
|
|
44375
44522
|
}
|
|
44376
|
-
function createMeshHostPairingToken(
|
|
44523
|
+
function createMeshHostPairingToken(...args) {
|
|
44524
|
+
return withMeshConfigWriteLock(() => createMeshHostPairingTokenUnlocked(...args));
|
|
44525
|
+
}
|
|
44526
|
+
function createMeshHostPairingTokenUnlocked(meshId, opts = {}) {
|
|
44377
44527
|
const config2 = loadMeshConfig();
|
|
44378
44528
|
const mesh = config2.meshes.find((m) => m.id === meshId);
|
|
44379
44529
|
if (!mesh) return void 0;
|
|
@@ -44401,7 +44551,10 @@ ${error48.message || ""}`;
|
|
|
44401
44551
|
saveMeshConfig(config2);
|
|
44402
44552
|
return { mesh, meshHost, token, tokenId, ...expiresAt ? { expiresAt } : {} };
|
|
44403
44553
|
}
|
|
44404
|
-
function applyMeshHostJoinRequest(
|
|
44554
|
+
function applyMeshHostJoinRequest(...args) {
|
|
44555
|
+
return withMeshConfigWriteLock(() => applyMeshHostJoinRequestUnlocked(...args));
|
|
44556
|
+
}
|
|
44557
|
+
function applyMeshHostJoinRequestUnlocked(meshId, opts) {
|
|
44405
44558
|
const config2 = loadMeshConfig();
|
|
44406
44559
|
const mesh = config2.meshes.find((m) => m.id === meshId);
|
|
44407
44560
|
if (!mesh) return void 0;
|
|
@@ -44466,7 +44619,10 @@ ${error48.message || ""}`;
|
|
|
44466
44619
|
saveMeshConfig(config2);
|
|
44467
44620
|
return { accepted: true, mesh, meshHost: mesh.meshHost, node, tokenId: validation.tokenId };
|
|
44468
44621
|
}
|
|
44469
|
-
function setMeshHostPin(
|
|
44622
|
+
function setMeshHostPin(...args) {
|
|
44623
|
+
return withMeshConfigWriteLock(() => setMeshHostPinUnlocked(...args));
|
|
44624
|
+
}
|
|
44625
|
+
function setMeshHostPinUnlocked(meshId, opts) {
|
|
44470
44626
|
const config2 = loadMeshConfig();
|
|
44471
44627
|
const mesh = config2.meshes.find((m) => m.id === meshId);
|
|
44472
44628
|
if (!mesh) return void 0;
|
|
@@ -44546,7 +44702,10 @@ ${error48.message || ""}`;
|
|
|
44546
44702
|
...mesh.meshHost.hostNodeId ? { hostNodeId: mesh.meshHost.hostNodeId } : {}
|
|
44547
44703
|
};
|
|
44548
44704
|
}
|
|
44549
|
-
function markMeshHostPairingJoined(
|
|
44705
|
+
function markMeshHostPairingJoined(...args) {
|
|
44706
|
+
return withMeshConfigWriteLock(() => markMeshHostPairingJoinedUnlocked(...args));
|
|
44707
|
+
}
|
|
44708
|
+
function markMeshHostPairingJoinedUnlocked(meshId, opts) {
|
|
44550
44709
|
const config2 = loadMeshConfig();
|
|
44551
44710
|
const mesh = config2.meshes.find((m) => m.id === meshId);
|
|
44552
44711
|
if (!mesh) return void 0;
|
|
@@ -44570,7 +44729,10 @@ ${error48.message || ""}`;
|
|
|
44570
44729
|
saveMeshConfig(config2);
|
|
44571
44730
|
return { mesh, meshHost: mesh.meshHost };
|
|
44572
44731
|
}
|
|
44573
|
-
function addNode(
|
|
44732
|
+
function addNode(...args) {
|
|
44733
|
+
return withMeshConfigWriteLock(() => addNodeUnlocked(...args));
|
|
44734
|
+
}
|
|
44735
|
+
function addNodeUnlocked(meshId, opts) {
|
|
44574
44736
|
const config2 = loadMeshConfig();
|
|
44575
44737
|
const mesh = config2.meshes.find((m) => m.id === meshId);
|
|
44576
44738
|
if (!mesh) return void 0;
|
|
@@ -44617,7 +44779,10 @@ ${error48.message || ""}`;
|
|
|
44617
44779
|
saveMeshConfig(config2);
|
|
44618
44780
|
return node;
|
|
44619
44781
|
}
|
|
44620
|
-
function removeNode(
|
|
44782
|
+
function removeNode(...args) {
|
|
44783
|
+
return withMeshConfigWriteLock(() => removeNodeUnlocked(...args));
|
|
44784
|
+
}
|
|
44785
|
+
function removeNodeUnlocked(meshId, nodeId) {
|
|
44621
44786
|
const config2 = loadMeshConfig();
|
|
44622
44787
|
const mesh = config2.meshes.find((m) => m.id === meshId);
|
|
44623
44788
|
if (!mesh) return false;
|
|
@@ -44629,7 +44794,10 @@ ${error48.message || ""}`;
|
|
|
44629
44794
|
saveMeshConfig(config2);
|
|
44630
44795
|
return true;
|
|
44631
44796
|
}
|
|
44632
|
-
function updateNode(
|
|
44797
|
+
function updateNode(...args) {
|
|
44798
|
+
return withMeshConfigWriteLock(() => updateNodeUnlocked(...args));
|
|
44799
|
+
}
|
|
44800
|
+
function updateNodeUnlocked(meshId, nodeId, opts) {
|
|
44633
44801
|
const config2 = loadMeshConfig();
|
|
44634
44802
|
const mesh = config2.meshes.find((m) => m.id === meshId);
|
|
44635
44803
|
if (!mesh) return void 0;
|
|
@@ -44759,7 +44927,10 @@ ${error48.message || ""}`;
|
|
|
44759
44927
|
const config2 = loadMeshConfig();
|
|
44760
44928
|
return resolveScopedMesh(config2, meshId)?.magiKindPanels?.[key2];
|
|
44761
44929
|
}
|
|
44762
|
-
function setMagiKindPanel(
|
|
44930
|
+
function setMagiKindPanel(...args) {
|
|
44931
|
+
return withMeshConfigWriteLock(() => setMagiKindPanelUnlocked(...args));
|
|
44932
|
+
}
|
|
44933
|
+
function setMagiKindPanelUnlocked(kind, slots, meshId) {
|
|
44763
44934
|
const key2 = normalizeMagiTaskKindKey(kind);
|
|
44764
44935
|
const stored = loadMeshConfig();
|
|
44765
44936
|
const mesh = resolveScopedMesh(stored, meshId);
|
|
@@ -44776,7 +44947,10 @@ ${error48.message || ""}`;
|
|
|
44776
44947
|
saveMeshConfig(stored);
|
|
44777
44948
|
return normalized;
|
|
44778
44949
|
}
|
|
44779
|
-
function removeMagiKindPanel(
|
|
44950
|
+
function removeMagiKindPanel(...args) {
|
|
44951
|
+
return withMeshConfigWriteLock(() => removeMagiKindPanelUnlocked(...args));
|
|
44952
|
+
}
|
|
44953
|
+
function removeMagiKindPanelUnlocked(kind, meshId) {
|
|
44780
44954
|
let key2;
|
|
44781
44955
|
try {
|
|
44782
44956
|
key2 = normalizeMagiTaskKindKey(kind);
|
|
@@ -44813,7 +44987,10 @@ ${error48.message || ""}`;
|
|
|
44813
44987
|
const normalized = normalizeDifficultyBrainMap(stored);
|
|
44814
44988
|
return Object.keys(normalized).length > 0 ? normalized : { ...DEFAULT_DIFFICULTY_BRAINS };
|
|
44815
44989
|
}
|
|
44816
|
-
function setDifficultyBrains(
|
|
44990
|
+
function setDifficultyBrains(...args) {
|
|
44991
|
+
return withMeshConfigWriteLock(() => setDifficultyBrainsUnlocked(...args));
|
|
44992
|
+
}
|
|
44993
|
+
function setDifficultyBrainsUnlocked(map3, meshId) {
|
|
44817
44994
|
const normalized = normalizeDifficultyBrainMap(map3);
|
|
44818
44995
|
const stored = loadMeshConfig();
|
|
44819
44996
|
const mesh = resolveScopedMesh(stored, meshId);
|
|
@@ -44859,7 +45036,10 @@ ${error48.message || ""}`;
|
|
|
44859
45036
|
const stored = resolveScopedMesh(config2, meshId)?.policy?.quotaRouting;
|
|
44860
45037
|
return normalizeQuotaRoutingPolicy(stored) ?? {};
|
|
44861
45038
|
}
|
|
44862
|
-
function setMeshQuotaRouting(
|
|
45039
|
+
function setMeshQuotaRouting(...args) {
|
|
45040
|
+
return withMeshConfigWriteLock(() => setMeshQuotaRoutingUnlocked(...args));
|
|
45041
|
+
}
|
|
45042
|
+
function setMeshQuotaRoutingUnlocked(input, meshId) {
|
|
44863
45043
|
const overrides = validateQuotaRoutingOverrides(input);
|
|
44864
45044
|
const stored = loadMeshConfig();
|
|
44865
45045
|
const mesh = resolveScopedMesh(stored, meshId);
|
|
@@ -44876,6 +45056,10 @@ ${error48.message || ""}`;
|
|
|
44876
45056
|
var import_fs5;
|
|
44877
45057
|
var import_path5;
|
|
44878
45058
|
var import_crypto3;
|
|
45059
|
+
var MESH_CONFIG_LOCK_WAIT_MS;
|
|
45060
|
+
var MESH_CONFIG_LOCK_STALE_MS;
|
|
45061
|
+
var MESH_CONFIG_LOCK_POLL_MS;
|
|
45062
|
+
var meshConfigLockHeldInProcess;
|
|
44879
45063
|
var mergeMeshPolicy;
|
|
44880
45064
|
var MAGI_KIND_PANEL_KINDS;
|
|
44881
45065
|
var MAX_MAGI_KIND_SLOTS;
|
|
@@ -44894,6 +45078,10 @@ ${error48.message || ""}`;
|
|
|
44894
45078
|
init_dist();
|
|
44895
45079
|
init_repo_mesh_types();
|
|
44896
45080
|
init_mesh_host_ownership();
|
|
45081
|
+
MESH_CONFIG_LOCK_WAIT_MS = 2e3;
|
|
45082
|
+
MESH_CONFIG_LOCK_STALE_MS = 15e3;
|
|
45083
|
+
MESH_CONFIG_LOCK_POLL_MS = 25;
|
|
45084
|
+
meshConfigLockHeldInProcess = false;
|
|
44897
45085
|
mergeMeshPolicy = mergeAndNormalizePolicy;
|
|
44898
45086
|
MAGI_KIND_PANEL_KINDS = ["claim_audit", "rca", "design", "freeform"];
|
|
44899
45087
|
MAX_MAGI_KIND_SLOTS = 24;
|
|
@@ -49721,6 +49909,176 @@ The instruction it carried was never delivered to anyone. If it still matters, r
|
|
|
49721
49909
|
PARK_RETENTION_EXPIRED_REASON = "parked_task_retention_expired";
|
|
49722
49910
|
}
|
|
49723
49911
|
});
|
|
49912
|
+
function isWorkerAbsenceDispatchFailure(reason) {
|
|
49913
|
+
const text = readNonEmptyString(reason);
|
|
49914
|
+
if (!text) return false;
|
|
49915
|
+
const normalized = text.toLowerCase();
|
|
49916
|
+
return normalized.includes("cli agent not running") || normalized.includes("no provider instance for session") || normalized.includes("no mesh worker session bound to node");
|
|
49917
|
+
}
|
|
49918
|
+
function resolveTunedReconcileMs(envName, def, min, max) {
|
|
49919
|
+
const raw = readNonEmptyString(process.env[envName]);
|
|
49920
|
+
if (raw) {
|
|
49921
|
+
const parsed = Number.parseInt(raw, 10);
|
|
49922
|
+
if (Number.isFinite(parsed) && parsed >= min && parsed <= max) return parsed;
|
|
49923
|
+
}
|
|
49924
|
+
return def;
|
|
49925
|
+
}
|
|
49926
|
+
function resolveAckedDeathDeadlineMs() {
|
|
49927
|
+
return resolveTunedReconcileMs("MESH_INFLIGHT_ACKED_DEATH_DEADLINE_MS", 8 * 6e4, 0, 60 * 6e4);
|
|
49928
|
+
}
|
|
49929
|
+
function resolveAckedTranscriptFastTrackGraceMs() {
|
|
49930
|
+
return resolveTunedReconcileMs("MESH_INFLIGHT_ACKED_TRANSCRIPT_FASTTRACK_GRACE_MS", 4e4, 0, 5 * 6e4);
|
|
49931
|
+
}
|
|
49932
|
+
function resolveAckedHoldHardCeilingMs() {
|
|
49933
|
+
return resolveTunedReconcileMs("MESH_INFLIGHT_ACKED_HOLD_HARD_CEILING_MS", 90 * 6e4, 0, 24 * 60 * 6e4);
|
|
49934
|
+
}
|
|
49935
|
+
function inFlightSynthKey(meshId, taskId) {
|
|
49936
|
+
return `${meshId}::${taskId}`;
|
|
49937
|
+
}
|
|
49938
|
+
function taskIdFromSynthKey(meshId, synthKey) {
|
|
49939
|
+
const prefix = `${meshId}::`;
|
|
49940
|
+
return synthKey.startsWith(prefix) ? synthKey.slice(prefix.length) : synthKey;
|
|
49941
|
+
}
|
|
49942
|
+
function holdStore() {
|
|
49943
|
+
try {
|
|
49944
|
+
return MeshRuntimeStore.getInstance();
|
|
49945
|
+
} catch {
|
|
49946
|
+
return void 0;
|
|
49947
|
+
}
|
|
49948
|
+
}
|
|
49949
|
+
function getHoldState(synthKey, meshId) {
|
|
49950
|
+
const cached5 = inFlightAckedHoldState.get(synthKey);
|
|
49951
|
+
if (cached5) return cached5;
|
|
49952
|
+
const store = holdStore();
|
|
49953
|
+
if (!store) return void 0;
|
|
49954
|
+
let row;
|
|
49955
|
+
try {
|
|
49956
|
+
row = store.getInflightHold(taskIdFromSynthKey(meshId, synthKey));
|
|
49957
|
+
} catch {
|
|
49958
|
+
return void 0;
|
|
49959
|
+
}
|
|
49960
|
+
if (!row) return void 0;
|
|
49961
|
+
const state = {
|
|
49962
|
+
liveConfirmedSinceAck: row.holdReason === "live",
|
|
49963
|
+
consecutiveReadFailures: row.readFailureCount ?? 0,
|
|
49964
|
+
...row.firstIdleSinceAck !== null && row.firstIdleSinceAck !== void 0 ? { transcriptIdleSinceMs: row.firstIdleSinceAck } : {},
|
|
49965
|
+
...row.heldAt !== null && row.heldAt !== void 0 ? { heldSinceMs: row.heldAt } : {}
|
|
49966
|
+
};
|
|
49967
|
+
inFlightAckedHoldState.set(synthKey, state);
|
|
49968
|
+
return state;
|
|
49969
|
+
}
|
|
49970
|
+
function setHoldState(synthKey, meshId, state) {
|
|
49971
|
+
const store = holdStore();
|
|
49972
|
+
let priorHeldSinceMs = state.heldSinceMs ?? inFlightAckedHoldState.get(synthKey)?.heldSinceMs;
|
|
49973
|
+
if (priorHeldSinceMs === void 0 && store) {
|
|
49974
|
+
try {
|
|
49975
|
+
priorHeldSinceMs = store.getInflightHold(taskIdFromSynthKey(meshId, synthKey))?.heldAt ?? void 0;
|
|
49976
|
+
} catch {
|
|
49977
|
+
}
|
|
49978
|
+
}
|
|
49979
|
+
const heldSinceMs = priorHeldSinceMs ?? Date.now();
|
|
49980
|
+
inFlightAckedHoldState.set(synthKey, { ...state, heldSinceMs });
|
|
49981
|
+
if (!store) return;
|
|
49982
|
+
try {
|
|
49983
|
+
store.upsertInflightHold({
|
|
49984
|
+
taskId: taskIdFromSynthKey(meshId, synthKey),
|
|
49985
|
+
meshId,
|
|
49986
|
+
holdReason: state.liveConfirmedSinceAck ? "live" : "unconfirmed",
|
|
49987
|
+
// Only meaningful when the row is NEW — upsertInflightHold deliberately
|
|
49988
|
+
// preserves held_at on conflict, so an existing row keeps its original anchor.
|
|
49989
|
+
heldAt: heldSinceMs,
|
|
49990
|
+
firstIdleSinceAck: state.transcriptIdleSinceMs ?? null,
|
|
49991
|
+
readFailureCount: state.consecutiveReadFailures
|
|
49992
|
+
});
|
|
49993
|
+
} catch {
|
|
49994
|
+
}
|
|
49995
|
+
}
|
|
49996
|
+
function deleteHoldState(synthKey, meshId) {
|
|
49997
|
+
inFlightAckedHoldState.delete(synthKey);
|
|
49998
|
+
const store = holdStore();
|
|
49999
|
+
if (!store) return;
|
|
50000
|
+
try {
|
|
50001
|
+
store.deleteInflightHold(taskIdFromSynthKey(meshId, synthKey));
|
|
50002
|
+
} catch {
|
|
50003
|
+
}
|
|
50004
|
+
}
|
|
50005
|
+
function recordAckedHoldDispatchOutcome(meshId, taskId, outcome) {
|
|
50006
|
+
const key2 = inFlightSynthKey(meshId, taskId);
|
|
50007
|
+
if (outcome.ok || !isWorkerAbsenceDispatchFailure(outcome.reason)) {
|
|
50008
|
+
ackedHoldDispatchFailureStreak.delete(key2);
|
|
50009
|
+
return;
|
|
50010
|
+
}
|
|
50011
|
+
const prior = ackedHoldDispatchFailureStreak.get(key2)?.count ?? 0;
|
|
50012
|
+
ackedHoldDispatchFailureStreak.set(key2, {
|
|
50013
|
+
count: prior + 1,
|
|
50014
|
+
lastReason: readNonEmptyString(outcome.reason) || "worker_absent"
|
|
50015
|
+
});
|
|
50016
|
+
}
|
|
50017
|
+
function getAckedHoldDispatchFailureStreak(meshId, taskId) {
|
|
50018
|
+
return ackedHoldDispatchFailureStreak.get(inFlightSynthKey(meshId, taskId));
|
|
50019
|
+
}
|
|
50020
|
+
function clearAckedHoldDispatchFailureStreak(synthKey) {
|
|
50021
|
+
ackedHoldDispatchFailureStreak.delete(synthKey);
|
|
50022
|
+
}
|
|
50023
|
+
function rehydrateAckedHoldsForMesh(meshId) {
|
|
50024
|
+
if (rehydratedHoldMeshes.has(meshId)) return;
|
|
50025
|
+
rehydratedHoldMeshes.add(meshId);
|
|
50026
|
+
const store = holdStore();
|
|
50027
|
+
if (!store) return;
|
|
50028
|
+
let rows;
|
|
50029
|
+
try {
|
|
50030
|
+
rows = store.listInflightHoldsByMesh(meshId);
|
|
50031
|
+
} catch {
|
|
50032
|
+
return;
|
|
50033
|
+
}
|
|
50034
|
+
for (const row of rows) {
|
|
50035
|
+
const synthKey = inFlightSynthKey(meshId, row.taskId);
|
|
50036
|
+
if (inFlightAckedHoldState.has(synthKey)) continue;
|
|
50037
|
+
inFlightAckedHoldState.set(synthKey, {
|
|
50038
|
+
liveConfirmedSinceAck: row.holdReason === "live",
|
|
50039
|
+
consecutiveReadFailures: row.readFailureCount ?? 0,
|
|
50040
|
+
...row.firstIdleSinceAck !== null && row.firstIdleSinceAck !== void 0 ? { transcriptIdleSinceMs: row.firstIdleSinceAck } : {},
|
|
50041
|
+
...row.heldAt !== null && row.heldAt !== void 0 ? { heldSinceMs: row.heldAt } : {}
|
|
50042
|
+
});
|
|
50043
|
+
}
|
|
50044
|
+
if (rows.length > 0) {
|
|
50045
|
+
LOG2.info("MeshReconcile", `Rehydrated ${rows.length} persisted acked-hold row(s) for mesh ${meshId} after (re)start`);
|
|
50046
|
+
}
|
|
50047
|
+
}
|
|
50048
|
+
function collectHeldSynthKeysForMesh(meshId) {
|
|
50049
|
+
const heldKeys = /* @__PURE__ */ new Set();
|
|
50050
|
+
for (const key2 of inFlightAckedHoldState.keys()) {
|
|
50051
|
+
if (key2.startsWith(`${meshId}::`)) heldKeys.add(key2);
|
|
50052
|
+
}
|
|
50053
|
+
const store = holdStore();
|
|
50054
|
+
if (store) {
|
|
50055
|
+
try {
|
|
50056
|
+
for (const row of store.listInflightHoldsByMesh(meshId)) {
|
|
50057
|
+
heldKeys.add(inFlightSynthKey(meshId, row.taskId));
|
|
50058
|
+
}
|
|
50059
|
+
} catch {
|
|
50060
|
+
}
|
|
50061
|
+
}
|
|
50062
|
+
return heldKeys;
|
|
50063
|
+
}
|
|
50064
|
+
var ACKED_DEATH_CONSECUTIVE_READ_FAILURES;
|
|
50065
|
+
var ACKED_DEATH_CONSECUTIVE_DISPATCH_FAILURES;
|
|
50066
|
+
var inFlightAckedHoldState;
|
|
50067
|
+
var rehydratedHoldMeshes;
|
|
50068
|
+
var ackedHoldDispatchFailureStreak;
|
|
50069
|
+
var init_mesh_reconcile_acked_hold = __esm2({
|
|
50070
|
+
"src/mesh/mesh-reconcile-acked-hold.ts"() {
|
|
50071
|
+
"use strict";
|
|
50072
|
+
init_logger();
|
|
50073
|
+
init_mesh_runtime_store();
|
|
50074
|
+
init_mesh_events_utils();
|
|
50075
|
+
ACKED_DEATH_CONSECUTIVE_READ_FAILURES = 3;
|
|
50076
|
+
ACKED_DEATH_CONSECUTIVE_DISPATCH_FAILURES = 3;
|
|
50077
|
+
inFlightAckedHoldState = /* @__PURE__ */ new Map();
|
|
50078
|
+
rehydratedHoldMeshes = /* @__PURE__ */ new Set();
|
|
50079
|
+
ackedHoldDispatchFailureStreak = /* @__PURE__ */ new Map();
|
|
50080
|
+
}
|
|
50081
|
+
});
|
|
49724
50082
|
function readPayloadTaskId(entry) {
|
|
49725
50083
|
const value = entry.payload?.taskId;
|
|
49726
50084
|
return typeof value === "string" && value.trim() ? value.trim() : "";
|
|
@@ -50227,6 +50585,7 @@ The instruction it carried was never delivered to anyone. If it still matters, r
|
|
|
50227
50585
|
normalizeMeshTaskPriority: () => normalizeMeshTaskPriority,
|
|
50228
50586
|
parkTaskTargetPin: () => parkTaskTargetPin,
|
|
50229
50587
|
reclaimStrandedAssignedTask: () => reclaimStrandedAssignedTask,
|
|
50588
|
+
recordAckedHoldDispatchOutcome: () => recordAckedHoldDispatchOutcome,
|
|
50230
50589
|
recordDirectDispatchTask: () => recordDirectDispatchTask,
|
|
50231
50590
|
recordMeshToolCall: () => recordMeshToolCall,
|
|
50232
50591
|
recordTaskAutoLaunch: () => recordTaskAutoLaunch,
|
|
@@ -51125,6 +51484,7 @@ The instruction it carried was never delivered to anyone. If it still matters, r
|
|
|
51125
51484
|
init_mesh_task_mode_guardrail();
|
|
51126
51485
|
init_mesh_task_parking();
|
|
51127
51486
|
init_mesh_task_mode_guardrail();
|
|
51487
|
+
init_mesh_reconcile_acked_hold();
|
|
51128
51488
|
ACTIVE_MESH_QUEUE_STATUSES = ["pending", "assigned"];
|
|
51129
51489
|
HISTORICAL_MESH_QUEUE_STATUSES = ["completed", "failed", "cancelled"];
|
|
51130
51490
|
MESH_TASK_MODES = ["code_change", "validation", "live_debug_readonly", "launch_app", "convergence"];
|
|
@@ -57908,6 +58268,7 @@ Valid status values: \`completed\` | \`failed\` | \`blocked\` | \`partial\`.`;
|
|
|
57908
58268
|
"task_approval_needed",
|
|
57909
58269
|
"task_question_pending",
|
|
57910
58270
|
"p2p_dispatch_failed",
|
|
58271
|
+
"dispatch_failed",
|
|
57911
58272
|
"dispatch_duplicate_rebound",
|
|
57912
58273
|
"queue_hold_hard_deadline"
|
|
57913
58274
|
]);
|
|
@@ -61442,6 +61803,10 @@ ${rendered}`, "utf-8");
|
|
|
61442
61803
|
if (cachedInline && registry2?.updateInlineMeshNode) {
|
|
61443
61804
|
registry2.updateInlineMeshNode(req.meshId, cachedInline, node);
|
|
61444
61805
|
published = true;
|
|
61806
|
+
} else if (!cachedInline && !mesh && registry2?.updateInlineMeshNode) {
|
|
61807
|
+
const shell = { id: req.meshId, nodes: [], updatedAt: (/* @__PURE__ */ new Date()).toISOString() };
|
|
61808
|
+
registry2.updateInlineMeshNode(req.meshId, shell, node);
|
|
61809
|
+
published = true;
|
|
61445
61810
|
}
|
|
61446
61811
|
} catch {
|
|
61447
61812
|
}
|
|
@@ -61801,7 +62166,7 @@ ${rendered}`, "utf-8");
|
|
|
61801
62166
|
}
|
|
61802
62167
|
async function registerWorkspaceNodeBestEffort(intent, created, ports, bootstrapStatus) {
|
|
61803
62168
|
try {
|
|
61804
|
-
await ports.registerNode({
|
|
62169
|
+
const published = await ports.registerNode({
|
|
61805
62170
|
meshId: intent.meshId,
|
|
61806
62171
|
nodeId: created.nodeId,
|
|
61807
62172
|
worktreePath: created.worktreePath,
|
|
@@ -61809,6 +62174,9 @@ ${rendered}`, "utf-8");
|
|
|
61809
62174
|
sourceNodeId: intent.sourceNodeId,
|
|
61810
62175
|
bootstrapStatus
|
|
61811
62176
|
});
|
|
62177
|
+
if (!published) {
|
|
62178
|
+
LOG2.warn("MeshGraphWorkspace", `node registration (${bootstrapStatus}) published NOTHING for ${intent.graphId}/${intent.workspaceRef}: node ${created.nodeId} exists on disk at ${created.worktreePath} but is in no membership view (mesh ${intent.meshId} has no config twin on this daemon and no inline-cache seam accepted it) \u2014 mesh_list_nodes will not show it`);
|
|
62179
|
+
}
|
|
61812
62180
|
} catch (e) {
|
|
61813
62181
|
LOG2.warn("MeshGraphWorkspace", `node registration (${bootstrapStatus}) failed for ${intent.graphId}/${intent.workspaceRef}: ${e?.message || e}`);
|
|
61814
62182
|
}
|
|
@@ -68019,7 +68387,7 @@ The mesh has no work in flight. For each mission, decide its outcome: continue i
|
|
|
68019
68387
|
const base = 1;
|
|
68020
68388
|
let difficulty = 0;
|
|
68021
68389
|
const diff = isMeshTaskDifficulty(task.difficulty) ? task.difficulty : void 0;
|
|
68022
|
-
if (diff) {
|
|
68390
|
+
if (diff && diff !== "freeform") {
|
|
68023
68391
|
if (slot.difficulty?.length) {
|
|
68024
68392
|
difficulty = slot.difficulty.includes(diff) ? 100 : 0;
|
|
68025
68393
|
} else {
|
|
@@ -68690,6 +69058,146 @@ The mesh has no work in flight. For each mission, decide its outcome: continue i
|
|
|
68690
69058
|
CLASSIFIED_DIFFICULTIES = ["easy", "medium", "difficult"];
|
|
68691
69059
|
}
|
|
68692
69060
|
});
|
|
69061
|
+
function normalizeProviderPriority2(policy) {
|
|
69062
|
+
const raw = policy && typeof policy === "object" && !Array.isArray(policy) ? policy.providerPriority : void 0;
|
|
69063
|
+
if (!Array.isArray(raw)) return [];
|
|
69064
|
+
const seen = /* @__PURE__ */ new Set();
|
|
69065
|
+
return raw.map((type2) => typeof type2 === "string" ? type2.trim() : "").filter(Boolean).filter((type2) => {
|
|
69066
|
+
if (seen.has(type2)) return false;
|
|
69067
|
+
seen.add(type2);
|
|
69068
|
+
return true;
|
|
69069
|
+
});
|
|
69070
|
+
}
|
|
69071
|
+
function isTerminalSessionStatus(status) {
|
|
69072
|
+
return ["stopped", "failed", "terminated", "exited", "closed"].includes(status);
|
|
69073
|
+
}
|
|
69074
|
+
function isIdleSessionState3(state) {
|
|
69075
|
+
const status = readNonEmptyString(state?.status).toLowerCase();
|
|
69076
|
+
if (isTerminalSessionStatus(status)) return false;
|
|
69077
|
+
return status === "idle" || state?.activeChat?.status === "waiting_input";
|
|
69078
|
+
}
|
|
69079
|
+
function sessionStateLooksActive(state) {
|
|
69080
|
+
const status = readNonEmptyString(state?.status).toLowerCase();
|
|
69081
|
+
const chatStatus = readNonEmptyString(state?.activeChat?.status).toLowerCase();
|
|
69082
|
+
const active = /* @__PURE__ */ new Set(["generating", "streaming", "no_progress", "long_generating", "working", "starting", "waiting_approval"]);
|
|
69083
|
+
return active.has(status) || active.has(chatStatus);
|
|
69084
|
+
}
|
|
69085
|
+
function nodeHasActiveMeshWork(components, meshId, nodeId, currentSessionId) {
|
|
69086
|
+
if (nodeHasActiveAssignment(meshId, nodeId)) return true;
|
|
69087
|
+
return components.instanceManager.getByCategory("cli").some((inst) => {
|
|
69088
|
+
const state = inst.getState();
|
|
69089
|
+
const settings = state.settings || {};
|
|
69090
|
+
if (readNonEmptyString(settings.meshNodeFor) !== meshId) return false;
|
|
69091
|
+
const instNodeId = readNonEmptyString(settings.meshNodeId) || readNonEmptyString(settings.nodeId);
|
|
69092
|
+
if (!daemonIdsEquivalent(instNodeId, nodeId)) return false;
|
|
69093
|
+
const sessionId = readNonEmptyString(state.instanceId);
|
|
69094
|
+
if (currentSessionId && sessionIdsEquivalent(sessionId, currentSessionId) && isIdleSessionState3(state)) return false;
|
|
69095
|
+
return sessionStateLooksActive(state);
|
|
69096
|
+
});
|
|
69097
|
+
}
|
|
69098
|
+
function isLaunchableNode(node) {
|
|
69099
|
+
if (!node || node.status === "disabled" || node.status === "removed") return false;
|
|
69100
|
+
if (shouldDeferDispatchForBootstrap(node)) {
|
|
69101
|
+
return false;
|
|
69102
|
+
}
|
|
69103
|
+
return isMeshNodeHealthLaunchable(node);
|
|
69104
|
+
}
|
|
69105
|
+
function isLocalAutoLaunchNode(node) {
|
|
69106
|
+
const daemonId = readNonEmptyString(node?.daemonId);
|
|
69107
|
+
const machineId = readNonEmptyString(node?.machineId);
|
|
69108
|
+
const appConfig = loadConfig2();
|
|
69109
|
+
const localMachineId = readNonEmptyString(appConfig.machineId) || readNonEmptyString(appConfig.registeredMachineId);
|
|
69110
|
+
const daemonMatchesLocal = !daemonId || daemonIdsEquivalent(daemonId, localMachineId);
|
|
69111
|
+
const machineMatchesLocal = !machineId || daemonIdsEquivalent(machineId, localMachineId);
|
|
69112
|
+
if (node?.isLocalWorktree === true) {
|
|
69113
|
+
return daemonMatchesLocal && machineMatchesLocal;
|
|
69114
|
+
}
|
|
69115
|
+
if (daemonId || machineId) {
|
|
69116
|
+
return daemonMatchesLocal && machineMatchesLocal;
|
|
69117
|
+
}
|
|
69118
|
+
return true;
|
|
69119
|
+
}
|
|
69120
|
+
function isSessionActivelyGenerating(components, sessionId) {
|
|
69121
|
+
if (!sessionId) return false;
|
|
69122
|
+
const state = components.instanceManager?.getInstance?.(sessionId)?.getState?.();
|
|
69123
|
+
if (!state) return false;
|
|
69124
|
+
return sessionStateLooksActive(state);
|
|
69125
|
+
}
|
|
69126
|
+
function resolveSessionBusyVerdict(components, sessionId) {
|
|
69127
|
+
if (!sessionId) return "UNKNOWN";
|
|
69128
|
+
try {
|
|
69129
|
+
const instances = components.instanceManager?.getByCategory?.("cli") || [];
|
|
69130
|
+
const inst = instances.find((i) => {
|
|
69131
|
+
const sid = readNonEmptyString(i?.getState?.().instanceId);
|
|
69132
|
+
return sid && sessionIdsEquivalent(sid, sessionId);
|
|
69133
|
+
});
|
|
69134
|
+
if (!inst) return "UNKNOWN";
|
|
69135
|
+
const state = inst.getState?.();
|
|
69136
|
+
if (!state) return "UNKNOWN";
|
|
69137
|
+
return sessionStateLooksActive(state) ? "GENERATING" : "IDLE_CONFIRMED";
|
|
69138
|
+
} catch {
|
|
69139
|
+
return "UNKNOWN";
|
|
69140
|
+
}
|
|
69141
|
+
}
|
|
69142
|
+
function liveSessionCountForNode(components, meshId, nodeId) {
|
|
69143
|
+
const localInstances = components.instanceManager.getByCategory("cli").filter((inst) => {
|
|
69144
|
+
const state = inst.getState();
|
|
69145
|
+
const settings = state.settings || {};
|
|
69146
|
+
if (readNonEmptyString(settings.meshNodeFor) !== meshId) return false;
|
|
69147
|
+
const instNodeId = readNonEmptyString(settings.meshNodeId) || readNonEmptyString(settings.nodeId);
|
|
69148
|
+
if (!daemonIdsEquivalent(instNodeId, nodeId)) return false;
|
|
69149
|
+
const status = readNonEmptyString(state.status).toLowerCase();
|
|
69150
|
+
return !isTerminalSessionStatus(status);
|
|
69151
|
+
});
|
|
69152
|
+
let count = localInstances.length;
|
|
69153
|
+
const localSessionIds = localInstances.map((inst) => readNonEmptyString(inst.getState().instanceId)).filter(Boolean);
|
|
69154
|
+
for (const sid of inWindowAutoLaunchSessionIdsForNode(meshId, nodeId)) {
|
|
69155
|
+
if (!localSessionIds.some((local) => sessionIdsEquivalent(local, sid))) count += 1;
|
|
69156
|
+
}
|
|
69157
|
+
return count;
|
|
69158
|
+
}
|
|
69159
|
+
function nodeHasLiveSessionPendingClaim(components, meshId, nodeId, task, node) {
|
|
69160
|
+
if (inWindowAutoLaunchSessionIdsForNode(meshId, nodeId).length > 0) return true;
|
|
69161
|
+
const busySessionIds = new Set(
|
|
69162
|
+
getQueue(meshId, { status: ["assigned"] }).filter((task2) => daemonIdsEquivalent(task2.assignedNodeId, nodeId)).map((task2) => readNonEmptyString(task2.assignedSessionId)).filter(Boolean)
|
|
69163
|
+
);
|
|
69164
|
+
return components.instanceManager.getByCategory("cli").some((inst) => {
|
|
69165
|
+
const state = inst.getState();
|
|
69166
|
+
const settings = state.settings || {};
|
|
69167
|
+
if (readNonEmptyString(settings.meshNodeFor) !== meshId) return false;
|
|
69168
|
+
if (readNonEmptyString(settings.meshCoordinatorFor) === meshId) return false;
|
|
69169
|
+
const instNodeId = readNonEmptyString(settings.meshNodeId) || readNonEmptyString(settings.nodeId);
|
|
69170
|
+
if (!daemonIdsEquivalent(instNodeId, nodeId)) return false;
|
|
69171
|
+
const status = readNonEmptyString(state.status).toLowerCase();
|
|
69172
|
+
if (isTerminalSessionStatus(status)) return false;
|
|
69173
|
+
const sessionId = readNonEmptyString(state.instanceId);
|
|
69174
|
+
if (sessionId && busySessionIds.has(sessionId)) return false;
|
|
69175
|
+
const sessionProviderType = state.type || readNonEmptyString(settings.providerType);
|
|
69176
|
+
if (task.requiredTags?.length) {
|
|
69177
|
+
if (sessionProviderType && !nodeSatisfiesRequiredTags(task.requiredTags, buildMeshNodeCapabilityTags(node, sessionProviderType))) {
|
|
69178
|
+
return false;
|
|
69179
|
+
}
|
|
69180
|
+
}
|
|
69181
|
+
const allowance = allowedClassifiedDifficultiesForSession(node, resolveNodeCapabilitySlots(node, meshId), sessionProviderType, readSessionModel(state));
|
|
69182
|
+
if (!taskMeetsSessionDifficultyFloor(task, allowance)) return false;
|
|
69183
|
+
return true;
|
|
69184
|
+
});
|
|
69185
|
+
}
|
|
69186
|
+
var init_mesh_candidacy_predicates = __esm2({
|
|
69187
|
+
"src/mesh/mesh-candidacy-predicates.ts"() {
|
|
69188
|
+
"use strict";
|
|
69189
|
+
init_config();
|
|
69190
|
+
init_mesh_work_queue();
|
|
69191
|
+
init_dist();
|
|
69192
|
+
init_mesh_events_utils();
|
|
69193
|
+
init_mesh_node_identity();
|
|
69194
|
+
init_worktree_bootstrap_config();
|
|
69195
|
+
init_mesh_autolaunch_integrity();
|
|
69196
|
+
init_mesh_scheduling_fitness();
|
|
69197
|
+
init_mesh_node_slots();
|
|
69198
|
+
init_mesh_difficulty_floor();
|
|
69199
|
+
}
|
|
69200
|
+
});
|
|
68693
69201
|
function localCoordinatorDaemonId2() {
|
|
68694
69202
|
return canonicalDaemonId(readNonEmptyString(loadConfig2().machineId));
|
|
68695
69203
|
}
|
|
@@ -68886,6 +69394,7 @@ The mesh has no work in flight. For each mission, decide its outcome: continue i
|
|
|
68886
69394
|
if (timer) clearTimeout(timer);
|
|
68887
69395
|
const isQueued = res && typeof res === "object" && res.status === "queued";
|
|
68888
69396
|
updateSessionDeliveryStatus(delivery.id, isQueued ? "queued" : "delivered");
|
|
69397
|
+
recordAckedHoldDispatchOutcome(ctx.meshId, ctx.task.id, { ok: true });
|
|
68889
69398
|
if (ctx.task.attemptId) {
|
|
68890
69399
|
try {
|
|
68891
69400
|
recordTurnAck({
|
|
@@ -68934,6 +69443,7 @@ The mesh has no work in flight. For each mission, decide its outcome: continue i
|
|
|
68934
69443
|
}
|
|
68935
69444
|
LOG2.error("MeshQueue", `Failed to dispatch task via ${ctx.transport} to node ${ctx.nodeId}: ${e?.message}`);
|
|
68936
69445
|
updateSessionDeliveryStatus(delivery.id, "failed", { lastError: e?.message, incrementAttempt: true });
|
|
69446
|
+
recordAckedHoldDispatchOutcome(ctx.meshId, ctx.task.id, { ok: false, reason: e?.message });
|
|
68937
69447
|
endTaskDispatchInFlight(ctx.meshId, ctx.task.id);
|
|
68938
69448
|
try {
|
|
68939
69449
|
closeAttemptForReassignment({ meshId: ctx.meshId, taskId: ctx.task.id, reason: "dispatch_failed" });
|
|
@@ -68954,6 +69464,12 @@ The mesh has no work in flight. For each mission, decide its outcome: continue i
|
|
|
68954
69464
|
}
|
|
68955
69465
|
try {
|
|
68956
69466
|
appendLedgerEntry(ctx.meshId, {
|
|
69467
|
+
// 'dispatch_failed' is a real MeshLedgerKind and a member of
|
|
69468
|
+
// TASK_LIFECYCLE_LEDGER_KINDS, so appendLedgerEntry derives the top-level
|
|
69469
|
+
// taskId from payload.taskId below. It spent its whole life as
|
|
69470
|
+
// `as any` — off the union, hence off the lifecycle set, hence written to
|
|
69471
|
+
// the indexed SQLite task_id column as NULL and unreachable by the
|
|
69472
|
+
// kind+taskId join every reader uses. Do not reintroduce the cast.
|
|
68957
69473
|
kind: "dispatch_failed",
|
|
68958
69474
|
nodeId: ctx.nodeId,
|
|
68959
69475
|
sessionId: ctx.sessionId,
|
|
@@ -69299,65 +69815,6 @@ The mesh has no work in flight. For each mission, decide its outcome: continue i
|
|
|
69299
69815
|
if (now >= until) autoLaunchCooldownUntil.delete(key2);
|
|
69300
69816
|
}
|
|
69301
69817
|
}
|
|
69302
|
-
function normalizeProviderPriority2(policy) {
|
|
69303
|
-
const raw = policy && typeof policy === "object" && !Array.isArray(policy) ? policy.providerPriority : void 0;
|
|
69304
|
-
if (!Array.isArray(raw)) return [];
|
|
69305
|
-
const seen = /* @__PURE__ */ new Set();
|
|
69306
|
-
return raw.map((type2) => typeof type2 === "string" ? type2.trim() : "").filter(Boolean).filter((type2) => {
|
|
69307
|
-
if (seen.has(type2)) return false;
|
|
69308
|
-
seen.add(type2);
|
|
69309
|
-
return true;
|
|
69310
|
-
});
|
|
69311
|
-
}
|
|
69312
|
-
function isTerminalSessionStatus(status) {
|
|
69313
|
-
return ["stopped", "failed", "terminated", "exited", "closed"].includes(status);
|
|
69314
|
-
}
|
|
69315
|
-
function isIdleSessionState3(state) {
|
|
69316
|
-
const status = readNonEmptyString(state?.status).toLowerCase();
|
|
69317
|
-
if (isTerminalSessionStatus(status)) return false;
|
|
69318
|
-
return status === "idle" || state?.activeChat?.status === "waiting_input";
|
|
69319
|
-
}
|
|
69320
|
-
function sessionStateLooksActive(state) {
|
|
69321
|
-
const status = readNonEmptyString(state?.status).toLowerCase();
|
|
69322
|
-
const chatStatus = readNonEmptyString(state?.activeChat?.status).toLowerCase();
|
|
69323
|
-
const active = /* @__PURE__ */ new Set(["generating", "streaming", "no_progress", "long_generating", "working", "starting", "waiting_approval"]);
|
|
69324
|
-
return active.has(status) || active.has(chatStatus);
|
|
69325
|
-
}
|
|
69326
|
-
function nodeHasActiveMeshWork(components, meshId, nodeId, currentSessionId) {
|
|
69327
|
-
if (nodeHasActiveAssignment(meshId, nodeId)) return true;
|
|
69328
|
-
return components.instanceManager.getByCategory("cli").some((inst) => {
|
|
69329
|
-
const state = inst.getState();
|
|
69330
|
-
const settings = state.settings || {};
|
|
69331
|
-
if (readNonEmptyString(settings.meshNodeFor) !== meshId) return false;
|
|
69332
|
-
const instNodeId = readNonEmptyString(settings.meshNodeId) || readNonEmptyString(settings.nodeId);
|
|
69333
|
-
if (!daemonIdsEquivalent(instNodeId, nodeId)) return false;
|
|
69334
|
-
const sessionId = readNonEmptyString(state.instanceId);
|
|
69335
|
-
if (currentSessionId && sessionIdsEquivalent(sessionId, currentSessionId) && isIdleSessionState3(state)) return false;
|
|
69336
|
-
return sessionStateLooksActive(state);
|
|
69337
|
-
});
|
|
69338
|
-
}
|
|
69339
|
-
function isLaunchableNode(node) {
|
|
69340
|
-
if (!node || node.status === "disabled" || node.status === "removed") return false;
|
|
69341
|
-
if (shouldDeferDispatchForBootstrap(node)) {
|
|
69342
|
-
return false;
|
|
69343
|
-
}
|
|
69344
|
-
return isMeshNodeHealthLaunchable(node);
|
|
69345
|
-
}
|
|
69346
|
-
function isLocalAutoLaunchNode(node) {
|
|
69347
|
-
const daemonId = readNonEmptyString(node?.daemonId);
|
|
69348
|
-
const machineId = readNonEmptyString(node?.machineId);
|
|
69349
|
-
const appConfig = loadConfig2();
|
|
69350
|
-
const localMachineId = readNonEmptyString(appConfig.machineId) || readNonEmptyString(appConfig.registeredMachineId);
|
|
69351
|
-
const daemonMatchesLocal = !daemonId || daemonIdsEquivalent(daemonId, localMachineId);
|
|
69352
|
-
const machineMatchesLocal = !machineId || daemonIdsEquivalent(machineId, localMachineId);
|
|
69353
|
-
if (node?.isLocalWorktree === true) {
|
|
69354
|
-
return daemonMatchesLocal && machineMatchesLocal;
|
|
69355
|
-
}
|
|
69356
|
-
if (daemonId || machineId) {
|
|
69357
|
-
return daemonMatchesLocal && machineMatchesLocal;
|
|
69358
|
-
}
|
|
69359
|
-
return true;
|
|
69360
|
-
}
|
|
69361
69818
|
function resolveAutoLaunchTarget(components, node) {
|
|
69362
69819
|
if (isLocalAutoLaunchNode(node)) return { mode: "local" };
|
|
69363
69820
|
const daemonId = readMeshNodeDaemonId(node ?? {});
|
|
@@ -69367,72 +69824,6 @@ The mesh has no work in flight. For each mission, decide its outcome: continue i
|
|
|
69367
69824
|
if (!coordinatorDaemonId) return { mode: "skip", reason: "remote_auto_launch_no_coordinator_daemon_id" };
|
|
69368
69825
|
return { mode: "remote", daemonId, coordinatorDaemonId };
|
|
69369
69826
|
}
|
|
69370
|
-
function isSessionActivelyGenerating(components, sessionId) {
|
|
69371
|
-
if (!sessionId) return false;
|
|
69372
|
-
const state = components.instanceManager?.getInstance?.(sessionId)?.getState?.();
|
|
69373
|
-
if (!state) return false;
|
|
69374
|
-
return sessionStateLooksActive(state);
|
|
69375
|
-
}
|
|
69376
|
-
function resolveSessionBusyVerdict(components, sessionId) {
|
|
69377
|
-
if (!sessionId) return "UNKNOWN";
|
|
69378
|
-
try {
|
|
69379
|
-
const instances = components.instanceManager?.getByCategory?.("cli") || [];
|
|
69380
|
-
const inst = instances.find((i) => {
|
|
69381
|
-
const sid = readNonEmptyString(i?.getState?.().instanceId);
|
|
69382
|
-
return sid && sessionIdsEquivalent(sid, sessionId);
|
|
69383
|
-
});
|
|
69384
|
-
if (!inst) return "UNKNOWN";
|
|
69385
|
-
const state = inst.getState?.();
|
|
69386
|
-
if (!state) return "UNKNOWN";
|
|
69387
|
-
return sessionStateLooksActive(state) ? "GENERATING" : "IDLE_CONFIRMED";
|
|
69388
|
-
} catch {
|
|
69389
|
-
return "UNKNOWN";
|
|
69390
|
-
}
|
|
69391
|
-
}
|
|
69392
|
-
function liveSessionCountForNode(components, meshId, nodeId) {
|
|
69393
|
-
const localInstances = components.instanceManager.getByCategory("cli").filter((inst) => {
|
|
69394
|
-
const state = inst.getState();
|
|
69395
|
-
const settings = state.settings || {};
|
|
69396
|
-
if (readNonEmptyString(settings.meshNodeFor) !== meshId) return false;
|
|
69397
|
-
const instNodeId = readNonEmptyString(settings.meshNodeId) || readNonEmptyString(settings.nodeId);
|
|
69398
|
-
if (!daemonIdsEquivalent(instNodeId, nodeId)) return false;
|
|
69399
|
-
const status = readNonEmptyString(state.status).toLowerCase();
|
|
69400
|
-
return !isTerminalSessionStatus(status);
|
|
69401
|
-
});
|
|
69402
|
-
let count = localInstances.length;
|
|
69403
|
-
const localSessionIds = localInstances.map((inst) => readNonEmptyString(inst.getState().instanceId)).filter(Boolean);
|
|
69404
|
-
for (const sid of inWindowAutoLaunchSessionIdsForNode(meshId, nodeId)) {
|
|
69405
|
-
if (!localSessionIds.some((local) => sessionIdsEquivalent(local, sid))) count += 1;
|
|
69406
|
-
}
|
|
69407
|
-
return count;
|
|
69408
|
-
}
|
|
69409
|
-
function nodeHasLiveSessionPendingClaim(components, meshId, nodeId, task, node) {
|
|
69410
|
-
if (inWindowAutoLaunchSessionIdsForNode(meshId, nodeId).length > 0) return true;
|
|
69411
|
-
const busySessionIds = new Set(
|
|
69412
|
-
getQueue(meshId, { status: ["assigned"] }).filter((task2) => daemonIdsEquivalent(task2.assignedNodeId, nodeId)).map((task2) => readNonEmptyString(task2.assignedSessionId)).filter(Boolean)
|
|
69413
|
-
);
|
|
69414
|
-
return components.instanceManager.getByCategory("cli").some((inst) => {
|
|
69415
|
-
const state = inst.getState();
|
|
69416
|
-
const settings = state.settings || {};
|
|
69417
|
-
if (readNonEmptyString(settings.meshNodeFor) !== meshId) return false;
|
|
69418
|
-
if (readNonEmptyString(settings.meshCoordinatorFor) === meshId) return false;
|
|
69419
|
-
const instNodeId = readNonEmptyString(settings.meshNodeId) || readNonEmptyString(settings.nodeId);
|
|
69420
|
-
if (!daemonIdsEquivalent(instNodeId, nodeId)) return false;
|
|
69421
|
-
const status = readNonEmptyString(state.status).toLowerCase();
|
|
69422
|
-
if (isTerminalSessionStatus(status)) return false;
|
|
69423
|
-
const sessionId = readNonEmptyString(state.instanceId);
|
|
69424
|
-
if (sessionId && busySessionIds.has(sessionId)) return false;
|
|
69425
|
-
const sessionProviderType = state.type || readNonEmptyString(settings.providerType);
|
|
69426
|
-
if (task.requiredTags?.length) {
|
|
69427
|
-
if (sessionProviderType && !nodeSatisfiesRequiredTags(task.requiredTags, buildMeshNodeCapabilityTags(node, sessionProviderType))) {
|
|
69428
|
-
return false;
|
|
69429
|
-
}
|
|
69430
|
-
}
|
|
69431
|
-
const allowance = allowedClassifiedDifficultiesForSession(node, resolveNodeCapabilitySlots(node, meshId), sessionProviderType, readSessionModel(state));
|
|
69432
|
-
if (!taskMeetsSessionDifficultyFloor(task, allowance)) return false;
|
|
69433
|
-
return true;
|
|
69434
|
-
});
|
|
69435
|
-
}
|
|
69436
69827
|
function markAutoLaunch(meshId, taskId, args) {
|
|
69437
69828
|
const reason = args.reason || args.error;
|
|
69438
69829
|
const difficultyFloorSkip = args.status === "skipped" && isDifficultyFloorWaitReason(reason);
|
|
@@ -70172,6 +70563,7 @@ The mesh has no work in flight. For each mission, decide its outcome: continue i
|
|
|
70172
70563
|
init_mesh_routing_decision();
|
|
70173
70564
|
init_mesh_autolaunch_integrity();
|
|
70174
70565
|
init_mesh_difficulty_floor();
|
|
70566
|
+
init_mesh_candidacy_predicates();
|
|
70175
70567
|
init_mesh_difficulty_floor();
|
|
70176
70568
|
init_mesh_auto_fast_forward();
|
|
70177
70569
|
init_mesh_skip_notify();
|
|
@@ -74573,148 +74965,6 @@ ${cleanBody}`;
|
|
|
74573
74965
|
init_mesh_events_utils();
|
|
74574
74966
|
}
|
|
74575
74967
|
});
|
|
74576
|
-
function resolveTunedReconcileMs(envName, def, min, max) {
|
|
74577
|
-
const raw = readNonEmptyString(process.env[envName]);
|
|
74578
|
-
if (raw) {
|
|
74579
|
-
const parsed = Number.parseInt(raw, 10);
|
|
74580
|
-
if (Number.isFinite(parsed) && parsed >= min && parsed <= max) return parsed;
|
|
74581
|
-
}
|
|
74582
|
-
return def;
|
|
74583
|
-
}
|
|
74584
|
-
function resolveAckedDeathDeadlineMs() {
|
|
74585
|
-
return resolveTunedReconcileMs("MESH_INFLIGHT_ACKED_DEATH_DEADLINE_MS", 8 * 6e4, 0, 60 * 6e4);
|
|
74586
|
-
}
|
|
74587
|
-
function resolveAckedTranscriptFastTrackGraceMs() {
|
|
74588
|
-
return resolveTunedReconcileMs("MESH_INFLIGHT_ACKED_TRANSCRIPT_FASTTRACK_GRACE_MS", 4e4, 0, 5 * 6e4);
|
|
74589
|
-
}
|
|
74590
|
-
function resolveAckedHoldHardCeilingMs() {
|
|
74591
|
-
return resolveTunedReconcileMs("MESH_INFLIGHT_ACKED_HOLD_HARD_CEILING_MS", 90 * 6e4, 0, 24 * 60 * 6e4);
|
|
74592
|
-
}
|
|
74593
|
-
function inFlightSynthKey(meshId, taskId) {
|
|
74594
|
-
return `${meshId}::${taskId}`;
|
|
74595
|
-
}
|
|
74596
|
-
function taskIdFromSynthKey(meshId, synthKey) {
|
|
74597
|
-
const prefix = `${meshId}::`;
|
|
74598
|
-
return synthKey.startsWith(prefix) ? synthKey.slice(prefix.length) : synthKey;
|
|
74599
|
-
}
|
|
74600
|
-
function holdStore() {
|
|
74601
|
-
try {
|
|
74602
|
-
return MeshRuntimeStore.getInstance();
|
|
74603
|
-
} catch {
|
|
74604
|
-
return void 0;
|
|
74605
|
-
}
|
|
74606
|
-
}
|
|
74607
|
-
function getHoldState(synthKey, meshId) {
|
|
74608
|
-
const cached5 = inFlightAckedHoldState.get(synthKey);
|
|
74609
|
-
if (cached5) return cached5;
|
|
74610
|
-
const store = holdStore();
|
|
74611
|
-
if (!store) return void 0;
|
|
74612
|
-
let row;
|
|
74613
|
-
try {
|
|
74614
|
-
row = store.getInflightHold(taskIdFromSynthKey(meshId, synthKey));
|
|
74615
|
-
} catch {
|
|
74616
|
-
return void 0;
|
|
74617
|
-
}
|
|
74618
|
-
if (!row) return void 0;
|
|
74619
|
-
const state = {
|
|
74620
|
-
liveConfirmedSinceAck: row.holdReason === "live",
|
|
74621
|
-
consecutiveReadFailures: row.readFailureCount ?? 0,
|
|
74622
|
-
...row.firstIdleSinceAck !== null && row.firstIdleSinceAck !== void 0 ? { transcriptIdleSinceMs: row.firstIdleSinceAck } : {},
|
|
74623
|
-
...row.heldAt !== null && row.heldAt !== void 0 ? { heldSinceMs: row.heldAt } : {}
|
|
74624
|
-
};
|
|
74625
|
-
inFlightAckedHoldState.set(synthKey, state);
|
|
74626
|
-
return state;
|
|
74627
|
-
}
|
|
74628
|
-
function setHoldState(synthKey, meshId, state) {
|
|
74629
|
-
const store = holdStore();
|
|
74630
|
-
let priorHeldSinceMs = state.heldSinceMs ?? inFlightAckedHoldState.get(synthKey)?.heldSinceMs;
|
|
74631
|
-
if (priorHeldSinceMs === void 0 && store) {
|
|
74632
|
-
try {
|
|
74633
|
-
priorHeldSinceMs = store.getInflightHold(taskIdFromSynthKey(meshId, synthKey))?.heldAt ?? void 0;
|
|
74634
|
-
} catch {
|
|
74635
|
-
}
|
|
74636
|
-
}
|
|
74637
|
-
const heldSinceMs = priorHeldSinceMs ?? Date.now();
|
|
74638
|
-
inFlightAckedHoldState.set(synthKey, { ...state, heldSinceMs });
|
|
74639
|
-
if (!store) return;
|
|
74640
|
-
try {
|
|
74641
|
-
store.upsertInflightHold({
|
|
74642
|
-
taskId: taskIdFromSynthKey(meshId, synthKey),
|
|
74643
|
-
meshId,
|
|
74644
|
-
holdReason: state.liveConfirmedSinceAck ? "live" : "unconfirmed",
|
|
74645
|
-
// Only meaningful when the row is NEW — upsertInflightHold deliberately
|
|
74646
|
-
// preserves held_at on conflict, so an existing row keeps its original anchor.
|
|
74647
|
-
heldAt: heldSinceMs,
|
|
74648
|
-
firstIdleSinceAck: state.transcriptIdleSinceMs ?? null,
|
|
74649
|
-
readFailureCount: state.consecutiveReadFailures
|
|
74650
|
-
});
|
|
74651
|
-
} catch {
|
|
74652
|
-
}
|
|
74653
|
-
}
|
|
74654
|
-
function deleteHoldState(synthKey, meshId) {
|
|
74655
|
-
inFlightAckedHoldState.delete(synthKey);
|
|
74656
|
-
const store = holdStore();
|
|
74657
|
-
if (!store) return;
|
|
74658
|
-
try {
|
|
74659
|
-
store.deleteInflightHold(taskIdFromSynthKey(meshId, synthKey));
|
|
74660
|
-
} catch {
|
|
74661
|
-
}
|
|
74662
|
-
}
|
|
74663
|
-
function rehydrateAckedHoldsForMesh(meshId) {
|
|
74664
|
-
if (rehydratedHoldMeshes.has(meshId)) return;
|
|
74665
|
-
rehydratedHoldMeshes.add(meshId);
|
|
74666
|
-
const store = holdStore();
|
|
74667
|
-
if (!store) return;
|
|
74668
|
-
let rows;
|
|
74669
|
-
try {
|
|
74670
|
-
rows = store.listInflightHoldsByMesh(meshId);
|
|
74671
|
-
} catch {
|
|
74672
|
-
return;
|
|
74673
|
-
}
|
|
74674
|
-
for (const row of rows) {
|
|
74675
|
-
const synthKey = inFlightSynthKey(meshId, row.taskId);
|
|
74676
|
-
if (inFlightAckedHoldState.has(synthKey)) continue;
|
|
74677
|
-
inFlightAckedHoldState.set(synthKey, {
|
|
74678
|
-
liveConfirmedSinceAck: row.holdReason === "live",
|
|
74679
|
-
consecutiveReadFailures: row.readFailureCount ?? 0,
|
|
74680
|
-
...row.firstIdleSinceAck !== null && row.firstIdleSinceAck !== void 0 ? { transcriptIdleSinceMs: row.firstIdleSinceAck } : {},
|
|
74681
|
-
...row.heldAt !== null && row.heldAt !== void 0 ? { heldSinceMs: row.heldAt } : {}
|
|
74682
|
-
});
|
|
74683
|
-
}
|
|
74684
|
-
if (rows.length > 0) {
|
|
74685
|
-
LOG2.info("MeshReconcile", `Rehydrated ${rows.length} persisted acked-hold row(s) for mesh ${meshId} after (re)start`);
|
|
74686
|
-
}
|
|
74687
|
-
}
|
|
74688
|
-
function collectHeldSynthKeysForMesh(meshId) {
|
|
74689
|
-
const heldKeys = /* @__PURE__ */ new Set();
|
|
74690
|
-
for (const key2 of inFlightAckedHoldState.keys()) {
|
|
74691
|
-
if (key2.startsWith(`${meshId}::`)) heldKeys.add(key2);
|
|
74692
|
-
}
|
|
74693
|
-
const store = holdStore();
|
|
74694
|
-
if (store) {
|
|
74695
|
-
try {
|
|
74696
|
-
for (const row of store.listInflightHoldsByMesh(meshId)) {
|
|
74697
|
-
heldKeys.add(inFlightSynthKey(meshId, row.taskId));
|
|
74698
|
-
}
|
|
74699
|
-
} catch {
|
|
74700
|
-
}
|
|
74701
|
-
}
|
|
74702
|
-
return heldKeys;
|
|
74703
|
-
}
|
|
74704
|
-
var ACKED_DEATH_CONSECUTIVE_READ_FAILURES;
|
|
74705
|
-
var inFlightAckedHoldState;
|
|
74706
|
-
var rehydratedHoldMeshes;
|
|
74707
|
-
var init_mesh_reconcile_acked_hold = __esm2({
|
|
74708
|
-
"src/mesh/mesh-reconcile-acked-hold.ts"() {
|
|
74709
|
-
"use strict";
|
|
74710
|
-
init_logger();
|
|
74711
|
-
init_mesh_runtime_store();
|
|
74712
|
-
init_mesh_events_utils();
|
|
74713
|
-
ACKED_DEATH_CONSECUTIVE_READ_FAILURES = 3;
|
|
74714
|
-
inFlightAckedHoldState = /* @__PURE__ */ new Map();
|
|
74715
|
-
rehydratedHoldMeshes = /* @__PURE__ */ new Set();
|
|
74716
|
-
}
|
|
74717
|
-
});
|
|
74718
74968
|
function resolveAutoPruneMinAgeMs() {
|
|
74719
74969
|
const raw = readNonEmptyString(process.env.MESH_AUTO_PRUNE_MIN_AGE_MS);
|
|
74720
74970
|
if (raw) {
|
|
@@ -74946,6 +75196,109 @@ ${cleanBody}`;
|
|
|
74946
75196
|
init_mesh_reconcile_identity();
|
|
74947
75197
|
}
|
|
74948
75198
|
});
|
|
75199
|
+
function formatBytes(bytes) {
|
|
75200
|
+
if (!Number.isFinite(bytes) || bytes < 0) return "unknown";
|
|
75201
|
+
const units = ["B", "KiB", "MiB", "GiB", "TiB"];
|
|
75202
|
+
let value = bytes;
|
|
75203
|
+
let unit = 0;
|
|
75204
|
+
while (value >= 1024 && unit < units.length - 1) {
|
|
75205
|
+
value /= 1024;
|
|
75206
|
+
unit += 1;
|
|
75207
|
+
}
|
|
75208
|
+
return `${value >= 10 || unit === 0 ? Math.round(value) : value.toFixed(1)}${units[unit]}`;
|
|
75209
|
+
}
|
|
75210
|
+
function classifyDiskSpace(stats) {
|
|
75211
|
+
if (!Number.isFinite(stats.totalBytes) || stats.totalBytes <= 0) return "ok";
|
|
75212
|
+
const { percentFree, freeBytes } = stats;
|
|
75213
|
+
if (percentFree < DISK_CRITICAL_PERCENT_FREE && freeBytes < DISK_CRITICAL_FREE_BYTES) {
|
|
75214
|
+
return "critical";
|
|
75215
|
+
}
|
|
75216
|
+
if (percentFree < DISK_WARNING_PERCENT_FREE && freeBytes < DISK_WARNING_FREE_BYTES) {
|
|
75217
|
+
return "warning";
|
|
75218
|
+
}
|
|
75219
|
+
return "ok";
|
|
75220
|
+
}
|
|
75221
|
+
function describeDiskSpace(stats, level, path60) {
|
|
75222
|
+
const pct = Number.isFinite(stats.percentFree) ? stats.percentFree.toFixed(1) : "?";
|
|
75223
|
+
const used = Number.isFinite(stats.percentFree) ? (100 - stats.percentFree).toFixed(1) : "?";
|
|
75224
|
+
return `disk ${level.toUpperCase()} at ${path60}: ${formatBytes(stats.freeBytes)} free of ${formatBytes(stats.totalBytes)} (${pct}% free / ${used}% used)`;
|
|
75225
|
+
}
|
|
75226
|
+
function readDiskSpace(path60) {
|
|
75227
|
+
try {
|
|
75228
|
+
const stats = (0, import_fs16.statfsSync)(path60);
|
|
75229
|
+
const blockSize = Number(stats.bsize);
|
|
75230
|
+
const freeBytes = Number(stats.bavail) * blockSize;
|
|
75231
|
+
const totalBytes = Number(stats.blocks) * blockSize;
|
|
75232
|
+
if (!Number.isFinite(freeBytes) || !Number.isFinite(totalBytes) || totalBytes <= 0) {
|
|
75233
|
+
return null;
|
|
75234
|
+
}
|
|
75235
|
+
return {
|
|
75236
|
+
freeBytes,
|
|
75237
|
+
totalBytes,
|
|
75238
|
+
percentFree: freeBytes / totalBytes * 100
|
|
75239
|
+
};
|
|
75240
|
+
} catch {
|
|
75241
|
+
return null;
|
|
75242
|
+
}
|
|
75243
|
+
}
|
|
75244
|
+
function checkDiskSpace(path60) {
|
|
75245
|
+
const stats = readDiskSpace(path60);
|
|
75246
|
+
if (!stats) return null;
|
|
75247
|
+
const level = classifyDiskSpace(stats);
|
|
75248
|
+
return { ...stats, level, path: path60, summary: describeDiskSpace(stats, level, path60) };
|
|
75249
|
+
}
|
|
75250
|
+
function logDiskSpaceStatus(status, context) {
|
|
75251
|
+
if (!status) {
|
|
75252
|
+
LOG2.debug("DiskSpace", `${context}: volume not measurable (statfs unavailable)`);
|
|
75253
|
+
return;
|
|
75254
|
+
}
|
|
75255
|
+
switch (status.level) {
|
|
75256
|
+
case "critical":
|
|
75257
|
+
LOG2.error("DiskSpace", `${context}: ${status.summary} \u2014 writes are expected to fail with ENOSPC`);
|
|
75258
|
+
break;
|
|
75259
|
+
case "warning":
|
|
75260
|
+
LOG2.warn("DiskSpace", `${context}: ${status.summary}`);
|
|
75261
|
+
break;
|
|
75262
|
+
default:
|
|
75263
|
+
LOG2.debug("DiskSpace", `${context}: ${status.summary}`);
|
|
75264
|
+
break;
|
|
75265
|
+
}
|
|
75266
|
+
}
|
|
75267
|
+
function preflightDiskSpace(path60, operation, options = {}) {
|
|
75268
|
+
const status = checkDiskSpace(path60);
|
|
75269
|
+
logDiskSpaceStatus(status, `preflight before ${operation}`);
|
|
75270
|
+
if (status?.level === "critical" && options.throwOnCritical !== false) {
|
|
75271
|
+
throw new LowDiskSpaceError(status, operation);
|
|
75272
|
+
}
|
|
75273
|
+
return status;
|
|
75274
|
+
}
|
|
75275
|
+
var import_fs16;
|
|
75276
|
+
var DISK_CRITICAL_PERCENT_FREE;
|
|
75277
|
+
var DISK_CRITICAL_FREE_BYTES;
|
|
75278
|
+
var DISK_WARNING_PERCENT_FREE;
|
|
75279
|
+
var DISK_WARNING_FREE_BYTES;
|
|
75280
|
+
var LowDiskSpaceError;
|
|
75281
|
+
var init_disk_space_preflight = __esm2({
|
|
75282
|
+
"src/diagnostics/disk-space-preflight.ts"() {
|
|
75283
|
+
"use strict";
|
|
75284
|
+
import_fs16 = require("fs");
|
|
75285
|
+
init_logger();
|
|
75286
|
+
DISK_CRITICAL_PERCENT_FREE = 2;
|
|
75287
|
+
DISK_CRITICAL_FREE_BYTES = 1 * 1024 * 1024 * 1024;
|
|
75288
|
+
DISK_WARNING_PERCENT_FREE = 5;
|
|
75289
|
+
DISK_WARNING_FREE_BYTES = 5 * 1024 * 1024 * 1024;
|
|
75290
|
+
LowDiskSpaceError = class extends Error {
|
|
75291
|
+
status;
|
|
75292
|
+
constructor(status, operation) {
|
|
75293
|
+
super(
|
|
75294
|
+
`Refusing to ${operation}: ${status.summary}. Writes would fail with ENOSPC mid-operation. Free space and retry (see \`adhdev doctor\` for the largest reclaimable paths).`
|
|
75295
|
+
);
|
|
75296
|
+
this.name = "LowDiskSpaceError";
|
|
75297
|
+
this.status = status;
|
|
75298
|
+
}
|
|
75299
|
+
};
|
|
75300
|
+
}
|
|
75301
|
+
});
|
|
74949
75302
|
function selectExpiredLedgerJsonl(files, now, maxAgeMs = LEDGER_JSONL_MAX_AGE_MS) {
|
|
74950
75303
|
return files.filter((f) => now - f.mtimeMs > maxAgeMs);
|
|
74951
75304
|
}
|
|
@@ -74980,7 +75333,7 @@ ${cleanBody}`;
|
|
|
74980
75333
|
}
|
|
74981
75334
|
function safeUnlink(path60) {
|
|
74982
75335
|
try {
|
|
74983
|
-
(0,
|
|
75336
|
+
(0, import_fs17.unlinkSync)(path60);
|
|
74984
75337
|
return true;
|
|
74985
75338
|
} catch (e) {
|
|
74986
75339
|
LOG2.warn("DiskRetention", `Failed to delete ${path60}: ${e?.message || e}`);
|
|
@@ -74988,18 +75341,18 @@ ${cleanBody}`;
|
|
|
74988
75341
|
}
|
|
74989
75342
|
}
|
|
74990
75343
|
function listDirFiles(dir) {
|
|
74991
|
-
if (!(0,
|
|
75344
|
+
if (!(0, import_fs17.existsSync)(dir)) return [];
|
|
74992
75345
|
const out = [];
|
|
74993
75346
|
let names;
|
|
74994
75347
|
try {
|
|
74995
|
-
names = (0,
|
|
75348
|
+
names = (0, import_fs17.readdirSync)(dir);
|
|
74996
75349
|
} catch {
|
|
74997
75350
|
return [];
|
|
74998
75351
|
}
|
|
74999
75352
|
for (const name of names) {
|
|
75000
75353
|
const path60 = (0, import_path14.join)(dir, name);
|
|
75001
75354
|
try {
|
|
75002
|
-
const st = (0,
|
|
75355
|
+
const st = (0, import_fs17.statSync)(path60);
|
|
75003
75356
|
if (st.isFile()) out.push({ path: path60, mtimeMs: st.mtimeMs });
|
|
75004
75357
|
} catch {
|
|
75005
75358
|
}
|
|
@@ -75026,22 +75379,22 @@ ${cleanBody}`;
|
|
|
75026
75379
|
}
|
|
75027
75380
|
function pruneExpiredSessionHostRuntimes(now = Date.now()) {
|
|
75028
75381
|
const root = (0, import_path14.join)(getConfigDir2(), "session-host");
|
|
75029
|
-
if (!(0,
|
|
75382
|
+
if (!(0, import_fs17.existsSync)(root)) return 0;
|
|
75030
75383
|
let apps;
|
|
75031
75384
|
try {
|
|
75032
|
-
apps = (0,
|
|
75385
|
+
apps = (0, import_fs17.readdirSync)(root);
|
|
75033
75386
|
} catch {
|
|
75034
75387
|
return 0;
|
|
75035
75388
|
}
|
|
75036
75389
|
const candidates = [];
|
|
75037
75390
|
for (const app of apps) {
|
|
75038
75391
|
const runtimesDir = (0, import_path14.join)(root, app, "runtimes");
|
|
75039
|
-
if (!(0,
|
|
75392
|
+
if (!(0, import_fs17.existsSync)(runtimesDir)) continue;
|
|
75040
75393
|
for (const f of listDirFiles(runtimesDir)) {
|
|
75041
75394
|
if (!f.path.endsWith(".json")) continue;
|
|
75042
75395
|
let record2 = null;
|
|
75043
75396
|
try {
|
|
75044
|
-
const parsed = JSON.parse((0,
|
|
75397
|
+
const parsed = JSON.parse((0, import_fs17.readFileSync)(f.path, "utf-8"));
|
|
75045
75398
|
const rec = parsed && typeof parsed === "object" ? parsed.record : null;
|
|
75046
75399
|
record2 = rec && typeof rec === "object" ? rec : null;
|
|
75047
75400
|
} catch {
|
|
@@ -75087,7 +75440,15 @@ ${cleanBody}`;
|
|
|
75087
75440
|
} catch (e) {
|
|
75088
75441
|
LOG2.warn("DiskRetention", `Ledger rotation cap sweep failed: ${e?.message || e}`);
|
|
75089
75442
|
}
|
|
75090
|
-
|
|
75443
|
+
let diskLevel = "ok";
|
|
75444
|
+
try {
|
|
75445
|
+
const status = checkDiskSpace(getConfigDir2());
|
|
75446
|
+
logDiskSpaceStatus(status, "disk retention sweep");
|
|
75447
|
+
if (status) diskLevel = status.level;
|
|
75448
|
+
} catch (e) {
|
|
75449
|
+
LOG2.warn("DiskRetention", `Disk space check failed: ${e?.message || e}`);
|
|
75450
|
+
}
|
|
75451
|
+
return { ledgerJsonl, dbBackups, sessionHostRuntimes, rotationEvicted, rotationEvictedBytes, diskLevel };
|
|
75091
75452
|
}
|
|
75092
75453
|
async function detectAndSignalOrphanWorktrees(mesh, now = Date.now()) {
|
|
75093
75454
|
const nodes = Array.isArray(mesh.nodes) ? mesh.nodes : [];
|
|
@@ -75138,7 +75499,7 @@ ${cleanBody}`;
|
|
|
75138
75499
|
}
|
|
75139
75500
|
return signalled;
|
|
75140
75501
|
}
|
|
75141
|
-
var
|
|
75502
|
+
var import_fs17;
|
|
75142
75503
|
var import_path14;
|
|
75143
75504
|
var DAY_MS2;
|
|
75144
75505
|
var LEDGER_JSONL_MAX_AGE_MS;
|
|
@@ -75148,13 +75509,14 @@ ${cleanBody}`;
|
|
|
75148
75509
|
var init_mesh_disk_retention = __esm2({
|
|
75149
75510
|
"src/mesh/mesh-disk-retention.ts"() {
|
|
75150
75511
|
"use strict";
|
|
75151
|
-
|
|
75512
|
+
import_fs17 = require("fs");
|
|
75152
75513
|
import_path14 = require("path");
|
|
75153
75514
|
init_config();
|
|
75154
75515
|
init_mesh_ledger();
|
|
75155
75516
|
init_runtime_surface();
|
|
75156
75517
|
init_git_worktree();
|
|
75157
75518
|
init_logger();
|
|
75519
|
+
init_disk_space_preflight();
|
|
75158
75520
|
DAY_MS2 = 24 * 60 * 60 * 1e3;
|
|
75159
75521
|
LEDGER_JSONL_MAX_AGE_MS = 30 * DAY_MS2;
|
|
75160
75522
|
SESSION_HOST_RUNTIME_MAX_AGE_MS = 14 * DAY_MS2;
|
|
@@ -76167,6 +76529,7 @@ ${cleanBody}`;
|
|
|
76167
76529
|
const { meshId, taskId, sessionId, nodeId, providerType, synthKey, reason, detail } = args;
|
|
76168
76530
|
updateDirectDispatchStatus(meshId, sessionId, "stale", taskId);
|
|
76169
76531
|
deleteHoldState(synthKey, meshId);
|
|
76532
|
+
clearAckedHoldDispatchFailureStreak(synthKey);
|
|
76170
76533
|
try {
|
|
76171
76534
|
appendLedgerEntry(meshId, {
|
|
76172
76535
|
kind: "acked_hold_terminalized",
|
|
@@ -76222,6 +76585,27 @@ ${cleanBody}`;
|
|
|
76222
76585
|
};
|
|
76223
76586
|
const synthKey = inFlightSynthKey(mesh.id, taskId);
|
|
76224
76587
|
const isAcked = dispatch.status === "acked";
|
|
76588
|
+
if (isAcked) {
|
|
76589
|
+
const dispatchStreak = getAckedHoldDispatchFailureStreak(mesh.id, taskId);
|
|
76590
|
+
if (dispatchStreak && dispatchStreak.count >= ACKED_DEATH_CONSECUTIVE_DISPATCH_FAILURES) {
|
|
76591
|
+
LOG2.warn("MeshReconcile", `Acked-hold dispatch-failure death signal: task ${taskId} on node ${nodeId} (mesh ${mesh.id}) failed dispatch ${dispatchStreak.count}x consecutively with a worker-absence reason ("${dispatchStreak.lastReason}") \u2014 the target adapter does not exist, so the worker cannot be holding this turn; marking the dispatch row STALE and deleting the synth hold (no completion is asserted \u2014 the transcript never showed one).`);
|
|
76592
|
+
terminalizeAckedHold({
|
|
76593
|
+
meshId: mesh.id,
|
|
76594
|
+
taskId,
|
|
76595
|
+
sessionId,
|
|
76596
|
+
nodeId,
|
|
76597
|
+
...providerType ? { providerType } : {},
|
|
76598
|
+
synthKey,
|
|
76599
|
+
reason: "acked_dispatch_failure_death",
|
|
76600
|
+
detail: {
|
|
76601
|
+
consecutiveDispatchFailures: dispatchStreak.count,
|
|
76602
|
+
threshold: ACKED_DEATH_CONSECUTIVE_DISPATCH_FAILURES,
|
|
76603
|
+
lastReason: dispatchStreak.lastReason
|
|
76604
|
+
}
|
|
76605
|
+
});
|
|
76606
|
+
continue;
|
|
76607
|
+
}
|
|
76608
|
+
}
|
|
76225
76609
|
if (isAcked) {
|
|
76226
76610
|
const ceilingMs = resolveAckedHoldHardCeilingMs();
|
|
76227
76611
|
const heldSinceMs = getHoldState(synthKey, mesh.id)?.heldSinceMs;
|
|
@@ -81175,6 +81559,69 @@ ${cleanBody}`;
|
|
|
81175
81559
|
return void 0;
|
|
81176
81560
|
}
|
|
81177
81561
|
}
|
|
81562
|
+
function gitRefsResolvable(cwd, refs) {
|
|
81563
|
+
for (const ref of refs) {
|
|
81564
|
+
if (!ref) return false;
|
|
81565
|
+
try {
|
|
81566
|
+
(0, import_node_child_process11.execFileSync)(GIT4, ["rev-parse", "--verify", "--quiet", `${ref}^{commit}`], { cwd, stdio: "ignore", windowsHide: true });
|
|
81567
|
+
} catch {
|
|
81568
|
+
return false;
|
|
81569
|
+
}
|
|
81570
|
+
}
|
|
81571
|
+
return true;
|
|
81572
|
+
}
|
|
81573
|
+
function probeGitAncestry(cwd, ancestor, descendant) {
|
|
81574
|
+
try {
|
|
81575
|
+
if (!fs51.existsSync(cwd)) return "undeterminable";
|
|
81576
|
+
} catch {
|
|
81577
|
+
return "undeterminable";
|
|
81578
|
+
}
|
|
81579
|
+
if (!gitRefsResolvable(cwd, [ancestor, descendant])) return "undeterminable";
|
|
81580
|
+
try {
|
|
81581
|
+
(0, import_node_child_process11.execFileSync)(GIT4, ["merge-base", "--is-ancestor", ancestor, descendant], { cwd, stdio: "ignore", windowsHide: true });
|
|
81582
|
+
return true;
|
|
81583
|
+
} catch (e) {
|
|
81584
|
+
return e?.status === 1 ? false : "undeterminable";
|
|
81585
|
+
}
|
|
81586
|
+
}
|
|
81587
|
+
function probeSubmoduleGitlinkReachability(input) {
|
|
81588
|
+
const { path: path60, baseCommit, branchCommit, probeRoot, baseRepoRoot } = input;
|
|
81589
|
+
const submoduleRepo = (0, import_path17.resolve)(probeRoot, path60);
|
|
81590
|
+
const baseSubmoduleRepo = (0, import_path17.resolve)(baseRepoRoot, path60);
|
|
81591
|
+
if (baseCommit) ensureSubmoduleCommitLocal(submoduleRepo, baseSubmoduleRepo, baseCommit);
|
|
81592
|
+
if (branchCommit) ensureSubmoduleCommitLocal(submoduleRepo, baseSubmoduleRepo, branchCommit);
|
|
81593
|
+
let fastForward;
|
|
81594
|
+
let reachableFromOriginMain;
|
|
81595
|
+
const undeterminable = [];
|
|
81596
|
+
if (branchCommit) {
|
|
81597
|
+
if (baseCommit) {
|
|
81598
|
+
const ff = probeGitAncestry(submoduleRepo, baseCommit, branchCommit);
|
|
81599
|
+
if (ff === "undeterminable") undeterminable.push("fastForward");
|
|
81600
|
+
else fastForward = ff;
|
|
81601
|
+
}
|
|
81602
|
+
const reach = probeGitAncestry(submoduleRepo, branchCommit, "refs/remotes/origin/main");
|
|
81603
|
+
if (reach === "undeterminable") undeterminable.push("reachableFromOriginMain");
|
|
81604
|
+
else reachableFromOriginMain = reach;
|
|
81605
|
+
}
|
|
81606
|
+
return {
|
|
81607
|
+
path: path60,
|
|
81608
|
+
baseCommit,
|
|
81609
|
+
branchCommit,
|
|
81610
|
+
fastForward,
|
|
81611
|
+
reachableFromOriginMain,
|
|
81612
|
+
...undeterminable.length ? { undeterminable } : {},
|
|
81613
|
+
probedRepo: submoduleRepo
|
|
81614
|
+
};
|
|
81615
|
+
}
|
|
81616
|
+
function buildSubmoduleReachabilityUndeterminableWarning(nodeId, evidence) {
|
|
81617
|
+
if (!evidence.submoduleReachabilityUndeterminable) return void 0;
|
|
81618
|
+
const entries = (evidence.submoduleGitlinks || []).filter((g) => (g.undeterminable || []).includes("reachableFromOriginMain")).map((g) => `${g.path}@${(g.branchCommit || "?").slice(0, 12)} (probed: ${g.probedRepo || "unknown"})`).join(", ");
|
|
81619
|
+
return `[Refinery] Could NOT determine submodule gitlink reachability from submodule origin/main for node ${nodeId} \u2014 probe had NO ANSWER (missing commit object and/or missing refs/remotes/origin/main in the probed repo). "undeterminable", NOT "unpublished" and NOT "nothing to converge": ${entries}`;
|
|
81620
|
+
}
|
|
81621
|
+
function warnRefineSubmoduleUndeterminable(nodeId, evidence) {
|
|
81622
|
+
const message = buildSubmoduleReachabilityUndeterminableWarning(nodeId, evidence);
|
|
81623
|
+
if (message) LOG2.warn("Mesh", message);
|
|
81624
|
+
}
|
|
81178
81625
|
function submoduleCommitPresent(submoduleRepoPath, commit) {
|
|
81179
81626
|
if (!commit) return false;
|
|
81180
81627
|
try {
|
|
@@ -81220,8 +81667,52 @@ ${cleanBody}`;
|
|
|
81220
81667
|
}
|
|
81221
81668
|
return false;
|
|
81222
81669
|
}
|
|
81670
|
+
function probeSubmoduleFastForward(submoduleRepoPath, baseCommit, branchCommit) {
|
|
81671
|
+
if (!baseCommit || !branchCommit) return "undeterminable";
|
|
81672
|
+
if (baseCommit === branchCommit) return true;
|
|
81673
|
+
return probeGitAncestry(submoduleRepoPath, baseCommit, branchCommit);
|
|
81674
|
+
}
|
|
81675
|
+
function isSubmoduleFastForward(submoduleRepoPath, baseCommit, branchCommit) {
|
|
81676
|
+
return probeSubmoduleFastForward(submoduleRepoPath, baseCommit, branchCommit) === true;
|
|
81677
|
+
}
|
|
81678
|
+
function buildGitlinkFastForwardUndeterminableWarning(label, gitlinks) {
|
|
81679
|
+
const entries = gitlinks.filter((entry) => entry.fastForwardUndeterminable);
|
|
81680
|
+
if (entries.length === 0) return void 0;
|
|
81681
|
+
const detail = entries.map((entry) => `${entry.path} (base=${(entry.baseCommit || "?").slice(0, 12)} branch=${(entry.branchCommit || "?").slice(0, 12)})`).join(", ");
|
|
81682
|
+
return `[Refinery] Could NOT determine submodule gitlink fast-forward for ${label} \u2014 ancestry probe had NO ANSWER (a gitlink commit is missing from the local submodule object store, or the submodule checkout is absent). "undeterminable", NOT "diverged": ${detail}`;
|
|
81683
|
+
}
|
|
81684
|
+
function warnGitlinkFastForwardUndeterminable(label, gitlinks) {
|
|
81685
|
+
const message = buildGitlinkFastForwardUndeterminableWarning(label, gitlinks);
|
|
81686
|
+
if (message) LOG2.warn("Mesh", message);
|
|
81687
|
+
}
|
|
81688
|
+
function readChangedPathKinds(repoRoot, fromRef, toRef) {
|
|
81689
|
+
try {
|
|
81690
|
+
const output = (0, import_node_child_process11.execFileSync)(GIT4, ["diff", "--raw", "--no-abbrev", fromRef, toRef], {
|
|
81691
|
+
cwd: repoRoot,
|
|
81692
|
+
encoding: "utf8",
|
|
81693
|
+
maxBuffer: REFINE_PATCH_EQUIVALENCE_OUTPUT_LIMIT_BYTES
|
|
81694
|
+
});
|
|
81695
|
+
const result = [];
|
|
81696
|
+
const seen = /* @__PURE__ */ new Set();
|
|
81697
|
+
for (const line of output.split("\n")) {
|
|
81698
|
+
if (!line.trim()) continue;
|
|
81699
|
+
const metaAndPath = line.split(" ");
|
|
81700
|
+
const meta3 = metaAndPath[0] || "";
|
|
81701
|
+
const path60 = metaAndPath[metaAndPath.length - 1]?.trim();
|
|
81702
|
+
if (!path60 || seen.has(path60)) continue;
|
|
81703
|
+
seen.add(path60);
|
|
81704
|
+
const parts = meta3.split(/\s+/);
|
|
81705
|
+
const isGitlink = !!(parts[0]?.includes("160000") || parts[1]?.includes("160000"));
|
|
81706
|
+
result.push({ path: path60, isGitlink });
|
|
81707
|
+
}
|
|
81708
|
+
return result;
|
|
81709
|
+
} catch {
|
|
81710
|
+
return [];
|
|
81711
|
+
}
|
|
81712
|
+
}
|
|
81223
81713
|
var fs51;
|
|
81224
81714
|
var import_node_child_process11;
|
|
81715
|
+
var import_path17;
|
|
81225
81716
|
var GIT4;
|
|
81226
81717
|
var REFINE_PATCH_EQUIVALENCE_OUTPUT_LIMIT_BYTES;
|
|
81227
81718
|
var init_mesh_refine_gitlink_utils = __esm2({
|
|
@@ -81229,6 +81720,8 @@ ${cleanBody}`;
|
|
|
81229
81720
|
"use strict";
|
|
81230
81721
|
fs51 = __toESM2(require("fs"));
|
|
81231
81722
|
import_node_child_process11 = require("child_process");
|
|
81723
|
+
import_path17 = require("path");
|
|
81724
|
+
init_logger();
|
|
81232
81725
|
init_resolve_executable();
|
|
81233
81726
|
GIT4 = process.platform === "win32" ? resolveWin32Executable("git") : "git";
|
|
81234
81727
|
REFINE_PATCH_EQUIVALENCE_OUTPUT_LIMIT_BYTES = 4 * 1024 * 1024;
|
|
@@ -81302,7 +81795,16 @@ ${cleanBody}`;
|
|
|
81302
81795
|
}
|
|
81303
81796
|
return void 0;
|
|
81304
81797
|
}
|
|
81305
|
-
function
|
|
81798
|
+
function isCommitReachableFromRemoteMain(submoduleRepoPath, commit, remoteMainRef) {
|
|
81799
|
+
if (!remoteMainRef) return false;
|
|
81800
|
+
try {
|
|
81801
|
+
(0, import_node_child_process12.execFileSync)(GIT4, ["merge-base", "--is-ancestor", commit, remoteMainRef], { cwd: submoduleRepoPath, stdio: "ignore" });
|
|
81802
|
+
return true;
|
|
81803
|
+
} catch {
|
|
81804
|
+
return false;
|
|
81805
|
+
}
|
|
81806
|
+
}
|
|
81807
|
+
function convergeDivergedSubmoduleGitlinks(worktreeRoot, baseRepoRoot, baseHead, branchHead, options = {}) {
|
|
81306
81808
|
const changed = readChangedGitlinkPaths(worktreeRoot, baseHead, branchHead);
|
|
81307
81809
|
if (changed.length === 0) {
|
|
81308
81810
|
return { converged: false, reason: "no_changed_gitlinks", resolutions: [], gitlinks: [] };
|
|
@@ -81314,9 +81816,9 @@ ${cleanBody}`;
|
|
|
81314
81816
|
for (const path60 of changed) {
|
|
81315
81817
|
const baseCommit = readTreeObject(baseRepoRoot, baseHead, path60);
|
|
81316
81818
|
const branchCommit = readTreeObject(worktreeRoot, branchHead, path60);
|
|
81317
|
-
const submoduleRepoPath = (0,
|
|
81819
|
+
const submoduleRepoPath = (0, import_path18.resolve)(worktreeRoot, path60);
|
|
81318
81820
|
if (baseCommit) {
|
|
81319
|
-
ensureSubmoduleCommitLocal(submoduleRepoPath, (0,
|
|
81821
|
+
ensureSubmoduleCommitLocal(submoduleRepoPath, (0, import_path18.resolve)(baseRepoRoot, path60), baseCommit);
|
|
81320
81822
|
}
|
|
81321
81823
|
const markUndeterminable = () => {
|
|
81322
81824
|
const unavailable = [];
|
|
@@ -81354,6 +81856,30 @@ ${cleanBody}`;
|
|
|
81354
81856
|
resolutions.push({ path: path60, baseCommit, branchCommit, rebasedCommit: publishedEquivalent });
|
|
81355
81857
|
continue;
|
|
81356
81858
|
}
|
|
81859
|
+
const branchAlreadyPublished = isCommitReachableFromRemoteMain(submoduleRepoPath, branchCommit, remoteMainRef);
|
|
81860
|
+
const willMintUnpublishedCommit = !branchAlreadyPublished;
|
|
81861
|
+
const wouldConflict = (() => {
|
|
81862
|
+
try {
|
|
81863
|
+
(0, import_node_child_process12.execFileSync)(GIT4, ["merge-tree", "--write-tree", baseCommit, branchCommit], {
|
|
81864
|
+
cwd: submoduleRepoPath,
|
|
81865
|
+
encoding: "utf8",
|
|
81866
|
+
stdio: ["ignore", "pipe", "pipe"]
|
|
81867
|
+
});
|
|
81868
|
+
return false;
|
|
81869
|
+
} catch {
|
|
81870
|
+
return true;
|
|
81871
|
+
}
|
|
81872
|
+
})();
|
|
81873
|
+
if (willMintUnpublishedCommit && !wouldConflict && options.allowAutoPublishSubmoduleMainCommits !== true) {
|
|
81874
|
+
gitlinks.push({
|
|
81875
|
+
path: path60,
|
|
81876
|
+
baseCommit,
|
|
81877
|
+
branchCommit,
|
|
81878
|
+
action: "publish_required_before_rebase",
|
|
81879
|
+
remoteMainRef
|
|
81880
|
+
});
|
|
81881
|
+
return { converged: false, reason: "submodule_publish_required", resolutions: [], gitlinks };
|
|
81882
|
+
}
|
|
81357
81883
|
let rebasedCommit;
|
|
81358
81884
|
try {
|
|
81359
81885
|
(0, import_node_child_process12.execFileSync)(GIT4, ["checkout", "-q", "--detach", branchCommit], { cwd: submoduleRepoPath, stdio: ["ignore", "ignore", "pipe"] });
|
|
@@ -81393,7 +81919,14 @@ ${cleanBody}`;
|
|
|
81393
81919
|
gitlinks.push({ path: path60, baseCommit, branchCommit, rebasedCommit, action: "rebase_dropped_branch_commits" });
|
|
81394
81920
|
return { converged: false, reason: "rebase_dropped_branch_commits", resolutions: [], gitlinks };
|
|
81395
81921
|
}
|
|
81396
|
-
gitlinks.push({
|
|
81922
|
+
gitlinks.push({
|
|
81923
|
+
path: path60,
|
|
81924
|
+
baseCommit,
|
|
81925
|
+
branchCommit,
|
|
81926
|
+
rebasedCommit,
|
|
81927
|
+
action: "rebased",
|
|
81928
|
+
...willMintUnpublishedCommit ? { mintedUnpublishedCommit: true, remoteMainRef } : {}
|
|
81929
|
+
});
|
|
81397
81930
|
resolutions.push({ path: path60, baseCommit, branchCommit, rebasedCommit });
|
|
81398
81931
|
}
|
|
81399
81932
|
if (!sawDiverged) {
|
|
@@ -81402,6 +81935,31 @@ ${cleanBody}`;
|
|
|
81402
81935
|
}
|
|
81403
81936
|
return { converged: resolutions.length > 0, resolutions, gitlinks };
|
|
81404
81937
|
}
|
|
81938
|
+
function describeSubmodulePublishRequired(nodeId, gitlinks) {
|
|
81939
|
+
const pending = gitlinks.filter((g) => g.action === "publish_required_before_rebase");
|
|
81940
|
+
return `[Refinery] Refusing to auto-converge diverged submodule gitlink(s) for node ${nodeId} \u2014 the rebase would create a NEW submodule commit that is not reachable from the submodule remote, and allowAutoPublishSubmoduleMainCommits is disabled, so the reachability gate would reject it. The branch was left untouched. NEXT STEP: publish the branch-side submodule commit(s) to submodule origin main, then rerun mesh_refine_node \u2014 do NOT rebase: ` + pending.map((g) => `${g.path} (branch=${(g.branchCommit || "?").slice(0, 12)} base=${(g.baseCommit || "?").slice(0, 12)} remote=${g.remoteMainRef || "unresolved"})`).join(", ");
|
|
81941
|
+
}
|
|
81942
|
+
function describeSubmoduleConvergeDecline(nodeId, reason, gitlinks) {
|
|
81943
|
+
if (reason === "submodule_publish_required") {
|
|
81944
|
+
return describeSubmodulePublishRequired(nodeId, gitlinks);
|
|
81945
|
+
}
|
|
81946
|
+
if (reason === "submodule_commit_unavailable") {
|
|
81947
|
+
return `[Refinery] Could NOT determine submodule gitlink divergence for node ${nodeId} \u2014 a gitlink commit is missing from the local submodule object store (auto-converge could not run): ` + gitlinks.filter((g) => g.action === "skipped_commit_unavailable").map((g) => `${g.path} (missing: ${(g.unavailable || []).join("+") || "unknown"}; base=${(g.baseCommit || "?").slice(0, 12)} branch=${(g.branchCommit || "?").slice(0, 12)})`).join(", ");
|
|
81948
|
+
}
|
|
81949
|
+
return void 0;
|
|
81950
|
+
}
|
|
81951
|
+
function buildSubmoduleConvergeDeclineDetails(reason, autoPublishEnabled) {
|
|
81952
|
+
if (reason !== "submodule_publish_required") return {};
|
|
81953
|
+
return {
|
|
81954
|
+
recommendedAction: SUBMODULE_PUBLISH_REQUIRED_RECOMMENDED_ACTION,
|
|
81955
|
+
autoPublishAllowed: autoPublishEnabled
|
|
81956
|
+
};
|
|
81957
|
+
}
|
|
81958
|
+
function describeMintedUnpublishedCommits(nodeId, gitlinks, autoPublishEnabled) {
|
|
81959
|
+
const minted = gitlinks.filter((g) => g.mintedUnpublishedCommit);
|
|
81960
|
+
if (minted.length === 0) return void 0;
|
|
81961
|
+
return `[Refinery] Node ${nodeId}: the convergence MINTED ${minted.length} new submodule commit(s) not reachable from the submodule remote (allowed because allowAutoPublishSubmoduleMainCommits=${autoPublishEnabled}); a publish is still required before merge: ` + minted.map((g) => `${g.path}\u2192${(g.rebasedCommit || "?").slice(0, 12)} (remote=${g.remoteMainRef || "unresolved"})`).join(", ");
|
|
81962
|
+
}
|
|
81405
81963
|
function rootRebaseResolvingGitlinks(worktreeRoot, baseHead, resolutions) {
|
|
81406
81964
|
const resolveByPath = new Map(resolutions.map((r) => [r.path, r.rebasedCommit]));
|
|
81407
81965
|
const runRebase = (args) => {
|
|
@@ -81462,7 +82020,7 @@ ${cleanBody}`;
|
|
|
81462
82020
|
for (const p of conflicts) {
|
|
81463
82021
|
const commit = resolveByPath.get(p);
|
|
81464
82022
|
try {
|
|
81465
|
-
(0, import_node_child_process12.execFileSync)(GIT4, ["checkout", "-q", "--detach", commit], { cwd: (0,
|
|
82023
|
+
(0, import_node_child_process12.execFileSync)(GIT4, ["checkout", "-q", "--detach", commit], { cwd: (0, import_path18.resolve)(worktreeRoot, p), stdio: "ignore" });
|
|
81466
82024
|
} catch {
|
|
81467
82025
|
}
|
|
81468
82026
|
try {
|
|
@@ -81481,15 +82039,17 @@ ${cleanBody}`;
|
|
|
81481
82039
|
return { ok: true, branchHead };
|
|
81482
82040
|
}
|
|
81483
82041
|
var fs52;
|
|
81484
|
-
var
|
|
82042
|
+
var import_path18;
|
|
81485
82043
|
var import_node_child_process12;
|
|
82044
|
+
var SUBMODULE_PUBLISH_REQUIRED_RECOMMENDED_ACTION;
|
|
81486
82045
|
var init_mesh_refine_submodule_converge = __esm2({
|
|
81487
82046
|
"src/mesh/mesh-refine-submodule-converge.ts"() {
|
|
81488
82047
|
"use strict";
|
|
81489
82048
|
fs52 = __toESM2(require("fs"));
|
|
81490
|
-
|
|
82049
|
+
import_path18 = require("path");
|
|
81491
82050
|
import_node_child_process12 = require("child_process");
|
|
81492
82051
|
init_mesh_refine_gitlink_utils();
|
|
82052
|
+
SUBMODULE_PUBLISH_REQUIRED_RECOMMENDED_ACTION = "Publish the branch-side submodule commit(s) to submodule origin main, then rerun mesh_refine_node. Do NOT retry the rebase: the branch was intentionally left unrewritten because a rebase here would mint a submodule commit the reachability gate must reject.";
|
|
81493
82053
|
}
|
|
81494
82054
|
});
|
|
81495
82055
|
function truncateValidationOutput(value) {
|
|
@@ -81509,10 +82069,10 @@ ${tail}`;
|
|
|
81509
82069
|
}
|
|
81510
82070
|
function writeValidationFailureLog(workspace, index, candidate, streams, now = () => /* @__PURE__ */ new Date()) {
|
|
81511
82071
|
try {
|
|
81512
|
-
const dir = (0,
|
|
82072
|
+
const dir = (0, import_path19.join)(workspace, REFINE_VALIDATION_LOG_DIR);
|
|
81513
82073
|
fs53.mkdirSync(dir, { recursive: true });
|
|
81514
82074
|
const stamp = now().toISOString().replace(/[:.]/g, "-");
|
|
81515
|
-
const file2 = (0,
|
|
82075
|
+
const file2 = (0, import_path19.join)(dir, `refine-${stamp}-${index}.log`);
|
|
81516
82076
|
const asText = (v) => typeof v === "string" ? v : v == null ? "" : String(v);
|
|
81517
82077
|
const shown = candidate.displayCommand || [candidate.command, ...candidate.args || []].join(" ");
|
|
81518
82078
|
fs53.writeFileSync(
|
|
@@ -81632,6 +82192,7 @@ ${mergeTreeErr?.stderr || ""}`;
|
|
|
81632
82192
|
if (!isSubmoduleConflict) throw mergeTreeErr;
|
|
81633
82193
|
const evaluation = evaluateGitlinkTrivialFastForward(repoRoot, baseHead, branchHead);
|
|
81634
82194
|
if (!evaluation.trivial) {
|
|
82195
|
+
warnGitlinkFastForwardUndeterminable("patch-equivalence gate", evaluation.gitlinks);
|
|
81635
82196
|
return {
|
|
81636
82197
|
status: "failed",
|
|
81637
82198
|
equivalent: false,
|
|
@@ -81700,9 +82261,15 @@ ${e?.stderr || ""}`
|
|
|
81700
82261
|
};
|
|
81701
82262
|
}
|
|
81702
82263
|
}
|
|
82264
|
+
async function classifyAndWarnPatchEquivalenceFailure(nodeId, repoRoot, baseHead, branchHead, summary, options = {}) {
|
|
82265
|
+
const classification = await classifyPatchEquivalenceFailure(repoRoot, baseHead, branchHead, summary, options);
|
|
82266
|
+
warnRefineSubmoduleUndeterminable(nodeId, classification.evidence);
|
|
82267
|
+
return classification;
|
|
82268
|
+
}
|
|
81703
82269
|
async function classifyPatchEquivalenceFailure(repoRoot, baseHead, branchHead, summary, options = {}) {
|
|
81704
82270
|
const targetBaseRef = options.targetBaseRef || baseHead;
|
|
81705
82271
|
const autoPublish = options.autoPublishSubmoduleMainCommits;
|
|
82272
|
+
const submoduleProbeRoot = options.worktreeRoot || repoRoot;
|
|
81706
82273
|
const evidence = {
|
|
81707
82274
|
baseHead,
|
|
81708
82275
|
branchHead,
|
|
@@ -81719,14 +82286,6 @@ ${e?.stderr || ""}`
|
|
|
81719
82286
|
maxBuffer: REFINE_PATCH_EQUIVALENCE_OUTPUT_LIMIT_BYTES,
|
|
81720
82287
|
windowsHide: true
|
|
81721
82288
|
});
|
|
81722
|
-
const gitOk = (args) => {
|
|
81723
|
-
try {
|
|
81724
|
-
git3(args);
|
|
81725
|
-
return true;
|
|
81726
|
-
} catch {
|
|
81727
|
-
return false;
|
|
81728
|
-
}
|
|
81729
|
-
};
|
|
81730
82289
|
let ahead = 0;
|
|
81731
82290
|
let behind = 0;
|
|
81732
82291
|
try {
|
|
@@ -81738,8 +82297,13 @@ ${e?.stderr || ""}`
|
|
|
81738
82297
|
}
|
|
81739
82298
|
evidence.ahead = ahead;
|
|
81740
82299
|
evidence.behind = behind;
|
|
81741
|
-
const
|
|
81742
|
-
|
|
82300
|
+
const baseAncestry = probeGitAncestry(repoRoot, targetBaseRef, branchHead);
|
|
82301
|
+
const baseIsAncestor = baseAncestry === true;
|
|
82302
|
+
if (baseAncestry === "undeterminable") {
|
|
82303
|
+
evidence.baseAncestryUndeterminable = true;
|
|
82304
|
+
} else {
|
|
82305
|
+
evidence.baseDiverged = !baseAncestry;
|
|
82306
|
+
}
|
|
81743
82307
|
let diffStat = "";
|
|
81744
82308
|
try {
|
|
81745
82309
|
if (summary.mergedTree) {
|
|
@@ -81767,20 +82331,19 @@ ${e?.stderr || ""}`
|
|
|
81767
82331
|
} catch {
|
|
81768
82332
|
continue;
|
|
81769
82333
|
}
|
|
81770
|
-
|
|
81771
|
-
|
|
81772
|
-
|
|
81773
|
-
|
|
81774
|
-
|
|
81775
|
-
|
|
81776
|
-
|
|
81777
|
-
reachableFromOriginMain = execGitOk(submoduleRepo, ["merge-base", "--is-ancestor", branchCommit, "refs/remotes/origin/main"]);
|
|
81778
|
-
}
|
|
81779
|
-
submoduleGitlinks.push({ path: p, baseCommit, branchCommit, fastForward, reachableFromOriginMain });
|
|
82334
|
+
submoduleGitlinks.push(probeSubmoduleGitlinkReachability({
|
|
82335
|
+
path: p,
|
|
82336
|
+
baseCommit,
|
|
82337
|
+
branchCommit,
|
|
82338
|
+
probeRoot: submoduleProbeRoot,
|
|
82339
|
+
baseRepoRoot: repoRoot
|
|
82340
|
+
}));
|
|
81780
82341
|
}
|
|
81781
82342
|
} catch {
|
|
81782
82343
|
}
|
|
81783
82344
|
if (submoduleGitlinks.length) evidence.submoduleGitlinks = submoduleGitlinks;
|
|
82345
|
+
const undeterminableGitlinks = submoduleGitlinks.filter((g) => (g.undeterminable || []).includes("reachableFromOriginMain"));
|
|
82346
|
+
if (undeterminableGitlinks.length > 0) evidence.submoduleReachabilityUndeterminable = true;
|
|
81784
82347
|
const gitlinkFf = summary.gitlinkTrivialFastForward;
|
|
81785
82348
|
const noResidualDiff = !evidence.diffStat && (!summary.actualPatchId || summary.actualPatchId === "");
|
|
81786
82349
|
if (ahead === 0 && behind === 0 && noResidualDiff) {
|
|
@@ -81801,6 +82364,15 @@ ${e?.stderr || ""}`
|
|
|
81801
82364
|
evidence
|
|
81802
82365
|
};
|
|
81803
82366
|
}
|
|
82367
|
+
if (undeterminableGitlinks.length > 0) {
|
|
82368
|
+
const refs = undeterminableGitlinks.map((g) => `${g.path}@${(g.branchCommit || "?").slice(0, 12)} (probed: ${g.probedRepo || "unknown"})`).join(", ");
|
|
82369
|
+
return {
|
|
82370
|
+
detailedReason: "submodule_reachability_undeterminable",
|
|
82371
|
+
detailedReasonDescription: `Could NOT determine whether submodule gitlink commit(s) are reachable from submodule origin/main \u2014 the probe had no answer (missing commit object and/or missing refs/remotes/origin/main in the probed repo): ${refs}. This is "undeterminable", NOT "unpublished".`,
|
|
82372
|
+
recommendedAction: "Make the probe answerable, then rerun mesh_refine_node: fetch the submodule remote in the probed checkout (`git -C <probedRepo> fetch origin main`) so both the gitlink commit object and refs/remotes/origin/main exist locally. Do NOT publish/push the submodule commit on the strength of this result \u2014 reachability was never established either way.",
|
|
82373
|
+
evidence
|
|
82374
|
+
};
|
|
82375
|
+
}
|
|
81804
82376
|
const changedGitlinks = submoduleGitlinks.length > 0;
|
|
81805
82377
|
const allGitlinksFf = changedGitlinks && submoduleGitlinks.every((g) => g.fastForward === true);
|
|
81806
82378
|
const gateSawUnresolvedGitlinkFf = gitlinkFf?.resolved === false && Array.isArray(gitlinkFf.gitlinks) && gitlinkFf.gitlinks.some((g) => g.fastForward);
|
|
@@ -81812,6 +82384,14 @@ ${e?.stderr || ""}`
|
|
|
81812
82384
|
evidence
|
|
81813
82385
|
};
|
|
81814
82386
|
}
|
|
82387
|
+
if (baseAncestry === "undeterminable") {
|
|
82388
|
+
return {
|
|
82389
|
+
detailedReason: "base_ancestry_undeterminable",
|
|
82390
|
+
detailedReasonDescription: `Could NOT determine whether HEAD descends ${targetBaseRef} \u2014 the ancestry probe had no answer (${targetBaseRef} and/or ${branchHead.slice(0, 12)} does not resolve in ${repoRoot}). This is "undeterminable", NOT "diverged": the ahead/behind counts above are unmeasured, not zero.`,
|
|
82391
|
+
recommendedAction: `Make the probe answerable before judging: fetch/verify that ${targetBaseRef} and the branch head both resolve in ${repoRoot} (e.g. git fetch origin, git rev-parse --verify), then retry mesh_refine_node. Do NOT rebase on the strength of this result \u2014 no divergence has been measured.`,
|
|
82392
|
+
evidence
|
|
82393
|
+
};
|
|
82394
|
+
}
|
|
81815
82395
|
if (!baseIsAncestor) {
|
|
81816
82396
|
return {
|
|
81817
82397
|
detailedReason: "base_divergence",
|
|
@@ -81836,14 +82416,6 @@ ${e?.stderr || ""}`
|
|
|
81836
82416
|
};
|
|
81837
82417
|
}
|
|
81838
82418
|
}
|
|
81839
|
-
function execGitOk(cwd, args) {
|
|
81840
|
-
try {
|
|
81841
|
-
(0, import_node_child_process13.execFileSync)(GIT4, args, { cwd, encoding: "utf8", maxBuffer: REFINE_PATCH_EQUIVALENCE_OUTPUT_LIMIT_BYTES, windowsHide: true });
|
|
81842
|
-
return true;
|
|
81843
|
-
} catch {
|
|
81844
|
-
return false;
|
|
81845
|
-
}
|
|
81846
|
-
}
|
|
81847
82419
|
async function checkWorktreeChangesPatchEquivalentInRef(repoRoot, ref, worktreeHead) {
|
|
81848
82420
|
const startedAt = Date.now();
|
|
81849
82421
|
try {
|
|
@@ -81865,6 +82437,7 @@ ${mergeTreeErr?.stderr || ""}`;
|
|
|
81865
82437
|
if (!isSubmoduleConflict) throw mergeTreeErr;
|
|
81866
82438
|
const evaluation = evaluateGitlinkTrivialFastForward(repoRoot, ref, worktreeHead);
|
|
81867
82439
|
if (!evaluation.trivial) {
|
|
82440
|
+
warnGitlinkFastForwardUndeterminable(`containment check for ${ref}`, evaluation.gitlinks);
|
|
81868
82441
|
return {
|
|
81869
82442
|
contained: false,
|
|
81870
82443
|
ref,
|
|
@@ -81994,50 +82567,12 @@ ${mergeTreeErr?.stderr || ""}`;
|
|
|
81994
82567
|
}).trim();
|
|
81995
82568
|
return out;
|
|
81996
82569
|
}
|
|
81997
|
-
function isSubmoduleFastForward(submoduleRepoPath, baseCommit, branchCommit) {
|
|
81998
|
-
if (!baseCommit || !branchCommit) return false;
|
|
81999
|
-
if (baseCommit === branchCommit) return true;
|
|
82000
|
-
try {
|
|
82001
|
-
if (!fs53.existsSync(submoduleRepoPath)) return false;
|
|
82002
|
-
(0, import_node_child_process13.execFileSync)(GIT4, ["cat-file", "-e", `${baseCommit}^{commit}`], { cwd: submoduleRepoPath, stdio: "ignore" });
|
|
82003
|
-
(0, import_node_child_process13.execFileSync)(GIT4, ["cat-file", "-e", `${branchCommit}^{commit}`], { cwd: submoduleRepoPath, stdio: "ignore" });
|
|
82004
|
-
(0, import_node_child_process13.execFileSync)(GIT4, ["merge-base", "--is-ancestor", baseCommit, branchCommit], { cwd: submoduleRepoPath, stdio: "ignore" });
|
|
82005
|
-
return true;
|
|
82006
|
-
} catch {
|
|
82007
|
-
return false;
|
|
82008
|
-
}
|
|
82009
|
-
}
|
|
82010
|
-
function readChangedPathKinds(repoRoot, fromRef, toRef) {
|
|
82011
|
-
try {
|
|
82012
|
-
const output = (0, import_node_child_process13.execFileSync)(GIT4, ["diff", "--raw", "--no-abbrev", fromRef, toRef], {
|
|
82013
|
-
cwd: repoRoot,
|
|
82014
|
-
encoding: "utf8",
|
|
82015
|
-
maxBuffer: REFINE_PATCH_EQUIVALENCE_OUTPUT_LIMIT_BYTES
|
|
82016
|
-
});
|
|
82017
|
-
const result = [];
|
|
82018
|
-
const seen = /* @__PURE__ */ new Set();
|
|
82019
|
-
for (const line of output.split("\n")) {
|
|
82020
|
-
if (!line.trim()) continue;
|
|
82021
|
-
const metaAndPath = line.split(" ");
|
|
82022
|
-
const meta3 = metaAndPath[0] || "";
|
|
82023
|
-
const path60 = metaAndPath[metaAndPath.length - 1]?.trim();
|
|
82024
|
-
if (!path60 || seen.has(path60)) continue;
|
|
82025
|
-
seen.add(path60);
|
|
82026
|
-
const parts = meta3.split(/\s+/);
|
|
82027
|
-
const isGitlink = !!(parts[0]?.includes("160000") || parts[1]?.includes("160000"));
|
|
82028
|
-
result.push({ path: path60, isGitlink });
|
|
82029
|
-
}
|
|
82030
|
-
return result;
|
|
82031
|
-
} catch {
|
|
82032
|
-
return [];
|
|
82033
|
-
}
|
|
82034
|
-
}
|
|
82035
82570
|
function collectFastForwardGitlinkPaths(repoRoot, baseHead, branchHead) {
|
|
82036
82571
|
return readChangedGitlinkPaths(repoRoot, baseHead, branchHead).filter((path60) => {
|
|
82037
82572
|
const baseCommit = readTreeObject(repoRoot, baseHead, path60);
|
|
82038
82573
|
const branchCommit = readTreeObject(repoRoot, branchHead, path60);
|
|
82039
82574
|
if (!baseCommit || !branchCommit) return false;
|
|
82040
|
-
return isSubmoduleFastForward((0,
|
|
82575
|
+
return isSubmoduleFastForward((0, import_path19.resolve)(repoRoot, path60), baseCommit, branchCommit);
|
|
82041
82576
|
});
|
|
82042
82577
|
}
|
|
82043
82578
|
function collectTrivialFastForwardGitlinkResolutions(worktreeRoot, baseRepoRoot, baseHead, branchHead) {
|
|
@@ -82046,8 +82581,8 @@ ${mergeTreeErr?.stderr || ""}`;
|
|
|
82046
82581
|
const baseCommit = readTreeObject(baseRepoRoot, baseHead, path60);
|
|
82047
82582
|
const branchCommit = readTreeObject(worktreeRoot, branchHead, path60);
|
|
82048
82583
|
if (!baseCommit || !branchCommit) continue;
|
|
82049
|
-
const submoduleRepoPath = (0,
|
|
82050
|
-
ensureSubmoduleCommitLocal(submoduleRepoPath, (0,
|
|
82584
|
+
const submoduleRepoPath = (0, import_path19.resolve)(worktreeRoot, path60);
|
|
82585
|
+
ensureSubmoduleCommitLocal(submoduleRepoPath, (0, import_path19.resolve)(baseRepoRoot, path60), baseCommit);
|
|
82051
82586
|
if (baseCommit === branchCommit) {
|
|
82052
82587
|
continue;
|
|
82053
82588
|
}
|
|
@@ -82063,20 +82598,28 @@ ${mergeTreeErr?.stderr || ""}`;
|
|
|
82063
82598
|
const changedGitlinks = readChangedGitlinkPaths(repoRoot, baseHead, branchHead).map((path60) => {
|
|
82064
82599
|
const baseCommit = readTreeObject(repoRoot, baseHead, path60);
|
|
82065
82600
|
const branchCommit = readTreeObject(repoRoot, branchHead, path60);
|
|
82066
|
-
const submoduleRepoPath = (0,
|
|
82067
|
-
const
|
|
82068
|
-
return {
|
|
82601
|
+
const submoduleRepoPath = (0, import_path19.resolve)(repoRoot, path60);
|
|
82602
|
+
const probe = !!baseCommit && !!branchCommit ? probeSubmoduleFastForward(submoduleRepoPath, baseCommit, branchCommit) : "undeterminable";
|
|
82603
|
+
return {
|
|
82604
|
+
path: path60,
|
|
82605
|
+
baseCommit,
|
|
82606
|
+
branchCommit,
|
|
82607
|
+
fastForward: probe === true,
|
|
82608
|
+
...probe === "undeterminable" ? { fastForwardUndeterminable: true } : {}
|
|
82609
|
+
};
|
|
82069
82610
|
});
|
|
82070
82611
|
if (changedGitlinks.length === 0) {
|
|
82071
82612
|
return { trivial: false, reason: "no_changed_gitlinks", gitlinks: changedGitlinks };
|
|
82072
82613
|
}
|
|
82073
|
-
const
|
|
82074
|
-
|
|
82075
|
-
|
|
82076
|
-
|
|
82077
|
-
|
|
82078
|
-
|
|
82079
|
-
|
|
82614
|
+
const undeterminable = changedGitlinks.filter((entry) => entry.fastForwardUndeterminable);
|
|
82615
|
+
const diverged = changedGitlinks.filter((entry) => !entry.fastForward && !entry.fastForwardUndeterminable);
|
|
82616
|
+
if (undeterminable.length > 0 || diverged.length > 0) {
|
|
82617
|
+
const parts = [];
|
|
82618
|
+
if (diverged.length > 0) parts.push(`diverged_gitlinks:${diverged.map((entry) => entry.path).join(",")}`);
|
|
82619
|
+
if (undeterminable.length > 0) {
|
|
82620
|
+
parts.push(`undeterminable_gitlinks:${undeterminable.map((entry) => entry.path).join(",")}`);
|
|
82621
|
+
}
|
|
82622
|
+
return { trivial: false, reason: parts.join(" "), gitlinks: changedGitlinks };
|
|
82080
82623
|
}
|
|
82081
82624
|
let mergeBase = "";
|
|
82082
82625
|
try {
|
|
@@ -82118,7 +82661,7 @@ ${mergeTreeErr?.stderr || ""}`;
|
|
|
82118
82661
|
if (!tree) return void 0;
|
|
82119
82662
|
const updates = paths.map((path60) => `160000 commit ${placeholderCommit} ${path60}`).join("\n");
|
|
82120
82663
|
if (!updates) return tree;
|
|
82121
|
-
const tmpIndex = (0,
|
|
82664
|
+
const tmpIndex = (0, import_path19.join)(resolveGitDir(repoRoot), `adhdev-refine-eq-${commitish.slice(0, 12)}.index`);
|
|
82122
82665
|
const env2 = { ...process.env, GIT_INDEX_FILE: tmpIndex };
|
|
82123
82666
|
try {
|
|
82124
82667
|
(0, import_node_child_process13.execFileSync)(GIT4, ["read-tree", tree], { cwd: repoRoot, env: env2, stdio: "ignore" });
|
|
@@ -82193,7 +82736,7 @@ ${mergeTreeErr?.stderr || ""}`;
|
|
|
82193
82736
|
if (!contentTree) return void 0;
|
|
82194
82737
|
const updates = branchGitlinks.map((entry) => `160000 commit ${entry.branchCommit} ${entry.path}`).join("\n");
|
|
82195
82738
|
if (!updates) return contentTree;
|
|
82196
|
-
const tmpIndex = (0,
|
|
82739
|
+
const tmpIndex = (0, import_path19.join)(resolveGitDir(repoRoot), `adhdev-refine-ff-${baseHead.slice(0, 12)}-${branchHead.slice(0, 12)}.index`);
|
|
82197
82740
|
const env2 = { ...process.env, GIT_INDEX_FILE: tmpIndex };
|
|
82198
82741
|
try {
|
|
82199
82742
|
(0, import_node_child_process13.execFileSync)(GIT4, ["read-tree", contentTree], { cwd: repoRoot, env: env2, stdio: "ignore" });
|
|
@@ -82350,7 +82893,7 @@ ${mergeTreeErr?.stderr || ""}`;
|
|
|
82350
82893
|
return match ? { commit: match[1], path: match[2] } : null;
|
|
82351
82894
|
}).filter((entry) => !!entry);
|
|
82352
82895
|
for (const gitlink of gitlinks) {
|
|
82353
|
-
const submodulePath = (0,
|
|
82896
|
+
const submodulePath = (0, import_path19.resolve)(repoRoot, gitlink.path);
|
|
82354
82897
|
const entry = {
|
|
82355
82898
|
path: gitlink.path,
|
|
82356
82899
|
commit: gitlink.commit,
|
|
@@ -82377,7 +82920,7 @@ ${mergeTreeErr?.stderr || ""}`;
|
|
|
82377
82920
|
entry.localReachable = false;
|
|
82378
82921
|
if (options.allowAutoPublishSubmoduleMainCommits === true && options.worktreeRoot) {
|
|
82379
82922
|
try {
|
|
82380
|
-
const imported = await importCommitFromWorktreeSubmodule(submodulePath, (0,
|
|
82923
|
+
const imported = await importCommitFromWorktreeSubmodule(submodulePath, (0, import_path19.resolve)(options.worktreeRoot, gitlink.path), gitlink.commit);
|
|
82381
82924
|
if (imported) {
|
|
82382
82925
|
entry.localReachable = true;
|
|
82383
82926
|
entry.importedFromWorktree = true;
|
|
@@ -82607,13 +83150,13 @@ ${mergeTreeErr?.stderr || ""}`;
|
|
|
82607
83150
|
...extras
|
|
82608
83151
|
});
|
|
82609
83152
|
const isPackageManagerValidation = (candidate) => {
|
|
82610
|
-
const command = (0,
|
|
83153
|
+
const command = (0, import_path19.basename)(candidate.command).replace(/\.(?:cmd|exe)$/i, "");
|
|
82611
83154
|
return ["npm", "pnpm", "yarn", "bun"].includes(command) && candidate.args.some((arg) => arg === "run" || arg === "test" || arg === "exec");
|
|
82612
83155
|
};
|
|
82613
83156
|
const dependenciesLikelyMissing = (cwd) => {
|
|
82614
|
-
if (!fs53.existsSync((0,
|
|
82615
|
-
if (fs53.existsSync((0,
|
|
82616
|
-
return ["package-lock.json", "npm-shrinkwrap.json", "pnpm-lock.yaml", "yarn.lock", "bun.lockb", "bun.lock"].some((lock) => fs53.existsSync((0,
|
|
83157
|
+
if (!fs53.existsSync((0, import_path19.join)(cwd, "package.json"))) return false;
|
|
83158
|
+
if (fs53.existsSync((0, import_path19.join)(cwd, "node_modules"))) return false;
|
|
83159
|
+
return ["package-lock.json", "npm-shrinkwrap.json", "pnpm-lock.yaml", "yarn.lock", "bun.lockb", "bun.lock"].some((lock) => fs53.existsSync((0, import_path19.join)(cwd, lock)));
|
|
82617
83160
|
};
|
|
82618
83161
|
const needsNodeModules = (candidate, cwd) => isPackageManagerValidation(candidate) && dependenciesLikelyMissing(cwd);
|
|
82619
83162
|
const isDaemonScopedCommand = (candidate) => {
|
|
@@ -82680,7 +83223,7 @@ ${mergeTreeErr?.stderr || ""}`;
|
|
|
82680
83223
|
summary.bootstrap = { stage: "legacy" };
|
|
82681
83224
|
for (const candidate of selection.bootstrapCommands) {
|
|
82682
83225
|
const startedAt = Date.now();
|
|
82683
|
-
const cwd = candidate.cwd ? (0,
|
|
83226
|
+
const cwd = candidate.cwd ? (0, import_path19.resolve)(workspace, candidate.cwd) : workspace;
|
|
82684
83227
|
const timeout = candidate.timeoutMs || REFINE_VALIDATION_TIMEOUT_MS;
|
|
82685
83228
|
const resolvedCommand = resolveWin32Executable(candidate.command);
|
|
82686
83229
|
const spawn7 = buildWin32ExecFileSpawn(resolvedCommand, candidate.args);
|
|
@@ -82713,7 +83256,7 @@ ${mergeTreeErr?.stderr || ""}`;
|
|
|
82713
83256
|
let missingDepsBlocked = false;
|
|
82714
83257
|
for (const candidate of commandsToRun) {
|
|
82715
83258
|
const startedAt = Date.now();
|
|
82716
|
-
const cwd = candidate.cwd ? (0,
|
|
83259
|
+
const cwd = candidate.cwd ? (0, import_path19.resolve)(workspace, candidate.cwd) : workspace;
|
|
82717
83260
|
const timeout = candidate.timeoutMs || REFINE_VALIDATION_TIMEOUT_MS;
|
|
82718
83261
|
const bootstrapProvidedDependencies = summary.bootstrap?.stage === "cached" || summary.bootstrap?.stage === "ran" || summary.bootstrap?.stage === "legacy";
|
|
82719
83262
|
if (!bootstrapProvidedDependencies && needsNodeModules(candidate, cwd)) {
|
|
@@ -82780,7 +83323,7 @@ ${mergeTreeErr?.stderr || ""}`;
|
|
|
82780
83323
|
summary.status = "passed";
|
|
82781
83324
|
return summary;
|
|
82782
83325
|
}
|
|
82783
|
-
var
|
|
83326
|
+
var import_path19;
|
|
82784
83327
|
var fs53;
|
|
82785
83328
|
var import_node_child_process13;
|
|
82786
83329
|
var REFINE_VALIDATION_TIMEOUT_MS;
|
|
@@ -82795,19 +83338,20 @@ ${mergeTreeErr?.stderr || ""}`;
|
|
|
82795
83338
|
init_git_status();
|
|
82796
83339
|
init_refine_config();
|
|
82797
83340
|
init_worktree_bootstrap_config();
|
|
82798
|
-
|
|
83341
|
+
import_path19 = require("path");
|
|
82799
83342
|
fs53 = __toESM2(require("fs"));
|
|
82800
83343
|
import_node_child_process13 = require("child_process");
|
|
82801
83344
|
init_resolve_executable();
|
|
82802
83345
|
init_mesh_refine_worker_cap();
|
|
82803
83346
|
init_mesh_refine_gitlink_utils();
|
|
82804
83347
|
init_mesh_refine_submodule_converge();
|
|
83348
|
+
init_mesh_refine_gitlink_utils();
|
|
82805
83349
|
REFINE_VALIDATION_TIMEOUT_MS = 12e4;
|
|
82806
83350
|
REFINE_VALIDATION_OUTPUT_LIMIT_BYTES = 128 * 1024;
|
|
82807
83351
|
REFINE_VALIDATION_SUMMARY_HEAD_CHARS = 2e3;
|
|
82808
83352
|
REFINE_VALIDATION_SUMMARY_TAIL_CHARS = 6e3;
|
|
82809
83353
|
REFINE_VALIDATION_SUMMARY_CHARS = REFINE_VALIDATION_SUMMARY_HEAD_CHARS + REFINE_VALIDATION_SUMMARY_TAIL_CHARS;
|
|
82810
|
-
REFINE_VALIDATION_LOG_DIR = (0,
|
|
83354
|
+
REFINE_VALIDATION_LOG_DIR = (0, import_path19.join)(".adhdev", "logs");
|
|
82811
83355
|
}
|
|
82812
83356
|
});
|
|
82813
83357
|
function findOpenRefineDispatchForNode(args) {
|
|
@@ -83791,7 +84335,14 @@ ${excerpt}` : "\n--- git output ---\n(none captured)");
|
|
|
83791
84335
|
return { kind: "continue", ctx };
|
|
83792
84336
|
}
|
|
83793
84337
|
if (submoduleConflict) {
|
|
83794
|
-
const
|
|
84338
|
+
const convergeAutoPublish = resolveRefineryAutoPublishSubmoduleMainCommits(ctx.mesh, node.workspace);
|
|
84339
|
+
const converge = convergeDivergedSubmoduleGitlinks(
|
|
84340
|
+
node.workspace,
|
|
84341
|
+
repoRoot,
|
|
84342
|
+
baseHead,
|
|
84343
|
+
branchHead,
|
|
84344
|
+
{ allowAutoPublishSubmoduleMainCommits: convergeAutoPublish.enabled }
|
|
84345
|
+
);
|
|
83795
84346
|
if (converge.converged) {
|
|
83796
84347
|
gitlinkResolutions = converge.resolutions;
|
|
83797
84348
|
recordMeshRefineStage(refineStages, "submodule_gitlink_converge", "passed", syncStarted, {
|
|
@@ -83799,15 +84350,19 @@ ${excerpt}` : "\n--- git output ---\n(none captured)");
|
|
|
83799
84350
|
gitlinks: converge.gitlinks
|
|
83800
84351
|
});
|
|
83801
84352
|
LOG2.info("Mesh", `[Refinery] Auto-converged diverged submodule gitlink(s) onto base for node ${node.id}: ` + converge.resolutions.map((r) => `${r.path}\u2192${r.rebasedCommit.slice(0, 12)}`).join(", "));
|
|
84353
|
+
const minted = describeMintedUnpublishedCommits(node.id, converge.gitlinks, convergeAutoPublish.enabled);
|
|
84354
|
+
if (minted) LOG2.warn("Mesh", minted);
|
|
83802
84355
|
} else {
|
|
83803
84356
|
recordMeshRefineStage(refineStages, "submodule_gitlink_converge", "skipped", syncStarted, {
|
|
83804
84357
|
reason: "submodule_conflict_defer_to_patch_equivalence",
|
|
83805
84358
|
convergeReason: converge.reason,
|
|
83806
|
-
gitlinks: converge.gitlinks
|
|
84359
|
+
gitlinks: converge.gitlinks,
|
|
84360
|
+
// ★Structural next step, so the coordinator is told to PUBLISH
|
|
84361
|
+
// rather than retry the rebase (retrying re-mints the orphan).
|
|
84362
|
+
...buildSubmoduleConvergeDeclineDetails(converge.reason, convergeAutoPublish.enabled)
|
|
83807
84363
|
});
|
|
83808
|
-
|
|
83809
|
-
|
|
83810
|
-
}
|
|
84364
|
+
const declined = describeSubmoduleConvergeDecline(node.id, converge.reason, converge.gitlinks);
|
|
84365
|
+
if (declined) LOG2.warn("Mesh", declined);
|
|
83811
84366
|
recordMeshRefineStage(refineStages, "sync_base", "passed", syncStarted, {
|
|
83812
84367
|
ahead: divergence.ahead,
|
|
83813
84368
|
behind: divergence.behind,
|
|
@@ -83889,16 +84444,11 @@ ${excerpt}` : "\n--- git output ---\n(none captured)");
|
|
|
83889
84444
|
error: submoduleHintPatchEquivalence.error,
|
|
83890
84445
|
actionableHint: submoduleHintPatchEquivalence.actionableHint
|
|
83891
84446
|
});
|
|
83892
|
-
const classification = await
|
|
83893
|
-
|
|
83894
|
-
|
|
83895
|
-
ctx.
|
|
83896
|
-
|
|
83897
|
-
{
|
|
83898
|
-
targetBaseRef: baseHead,
|
|
83899
|
-
autoPublishSubmoduleMainCommits: resolveRefineryAutoPublishSubmoduleMainCommits(ctx.mesh, node.workspace).enabled
|
|
83900
|
-
}
|
|
83901
|
-
);
|
|
84447
|
+
const classification = await classifyAndWarnPatchEquivalenceFailure(node.id, repoRoot, baseHead, ctx.branchHead, submoduleHintPatchEquivalence, {
|
|
84448
|
+
targetBaseRef: baseHead,
|
|
84449
|
+
worktreeRoot: node.workspace,
|
|
84450
|
+
autoPublishSubmoduleMainCommits: resolveRefineryAutoPublishSubmoduleMainCommits(ctx.mesh, node.workspace).enabled
|
|
84451
|
+
});
|
|
83902
84452
|
return { kind: "terminal", result: {
|
|
83903
84453
|
success: false,
|
|
83904
84454
|
code: "patch_equivalence_failed",
|
|
@@ -84082,19 +84632,15 @@ ${tail}` : ""
|
|
|
84082
84632
|
if (!patchEquivalence.equivalent) {
|
|
84083
84633
|
const alreadyMergedViaOtherPath = !patchEquivalence.actualPatchId && !!patchEquivalence.expectedPatchId;
|
|
84084
84634
|
if (!alreadyMergedViaOtherPath) {
|
|
84085
|
-
const classification = await
|
|
84086
|
-
|
|
84087
|
-
|
|
84088
|
-
|
|
84089
|
-
|
|
84090
|
-
{
|
|
84091
|
-
targetBaseRef: baseHead,
|
|
84092
|
-
autoPublishSubmoduleMainCommits: resolveRefineryAutoPublishSubmoduleMainCommits(mesh, node.workspace).enabled
|
|
84093
|
-
}
|
|
84094
|
-
);
|
|
84635
|
+
const classification = await classifyAndWarnPatchEquivalenceFailure(node.id, repoRoot, baseHead, branchHead, patchEquivalence, {
|
|
84636
|
+
targetBaseRef: baseHead,
|
|
84637
|
+
worktreeRoot: node.workspace,
|
|
84638
|
+
autoPublishSubmoduleMainCommits: resolveRefineryAutoPublishSubmoduleMainCommits(mesh, node.workspace).enabled
|
|
84639
|
+
});
|
|
84095
84640
|
recordMeshRefineStage(refineStages, "patch_equivalence_classification", "failed", patchEquivalenceStarted, {
|
|
84096
84641
|
detailedReason: classification.detailedReason,
|
|
84097
|
-
recommendedAction: classification.recommendedAction
|
|
84642
|
+
recommendedAction: classification.recommendedAction,
|
|
84643
|
+
...classification.evidence.submoduleReachabilityUndeterminable ? { submoduleReachabilityUndeterminable: true } : {}
|
|
84098
84644
|
});
|
|
84099
84645
|
return { kind: "terminal", result: {
|
|
84100
84646
|
success: false,
|
|
@@ -85473,6 +86019,10 @@ ${e?.stderr || ""}`;
|
|
|
85473
86019
|
DEFAULT_STATUS_P2P_REPORT_INTERVAL_MS: () => DEFAULT_STATUS_P2P_REPORT_INTERVAL_MS,
|
|
85474
86020
|
DEFAULT_STATUS_SERVER_REPORT_INTERVAL_MS: () => DEFAULT_STATUS_SERVER_REPORT_INTERVAL_MS,
|
|
85475
86021
|
DEV_SERVER_PORT: () => DEV_SERVER_PORT,
|
|
86022
|
+
DISK_CRITICAL_FREE_BYTES: () => DISK_CRITICAL_FREE_BYTES,
|
|
86023
|
+
DISK_CRITICAL_PERCENT_FREE: () => DISK_CRITICAL_PERCENT_FREE,
|
|
86024
|
+
DISK_WARNING_FREE_BYTES: () => DISK_WARNING_FREE_BYTES,
|
|
86025
|
+
DISK_WARNING_PERCENT_FREE: () => DISK_WARNING_PERCENT_FREE,
|
|
85476
86026
|
DUPLICATE_MESH_DISPATCH_CODE: () => DUPLICATE_MESH_DISPATCH_CODE,
|
|
85477
86027
|
DaemonAgentStreamManager: () => DaemonAgentStreamManager,
|
|
85478
86028
|
DaemonCdpInitializer: () => DaemonCdpInitializer,
|
|
@@ -85497,8 +86047,11 @@ ${e?.stderr || ""}`;
|
|
|
85497
86047
|
KNOWN_DIGEST_ALGORITHMS: () => KNOWN_DIGEST_ALGORITHMS,
|
|
85498
86048
|
LEGACY_UNVERIFIED_ALGORITHM: () => LEGACY_UNVERIFIED_ALGORITHM,
|
|
85499
86049
|
LOG: () => LOG2,
|
|
86050
|
+
LowDiskSpaceError: () => LowDiskSpaceError,
|
|
85500
86051
|
MAGI_NEEDS_VERIFICATION_PREVIEW_CAP: () => MAGI_NEEDS_VERIFICATION_PREVIEW_CAP,
|
|
85501
86052
|
MAGI_RAW_ANSWER_CAP: () => MAGI_RAW_ANSWER_CAP,
|
|
86053
|
+
MAX_CAPTURE_LOG_GENERATIONS: () => MAX_CAPTURE_LOG_GENERATIONS,
|
|
86054
|
+
MAX_CAPTURE_LOG_SIZE: () => MAX_CAPTURE_LOG_SIZE,
|
|
85502
86055
|
MAX_LEDGER_SLICE_LIMIT: () => MAX_LEDGER_SLICE_LIMIT,
|
|
85503
86056
|
MAX_SESSIONS_PER_MESH: () => MAX_SESSIONS_PER_MESH,
|
|
85504
86057
|
MAX_SIZE_ROTATION_GENERATIONS: () => MAX_SIZE_ROTATION_GENERATIONS,
|
|
@@ -85628,9 +86181,11 @@ ${e?.stderr || ""}`;
|
|
|
85628
86181
|
buildUserChatMessage: () => buildUserChatMessage,
|
|
85629
86182
|
cancelTask: () => cancelTask,
|
|
85630
86183
|
canonicalDaemonId: () => canonicalDaemonId,
|
|
86184
|
+
checkDiskSpace: () => checkDiskSpace,
|
|
85631
86185
|
claimMeshGraphGate: () => claimMeshGraphGate,
|
|
85632
86186
|
claimNextTask: () => claimNextTask,
|
|
85633
86187
|
classifyChatMessageVisibility: () => classifyChatMessageVisibility,
|
|
86188
|
+
classifyDiskSpace: () => classifyDiskSpace,
|
|
85634
86189
|
classifyDuplicateMeshDispatch: () => classifyDuplicateMeshDispatch,
|
|
85635
86190
|
classifyHotChatSessionsForSubscriptionFlush: () => classifyHotChatSessionsForSubscriptionFlush2,
|
|
85636
86191
|
classifyP2pRelayFailure: () => classifyP2pRelayFailure,
|
|
@@ -85682,6 +86237,7 @@ ${e?.stderr || ""}`;
|
|
|
85682
86237
|
deriveMeshReviewInboxItems: () => deriveMeshReviewInboxItems,
|
|
85683
86238
|
deriveWorkspaceBranchIdentity: () => deriveWorkspaceBranchIdentity,
|
|
85684
86239
|
deriveWorkspaceOwnerTag: () => deriveWorkspaceOwnerTag,
|
|
86240
|
+
describeDiskSpace: () => describeDiskSpace,
|
|
85685
86241
|
describeTaskDependencyState: () => describeTaskDependencyState,
|
|
85686
86242
|
detectAllVersions: () => detectAllVersions,
|
|
85687
86243
|
detectCLI: () => detectCLI,
|
|
@@ -85717,6 +86273,7 @@ ${e?.stderr || ""}`;
|
|
|
85717
86273
|
flattenMessageParts: () => flattenMessageParts,
|
|
85718
86274
|
foldUsageRecords: () => foldUsageRecords,
|
|
85719
86275
|
forceRefreshQuota: () => forceRefreshQuota2,
|
|
86276
|
+
formatBytes: () => formatBytes,
|
|
85720
86277
|
formatManifestValidationIssues: () => formatManifestValidationIssues,
|
|
85721
86278
|
formatMeshTaskModeViolations: () => formatMeshTaskModeViolations,
|
|
85722
86279
|
forwardAgentStreamsToIdeInstance: () => forwardAgentStreamsToIdeInstance2,
|
|
@@ -85834,6 +86391,7 @@ ${e?.stderr || ""}`;
|
|
|
85834
86391
|
loadRepoSettings: () => loadRepoSettings,
|
|
85835
86392
|
loadState: () => loadState,
|
|
85836
86393
|
logCommand: () => logCommand,
|
|
86394
|
+
logDiskSpaceStatus: () => logDiskSpaceStatus,
|
|
85837
86395
|
machineCoreFromDaemonId: () => machineCoreFromDaemonId,
|
|
85838
86396
|
magiAutoLaunchedSessionCleanupDecision: () => magiAutoLaunchedSessionCleanupDecision,
|
|
85839
86397
|
makeUsage: () => makeUsage,
|
|
@@ -85890,6 +86448,7 @@ ${e?.stderr || ""}`;
|
|
|
85890
86448
|
partitionSessionHostDiagnosticsSessions: () => import_session_host_core32.partitionSessionHostDiagnosticsSessions,
|
|
85891
86449
|
partitionSessionHostRecords: () => import_session_host_core32.partitionSessionHostRecords,
|
|
85892
86450
|
planMeshOnboarding: () => planMeshOnboarding,
|
|
86451
|
+
preflightDiskSpace: () => preflightDiskSpace,
|
|
85893
86452
|
prepareSessionChatTailUpdate: () => prepareSessionChatTailUpdate2,
|
|
85894
86453
|
prepareSessionModalUpdate: () => prepareSessionModalUpdate2,
|
|
85895
86454
|
presentationFromAttemptRow: () => presentationFromAttemptRow,
|
|
@@ -85911,6 +86470,7 @@ ${e?.stderr || ""}`;
|
|
|
85911
86470
|
readChatHistory: () => readChatHistory,
|
|
85912
86471
|
readClaudeCliSession: () => readSession,
|
|
85913
86472
|
readCodexCliSession: () => readSession2,
|
|
86473
|
+
readDiskSpace: () => readDiskSpace,
|
|
85914
86474
|
readHermesCliSession: () => readSession4,
|
|
85915
86475
|
readLatestCodexRateLimits: () => readLatestCodexRateLimits,
|
|
85916
86476
|
readLedgerEntries: () => readLedgerEntries,
|
|
@@ -85992,6 +86552,7 @@ ${e?.stderr || ""}`;
|
|
|
85992
86552
|
resolveTurnAttemptRow: () => resolveTurnAttemptRow,
|
|
85993
86553
|
resolveWorktreeBaseDir: () => resolveWorktreeBaseDir,
|
|
85994
86554
|
resolveWorktreePath: () => resolveWorktreePath,
|
|
86555
|
+
rotateCaptureLogIfNeeded: () => rotateCaptureLogIfNeeded,
|
|
85995
86556
|
runAsyncBatch: () => runAsyncBatch2,
|
|
85996
86557
|
runGit: () => runGit,
|
|
85997
86558
|
runMeshWorktreeBootstrap: () => runMeshWorktreeBootstrap,
|
|
@@ -89543,7 +90104,7 @@ The pin is NOT cleared automatically: a pin often encodes required context conti
|
|
|
89543
90104
|
init_state_store();
|
|
89544
90105
|
var import_child_process5 = require("child_process");
|
|
89545
90106
|
var import_util22 = require("util");
|
|
89546
|
-
var
|
|
90107
|
+
var import_fs18 = require("fs");
|
|
89547
90108
|
var import_os3 = require("os");
|
|
89548
90109
|
var path24 = __toESM2(require("path"));
|
|
89549
90110
|
var fs16 = __toESM2(require("fs"));
|
|
@@ -89620,7 +90181,7 @@ The pin is NOT cleared automatically: a pin often encodes required context conti
|
|
|
89620
90181
|
if (path24.isAbsolute(trimmed) || trimmed.includes("/") || trimmed.includes("\\") || trimmed.startsWith("~")) {
|
|
89621
90182
|
const candidate = trimmed.startsWith("~") ? path24.join((0, import_os3.homedir)(), trimmed.slice(1)) : trimmed;
|
|
89622
90183
|
const resolved = path24.isAbsolute(candidate) ? candidate : path24.resolve(candidate);
|
|
89623
|
-
return (0,
|
|
90184
|
+
return (0, import_fs18.existsSync)(resolved) ? resolved : null;
|
|
89624
90185
|
}
|
|
89625
90186
|
const isWin = (0, import_os3.platform)() === "win32";
|
|
89626
90187
|
const paths = (process.env.PATH || "").split(isWin ? ";" : ":");
|
|
@@ -89630,8 +90191,8 @@ The pin is NOT cleared automatically: a pin often encodes required context conti
|
|
|
89630
90191
|
for (const ext of exes) {
|
|
89631
90192
|
const fullPath = path24.join(p, trimmed + ext);
|
|
89632
90193
|
try {
|
|
89633
|
-
if ((0,
|
|
89634
|
-
const stat2 = (0,
|
|
90194
|
+
if ((0, import_fs18.existsSync)(fullPath)) {
|
|
90195
|
+
const stat2 = (0, import_fs18.statSync)(fullPath);
|
|
89635
90196
|
if (stat2.isFile() && (isWin || stat2.mode & 73)) {
|
|
89636
90197
|
return fullPath;
|
|
89637
90198
|
}
|
|
@@ -89649,9 +90210,9 @@ The pin is NOT cleared automatically: a pin often encodes required context conti
|
|
|
89649
90210
|
if (normalized.includes("*")) {
|
|
89650
90211
|
const username = home.split(/[\\/]/).pop() || "";
|
|
89651
90212
|
const resolved = normalized.replace("*", username);
|
|
89652
|
-
if ((0,
|
|
90213
|
+
if ((0, import_fs18.existsSync)(resolved)) return resolved;
|
|
89653
90214
|
} else {
|
|
89654
|
-
if ((0,
|
|
90215
|
+
if ((0, import_fs18.existsSync)(normalized)) return normalized;
|
|
89655
90216
|
}
|
|
89656
90217
|
}
|
|
89657
90218
|
return null;
|
|
@@ -89665,7 +90226,7 @@ The pin is NOT cleared automatically: a pin often encodes required context conti
|
|
|
89665
90226
|
let resolvedCli = cliPath;
|
|
89666
90227
|
if (!resolvedCli && appPath && os33 === "darwin") {
|
|
89667
90228
|
const bundledCli = `${appPath}/Contents/Resources/app/bin/${def.cli}`;
|
|
89668
|
-
if ((0,
|
|
90229
|
+
if ((0, import_fs18.existsSync)(bundledCli)) resolvedCli = bundledCli;
|
|
89669
90230
|
}
|
|
89670
90231
|
if (!resolvedCli && appPath && os33 === "win32") {
|
|
89671
90232
|
const { dirname: dirname24 } = await import("path");
|
|
@@ -89678,7 +90239,7 @@ The pin is NOT cleared automatically: a pin often encodes required context conti
|
|
|
89678
90239
|
`${appDir}\\\\resources\\\\app\\\\bin\\\\${def.cli}.cmd`
|
|
89679
90240
|
];
|
|
89680
90241
|
for (const c of candidates) {
|
|
89681
|
-
if ((0,
|
|
90242
|
+
if ((0, import_fs18.existsSync)(c)) {
|
|
89682
90243
|
resolvedCli = c;
|
|
89683
90244
|
break;
|
|
89684
90245
|
}
|
|
@@ -101316,7 +101877,7 @@ ${marker}`,
|
|
|
101316
101877
|
var os24 = __toESM2(require("os"));
|
|
101317
101878
|
var path40 = __toESM2(require("path"));
|
|
101318
101879
|
var crypto6 = __toESM2(require("crypto"));
|
|
101319
|
-
var
|
|
101880
|
+
var import_fs19 = require("fs");
|
|
101320
101881
|
var import_child_process11 = require("child_process");
|
|
101321
101882
|
var import_chalk = __toESM2((init_source(), __toCommonJS(source_exports)));
|
|
101322
101883
|
var fs322 = __toESM2(require("fs"));
|
|
@@ -112640,7 +113201,7 @@ ${rawInput}` : rawInput;
|
|
|
112640
113201
|
const trimmed = command.trim();
|
|
112641
113202
|
if (!trimmed) return false;
|
|
112642
113203
|
if (isExplicitCommand(trimmed)) {
|
|
112643
|
-
return (0,
|
|
113204
|
+
return (0, import_fs19.existsSync)(expandExecutable(trimmed));
|
|
112644
113205
|
}
|
|
112645
113206
|
try {
|
|
112646
113207
|
(0, import_child_process11.execFileSync)(process.platform === "win32" ? "where" : "which", [trimmed], {
|
|
@@ -112786,10 +113347,10 @@ ${rawInput}` : rawInput;
|
|
|
112786
113347
|
}
|
|
112787
113348
|
function ensureEmptyDelegatedMcpConfig(workspace) {
|
|
112788
113349
|
const baseDir = path40.join(os24.tmpdir(), "adhdev-delegated-agent-empty-mcp");
|
|
112789
|
-
(0,
|
|
113350
|
+
(0, import_fs19.mkdirSync)(baseDir, { recursive: true });
|
|
112790
113351
|
const workspaceHash = shortHash(path40.resolve(workspace || os24.tmpdir()));
|
|
112791
113352
|
const filePath = path40.join(baseDir, `${workspaceHash}.json`);
|
|
112792
|
-
(0,
|
|
113353
|
+
(0, import_fs19.writeFileSync)(filePath, JSON.stringify({ mcpServers: {} }, null, 2), "utf-8");
|
|
112793
113354
|
return filePath;
|
|
112794
113355
|
}
|
|
112795
113356
|
function buildCoordinatorDelegatedCliLaunchOptions(input) {
|
|
@@ -120541,7 +121102,7 @@ ${formatManifestValidationIssues2(validation2.issues)}`);
|
|
|
120541
121102
|
normalizeRepoMeshDeclarativeConfig: normalizeRepoMeshDeclarativeConfig2,
|
|
120542
121103
|
MESH_JSON_CONFIG_LOCATIONS: MESH_JSON_CONFIG_LOCATIONS2
|
|
120543
121104
|
} = await Promise.resolve().then(() => (init_mesh_json_config(), mesh_json_config_exports));
|
|
120544
|
-
const { mkdirSync:
|
|
121105
|
+
const { mkdirSync: mkdirSync32, writeFileSync: writeFileSync31 } = await import("fs");
|
|
120545
121106
|
const { dirname: dirname24, join: join68 } = await import("path");
|
|
120546
121107
|
const scaffold = buildMeshJsonConfigScaffold2(mesh);
|
|
120547
121108
|
const scaffoldJson = serializeMeshJsonConfigScaffold2(scaffold);
|
|
@@ -120582,7 +121143,7 @@ ${formatManifestValidationIssues2(validation2.issues)}`);
|
|
|
120582
121143
|
note: "Dry-run: nothing written. Re-run with write=true to persist to the repo (commit target). meshes.json is untouched."
|
|
120583
121144
|
};
|
|
120584
121145
|
}
|
|
120585
|
-
|
|
121146
|
+
mkdirSync32(dirname24(absolutePath), { recursive: true });
|
|
120586
121147
|
writeFileSync31(absolutePath, `${scaffoldJson}
|
|
120587
121148
|
`, "utf-8");
|
|
120588
121149
|
return {
|
|
@@ -120652,7 +121213,7 @@ ${formatManifestValidationIssues2(validation2.issues)}`);
|
|
|
120652
121213
|
normalizeRepoMeshDeclarativeConfig: normalizeRepoMeshDeclarativeConfig2,
|
|
120653
121214
|
MESH_JSON_CONFIG_LOCATIONS: MESH_JSON_CONFIG_LOCATIONS2
|
|
120654
121215
|
} = await Promise.resolve().then(() => (init_mesh_json_config(), mesh_json_config_exports));
|
|
120655
|
-
const { existsSync: existsSync70, readFileSync: readFileSync55, mkdirSync:
|
|
121216
|
+
const { existsSync: existsSync70, readFileSync: readFileSync55, mkdirSync: mkdirSync32, writeFileSync: writeFileSync31 } = await import("fs");
|
|
120656
121217
|
const { dirname: dirname24, join: join68 } = await import("path");
|
|
120657
121218
|
const yaml6 = await Promise.resolve().then(() => (init_js_yaml(), js_yaml_exports));
|
|
120658
121219
|
const relativePath = MESH_JSON_CONFIG_LOCATIONS2[0];
|
|
@@ -120717,7 +121278,7 @@ ${formatManifestValidationIssues2(validation2.issues)}`);
|
|
|
120717
121278
|
note: "Dry-run: nothing written. Re-run with write=true to persist. Only the providerDefaults zone is merged; other repo zones are preserved."
|
|
120718
121279
|
};
|
|
120719
121280
|
}
|
|
120720
|
-
|
|
121281
|
+
mkdirSync32(dirname24(absolutePath), { recursive: true });
|
|
120721
121282
|
writeFileSync31(absolutePath, serialized, "utf-8");
|
|
120722
121283
|
return {
|
|
120723
121284
|
success: true,
|
|
@@ -121674,7 +122235,7 @@ ${formatManifestValidationIssues2(validation2.issues)}`);
|
|
|
121674
122235
|
error: applied.reason
|
|
121675
122236
|
};
|
|
121676
122237
|
}
|
|
121677
|
-
ctx.
|
|
122238
|
+
ctx.getCachedInlineMesh(meshId, applied.mesh);
|
|
121678
122239
|
ctx.invalidateAggregateMeshStatus(meshId);
|
|
121679
122240
|
try {
|
|
121680
122241
|
const { appendLedgerEntry: appendLedgerEntry2 } = await Promise.resolve().then(() => (init_mesh_ledger(), mesh_ledger_exports));
|
|
@@ -121807,14 +122368,14 @@ ${formatManifestValidationIssues2(validation2.issues)}`);
|
|
|
121807
122368
|
let daemonId;
|
|
121808
122369
|
if (nodeId) {
|
|
121809
122370
|
try {
|
|
121810
|
-
const [{ getMesh: getMesh2 }, { meshNodeIdMatches: meshNodeIdMatches2 }, { readMeshNodeDaemonId:
|
|
122371
|
+
const [{ getMesh: getMesh2 }, { meshNodeIdMatches: meshNodeIdMatches2 }, { readMeshNodeDaemonId: readMeshNodeDaemonId3 }] = await Promise.all([
|
|
121811
122372
|
Promise.resolve().then(() => (init_mesh_config(), mesh_config_exports)),
|
|
121812
122373
|
Promise.resolve().then(() => (init_dist(), dist_exports)),
|
|
121813
122374
|
Promise.resolve().then(() => (init_mesh_node_identity(), mesh_node_identity_exports))
|
|
121814
122375
|
]);
|
|
121815
122376
|
const mesh = getMesh2(meshId);
|
|
121816
122377
|
const node = mesh?.nodes?.find((n) => meshNodeIdMatches2(n, nodeId));
|
|
121817
|
-
daemonId = node ?
|
|
122378
|
+
daemonId = node ? readMeshNodeDaemonId3(node) || void 0 : void 0;
|
|
121818
122379
|
} catch {
|
|
121819
122380
|
}
|
|
121820
122381
|
}
|
|
@@ -123026,7 +123587,7 @@ ${ptyResult.output.slice(-2e3)}`);
|
|
|
123026
123587
|
workspace
|
|
123027
123588
|
};
|
|
123028
123589
|
}
|
|
123029
|
-
const { existsSync: existsSync70, readFileSync: readFileSync55, writeFileSync: writeFileSync31, copyFileSync: copyFileSync3, mkdirSync:
|
|
123590
|
+
const { existsSync: existsSync70, readFileSync: readFileSync55, writeFileSync: writeFileSync31, copyFileSync: copyFileSync3, mkdirSync: mkdirSync32 } = await import("fs");
|
|
123030
123591
|
const { dirname: dirname24 } = await import("path");
|
|
123031
123592
|
const mcpConfigPath = coordinatorSetup.configPath;
|
|
123032
123593
|
const hermesManualFallback = cliType === "hermes-cli" && configFormat === "hermes_config_yaml" ? createHermesManualMeshCoordinatorSetup(meshId, workspace) : null;
|
|
@@ -123064,7 +123625,7 @@ ${ptyResult.output.slice(-2e3)}`);
|
|
|
123064
123625
|
...mcpServerEnv ? { env: mcpServerEnv } : {}
|
|
123065
123626
|
});
|
|
123066
123627
|
try {
|
|
123067
|
-
|
|
123628
|
+
mkdirSync32(dirname24(mcpConfigPath), { recursive: true });
|
|
123068
123629
|
} catch (error48) {
|
|
123069
123630
|
const message = `Could not prepare MCP config path for automatic setup: ${error48?.message || error48}`;
|
|
123070
123631
|
LOG2.error("MeshCoordinator", message);
|
|
@@ -124092,7 +124653,7 @@ ${ptyResult.output.slice(-2e3)}`);
|
|
|
124092
124653
|
init_router_refine();
|
|
124093
124654
|
var fs54 = __toESM2(require("fs"));
|
|
124094
124655
|
var import_node_os22 = require("os");
|
|
124095
|
-
var
|
|
124656
|
+
var import_path20 = require("path");
|
|
124096
124657
|
init_logger();
|
|
124097
124658
|
init_git_locale();
|
|
124098
124659
|
init_dist();
|
|
@@ -124104,7 +124665,7 @@ ${ptyResult.output.slice(-2e3)}`);
|
|
|
124104
124665
|
function acceptableManagedWorktreePaths(resolveWorktreePath2, normalizePath2, repoRoot, meshName, branch, worktreeBaseDir) {
|
|
124105
124666
|
const safeBranch = branch.replace(/[/\\:*?"<>|]/g, "-").replace(/^\.+|\.+$/g, "");
|
|
124106
124667
|
const safeMeshName = meshName.replace(/[/\\:*?"<>|]/g, "-").replace(/^\.+|\.+$/g, "");
|
|
124107
|
-
const legacyPath = (0,
|
|
124668
|
+
const legacyPath = (0, import_path20.join)((0, import_path20.dirname)(repoRoot), LEGACY_WORKTREE_DIR_NAME, safeMeshName, safeBranch);
|
|
124108
124669
|
const candidates = [
|
|
124109
124670
|
resolveWorktreePath2(repoRoot, meshName, branch, worktreeBaseDir),
|
|
124110
124671
|
legacyPath
|
|
@@ -124131,8 +124692,8 @@ ${ptyResult.output.slice(-2e3)}`);
|
|
|
124131
124692
|
function looksLikeCrossTrackWorktreePath(actualPath, normalizePath2) {
|
|
124132
124693
|
const home = normalizePath2((0, import_node_os22.homedir)());
|
|
124133
124694
|
return TRACK_CONFIG_DIR_NAMES.some((trackDirName) => {
|
|
124134
|
-
const trackWorktreesDir = (0,
|
|
124135
|
-
return actualPath === normalizePath2(trackWorktreesDir) || actualPath.startsWith(normalizePath2(trackWorktreesDir) +
|
|
124695
|
+
const trackWorktreesDir = (0, import_path20.join)(home, trackDirName, "worktrees");
|
|
124696
|
+
return actualPath === normalizePath2(trackWorktreesDir) || actualPath.startsWith(normalizePath2(trackWorktreesDir) + import_path20.sep);
|
|
124136
124697
|
});
|
|
124137
124698
|
}
|
|
124138
124699
|
function unexpectedPathRecoveryHint(actualPath, normalizePath2, suffix) {
|
|
@@ -124242,7 +124803,7 @@ ${ptyResult.output.slice(-2e3)}`);
|
|
|
124242
124803
|
}
|
|
124243
124804
|
const { resolveWorktreePath: resolveWorktreePath2, listWorktrees: listWorktrees2 } = await Promise.resolve().then(() => (init_git_worktree(), git_worktree_exports));
|
|
124244
124805
|
const normalizePath2 = (value) => {
|
|
124245
|
-
const resolved = (0,
|
|
124806
|
+
const resolved = (0, import_path20.resolve)(value);
|
|
124246
124807
|
try {
|
|
124247
124808
|
return fs54.realpathSync(resolved);
|
|
124248
124809
|
} catch {
|
|
@@ -124369,7 +124930,7 @@ ${ptyResult.output.slice(-2e3)}`);
|
|
|
124369
124930
|
}
|
|
124370
124931
|
const { resolveWorktreePath: resolveWorktreePath2, listWorktrees: listWorktrees2, removeWorktree: removeWorktree2 } = await Promise.resolve().then(() => (init_git_worktree(), git_worktree_exports));
|
|
124371
124932
|
const normalizePath2 = (value) => {
|
|
124372
|
-
const resolved = (0,
|
|
124933
|
+
const resolved = (0, import_path20.resolve)(value);
|
|
124373
124934
|
try {
|
|
124374
124935
|
return fs54.realpathSync(resolved);
|
|
124375
124936
|
} catch {
|
|
@@ -125037,7 +125598,7 @@ ${ptyResult.output.slice(-2e3)}`);
|
|
|
125037
125598
|
init_logger();
|
|
125038
125599
|
var yaml5 = __toESM2(require_js_yaml());
|
|
125039
125600
|
var import_os5 = require("os");
|
|
125040
|
-
var
|
|
125601
|
+
var import_path21 = require("path");
|
|
125041
125602
|
var fs55 = __toESM2(require("fs"));
|
|
125042
125603
|
var MESH_COORDINATOR_AUTO_IMPORT_FORMATS = ["claude_mcp_json", "hermes_config_yaml", "opencode_json"];
|
|
125043
125604
|
function isSupportedMeshCoordinatorConfigFormat(format) {
|
|
@@ -125078,13 +125639,13 @@ ${ptyResult.output.slice(-2e3)}`);
|
|
|
125078
125639
|
}
|
|
125079
125640
|
function resolveHermesUserHome() {
|
|
125080
125641
|
const explicitHome = process.env.HERMES_HOME?.trim();
|
|
125081
|
-
return explicitHome || (0,
|
|
125642
|
+
return explicitHome || (0, import_path21.join)((0, import_os5.homedir)(), ".hermes");
|
|
125082
125643
|
}
|
|
125083
125644
|
function loadHermesCoordinatorBaseConfig(targetConfigPath) {
|
|
125084
125645
|
const sourceHome = resolveHermesUserHome();
|
|
125085
|
-
const sourceConfigPath = (0,
|
|
125646
|
+
const sourceConfigPath = (0, import_path21.join)(sourceHome, "config.yaml");
|
|
125086
125647
|
if (!fs55.existsSync(sourceConfigPath)) return { config: {}, sourceHome, sourceConfigPath };
|
|
125087
|
-
if ((0,
|
|
125648
|
+
if ((0, import_path21.resolve)(sourceConfigPath) === (0, import_path21.resolve)(targetConfigPath)) return { config: {}, sourceHome, sourceConfigPath };
|
|
125088
125649
|
const parsed = parseMeshCoordinatorMcpConfig(fs55.readFileSync(sourceConfigPath, "utf-8"), "hermes_config_yaml");
|
|
125089
125650
|
const { mcp_servers: _mcpServers, ...baseConfig } = parsed;
|
|
125090
125651
|
return { config: baseConfig, sourceHome, sourceConfigPath };
|
|
@@ -125118,10 +125679,10 @@ ${ptyResult.output.slice(-2e3)}`);
|
|
|
125118
125679
|
return sanitized;
|
|
125119
125680
|
}
|
|
125120
125681
|
function copyHermesCoordinatorCredentialFiles(sourceHome, targetHome) {
|
|
125121
|
-
if ((0,
|
|
125682
|
+
if ((0, import_path21.resolve)(sourceHome) === (0, import_path21.resolve)(targetHome)) return;
|
|
125122
125683
|
for (const fileName of [".env", "auth.json"]) {
|
|
125123
|
-
const sourcePath = (0,
|
|
125124
|
-
const targetPath = (0,
|
|
125684
|
+
const sourcePath = (0, import_path21.join)(sourceHome, fileName);
|
|
125685
|
+
const targetPath = (0, import_path21.join)(targetHome, fileName);
|
|
125125
125686
|
if (!fs55.existsSync(sourcePath)) continue;
|
|
125126
125687
|
try {
|
|
125127
125688
|
fs55.copyFileSync(sourcePath, targetPath);
|
|
@@ -126258,6 +126819,7 @@ ${ptyResult.output.slice(-2e3)}`);
|
|
|
126258
126819
|
init_track_identity();
|
|
126259
126820
|
init_normalize();
|
|
126260
126821
|
init_logger();
|
|
126822
|
+
init_disk_space_preflight();
|
|
126261
126823
|
var UNICODE_SYMBOLS = {
|
|
126262
126824
|
ok: "\u2713",
|
|
126263
126825
|
fail: "\u2717",
|
|
@@ -133326,6 +133888,7 @@ data: ${JSON.stringify(msg.data)}
|
|
|
133326
133888
|
var path59 = __toESM2(require("path"));
|
|
133327
133889
|
var import_session_host_core14 = require_dist();
|
|
133328
133890
|
init_logger();
|
|
133891
|
+
init_disk_space_preflight();
|
|
133329
133892
|
init_runtime_defaults();
|
|
133330
133893
|
function createManagedSessionHost2(options) {
|
|
133331
133894
|
const appName = options.appName;
|
|
@@ -133429,6 +133992,7 @@ data: ${JSON.stringify(msg.data)}
|
|
|
133429
133992
|
function spawnHost() {
|
|
133430
133993
|
const entry = resolveEntry();
|
|
133431
133994
|
verifyConptyPrebuildBeforeSpawn(entry);
|
|
133995
|
+
preflightDiskSpace(instance().configDir, "spawn the session host");
|
|
133432
133996
|
const nodeExecutable = resolveSessionHostNode();
|
|
133433
133997
|
let stdio = "ignore";
|
|
133434
133998
|
let logFd = null;
|
|
@@ -133444,7 +134008,20 @@ data: ${JSON.stringify(msg.data)}
|
|
|
133444
134008
|
windowsHide: true,
|
|
133445
134009
|
env: buildEnv(process.env)
|
|
133446
134010
|
});
|
|
133447
|
-
child
|
|
134011
|
+
if (typeof child?.on === "function") {
|
|
134012
|
+
child.on("error", (error48) => {
|
|
134013
|
+
LOG2.error("SessionHost", `Failed to spawn session-host process: ${error48?.message || error48}`);
|
|
134014
|
+
});
|
|
134015
|
+
child.on("exit", (code, signal) => {
|
|
134016
|
+
const how = signal ? `signal ${signal}` : `code ${code}`;
|
|
134017
|
+
const detail = options.spawnStdio === "logfile" ? ` \u2014 see ${path59.join(instance().configDir, "logs", "session-host.log")} for its stderr` : "";
|
|
134018
|
+
LOG2.error(
|
|
134019
|
+
"SessionHost",
|
|
134020
|
+
`Session-host process (pid ${child.pid ?? "unknown"}) exited with ${how}${detail}`
|
|
134021
|
+
);
|
|
134022
|
+
});
|
|
134023
|
+
}
|
|
134024
|
+
if (typeof child?.unref === "function") child.unref();
|
|
133448
134025
|
if (logFd !== null) {
|
|
133449
134026
|
try {
|
|
133450
134027
|
fs62.closeSync(logFd);
|
|
@@ -133895,8 +134472,8 @@ data: ${JSON.stringify(msg.data)}
|
|
|
133895
134472
|
init_config_dir();
|
|
133896
134473
|
init_mesh_events();
|
|
133897
134474
|
init_mesh_reconcile_loop();
|
|
133898
|
-
var
|
|
133899
|
-
var
|
|
134475
|
+
var import_fs20 = require("fs");
|
|
134476
|
+
var import_path222 = require("path");
|
|
133900
134477
|
var import_crypto18 = require("crypto");
|
|
133901
134478
|
init_logger();
|
|
133902
134479
|
init_mesh_ledger();
|
|
@@ -133964,31 +134541,31 @@ data: ${JSON.stringify(msg.data)}
|
|
|
133964
134541
|
} catch {
|
|
133965
134542
|
return result;
|
|
133966
134543
|
}
|
|
133967
|
-
if (!(0,
|
|
134544
|
+
if (!(0, import_fs20.existsSync)(dir)) return result;
|
|
133968
134545
|
let names;
|
|
133969
134546
|
try {
|
|
133970
|
-
names = (0,
|
|
134547
|
+
names = (0, import_fs20.readdirSync)(dir);
|
|
133971
134548
|
} catch (e) {
|
|
133972
134549
|
LOG2.warn("MeshEvents", `Pending-events migration: cannot read ledger dir: ${e?.message || e}`);
|
|
133973
134550
|
return result;
|
|
133974
134551
|
}
|
|
133975
134552
|
for (const name of names) {
|
|
133976
134553
|
if (!isPendingEventsFile(name)) continue;
|
|
133977
|
-
const path60 = (0,
|
|
134554
|
+
const path60 = (0, import_path222.join)(dir, name);
|
|
133978
134555
|
result.filesScanned++;
|
|
133979
134556
|
const claimed = `${path60}.migrating`;
|
|
133980
134557
|
try {
|
|
133981
|
-
(0,
|
|
134558
|
+
(0, import_fs20.renameSync)(path60, claimed);
|
|
133982
134559
|
} catch {
|
|
133983
134560
|
continue;
|
|
133984
134561
|
}
|
|
133985
134562
|
let content;
|
|
133986
134563
|
try {
|
|
133987
|
-
content = (0,
|
|
134564
|
+
content = (0, import_fs20.readFileSync)(claimed, "utf-8");
|
|
133988
134565
|
} catch (e) {
|
|
133989
134566
|
LOG2.warn("MeshEvents", `Pending-events migration: cannot read ${name}; leaving it for the next boot: ${e?.message || e}`);
|
|
133990
134567
|
try {
|
|
133991
|
-
(0,
|
|
134568
|
+
(0, import_fs20.renameSync)(claimed, path60);
|
|
133992
134569
|
} catch {
|
|
133993
134570
|
}
|
|
133994
134571
|
result.filesRetained++;
|
|
@@ -134003,14 +134580,14 @@ data: ${JSON.stringify(msg.data)}
|
|
|
134003
134580
|
}
|
|
134004
134581
|
if (!allImported) {
|
|
134005
134582
|
try {
|
|
134006
|
-
(0,
|
|
134583
|
+
(0, import_fs20.renameSync)(claimed, path60);
|
|
134007
134584
|
} catch {
|
|
134008
134585
|
}
|
|
134009
134586
|
result.filesRetained++;
|
|
134010
134587
|
continue;
|
|
134011
134588
|
}
|
|
134012
134589
|
try {
|
|
134013
|
-
(0,
|
|
134590
|
+
(0, import_fs20.unlinkSync)(claimed);
|
|
134014
134591
|
result.filesRemoved++;
|
|
134015
134592
|
} catch (e) {
|
|
134016
134593
|
LOG2.warn("MeshEvents", `Pending-events migration: imported ${name} but could not unlink it: ${e?.message || e}`);
|
|
@@ -135429,14 +136006,77 @@ function createLineParser(onEnvelope) {
|
|
|
135429
136006
|
}
|
|
135430
136007
|
};
|
|
135431
136008
|
}
|
|
136009
|
+
var establishedSockets = /* @__PURE__ */ new WeakSet();
|
|
135432
136010
|
var SessionHostClient = class {
|
|
135433
136011
|
endpoint;
|
|
135434
136012
|
socket = null;
|
|
135435
136013
|
requestWaiters = /* @__PURE__ */ new Map();
|
|
135436
136014
|
eventListeners = /* @__PURE__ */ new Set();
|
|
136015
|
+
disconnectListeners = /* @__PURE__ */ new Set();
|
|
136016
|
+
/** Guards against emitting both an 'error'-path and a 'close'-path disconnect for one socket. */
|
|
136017
|
+
disconnectedSockets = /* @__PURE__ */ new WeakSet();
|
|
135437
136018
|
constructor(options = {}) {
|
|
135438
136019
|
this.endpoint = options.endpoint || getDefaultSessionHostEndpoint(options.appName || "adhdev");
|
|
135439
136020
|
}
|
|
136021
|
+
/**
|
|
136022
|
+
* Fires when an established connection to the session host goes away.
|
|
136023
|
+
*
|
|
136024
|
+
* Before this existed the client registered only 'data' and 'error' handlers,
|
|
136025
|
+
* so a *clean* FIN — the host process exiting normally, or dying to an
|
|
136026
|
+
* uncaught exception that took the socket down without an error event on our
|
|
136027
|
+
* end — ran nothing at all: `this.socket` stayed non-null pointing at a dead
|
|
136028
|
+
* socket, in-flight waiters hung to their 30s timeout, and no caller was told.
|
|
136029
|
+
* That silence is what let a session-host death present downstream as an
|
|
136030
|
+
* unrelated application-level fault (a missing completion marker) instead of
|
|
136031
|
+
* "the host is gone".
|
|
136032
|
+
*/
|
|
136033
|
+
onDisconnect(listener) {
|
|
136034
|
+
this.disconnectListeners.add(listener);
|
|
136035
|
+
return () => {
|
|
136036
|
+
this.disconnectListeners.delete(listener);
|
|
136037
|
+
};
|
|
136038
|
+
}
|
|
136039
|
+
handleDisconnect(socket, reason, error48) {
|
|
136040
|
+
if (this.disconnectedSockets.has(socket)) return;
|
|
136041
|
+
this.disconnectedSockets.add(socket);
|
|
136042
|
+
const wasEstablished = establishedSockets.has(socket);
|
|
136043
|
+
if (!wasEstablished) {
|
|
136044
|
+
if (this.socket === socket) this.socket = null;
|
|
136045
|
+
try {
|
|
136046
|
+
socket.destroy();
|
|
136047
|
+
} catch {
|
|
136048
|
+
}
|
|
136049
|
+
const failure2 = error48 || new Error(`Session host connect failed (${this.endpoint.path})`);
|
|
136050
|
+
for (const waiter of this.requestWaiters.values()) waiter.reject(failure2);
|
|
136051
|
+
this.requestWaiters.clear();
|
|
136052
|
+
return;
|
|
136053
|
+
}
|
|
136054
|
+
const pendingRequests = this.requestWaiters.size;
|
|
136055
|
+
const failure = error48 || new Error(`Session host connection ${reason} (${this.endpoint.path})`);
|
|
136056
|
+
for (const waiter of this.requestWaiters.values()) {
|
|
136057
|
+
waiter.reject(failure);
|
|
136058
|
+
}
|
|
136059
|
+
this.requestWaiters.clear();
|
|
136060
|
+
if (this.socket === socket) {
|
|
136061
|
+
this.socket = null;
|
|
136062
|
+
}
|
|
136063
|
+
try {
|
|
136064
|
+
socket.destroy();
|
|
136065
|
+
} catch {
|
|
136066
|
+
}
|
|
136067
|
+
const info = {
|
|
136068
|
+
reason,
|
|
136069
|
+
endpointPath: this.endpoint.path,
|
|
136070
|
+
pendingRequests,
|
|
136071
|
+
error: error48
|
|
136072
|
+
};
|
|
136073
|
+
for (const listener of this.disconnectListeners) {
|
|
136074
|
+
try {
|
|
136075
|
+
listener(info);
|
|
136076
|
+
} catch {
|
|
136077
|
+
}
|
|
136078
|
+
}
|
|
136079
|
+
}
|
|
135440
136080
|
async connect() {
|
|
135441
136081
|
if (this.socket && !this.socket.destroyed) return;
|
|
135442
136082
|
if (this.socket) {
|
|
@@ -135462,20 +136102,19 @@ var SessionHostClient = class {
|
|
|
135462
136102
|
}
|
|
135463
136103
|
}));
|
|
135464
136104
|
socket.on("error", (error48) => {
|
|
135465
|
-
|
|
135466
|
-
|
|
135467
|
-
|
|
135468
|
-
this.
|
|
135469
|
-
|
|
135470
|
-
|
|
135471
|
-
|
|
135472
|
-
try {
|
|
135473
|
-
socket.destroy();
|
|
135474
|
-
} catch {
|
|
135475
|
-
}
|
|
136105
|
+
this.handleDisconnect(socket, "error", error48);
|
|
136106
|
+
});
|
|
136107
|
+
socket.on("close", () => {
|
|
136108
|
+
this.handleDisconnect(socket, "closed");
|
|
136109
|
+
});
|
|
136110
|
+
socket.on("end", () => {
|
|
136111
|
+
this.handleDisconnect(socket, "ended");
|
|
135476
136112
|
});
|
|
135477
136113
|
await new Promise((resolve3, reject) => {
|
|
135478
|
-
socket.once("connect", () =>
|
|
136114
|
+
socket.once("connect", () => {
|
|
136115
|
+
establishedSockets.add(socket);
|
|
136116
|
+
resolve3();
|
|
136117
|
+
});
|
|
135479
136118
|
socket.once("error", reject);
|
|
135480
136119
|
});
|
|
135481
136120
|
}
|
|
@@ -135517,6 +136156,7 @@ var SessionHostClient = class {
|
|
|
135517
136156
|
if (!this.socket) return;
|
|
135518
136157
|
const socket = this.socket;
|
|
135519
136158
|
this.socket = null;
|
|
136159
|
+
this.disconnectedSockets.add(socket);
|
|
135520
136160
|
for (const waiter of this.requestWaiters.values()) {
|
|
135521
136161
|
waiter.reject(new Error("Session host client closed"));
|
|
135522
136162
|
}
|