@adhdev/daemon-standalone 1.0.58-rc.1 → 1.0.58-rc.3
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 +957 -349
- package/dist/index.js.map +1 -1
- package/package.json +2 -2
- package/vendor/mcp-server/index.js +17 -0
- package/vendor/mcp-server/index.js.map +1 -1
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 ? "789e0aa08f214c5b059b3d12eff74e412488db3b" : void 0) ?? "unknown";
|
|
36835
|
+
const commitShort = readInjected(true ? "789e0aa0" : void 0) ?? (commit !== "unknown" ? commit.slice(0, 7) : "unknown");
|
|
36836
|
+
const version2 = readInjected(true ? "1.0.58-rc.3" : void 0) ?? readInjected(typeof process !== "undefined" ? process.env?.ADHDEV_PKG_VERSION : void 0) ?? "unknown";
|
|
36837
|
+
const builtAt = readInjected(true ? "2026-08-23T01:04:20.549Z" : 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;
|
|
@@ -44084,6 +44167,7 @@ ${error48.message || ""}`;
|
|
|
44084
44167
|
__export2(mesh_config_exports, {
|
|
44085
44168
|
addNode: () => addNode,
|
|
44086
44169
|
applyMeshHostJoinRequest: () => applyMeshHostJoinRequest,
|
|
44170
|
+
collectIgnoredMagiSlotFields: () => collectIgnoredMagiSlotFields,
|
|
44087
44171
|
configureMeshHostPairing: () => configureMeshHostPairing,
|
|
44088
44172
|
createMesh: () => createMesh,
|
|
44089
44173
|
createMeshHostPairingToken: () => createMeshHostPairingToken,
|
|
@@ -44116,25 +44200,75 @@ ${error48.message || ""}`;
|
|
|
44116
44200
|
function getMeshConfigPath() {
|
|
44117
44201
|
return (0, import_path5.join)(getConfigDir2(), "meshes.json");
|
|
44118
44202
|
}
|
|
44119
|
-
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() {
|
|
44120
44248
|
const path60 = getMeshConfigPath();
|
|
44121
44249
|
if (!(0, import_fs5.existsSync)(path60)) return { meshes: [] };
|
|
44122
44250
|
try {
|
|
44123
44251
|
const raw = JSON.parse((0, import_fs5.readFileSync)(path60, "utf-8"));
|
|
44124
44252
|
if (!raw || !Array.isArray(raw.meshes)) return { meshes: [] };
|
|
44125
|
-
|
|
44126
|
-
const migrated = migrateLoadedMeshConfig(config2);
|
|
44127
|
-
if (migrated && options.persistMigrations !== false) {
|
|
44128
|
-
try {
|
|
44129
|
-
saveMeshConfig(config2);
|
|
44130
|
-
} catch {
|
|
44131
|
-
}
|
|
44132
|
-
}
|
|
44133
|
-
return config2;
|
|
44253
|
+
return raw;
|
|
44134
44254
|
} catch {
|
|
44135
44255
|
return { meshes: [] };
|
|
44136
44256
|
}
|
|
44137
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
|
+
}
|
|
44138
44272
|
function migrateLoadedMeshConfig(config2) {
|
|
44139
44273
|
let changed = false;
|
|
44140
44274
|
if (foldLegacyTopLevelMeshSetting(config2, "magiKindPanels", "mesh_magi_kind_panel_set({ meshId, task_kind, slots })")) changed = true;
|
|
@@ -44219,7 +44353,9 @@ ${error48.message || ""}`;
|
|
|
44219
44353
|
}
|
|
44220
44354
|
function saveMeshConfig(config2) {
|
|
44221
44355
|
const path60 = getMeshConfigPath();
|
|
44222
|
-
|
|
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);
|
|
44223
44359
|
}
|
|
44224
44360
|
function normalizeRepoIdentity(remoteUrl) {
|
|
44225
44361
|
let identity = remoteUrl.trim().replace(/[?#].*$/, "").replace(/\/+$/, "");
|
|
@@ -44259,7 +44395,10 @@ ${error48.message || ""}`;
|
|
|
44259
44395
|
const normalized = normalizeRepoIdentity(repoIdentity);
|
|
44260
44396
|
return loadMeshConfig().meshes.find((m) => normalizeRepoIdentity(m.repoIdentity) === normalized);
|
|
44261
44397
|
}
|
|
44262
|
-
function createMesh(
|
|
44398
|
+
function createMesh(...args) {
|
|
44399
|
+
return withMeshConfigWriteLock(() => createMeshUnlocked(...args));
|
|
44400
|
+
}
|
|
44401
|
+
function createMeshUnlocked(opts) {
|
|
44263
44402
|
const config2 = loadMeshConfig();
|
|
44264
44403
|
if (config2.meshes.length >= 20) {
|
|
44265
44404
|
throw new Error("Maximum 20 meshes allowed");
|
|
@@ -44288,7 +44427,10 @@ ${error48.message || ""}`;
|
|
|
44288
44427
|
saveMeshConfig(config2);
|
|
44289
44428
|
return mesh;
|
|
44290
44429
|
}
|
|
44291
|
-
function updateMesh(
|
|
44430
|
+
function updateMesh(...args) {
|
|
44431
|
+
return withMeshConfigWriteLock(() => updateMeshUnlocked(...args));
|
|
44432
|
+
}
|
|
44433
|
+
function updateMeshUnlocked(meshId, opts) {
|
|
44292
44434
|
const config2 = loadMeshConfig();
|
|
44293
44435
|
const mesh = config2.meshes.find((m) => m.id === meshId);
|
|
44294
44436
|
if (!mesh) return void 0;
|
|
@@ -44301,7 +44443,10 @@ ${error48.message || ""}`;
|
|
|
44301
44443
|
saveMeshConfig(config2);
|
|
44302
44444
|
return mesh;
|
|
44303
44445
|
}
|
|
44304
|
-
function deleteMesh(
|
|
44446
|
+
function deleteMesh(...args) {
|
|
44447
|
+
return withMeshConfigWriteLock(() => deleteMeshUnlocked(...args));
|
|
44448
|
+
}
|
|
44449
|
+
function deleteMeshUnlocked(meshId) {
|
|
44305
44450
|
const config2 = loadMeshConfig();
|
|
44306
44451
|
const idx = config2.meshes.findIndex((m) => m.id === meshId);
|
|
44307
44452
|
if (idx === -1) return false;
|
|
@@ -44348,7 +44493,10 @@ ${error48.message || ""}`;
|
|
|
44348
44493
|
}
|
|
44349
44494
|
return { ok: true, tokenId: presentedTokenId };
|
|
44350
44495
|
}
|
|
44351
|
-
function configureMeshHostPairing(
|
|
44496
|
+
function configureMeshHostPairing(...args) {
|
|
44497
|
+
return withMeshConfigWriteLock(() => configureMeshHostPairingUnlocked(...args));
|
|
44498
|
+
}
|
|
44499
|
+
function configureMeshHostPairingUnlocked(meshId, opts) {
|
|
44352
44500
|
const hostAddress = normalizeManualHostAddress(opts.hostAddress);
|
|
44353
44501
|
const token = opts.token.trim();
|
|
44354
44502
|
if (!token) throw new Error("token required");
|
|
@@ -44372,7 +44520,10 @@ ${error48.message || ""}`;
|
|
|
44372
44520
|
saveMeshConfig(config2);
|
|
44373
44521
|
return { mesh, meshHost, hostAddress };
|
|
44374
44522
|
}
|
|
44375
|
-
function createMeshHostPairingToken(
|
|
44523
|
+
function createMeshHostPairingToken(...args) {
|
|
44524
|
+
return withMeshConfigWriteLock(() => createMeshHostPairingTokenUnlocked(...args));
|
|
44525
|
+
}
|
|
44526
|
+
function createMeshHostPairingTokenUnlocked(meshId, opts = {}) {
|
|
44376
44527
|
const config2 = loadMeshConfig();
|
|
44377
44528
|
const mesh = config2.meshes.find((m) => m.id === meshId);
|
|
44378
44529
|
if (!mesh) return void 0;
|
|
@@ -44400,7 +44551,10 @@ ${error48.message || ""}`;
|
|
|
44400
44551
|
saveMeshConfig(config2);
|
|
44401
44552
|
return { mesh, meshHost, token, tokenId, ...expiresAt ? { expiresAt } : {} };
|
|
44402
44553
|
}
|
|
44403
|
-
function applyMeshHostJoinRequest(
|
|
44554
|
+
function applyMeshHostJoinRequest(...args) {
|
|
44555
|
+
return withMeshConfigWriteLock(() => applyMeshHostJoinRequestUnlocked(...args));
|
|
44556
|
+
}
|
|
44557
|
+
function applyMeshHostJoinRequestUnlocked(meshId, opts) {
|
|
44404
44558
|
const config2 = loadMeshConfig();
|
|
44405
44559
|
const mesh = config2.meshes.find((m) => m.id === meshId);
|
|
44406
44560
|
if (!mesh) return void 0;
|
|
@@ -44465,7 +44619,10 @@ ${error48.message || ""}`;
|
|
|
44465
44619
|
saveMeshConfig(config2);
|
|
44466
44620
|
return { accepted: true, mesh, meshHost: mesh.meshHost, node, tokenId: validation.tokenId };
|
|
44467
44621
|
}
|
|
44468
|
-
function setMeshHostPin(
|
|
44622
|
+
function setMeshHostPin(...args) {
|
|
44623
|
+
return withMeshConfigWriteLock(() => setMeshHostPinUnlocked(...args));
|
|
44624
|
+
}
|
|
44625
|
+
function setMeshHostPinUnlocked(meshId, opts) {
|
|
44469
44626
|
const config2 = loadMeshConfig();
|
|
44470
44627
|
const mesh = config2.meshes.find((m) => m.id === meshId);
|
|
44471
44628
|
if (!mesh) return void 0;
|
|
@@ -44545,7 +44702,10 @@ ${error48.message || ""}`;
|
|
|
44545
44702
|
...mesh.meshHost.hostNodeId ? { hostNodeId: mesh.meshHost.hostNodeId } : {}
|
|
44546
44703
|
};
|
|
44547
44704
|
}
|
|
44548
|
-
function markMeshHostPairingJoined(
|
|
44705
|
+
function markMeshHostPairingJoined(...args) {
|
|
44706
|
+
return withMeshConfigWriteLock(() => markMeshHostPairingJoinedUnlocked(...args));
|
|
44707
|
+
}
|
|
44708
|
+
function markMeshHostPairingJoinedUnlocked(meshId, opts) {
|
|
44549
44709
|
const config2 = loadMeshConfig();
|
|
44550
44710
|
const mesh = config2.meshes.find((m) => m.id === meshId);
|
|
44551
44711
|
if (!mesh) return void 0;
|
|
@@ -44569,7 +44729,10 @@ ${error48.message || ""}`;
|
|
|
44569
44729
|
saveMeshConfig(config2);
|
|
44570
44730
|
return { mesh, meshHost: mesh.meshHost };
|
|
44571
44731
|
}
|
|
44572
|
-
function addNode(
|
|
44732
|
+
function addNode(...args) {
|
|
44733
|
+
return withMeshConfigWriteLock(() => addNodeUnlocked(...args));
|
|
44734
|
+
}
|
|
44735
|
+
function addNodeUnlocked(meshId, opts) {
|
|
44573
44736
|
const config2 = loadMeshConfig();
|
|
44574
44737
|
const mesh = config2.meshes.find((m) => m.id === meshId);
|
|
44575
44738
|
if (!mesh) return void 0;
|
|
@@ -44616,7 +44779,10 @@ ${error48.message || ""}`;
|
|
|
44616
44779
|
saveMeshConfig(config2);
|
|
44617
44780
|
return node;
|
|
44618
44781
|
}
|
|
44619
|
-
function removeNode(
|
|
44782
|
+
function removeNode(...args) {
|
|
44783
|
+
return withMeshConfigWriteLock(() => removeNodeUnlocked(...args));
|
|
44784
|
+
}
|
|
44785
|
+
function removeNodeUnlocked(meshId, nodeId) {
|
|
44620
44786
|
const config2 = loadMeshConfig();
|
|
44621
44787
|
const mesh = config2.meshes.find((m) => m.id === meshId);
|
|
44622
44788
|
if (!mesh) return false;
|
|
@@ -44628,7 +44794,10 @@ ${error48.message || ""}`;
|
|
|
44628
44794
|
saveMeshConfig(config2);
|
|
44629
44795
|
return true;
|
|
44630
44796
|
}
|
|
44631
|
-
function updateNode(
|
|
44797
|
+
function updateNode(...args) {
|
|
44798
|
+
return withMeshConfigWriteLock(() => updateNodeUnlocked(...args));
|
|
44799
|
+
}
|
|
44800
|
+
function updateNodeUnlocked(meshId, nodeId, opts) {
|
|
44632
44801
|
const config2 = loadMeshConfig();
|
|
44633
44802
|
const mesh = config2.meshes.find((m) => m.id === meshId);
|
|
44634
44803
|
if (!mesh) return void 0;
|
|
@@ -44680,6 +44849,22 @@ ${error48.message || ""}`;
|
|
|
44680
44849
|
}
|
|
44681
44850
|
return s2;
|
|
44682
44851
|
}
|
|
44852
|
+
function collectIgnoredMagiSlotFields(slots) {
|
|
44853
|
+
if (!Array.isArray(slots)) return [];
|
|
44854
|
+
const out = [];
|
|
44855
|
+
slots.forEach((entry, idx) => {
|
|
44856
|
+
if (!entry || typeof entry !== "object" || Array.isArray(entry)) return;
|
|
44857
|
+
for (const key2 of Object.keys(entry)) {
|
|
44858
|
+
if (MAGI_SLOT_KNOWN_KEYS.includes(key2)) continue;
|
|
44859
|
+
out.push({
|
|
44860
|
+
slot: idx,
|
|
44861
|
+
field: key2,
|
|
44862
|
+
reason: MAGI_SLOT_IGNORED_FIELD_REASONS[key2] ?? `not a recognized MAGI slot key (accepted: ${MAGI_SLOT_KNOWN_KEYS.join(", ")}); it was dropped and has no effect.`
|
|
44863
|
+
});
|
|
44864
|
+
}
|
|
44865
|
+
});
|
|
44866
|
+
return out;
|
|
44867
|
+
}
|
|
44683
44868
|
function normalizeMagiSlots(slots, knownNodeIds) {
|
|
44684
44869
|
const allowed = knownNodeIds ? new Set(knownNodeIds) : void 0;
|
|
44685
44870
|
if (!Array.isArray(slots) || slots.length === 0) {
|
|
@@ -44742,7 +44927,10 @@ ${error48.message || ""}`;
|
|
|
44742
44927
|
const config2 = loadMeshConfig();
|
|
44743
44928
|
return resolveScopedMesh(config2, meshId)?.magiKindPanels?.[key2];
|
|
44744
44929
|
}
|
|
44745
|
-
function setMagiKindPanel(
|
|
44930
|
+
function setMagiKindPanel(...args) {
|
|
44931
|
+
return withMeshConfigWriteLock(() => setMagiKindPanelUnlocked(...args));
|
|
44932
|
+
}
|
|
44933
|
+
function setMagiKindPanelUnlocked(kind, slots, meshId) {
|
|
44746
44934
|
const key2 = normalizeMagiTaskKindKey(kind);
|
|
44747
44935
|
const stored = loadMeshConfig();
|
|
44748
44936
|
const mesh = resolveScopedMesh(stored, meshId);
|
|
@@ -44759,7 +44947,10 @@ ${error48.message || ""}`;
|
|
|
44759
44947
|
saveMeshConfig(stored);
|
|
44760
44948
|
return normalized;
|
|
44761
44949
|
}
|
|
44762
|
-
function removeMagiKindPanel(
|
|
44950
|
+
function removeMagiKindPanel(...args) {
|
|
44951
|
+
return withMeshConfigWriteLock(() => removeMagiKindPanelUnlocked(...args));
|
|
44952
|
+
}
|
|
44953
|
+
function removeMagiKindPanelUnlocked(kind, meshId) {
|
|
44763
44954
|
let key2;
|
|
44764
44955
|
try {
|
|
44765
44956
|
key2 = normalizeMagiTaskKindKey(kind);
|
|
@@ -44796,7 +44987,10 @@ ${error48.message || ""}`;
|
|
|
44796
44987
|
const normalized = normalizeDifficultyBrainMap(stored);
|
|
44797
44988
|
return Object.keys(normalized).length > 0 ? normalized : { ...DEFAULT_DIFFICULTY_BRAINS };
|
|
44798
44989
|
}
|
|
44799
|
-
function setDifficultyBrains(
|
|
44990
|
+
function setDifficultyBrains(...args) {
|
|
44991
|
+
return withMeshConfigWriteLock(() => setDifficultyBrainsUnlocked(...args));
|
|
44992
|
+
}
|
|
44993
|
+
function setDifficultyBrainsUnlocked(map3, meshId) {
|
|
44800
44994
|
const normalized = normalizeDifficultyBrainMap(map3);
|
|
44801
44995
|
const stored = loadMeshConfig();
|
|
44802
44996
|
const mesh = resolveScopedMesh(stored, meshId);
|
|
@@ -44842,7 +45036,10 @@ ${error48.message || ""}`;
|
|
|
44842
45036
|
const stored = resolveScopedMesh(config2, meshId)?.policy?.quotaRouting;
|
|
44843
45037
|
return normalizeQuotaRoutingPolicy(stored) ?? {};
|
|
44844
45038
|
}
|
|
44845
|
-
function setMeshQuotaRouting(
|
|
45039
|
+
function setMeshQuotaRouting(...args) {
|
|
45040
|
+
return withMeshConfigWriteLock(() => setMeshQuotaRoutingUnlocked(...args));
|
|
45041
|
+
}
|
|
45042
|
+
function setMeshQuotaRoutingUnlocked(input, meshId) {
|
|
44846
45043
|
const overrides = validateQuotaRoutingOverrides(input);
|
|
44847
45044
|
const stored = loadMeshConfig();
|
|
44848
45045
|
const mesh = resolveScopedMesh(stored, meshId);
|
|
@@ -44859,9 +45056,15 @@ ${error48.message || ""}`;
|
|
|
44859
45056
|
var import_fs5;
|
|
44860
45057
|
var import_path5;
|
|
44861
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;
|
|
44862
45063
|
var mergeMeshPolicy;
|
|
44863
45064
|
var MAGI_KIND_PANEL_KINDS;
|
|
44864
45065
|
var MAX_MAGI_KIND_SLOTS;
|
|
45066
|
+
var MAGI_SLOT_KNOWN_KEYS;
|
|
45067
|
+
var MAGI_SLOT_IGNORED_FIELD_REASONS;
|
|
44865
45068
|
var QUOTA_ROUTING_PERCENT_FIELDS;
|
|
44866
45069
|
var QUOTA_ROUTING_NONNEGATIVE_FIELDS;
|
|
44867
45070
|
var init_mesh_config = __esm2({
|
|
@@ -44875,9 +45078,20 @@ ${error48.message || ""}`;
|
|
|
44875
45078
|
init_dist();
|
|
44876
45079
|
init_repo_mesh_types();
|
|
44877
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;
|
|
44878
45085
|
mergeMeshPolicy = mergeAndNormalizePolicy;
|
|
44879
45086
|
MAGI_KIND_PANEL_KINDS = ["claim_audit", "rca", "design", "freeform"];
|
|
44880
45087
|
MAX_MAGI_KIND_SLOTS = 24;
|
|
45088
|
+
MAGI_SLOT_KNOWN_KEYS = ["provider", "nodeId", "model", "capabilityTags", "n"];
|
|
45089
|
+
MAGI_SLOT_IGNORED_FIELD_REASONS = Object.freeze({
|
|
45090
|
+
thinkingLevel: "not part of a MAGI slot \u2014 a panel selects WHO answers independently, not how hard each replica thinks. Set thinkingLevel on the node's capability slots (mesh_node_slots_set), which is the routing axis.",
|
|
45091
|
+
difficulty: "not part of a MAGI slot \u2014 MAGI always enqueues its replicas with the fixed 'freeform' difficulty sentinel because the panel has already chosen the (node, provider) target. Set difficulty on the node's capability slots instead.",
|
|
45092
|
+
maxParallel: "not part of a MAGI slot \u2014 per-slot concurrency is a node capability-slot axis. Use the per-slot `n` replica count to control MAGI fan-out width.",
|
|
45093
|
+
capability: "not a MAGI slot key \u2014 did you mean `capabilityTags`?"
|
|
45094
|
+
});
|
|
44881
45095
|
QUOTA_ROUTING_PERCENT_FIELDS = /* @__PURE__ */ new Set(["sessionMinRemainingPercent", "weeklyMinRemainingPercent"]);
|
|
44882
45096
|
QUOTA_ROUTING_NONNEGATIVE_FIELDS = /* @__PURE__ */ new Set(["staleAfterMs", "sessionResetImminentMs", "spreadBonusMax"]);
|
|
44883
45097
|
}
|
|
@@ -48569,6 +48783,36 @@ ${blocks.join("\n\n")}`;
|
|
|
48569
48783
|
divergenceLogOnce = /* @__PURE__ */ new Set();
|
|
48570
48784
|
}
|
|
48571
48785
|
});
|
|
48786
|
+
function s(v) {
|
|
48787
|
+
return typeof v === "string" && v.trim() ? v.trim() : "";
|
|
48788
|
+
}
|
|
48789
|
+
function meshEventTraceKey(ctx) {
|
|
48790
|
+
const segs = [`task=${s(ctx.taskId) || "-"}`];
|
|
48791
|
+
const eventId = s(ctx.eventId);
|
|
48792
|
+
if (eventId) segs.push(`evt=${eventId}`);
|
|
48793
|
+
segs.push(`sess=${s(ctx.sessionId) || "-"}`);
|
|
48794
|
+
const nodeId = s(ctx.nodeId);
|
|
48795
|
+
if (nodeId) segs.push(`node=${nodeId}`);
|
|
48796
|
+
const meshId = s(ctx.meshId);
|
|
48797
|
+
if (meshId) segs.push(`mesh=${meshId}`);
|
|
48798
|
+
const event = s(ctx.event);
|
|
48799
|
+
if (event) segs.push(`event=${event}`);
|
|
48800
|
+
return segs.join(" ");
|
|
48801
|
+
}
|
|
48802
|
+
function traceMeshEventStage(stage, ctx, detail) {
|
|
48803
|
+
LOG2.info(CAT, `[stage:${stage}] ${meshEventTraceKey(ctx)}${detail ? ` \u2014 ${detail}` : ""}`);
|
|
48804
|
+
}
|
|
48805
|
+
function traceMeshEventDrop(reason, ctx, detail) {
|
|
48806
|
+
LOG2.warn(CAT, `[drop:${reason}] ${meshEventTraceKey(ctx)}${detail ? ` \u2014 ${detail}` : ""}`);
|
|
48807
|
+
}
|
|
48808
|
+
var CAT;
|
|
48809
|
+
var init_mesh_event_trace = __esm2({
|
|
48810
|
+
"src/mesh/mesh-event-trace.ts"() {
|
|
48811
|
+
"use strict";
|
|
48812
|
+
init_logger();
|
|
48813
|
+
CAT = "EvtTrace";
|
|
48814
|
+
}
|
|
48815
|
+
});
|
|
48572
48816
|
function isSupportedMeshProtocolVersion(value) {
|
|
48573
48817
|
return typeof value === "string" && SUPPORTED_MESH_PROTOCOL_VERSIONS.includes(value);
|
|
48574
48818
|
}
|
|
@@ -49039,13 +49283,55 @@ ${blocks.join("\n\n")}`;
|
|
|
49039
49283
|
}
|
|
49040
49284
|
return backfilled.reverse();
|
|
49041
49285
|
}
|
|
49286
|
+
function readPendingEventTaskId(event) {
|
|
49287
|
+
const metadataEvent = readRecord2(event.metadataEvent);
|
|
49288
|
+
return readNonEmptyString(metadataEvent?.taskId);
|
|
49289
|
+
}
|
|
49290
|
+
function dropStaleTerminalTaskEvents(meshId, events) {
|
|
49291
|
+
if (!events.some((event) => STALE_TASK_DROPPABLE_EVENTS.has(event.event))) return events;
|
|
49292
|
+
let store;
|
|
49293
|
+
try {
|
|
49294
|
+
store = MeshRuntimeStore.getInstance();
|
|
49295
|
+
} catch {
|
|
49296
|
+
return events;
|
|
49297
|
+
}
|
|
49298
|
+
const terminalByTaskId = /* @__PURE__ */ new Map();
|
|
49299
|
+
const isTaskTerminal = (taskId) => {
|
|
49300
|
+
const cached5 = terminalByTaskId.get(taskId);
|
|
49301
|
+
if (cached5 !== void 0) return cached5;
|
|
49302
|
+
let terminal = false;
|
|
49303
|
+
try {
|
|
49304
|
+
const entry = store.findQueueEntryById(meshId, taskId);
|
|
49305
|
+
terminal = !!entry && STALE_TASK_TERMINAL_STATUSES.has(entry.status);
|
|
49306
|
+
} catch {
|
|
49307
|
+
terminal = false;
|
|
49308
|
+
}
|
|
49309
|
+
terminalByTaskId.set(taskId, terminal);
|
|
49310
|
+
return terminal;
|
|
49311
|
+
};
|
|
49312
|
+
return events.filter((event) => {
|
|
49313
|
+
if (!STALE_TASK_DROPPABLE_EVENTS.has(event.event)) return true;
|
|
49314
|
+
const taskId = readPendingEventTaskId(event);
|
|
49315
|
+
if (!taskId) return true;
|
|
49316
|
+
if (!isTaskTerminal(taskId)) return true;
|
|
49317
|
+
traceMeshEventDrop("stale_task_terminal", {
|
|
49318
|
+
taskId,
|
|
49319
|
+
sessionId: resolveEventSessionId(event.metadataEvent) ?? event.targetCoordinatorSessionId,
|
|
49320
|
+
nodeId: event.nodeId,
|
|
49321
|
+
meshId,
|
|
49322
|
+
event: event.event
|
|
49323
|
+
}, "task row is already terminal (completed/failed/cancelled) \u2014 non-terminal alert is stale");
|
|
49324
|
+
return false;
|
|
49325
|
+
});
|
|
49326
|
+
}
|
|
49042
49327
|
function reconcilePendingMeshCoordinatorEvents(meshId, events) {
|
|
49043
49328
|
const backfilled = refineTerminalEventFromLedger(meshId, events);
|
|
49044
49329
|
const terminalJobIds = new Set(
|
|
49045
49330
|
[...events.filter((event) => REFINE_TERMINAL_EVENTS.has(event.event)), ...backfilled].map((event) => readRefineJobId2(event)).filter(Boolean)
|
|
49046
49331
|
);
|
|
49047
49332
|
const reconciled = terminalJobIds.size === 0 ? events : events.filter((event) => !(event.event === "refine:accepted" && terminalJobIds.has(readRefineJobId2(event))));
|
|
49048
|
-
|
|
49333
|
+
const fresh = dropStaleTerminalTaskEvents(meshId, reconciled);
|
|
49334
|
+
return backfilled.length === 0 ? fresh : [...fresh, ...backfilled];
|
|
49049
49335
|
}
|
|
49050
49336
|
function getPendingRetentionCounters() {
|
|
49051
49337
|
return { ...pendingRetentionCounters };
|
|
@@ -49430,6 +49716,8 @@ ${blocks.join("\n\n")}`;
|
|
|
49430
49716
|
var TERMINAL_COMPLETION_EVENTS;
|
|
49431
49717
|
var COORDINATOR_ALERT_EVENTS_WITH_REASON_FINGERPRINT;
|
|
49432
49718
|
var TERMINAL_COMPLETION_DEDUP_TTL_MS;
|
|
49719
|
+
var STALE_TASK_DROPPABLE_EVENTS;
|
|
49720
|
+
var STALE_TASK_TERMINAL_STATUSES;
|
|
49433
49721
|
var PENDING_EVENTS_DRAINED_RETENTION_MS;
|
|
49434
49722
|
var PENDING_EVENTS_UNDRAINED_RETENTION_MS;
|
|
49435
49723
|
var PENDING_RETENTION_EXPIRED_HOLD_REASON;
|
|
@@ -49444,6 +49732,7 @@ ${blocks.join("\n\n")}`;
|
|
|
49444
49732
|
init_mesh_runtime_store();
|
|
49445
49733
|
init_mesh_turn_presentation();
|
|
49446
49734
|
init_mesh_events_utils();
|
|
49735
|
+
init_mesh_event_trace();
|
|
49447
49736
|
init_dist();
|
|
49448
49737
|
init_contracts();
|
|
49449
49738
|
REFINE_TERMINAL_EVENTS = /* @__PURE__ */ new Set(["refine:completed", "refine:failed"]);
|
|
@@ -49484,6 +49773,15 @@ ${blocks.join("\n\n")}`;
|
|
|
49484
49773
|
"mesh:dispatch_blocked"
|
|
49485
49774
|
]);
|
|
49486
49775
|
TERMINAL_COMPLETION_DEDUP_TTL_MS = 60 * 60 * 1e3;
|
|
49776
|
+
STALE_TASK_DROPPABLE_EVENTS = /* @__PURE__ */ new Set([
|
|
49777
|
+
// Actionable dispatch-skip page ("this task will NOT dispatch on its own"). Meaningless
|
|
49778
|
+
// once the task is terminal — the measured 081317f3 case.
|
|
49779
|
+
"mesh:dispatch_blocked",
|
|
49780
|
+
// Stall watchdog ("no progress observed"). A terminal task cannot make progress; the
|
|
49781
|
+
// alert only invites the coordinator to re-drive already-finished work.
|
|
49782
|
+
"monitor:no_progress"
|
|
49783
|
+
]);
|
|
49784
|
+
STALE_TASK_TERMINAL_STATUSES = /* @__PURE__ */ new Set(["completed", "failed", "cancelled"]);
|
|
49487
49785
|
PENDING_EVENTS_DRAINED_RETENTION_MS = 7 * 24 * 60 * 60 * 1e3;
|
|
49488
49786
|
PENDING_EVENTS_UNDRAINED_RETENTION_MS = 30 * 24 * 60 * 60 * 1e3;
|
|
49489
49787
|
PENDING_RETENTION_EXPIRED_HOLD_REASON = "pending_retention_expired";
|
|
@@ -49504,36 +49802,6 @@ ${blocks.join("\n\n")}`;
|
|
|
49504
49802
|
};
|
|
49505
49803
|
}
|
|
49506
49804
|
});
|
|
49507
|
-
function s(v) {
|
|
49508
|
-
return typeof v === "string" && v.trim() ? v.trim() : "";
|
|
49509
|
-
}
|
|
49510
|
-
function meshEventTraceKey(ctx) {
|
|
49511
|
-
const segs = [`task=${s(ctx.taskId) || "-"}`];
|
|
49512
|
-
const eventId = s(ctx.eventId);
|
|
49513
|
-
if (eventId) segs.push(`evt=${eventId}`);
|
|
49514
|
-
segs.push(`sess=${s(ctx.sessionId) || "-"}`);
|
|
49515
|
-
const nodeId = s(ctx.nodeId);
|
|
49516
|
-
if (nodeId) segs.push(`node=${nodeId}`);
|
|
49517
|
-
const meshId = s(ctx.meshId);
|
|
49518
|
-
if (meshId) segs.push(`mesh=${meshId}`);
|
|
49519
|
-
const event = s(ctx.event);
|
|
49520
|
-
if (event) segs.push(`event=${event}`);
|
|
49521
|
-
return segs.join(" ");
|
|
49522
|
-
}
|
|
49523
|
-
function traceMeshEventStage(stage, ctx, detail) {
|
|
49524
|
-
LOG2.info(CAT, `[stage:${stage}] ${meshEventTraceKey(ctx)}${detail ? ` \u2014 ${detail}` : ""}`);
|
|
49525
|
-
}
|
|
49526
|
-
function traceMeshEventDrop(reason, ctx, detail) {
|
|
49527
|
-
LOG2.warn(CAT, `[drop:${reason}] ${meshEventTraceKey(ctx)}${detail ? ` \u2014 ${detail}` : ""}`);
|
|
49528
|
-
}
|
|
49529
|
-
var CAT;
|
|
49530
|
-
var init_mesh_event_trace = __esm2({
|
|
49531
|
-
"src/mesh/mesh-event-trace.ts"() {
|
|
49532
|
-
"use strict";
|
|
49533
|
-
init_logger();
|
|
49534
|
-
CAT = "EvtTrace";
|
|
49535
|
-
}
|
|
49536
|
-
});
|
|
49537
49805
|
function taskIsParked(task) {
|
|
49538
49806
|
return !!readNonEmptyString(task?.parked?.reason);
|
|
49539
49807
|
}
|
|
@@ -49641,6 +49909,176 @@ The instruction it carried was never delivered to anyone. If it still matters, r
|
|
|
49641
49909
|
PARK_RETENTION_EXPIRED_REASON = "parked_task_retention_expired";
|
|
49642
49910
|
}
|
|
49643
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
|
+
});
|
|
49644
50082
|
function readPayloadTaskId(entry) {
|
|
49645
50083
|
const value = entry.payload?.taskId;
|
|
49646
50084
|
return typeof value === "string" && value.trim() ? value.trim() : "";
|
|
@@ -50147,6 +50585,7 @@ The instruction it carried was never delivered to anyone. If it still matters, r
|
|
|
50147
50585
|
normalizeMeshTaskPriority: () => normalizeMeshTaskPriority,
|
|
50148
50586
|
parkTaskTargetPin: () => parkTaskTargetPin,
|
|
50149
50587
|
reclaimStrandedAssignedTask: () => reclaimStrandedAssignedTask,
|
|
50588
|
+
recordAckedHoldDispatchOutcome: () => recordAckedHoldDispatchOutcome,
|
|
50150
50589
|
recordDirectDispatchTask: () => recordDirectDispatchTask,
|
|
50151
50590
|
recordMeshToolCall: () => recordMeshToolCall,
|
|
50152
50591
|
recordTaskAutoLaunch: () => recordTaskAutoLaunch,
|
|
@@ -51045,6 +51484,7 @@ The instruction it carried was never delivered to anyone. If it still matters, r
|
|
|
51045
51484
|
init_mesh_task_mode_guardrail();
|
|
51046
51485
|
init_mesh_task_parking();
|
|
51047
51486
|
init_mesh_task_mode_guardrail();
|
|
51487
|
+
init_mesh_reconcile_acked_hold();
|
|
51048
51488
|
ACTIVE_MESH_QUEUE_STATUSES = ["pending", "assigned"];
|
|
51049
51489
|
HISTORICAL_MESH_QUEUE_STATUSES = ["completed", "failed", "cancelled"];
|
|
51050
51490
|
MESH_TASK_MODES = ["code_change", "validation", "live_debug_readonly", "launch_app", "convergence"];
|
|
@@ -58370,6 +58810,7 @@ ${rules.join("\n")}`;
|
|
|
58370
58810
|
- **Classify task difficulty honestly.** Judge each task's real difficulty (\`easy\`/\`medium\`/\`difficult\`/\`freeform\`) per the Task difficulty section above \u2014 it is a routing hint, and the matched slot's own model/thinking is what launches. Never bend difficulty to chase a model; retune slots instead (\`mesh_node_slots_set\`).
|
|
58371
58811
|
- **Retune node profiles when routing is a poor fit \u2014 but only with approval.** A node's capability slots (its provider/model/thinking + difficulty range + capability tags, seen via \`mesh_node_slots_list\`) are what task\u2192node fitness routing matches against. If you notice a persistent mismatch \u2014 e.g. every \`difficult\` task lands on a node whose only slot is a cheap model, or a capability a node clearly has isn't declared \u2014 you MAY propose a slot change with \`mesh_node_slots_set\` (write=false). That returns current-vs-proposed; present that diff to the user with a one-line reason and apply (write=true) ONLY after they approve. It is a WHOLESALE replacement of the node's slots, so include the slots you want to keep. Never rewrite a node's profile silently or without a clear routing reason.
|
|
58372
58812
|
- **Bootstrap a node's slots from what's actually installed.** When a node has NO slots configured (routing then falls back to "first available provider"), or CLI agents were newly installed on it, call \`mesh_node_slots_propose({ node_id })\` instead of hand-writing a profile. It detects the node's installed CLI agents and drafts a slot list from them \u2014 read-only, it never writes. Present its \`proposedSlots\` with the \`droppedSlots\` / \`destructive\` fields it reports (a wholesale write would delete any existing hand-tuned slot the draft doesn't reproduce, including providers not currently on PATH), then apply with \`mesh_node_slots_set({ slots: proposedSlots, write: true })\` after approval. It flags \`unknownProvider\` / \`provisional\` slots whose placement is a conservative guess rather than an attested one \u2014 call those out rather than presenting them as settled.
|
|
58813
|
+
- **When a MAGI panel is unconfigured, bootstrap it from the same detection.** \`mesh_magi_review({ task_kind })\` resolves its panel SOLELY from the configured kind-panel binding, so a task_kind with no slots fails outright with \`magi_kind_not_configured\` \u2014 MAGI is simply unavailable until someone binds it, and the usual reason nobody has is that this path is easy to miss. Pass \`mesh_node_slots_propose({ node_id, include_magi: true })\` to also get a \`magiPanel\` draft: one slot per DISTINCT detected provider, with no model pinned, because a panel's value is cross-provider independence rather than picking the best provider. It is read-only like the rest of the tool. Apply it per kind with \`mesh_magi_kind_panel_set({ task_kind, slots, write: true })\` after approval \u2014 and note that write is a WHOLESALE replacement of that kind's binding, so present the dry-run's \`currentSlots\` first. Do NOT reach for \`include_magi\` on every slot proposal; it is for when the panels are actually empty or a newly installed provider should join them.
|
|
58373
58814
|
- **Respect explicit provider requests.** Map: Hermes \u2192 \`hermes-cli\`, Claude/Claude Code \u2192 \`claude-cli\`, Codex \u2192 \`codex-cli\`, Gemini \u2192 \`gemini-cli\`, Antigravity \u2192 \`antigravity-cli\`. Never substitute the coordinator's own runtime.
|
|
58374
58815
|
- **Verify via git, not source.** Use \`mesh_git_status\` to confirm side effects. Treat agent summaries as self-reports, not verification.
|
|
58375
58816
|
- **Match concurrency to task kind.** Independent read-only tasks (\`live_debug_readonly\`) dispatch all at once up to the read-only cap \u2014 no worktree, no free node needed. Each write task needs its OWN branch workspace (Workflow 3.b0); spreading writes across base nodes is NOT a substitute: a mesh with four base nodes still has zero branch isolation. Ramp up cautiously only when tasks share a base branch or submodule pointer (landing order matters). Never launch a second session onto in-flight work for the same issue, even when \`mesh_read_chat\` shows no final message yet \u2014 successive stages of one investigation stay in their session (see Workflow 3f).
|
|
@@ -58530,6 +58971,7 @@ Before doing any coordinator work, confirm that the actual callable tool list in
|
|
|
58530
58971
|
e. For a continuation of the same issue in an existing session, send a concise **delta instruction**: current verified state, the exact failed/blocked step, the newly approved action, and final reporting requirements. Do not resend the full original task or open a new chat solely to continue the same work; that wastes coordinator and worker context.
|
|
58531
58972
|
f. **Let the investigator apply the fix when the findings settle it \u2014 otherwise split deliberately.** An investigator that has read the source and named the file:line and the fix already holds context a fresh worker must rebuild from scratch, and you would have to restate its findings in the new task message to get there. Task mode is **per task, not per session**: the read-only guardrail is evaluated on each dispatch from that task's own \`readonly\`/\`task_mode\`, so you hand off by sending a follow-up \`mesh_send_task\` to the SAME session WITHOUT the read-only flag (use \`task_mode: "code_change"\`). You do not need a new session or a fresh worktree for the mode to change. **Hand off in-session when** the findings match your hypothesis, the fix stays inside the files just investigated, and no user decision is pending. **Split to a separate task when** the investigation needs a user decision (it surfaced design options, or a cost/risk tradeoff), when it OVERTURNED your hypothesis so the direction itself needs rethinking, or when the fix touches files another in-flight worker owns. **Never convert an investigation whose own conclusion was "do not change this"** \u2014 a correct no-op finding is a completed task, and pushing it into a fix produces an unverified change nobody asked for. Dispatching the investigation as an ordinary report-first task skips the handoff, but drops the guardrail against premature fixes \u2014 keep \`live_debug_readonly\` whenever the point is to find out whether anything is wrong at all.
|
|
58532
58973
|
4. **Monitor** \u2014 Prefer event-driven completion/status notifications. Do **not** poll \`mesh_read_chat\` repeatedly. Do **not** repeatedly call \`mesh_status\` or \`mesh_view_queue\` just to wait for assigned/generating work. After dispatching a direct or queued task, send one progress update with the task/session handle, then stop. Wait for \`pendingCoordinatorEvents\` or another completion/approval/status signal, an explicit user status request, or a real timeout/stall signal before reading status/chat/queue again. Use at most one compact \`mesh_read_chat\` check after a terminal signal. Handle approvals via \`mesh_approve\`. **Proactively parallelize new work.** When the user reports a new bug or asks for new work, start it immediately if it is independent of in-flight tasks and there is headroom under \`maxParallelTasks\` \u2014 do not wait for a current task to finish or for the user to prompt you to parallelize. Read-only diagnosis (\`live_debug_readonly\`) has no isolation or merge cost, so dispatch it in parallel right away. The no-polling / concurrency-limit rules constrain *re-checking or duplicating already-dispatched work*; they are **not** a reason to defer starting a new, independent task.
|
|
58974
|
+
- **Arrival order is not occurrence order \u2014 identify every notification by its \`taskId\`/\`sessionId\`.** While you are generating, worker notifications are held in the queue and injected together on the tick after you go idle. This is intended (a raw write into a generating session is not consumed as a turn), and the delay is normally well under a minute \u2014 measured median ~1 minute, worst case ~10 minutes. The consequence is that a notification arriving now is **not necessarily about the task you most recently dispatched**. Never infer a notification's subject from timing or from what you just sent: read the \`taskId\`/\`sessionId\` in the notification itself and match it to your own record of what you dispatched. Also note that your own coordinator session id appears in these traces, so a session id in a notification is not automatically a worker's. If a notification refers to a task you have already cancelled or completed, treat it as stale \u2014 do not act on it, and say so rather than silently reinterpreting it as being about current work.
|
|
58533
58975
|
5. **Verify** \u2014 When a task reports completion or git work is visible, call \`mesh_git_status\` to verify changes were made.
|
|
58534
58976
|
6. **Checkpoint** \u2014 Call \`mesh_checkpoint\` to save the work.
|
|
58535
58977
|
7. **Converge branches** \u2014 Before marking any task complete, classify every touched node/branch into exactly one final state: \`merged_to_main\`, \`pushed_feature_branch_needs_merge\`, \`blocked_review\`, \`cleanup_candidate\`, or \`not_mergeable\`. Use \`mesh_status\` branchConvergenceSummary. For obvious clean branch catch-up (ahead 0, behind > 0, upstream fresh, no dirty/stash/submodule issues), use \`mesh_fast_forward_node\` dry-run first and execute only when explicitly safe/approved; this avoids consuming an agent session. Use \`mesh_refine_node\` for clean worktree branches when safe \u2014 but when 2+ sibling worktrees share a base, converge them with \`mesh_refine_batch\` rather than repeated single-node calls (see the sequencing rule in Rules). Before/refine merging root commits that contain submodule gitlink changes, require each submodule commit to be reachable from the configured submodule remote main branch, not merely present on a feature ref or local checkout. If \`mesh_refine_node\` returns \`submodule_reachability_failed\` or publish-required evidence, keep the public convergence bucket as \`blocked_review\`; unless \`allowAutoPublishSubmoduleMainCommits\` is explicitly enabled and Refinery reports successful non-force publish plus post-publish verification, ask the user for explicit approval to push/publish the unreachable submodule commit(s) to submodule main, then rerun \`mesh_refine_node\`. Do not merge the root branch until the submodule commit(s) are reachable from submodule origin/main. A task that remains on a non-main branch is not fully complete unless the final report names the follow-up state and next step.
|
|
@@ -61360,6 +61802,10 @@ ${rendered}`, "utf-8");
|
|
|
61360
61802
|
if (cachedInline && registry2?.updateInlineMeshNode) {
|
|
61361
61803
|
registry2.updateInlineMeshNode(req.meshId, cachedInline, node);
|
|
61362
61804
|
published = true;
|
|
61805
|
+
} else if (!cachedInline && !mesh && registry2?.updateInlineMeshNode) {
|
|
61806
|
+
const shell = { id: req.meshId, nodes: [], updatedAt: (/* @__PURE__ */ new Date()).toISOString() };
|
|
61807
|
+
registry2.updateInlineMeshNode(req.meshId, shell, node);
|
|
61808
|
+
published = true;
|
|
61363
61809
|
}
|
|
61364
61810
|
} catch {
|
|
61365
61811
|
}
|
|
@@ -61719,7 +62165,7 @@ ${rendered}`, "utf-8");
|
|
|
61719
62165
|
}
|
|
61720
62166
|
async function registerWorkspaceNodeBestEffort(intent, created, ports, bootstrapStatus) {
|
|
61721
62167
|
try {
|
|
61722
|
-
await ports.registerNode({
|
|
62168
|
+
const published = await ports.registerNode({
|
|
61723
62169
|
meshId: intent.meshId,
|
|
61724
62170
|
nodeId: created.nodeId,
|
|
61725
62171
|
worktreePath: created.worktreePath,
|
|
@@ -61727,6 +62173,9 @@ ${rendered}`, "utf-8");
|
|
|
61727
62173
|
sourceNodeId: intent.sourceNodeId,
|
|
61728
62174
|
bootstrapStatus
|
|
61729
62175
|
});
|
|
62176
|
+
if (!published) {
|
|
62177
|
+
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`);
|
|
62178
|
+
}
|
|
61730
62179
|
} catch (e) {
|
|
61731
62180
|
LOG2.warn("MeshGraphWorkspace", `node registration (${bootstrapStatus}) failed for ${intent.graphId}/${intent.workspaceRef}: ${e?.message || e}`);
|
|
61732
62181
|
}
|
|
@@ -67937,7 +68386,7 @@ The mesh has no work in flight. For each mission, decide its outcome: continue i
|
|
|
67937
68386
|
const base = 1;
|
|
67938
68387
|
let difficulty = 0;
|
|
67939
68388
|
const diff = isMeshTaskDifficulty(task.difficulty) ? task.difficulty : void 0;
|
|
67940
|
-
if (diff) {
|
|
68389
|
+
if (diff && diff !== "freeform") {
|
|
67941
68390
|
if (slot.difficulty?.length) {
|
|
67942
68391
|
difficulty = slot.difficulty.includes(diff) ? 100 : 0;
|
|
67943
68392
|
} else {
|
|
@@ -68804,6 +69253,7 @@ The mesh has no work in flight. For each mission, decide its outcome: continue i
|
|
|
68804
69253
|
if (timer) clearTimeout(timer);
|
|
68805
69254
|
const isQueued = res && typeof res === "object" && res.status === "queued";
|
|
68806
69255
|
updateSessionDeliveryStatus(delivery.id, isQueued ? "queued" : "delivered");
|
|
69256
|
+
recordAckedHoldDispatchOutcome(ctx.meshId, ctx.task.id, { ok: true });
|
|
68807
69257
|
if (ctx.task.attemptId) {
|
|
68808
69258
|
try {
|
|
68809
69259
|
recordTurnAck({
|
|
@@ -68852,6 +69302,7 @@ The mesh has no work in flight. For each mission, decide its outcome: continue i
|
|
|
68852
69302
|
}
|
|
68853
69303
|
LOG2.error("MeshQueue", `Failed to dispatch task via ${ctx.transport} to node ${ctx.nodeId}: ${e?.message}`);
|
|
68854
69304
|
updateSessionDeliveryStatus(delivery.id, "failed", { lastError: e?.message, incrementAttempt: true });
|
|
69305
|
+
recordAckedHoldDispatchOutcome(ctx.meshId, ctx.task.id, { ok: false, reason: e?.message });
|
|
68855
69306
|
endTaskDispatchInFlight(ctx.meshId, ctx.task.id);
|
|
68856
69307
|
try {
|
|
68857
69308
|
closeAttemptForReassignment({ meshId: ctx.meshId, taskId: ctx.task.id, reason: "dispatch_failed" });
|
|
@@ -74491,148 +74942,6 @@ ${cleanBody}`;
|
|
|
74491
74942
|
init_mesh_events_utils();
|
|
74492
74943
|
}
|
|
74493
74944
|
});
|
|
74494
|
-
function resolveTunedReconcileMs(envName, def, min, max) {
|
|
74495
|
-
const raw = readNonEmptyString(process.env[envName]);
|
|
74496
|
-
if (raw) {
|
|
74497
|
-
const parsed = Number.parseInt(raw, 10);
|
|
74498
|
-
if (Number.isFinite(parsed) && parsed >= min && parsed <= max) return parsed;
|
|
74499
|
-
}
|
|
74500
|
-
return def;
|
|
74501
|
-
}
|
|
74502
|
-
function resolveAckedDeathDeadlineMs() {
|
|
74503
|
-
return resolveTunedReconcileMs("MESH_INFLIGHT_ACKED_DEATH_DEADLINE_MS", 8 * 6e4, 0, 60 * 6e4);
|
|
74504
|
-
}
|
|
74505
|
-
function resolveAckedTranscriptFastTrackGraceMs() {
|
|
74506
|
-
return resolveTunedReconcileMs("MESH_INFLIGHT_ACKED_TRANSCRIPT_FASTTRACK_GRACE_MS", 4e4, 0, 5 * 6e4);
|
|
74507
|
-
}
|
|
74508
|
-
function resolveAckedHoldHardCeilingMs() {
|
|
74509
|
-
return resolveTunedReconcileMs("MESH_INFLIGHT_ACKED_HOLD_HARD_CEILING_MS", 90 * 6e4, 0, 24 * 60 * 6e4);
|
|
74510
|
-
}
|
|
74511
|
-
function inFlightSynthKey(meshId, taskId) {
|
|
74512
|
-
return `${meshId}::${taskId}`;
|
|
74513
|
-
}
|
|
74514
|
-
function taskIdFromSynthKey(meshId, synthKey) {
|
|
74515
|
-
const prefix = `${meshId}::`;
|
|
74516
|
-
return synthKey.startsWith(prefix) ? synthKey.slice(prefix.length) : synthKey;
|
|
74517
|
-
}
|
|
74518
|
-
function holdStore() {
|
|
74519
|
-
try {
|
|
74520
|
-
return MeshRuntimeStore.getInstance();
|
|
74521
|
-
} catch {
|
|
74522
|
-
return void 0;
|
|
74523
|
-
}
|
|
74524
|
-
}
|
|
74525
|
-
function getHoldState(synthKey, meshId) {
|
|
74526
|
-
const cached5 = inFlightAckedHoldState.get(synthKey);
|
|
74527
|
-
if (cached5) return cached5;
|
|
74528
|
-
const store = holdStore();
|
|
74529
|
-
if (!store) return void 0;
|
|
74530
|
-
let row;
|
|
74531
|
-
try {
|
|
74532
|
-
row = store.getInflightHold(taskIdFromSynthKey(meshId, synthKey));
|
|
74533
|
-
} catch {
|
|
74534
|
-
return void 0;
|
|
74535
|
-
}
|
|
74536
|
-
if (!row) return void 0;
|
|
74537
|
-
const state = {
|
|
74538
|
-
liveConfirmedSinceAck: row.holdReason === "live",
|
|
74539
|
-
consecutiveReadFailures: row.readFailureCount ?? 0,
|
|
74540
|
-
...row.firstIdleSinceAck !== null && row.firstIdleSinceAck !== void 0 ? { transcriptIdleSinceMs: row.firstIdleSinceAck } : {},
|
|
74541
|
-
...row.heldAt !== null && row.heldAt !== void 0 ? { heldSinceMs: row.heldAt } : {}
|
|
74542
|
-
};
|
|
74543
|
-
inFlightAckedHoldState.set(synthKey, state);
|
|
74544
|
-
return state;
|
|
74545
|
-
}
|
|
74546
|
-
function setHoldState(synthKey, meshId, state) {
|
|
74547
|
-
const store = holdStore();
|
|
74548
|
-
let priorHeldSinceMs = state.heldSinceMs ?? inFlightAckedHoldState.get(synthKey)?.heldSinceMs;
|
|
74549
|
-
if (priorHeldSinceMs === void 0 && store) {
|
|
74550
|
-
try {
|
|
74551
|
-
priorHeldSinceMs = store.getInflightHold(taskIdFromSynthKey(meshId, synthKey))?.heldAt ?? void 0;
|
|
74552
|
-
} catch {
|
|
74553
|
-
}
|
|
74554
|
-
}
|
|
74555
|
-
const heldSinceMs = priorHeldSinceMs ?? Date.now();
|
|
74556
|
-
inFlightAckedHoldState.set(synthKey, { ...state, heldSinceMs });
|
|
74557
|
-
if (!store) return;
|
|
74558
|
-
try {
|
|
74559
|
-
store.upsertInflightHold({
|
|
74560
|
-
taskId: taskIdFromSynthKey(meshId, synthKey),
|
|
74561
|
-
meshId,
|
|
74562
|
-
holdReason: state.liveConfirmedSinceAck ? "live" : "unconfirmed",
|
|
74563
|
-
// Only meaningful when the row is NEW — upsertInflightHold deliberately
|
|
74564
|
-
// preserves held_at on conflict, so an existing row keeps its original anchor.
|
|
74565
|
-
heldAt: heldSinceMs,
|
|
74566
|
-
firstIdleSinceAck: state.transcriptIdleSinceMs ?? null,
|
|
74567
|
-
readFailureCount: state.consecutiveReadFailures
|
|
74568
|
-
});
|
|
74569
|
-
} catch {
|
|
74570
|
-
}
|
|
74571
|
-
}
|
|
74572
|
-
function deleteHoldState(synthKey, meshId) {
|
|
74573
|
-
inFlightAckedHoldState.delete(synthKey);
|
|
74574
|
-
const store = holdStore();
|
|
74575
|
-
if (!store) return;
|
|
74576
|
-
try {
|
|
74577
|
-
store.deleteInflightHold(taskIdFromSynthKey(meshId, synthKey));
|
|
74578
|
-
} catch {
|
|
74579
|
-
}
|
|
74580
|
-
}
|
|
74581
|
-
function rehydrateAckedHoldsForMesh(meshId) {
|
|
74582
|
-
if (rehydratedHoldMeshes.has(meshId)) return;
|
|
74583
|
-
rehydratedHoldMeshes.add(meshId);
|
|
74584
|
-
const store = holdStore();
|
|
74585
|
-
if (!store) return;
|
|
74586
|
-
let rows;
|
|
74587
|
-
try {
|
|
74588
|
-
rows = store.listInflightHoldsByMesh(meshId);
|
|
74589
|
-
} catch {
|
|
74590
|
-
return;
|
|
74591
|
-
}
|
|
74592
|
-
for (const row of rows) {
|
|
74593
|
-
const synthKey = inFlightSynthKey(meshId, row.taskId);
|
|
74594
|
-
if (inFlightAckedHoldState.has(synthKey)) continue;
|
|
74595
|
-
inFlightAckedHoldState.set(synthKey, {
|
|
74596
|
-
liveConfirmedSinceAck: row.holdReason === "live",
|
|
74597
|
-
consecutiveReadFailures: row.readFailureCount ?? 0,
|
|
74598
|
-
...row.firstIdleSinceAck !== null && row.firstIdleSinceAck !== void 0 ? { transcriptIdleSinceMs: row.firstIdleSinceAck } : {},
|
|
74599
|
-
...row.heldAt !== null && row.heldAt !== void 0 ? { heldSinceMs: row.heldAt } : {}
|
|
74600
|
-
});
|
|
74601
|
-
}
|
|
74602
|
-
if (rows.length > 0) {
|
|
74603
|
-
LOG2.info("MeshReconcile", `Rehydrated ${rows.length} persisted acked-hold row(s) for mesh ${meshId} after (re)start`);
|
|
74604
|
-
}
|
|
74605
|
-
}
|
|
74606
|
-
function collectHeldSynthKeysForMesh(meshId) {
|
|
74607
|
-
const heldKeys = /* @__PURE__ */ new Set();
|
|
74608
|
-
for (const key2 of inFlightAckedHoldState.keys()) {
|
|
74609
|
-
if (key2.startsWith(`${meshId}::`)) heldKeys.add(key2);
|
|
74610
|
-
}
|
|
74611
|
-
const store = holdStore();
|
|
74612
|
-
if (store) {
|
|
74613
|
-
try {
|
|
74614
|
-
for (const row of store.listInflightHoldsByMesh(meshId)) {
|
|
74615
|
-
heldKeys.add(inFlightSynthKey(meshId, row.taskId));
|
|
74616
|
-
}
|
|
74617
|
-
} catch {
|
|
74618
|
-
}
|
|
74619
|
-
}
|
|
74620
|
-
return heldKeys;
|
|
74621
|
-
}
|
|
74622
|
-
var ACKED_DEATH_CONSECUTIVE_READ_FAILURES;
|
|
74623
|
-
var inFlightAckedHoldState;
|
|
74624
|
-
var rehydratedHoldMeshes;
|
|
74625
|
-
var init_mesh_reconcile_acked_hold = __esm2({
|
|
74626
|
-
"src/mesh/mesh-reconcile-acked-hold.ts"() {
|
|
74627
|
-
"use strict";
|
|
74628
|
-
init_logger();
|
|
74629
|
-
init_mesh_runtime_store();
|
|
74630
|
-
init_mesh_events_utils();
|
|
74631
|
-
ACKED_DEATH_CONSECUTIVE_READ_FAILURES = 3;
|
|
74632
|
-
inFlightAckedHoldState = /* @__PURE__ */ new Map();
|
|
74633
|
-
rehydratedHoldMeshes = /* @__PURE__ */ new Set();
|
|
74634
|
-
}
|
|
74635
|
-
});
|
|
74636
74945
|
function resolveAutoPruneMinAgeMs() {
|
|
74637
74946
|
const raw = readNonEmptyString(process.env.MESH_AUTO_PRUNE_MIN_AGE_MS);
|
|
74638
74947
|
if (raw) {
|
|
@@ -74864,6 +75173,109 @@ ${cleanBody}`;
|
|
|
74864
75173
|
init_mesh_reconcile_identity();
|
|
74865
75174
|
}
|
|
74866
75175
|
});
|
|
75176
|
+
function formatBytes(bytes) {
|
|
75177
|
+
if (!Number.isFinite(bytes) || bytes < 0) return "unknown";
|
|
75178
|
+
const units = ["B", "KiB", "MiB", "GiB", "TiB"];
|
|
75179
|
+
let value = bytes;
|
|
75180
|
+
let unit = 0;
|
|
75181
|
+
while (value >= 1024 && unit < units.length - 1) {
|
|
75182
|
+
value /= 1024;
|
|
75183
|
+
unit += 1;
|
|
75184
|
+
}
|
|
75185
|
+
return `${value >= 10 || unit === 0 ? Math.round(value) : value.toFixed(1)}${units[unit]}`;
|
|
75186
|
+
}
|
|
75187
|
+
function classifyDiskSpace(stats) {
|
|
75188
|
+
if (!Number.isFinite(stats.totalBytes) || stats.totalBytes <= 0) return "ok";
|
|
75189
|
+
const { percentFree, freeBytes } = stats;
|
|
75190
|
+
if (percentFree < DISK_CRITICAL_PERCENT_FREE && freeBytes < DISK_CRITICAL_FREE_BYTES) {
|
|
75191
|
+
return "critical";
|
|
75192
|
+
}
|
|
75193
|
+
if (percentFree < DISK_WARNING_PERCENT_FREE && freeBytes < DISK_WARNING_FREE_BYTES) {
|
|
75194
|
+
return "warning";
|
|
75195
|
+
}
|
|
75196
|
+
return "ok";
|
|
75197
|
+
}
|
|
75198
|
+
function describeDiskSpace(stats, level, path60) {
|
|
75199
|
+
const pct = Number.isFinite(stats.percentFree) ? stats.percentFree.toFixed(1) : "?";
|
|
75200
|
+
const used = Number.isFinite(stats.percentFree) ? (100 - stats.percentFree).toFixed(1) : "?";
|
|
75201
|
+
return `disk ${level.toUpperCase()} at ${path60}: ${formatBytes(stats.freeBytes)} free of ${formatBytes(stats.totalBytes)} (${pct}% free / ${used}% used)`;
|
|
75202
|
+
}
|
|
75203
|
+
function readDiskSpace(path60) {
|
|
75204
|
+
try {
|
|
75205
|
+
const stats = (0, import_fs16.statfsSync)(path60);
|
|
75206
|
+
const blockSize = Number(stats.bsize);
|
|
75207
|
+
const freeBytes = Number(stats.bavail) * blockSize;
|
|
75208
|
+
const totalBytes = Number(stats.blocks) * blockSize;
|
|
75209
|
+
if (!Number.isFinite(freeBytes) || !Number.isFinite(totalBytes) || totalBytes <= 0) {
|
|
75210
|
+
return null;
|
|
75211
|
+
}
|
|
75212
|
+
return {
|
|
75213
|
+
freeBytes,
|
|
75214
|
+
totalBytes,
|
|
75215
|
+
percentFree: freeBytes / totalBytes * 100
|
|
75216
|
+
};
|
|
75217
|
+
} catch {
|
|
75218
|
+
return null;
|
|
75219
|
+
}
|
|
75220
|
+
}
|
|
75221
|
+
function checkDiskSpace(path60) {
|
|
75222
|
+
const stats = readDiskSpace(path60);
|
|
75223
|
+
if (!stats) return null;
|
|
75224
|
+
const level = classifyDiskSpace(stats);
|
|
75225
|
+
return { ...stats, level, path: path60, summary: describeDiskSpace(stats, level, path60) };
|
|
75226
|
+
}
|
|
75227
|
+
function logDiskSpaceStatus(status, context) {
|
|
75228
|
+
if (!status) {
|
|
75229
|
+
LOG2.debug("DiskSpace", `${context}: volume not measurable (statfs unavailable)`);
|
|
75230
|
+
return;
|
|
75231
|
+
}
|
|
75232
|
+
switch (status.level) {
|
|
75233
|
+
case "critical":
|
|
75234
|
+
LOG2.error("DiskSpace", `${context}: ${status.summary} \u2014 writes are expected to fail with ENOSPC`);
|
|
75235
|
+
break;
|
|
75236
|
+
case "warning":
|
|
75237
|
+
LOG2.warn("DiskSpace", `${context}: ${status.summary}`);
|
|
75238
|
+
break;
|
|
75239
|
+
default:
|
|
75240
|
+
LOG2.debug("DiskSpace", `${context}: ${status.summary}`);
|
|
75241
|
+
break;
|
|
75242
|
+
}
|
|
75243
|
+
}
|
|
75244
|
+
function preflightDiskSpace(path60, operation, options = {}) {
|
|
75245
|
+
const status = checkDiskSpace(path60);
|
|
75246
|
+
logDiskSpaceStatus(status, `preflight before ${operation}`);
|
|
75247
|
+
if (status?.level === "critical" && options.throwOnCritical !== false) {
|
|
75248
|
+
throw new LowDiskSpaceError(status, operation);
|
|
75249
|
+
}
|
|
75250
|
+
return status;
|
|
75251
|
+
}
|
|
75252
|
+
var import_fs16;
|
|
75253
|
+
var DISK_CRITICAL_PERCENT_FREE;
|
|
75254
|
+
var DISK_CRITICAL_FREE_BYTES;
|
|
75255
|
+
var DISK_WARNING_PERCENT_FREE;
|
|
75256
|
+
var DISK_WARNING_FREE_BYTES;
|
|
75257
|
+
var LowDiskSpaceError;
|
|
75258
|
+
var init_disk_space_preflight = __esm2({
|
|
75259
|
+
"src/diagnostics/disk-space-preflight.ts"() {
|
|
75260
|
+
"use strict";
|
|
75261
|
+
import_fs16 = require("fs");
|
|
75262
|
+
init_logger();
|
|
75263
|
+
DISK_CRITICAL_PERCENT_FREE = 2;
|
|
75264
|
+
DISK_CRITICAL_FREE_BYTES = 1 * 1024 * 1024 * 1024;
|
|
75265
|
+
DISK_WARNING_PERCENT_FREE = 5;
|
|
75266
|
+
DISK_WARNING_FREE_BYTES = 5 * 1024 * 1024 * 1024;
|
|
75267
|
+
LowDiskSpaceError = class extends Error {
|
|
75268
|
+
status;
|
|
75269
|
+
constructor(status, operation) {
|
|
75270
|
+
super(
|
|
75271
|
+
`Refusing to ${operation}: ${status.summary}. Writes would fail with ENOSPC mid-operation. Free space and retry (see \`adhdev doctor\` for the largest reclaimable paths).`
|
|
75272
|
+
);
|
|
75273
|
+
this.name = "LowDiskSpaceError";
|
|
75274
|
+
this.status = status;
|
|
75275
|
+
}
|
|
75276
|
+
};
|
|
75277
|
+
}
|
|
75278
|
+
});
|
|
74867
75279
|
function selectExpiredLedgerJsonl(files, now, maxAgeMs = LEDGER_JSONL_MAX_AGE_MS) {
|
|
74868
75280
|
return files.filter((f) => now - f.mtimeMs > maxAgeMs);
|
|
74869
75281
|
}
|
|
@@ -74898,7 +75310,7 @@ ${cleanBody}`;
|
|
|
74898
75310
|
}
|
|
74899
75311
|
function safeUnlink(path60) {
|
|
74900
75312
|
try {
|
|
74901
|
-
(0,
|
|
75313
|
+
(0, import_fs17.unlinkSync)(path60);
|
|
74902
75314
|
return true;
|
|
74903
75315
|
} catch (e) {
|
|
74904
75316
|
LOG2.warn("DiskRetention", `Failed to delete ${path60}: ${e?.message || e}`);
|
|
@@ -74906,18 +75318,18 @@ ${cleanBody}`;
|
|
|
74906
75318
|
}
|
|
74907
75319
|
}
|
|
74908
75320
|
function listDirFiles(dir) {
|
|
74909
|
-
if (!(0,
|
|
75321
|
+
if (!(0, import_fs17.existsSync)(dir)) return [];
|
|
74910
75322
|
const out = [];
|
|
74911
75323
|
let names;
|
|
74912
75324
|
try {
|
|
74913
|
-
names = (0,
|
|
75325
|
+
names = (0, import_fs17.readdirSync)(dir);
|
|
74914
75326
|
} catch {
|
|
74915
75327
|
return [];
|
|
74916
75328
|
}
|
|
74917
75329
|
for (const name of names) {
|
|
74918
75330
|
const path60 = (0, import_path14.join)(dir, name);
|
|
74919
75331
|
try {
|
|
74920
|
-
const st = (0,
|
|
75332
|
+
const st = (0, import_fs17.statSync)(path60);
|
|
74921
75333
|
if (st.isFile()) out.push({ path: path60, mtimeMs: st.mtimeMs });
|
|
74922
75334
|
} catch {
|
|
74923
75335
|
}
|
|
@@ -74944,22 +75356,22 @@ ${cleanBody}`;
|
|
|
74944
75356
|
}
|
|
74945
75357
|
function pruneExpiredSessionHostRuntimes(now = Date.now()) {
|
|
74946
75358
|
const root = (0, import_path14.join)(getConfigDir2(), "session-host");
|
|
74947
|
-
if (!(0,
|
|
75359
|
+
if (!(0, import_fs17.existsSync)(root)) return 0;
|
|
74948
75360
|
let apps;
|
|
74949
75361
|
try {
|
|
74950
|
-
apps = (0,
|
|
75362
|
+
apps = (0, import_fs17.readdirSync)(root);
|
|
74951
75363
|
} catch {
|
|
74952
75364
|
return 0;
|
|
74953
75365
|
}
|
|
74954
75366
|
const candidates = [];
|
|
74955
75367
|
for (const app of apps) {
|
|
74956
75368
|
const runtimesDir = (0, import_path14.join)(root, app, "runtimes");
|
|
74957
|
-
if (!(0,
|
|
75369
|
+
if (!(0, import_fs17.existsSync)(runtimesDir)) continue;
|
|
74958
75370
|
for (const f of listDirFiles(runtimesDir)) {
|
|
74959
75371
|
if (!f.path.endsWith(".json")) continue;
|
|
74960
75372
|
let record2 = null;
|
|
74961
75373
|
try {
|
|
74962
|
-
const parsed = JSON.parse((0,
|
|
75374
|
+
const parsed = JSON.parse((0, import_fs17.readFileSync)(f.path, "utf-8"));
|
|
74963
75375
|
const rec = parsed && typeof parsed === "object" ? parsed.record : null;
|
|
74964
75376
|
record2 = rec && typeof rec === "object" ? rec : null;
|
|
74965
75377
|
} catch {
|
|
@@ -75005,7 +75417,15 @@ ${cleanBody}`;
|
|
|
75005
75417
|
} catch (e) {
|
|
75006
75418
|
LOG2.warn("DiskRetention", `Ledger rotation cap sweep failed: ${e?.message || e}`);
|
|
75007
75419
|
}
|
|
75008
|
-
|
|
75420
|
+
let diskLevel = "ok";
|
|
75421
|
+
try {
|
|
75422
|
+
const status = checkDiskSpace(getConfigDir2());
|
|
75423
|
+
logDiskSpaceStatus(status, "disk retention sweep");
|
|
75424
|
+
if (status) diskLevel = status.level;
|
|
75425
|
+
} catch (e) {
|
|
75426
|
+
LOG2.warn("DiskRetention", `Disk space check failed: ${e?.message || e}`);
|
|
75427
|
+
}
|
|
75428
|
+
return { ledgerJsonl, dbBackups, sessionHostRuntimes, rotationEvicted, rotationEvictedBytes, diskLevel };
|
|
75009
75429
|
}
|
|
75010
75430
|
async function detectAndSignalOrphanWorktrees(mesh, now = Date.now()) {
|
|
75011
75431
|
const nodes = Array.isArray(mesh.nodes) ? mesh.nodes : [];
|
|
@@ -75056,7 +75476,7 @@ ${cleanBody}`;
|
|
|
75056
75476
|
}
|
|
75057
75477
|
return signalled;
|
|
75058
75478
|
}
|
|
75059
|
-
var
|
|
75479
|
+
var import_fs17;
|
|
75060
75480
|
var import_path14;
|
|
75061
75481
|
var DAY_MS2;
|
|
75062
75482
|
var LEDGER_JSONL_MAX_AGE_MS;
|
|
@@ -75066,13 +75486,14 @@ ${cleanBody}`;
|
|
|
75066
75486
|
var init_mesh_disk_retention = __esm2({
|
|
75067
75487
|
"src/mesh/mesh-disk-retention.ts"() {
|
|
75068
75488
|
"use strict";
|
|
75069
|
-
|
|
75489
|
+
import_fs17 = require("fs");
|
|
75070
75490
|
import_path14 = require("path");
|
|
75071
75491
|
init_config();
|
|
75072
75492
|
init_mesh_ledger();
|
|
75073
75493
|
init_runtime_surface();
|
|
75074
75494
|
init_git_worktree();
|
|
75075
75495
|
init_logger();
|
|
75496
|
+
init_disk_space_preflight();
|
|
75076
75497
|
DAY_MS2 = 24 * 60 * 60 * 1e3;
|
|
75077
75498
|
LEDGER_JSONL_MAX_AGE_MS = 30 * DAY_MS2;
|
|
75078
75499
|
SESSION_HOST_RUNTIME_MAX_AGE_MS = 14 * DAY_MS2;
|
|
@@ -76085,6 +76506,7 @@ ${cleanBody}`;
|
|
|
76085
76506
|
const { meshId, taskId, sessionId, nodeId, providerType, synthKey, reason, detail } = args;
|
|
76086
76507
|
updateDirectDispatchStatus(meshId, sessionId, "stale", taskId);
|
|
76087
76508
|
deleteHoldState(synthKey, meshId);
|
|
76509
|
+
clearAckedHoldDispatchFailureStreak(synthKey);
|
|
76088
76510
|
try {
|
|
76089
76511
|
appendLedgerEntry(meshId, {
|
|
76090
76512
|
kind: "acked_hold_terminalized",
|
|
@@ -76140,6 +76562,27 @@ ${cleanBody}`;
|
|
|
76140
76562
|
};
|
|
76141
76563
|
const synthKey = inFlightSynthKey(mesh.id, taskId);
|
|
76142
76564
|
const isAcked = dispatch.status === "acked";
|
|
76565
|
+
if (isAcked) {
|
|
76566
|
+
const dispatchStreak = getAckedHoldDispatchFailureStreak(mesh.id, taskId);
|
|
76567
|
+
if (dispatchStreak && dispatchStreak.count >= ACKED_DEATH_CONSECUTIVE_DISPATCH_FAILURES) {
|
|
76568
|
+
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).`);
|
|
76569
|
+
terminalizeAckedHold({
|
|
76570
|
+
meshId: mesh.id,
|
|
76571
|
+
taskId,
|
|
76572
|
+
sessionId,
|
|
76573
|
+
nodeId,
|
|
76574
|
+
...providerType ? { providerType } : {},
|
|
76575
|
+
synthKey,
|
|
76576
|
+
reason: "acked_dispatch_failure_death",
|
|
76577
|
+
detail: {
|
|
76578
|
+
consecutiveDispatchFailures: dispatchStreak.count,
|
|
76579
|
+
threshold: ACKED_DEATH_CONSECUTIVE_DISPATCH_FAILURES,
|
|
76580
|
+
lastReason: dispatchStreak.lastReason
|
|
76581
|
+
}
|
|
76582
|
+
});
|
|
76583
|
+
continue;
|
|
76584
|
+
}
|
|
76585
|
+
}
|
|
76143
76586
|
if (isAcked) {
|
|
76144
76587
|
const ceilingMs = resolveAckedHoldHardCeilingMs();
|
|
76145
76588
|
const heldSinceMs = getHoldState(synthKey, mesh.id)?.heldSinceMs;
|
|
@@ -81093,6 +81536,69 @@ ${cleanBody}`;
|
|
|
81093
81536
|
return void 0;
|
|
81094
81537
|
}
|
|
81095
81538
|
}
|
|
81539
|
+
function gitRefsResolvable(cwd, refs) {
|
|
81540
|
+
for (const ref of refs) {
|
|
81541
|
+
if (!ref) return false;
|
|
81542
|
+
try {
|
|
81543
|
+
(0, import_node_child_process11.execFileSync)(GIT4, ["rev-parse", "--verify", "--quiet", `${ref}^{commit}`], { cwd, stdio: "ignore", windowsHide: true });
|
|
81544
|
+
} catch {
|
|
81545
|
+
return false;
|
|
81546
|
+
}
|
|
81547
|
+
}
|
|
81548
|
+
return true;
|
|
81549
|
+
}
|
|
81550
|
+
function probeGitAncestry(cwd, ancestor, descendant) {
|
|
81551
|
+
try {
|
|
81552
|
+
if (!fs51.existsSync(cwd)) return "undeterminable";
|
|
81553
|
+
} catch {
|
|
81554
|
+
return "undeterminable";
|
|
81555
|
+
}
|
|
81556
|
+
if (!gitRefsResolvable(cwd, [ancestor, descendant])) return "undeterminable";
|
|
81557
|
+
try {
|
|
81558
|
+
(0, import_node_child_process11.execFileSync)(GIT4, ["merge-base", "--is-ancestor", ancestor, descendant], { cwd, stdio: "ignore", windowsHide: true });
|
|
81559
|
+
return true;
|
|
81560
|
+
} catch (e) {
|
|
81561
|
+
return e?.status === 1 ? false : "undeterminable";
|
|
81562
|
+
}
|
|
81563
|
+
}
|
|
81564
|
+
function probeSubmoduleGitlinkReachability(input) {
|
|
81565
|
+
const { path: path60, baseCommit, branchCommit, probeRoot, baseRepoRoot } = input;
|
|
81566
|
+
const submoduleRepo = (0, import_path17.resolve)(probeRoot, path60);
|
|
81567
|
+
const baseSubmoduleRepo = (0, import_path17.resolve)(baseRepoRoot, path60);
|
|
81568
|
+
if (baseCommit) ensureSubmoduleCommitLocal(submoduleRepo, baseSubmoduleRepo, baseCommit);
|
|
81569
|
+
if (branchCommit) ensureSubmoduleCommitLocal(submoduleRepo, baseSubmoduleRepo, branchCommit);
|
|
81570
|
+
let fastForward;
|
|
81571
|
+
let reachableFromOriginMain;
|
|
81572
|
+
const undeterminable = [];
|
|
81573
|
+
if (branchCommit) {
|
|
81574
|
+
if (baseCommit) {
|
|
81575
|
+
const ff = probeGitAncestry(submoduleRepo, baseCommit, branchCommit);
|
|
81576
|
+
if (ff === "undeterminable") undeterminable.push("fastForward");
|
|
81577
|
+
else fastForward = ff;
|
|
81578
|
+
}
|
|
81579
|
+
const reach = probeGitAncestry(submoduleRepo, branchCommit, "refs/remotes/origin/main");
|
|
81580
|
+
if (reach === "undeterminable") undeterminable.push("reachableFromOriginMain");
|
|
81581
|
+
else reachableFromOriginMain = reach;
|
|
81582
|
+
}
|
|
81583
|
+
return {
|
|
81584
|
+
path: path60,
|
|
81585
|
+
baseCommit,
|
|
81586
|
+
branchCommit,
|
|
81587
|
+
fastForward,
|
|
81588
|
+
reachableFromOriginMain,
|
|
81589
|
+
...undeterminable.length ? { undeterminable } : {},
|
|
81590
|
+
probedRepo: submoduleRepo
|
|
81591
|
+
};
|
|
81592
|
+
}
|
|
81593
|
+
function buildSubmoduleReachabilityUndeterminableWarning(nodeId, evidence) {
|
|
81594
|
+
if (!evidence.submoduleReachabilityUndeterminable) return void 0;
|
|
81595
|
+
const entries = (evidence.submoduleGitlinks || []).filter((g) => (g.undeterminable || []).includes("reachableFromOriginMain")).map((g) => `${g.path}@${(g.branchCommit || "?").slice(0, 12)} (probed: ${g.probedRepo || "unknown"})`).join(", ");
|
|
81596
|
+
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}`;
|
|
81597
|
+
}
|
|
81598
|
+
function warnRefineSubmoduleUndeterminable(nodeId, evidence) {
|
|
81599
|
+
const message = buildSubmoduleReachabilityUndeterminableWarning(nodeId, evidence);
|
|
81600
|
+
if (message) LOG2.warn("Mesh", message);
|
|
81601
|
+
}
|
|
81096
81602
|
function submoduleCommitPresent(submoduleRepoPath, commit) {
|
|
81097
81603
|
if (!commit) return false;
|
|
81098
81604
|
try {
|
|
@@ -81140,6 +81646,7 @@ ${cleanBody}`;
|
|
|
81140
81646
|
}
|
|
81141
81647
|
var fs51;
|
|
81142
81648
|
var import_node_child_process11;
|
|
81649
|
+
var import_path17;
|
|
81143
81650
|
var GIT4;
|
|
81144
81651
|
var REFINE_PATCH_EQUIVALENCE_OUTPUT_LIMIT_BYTES;
|
|
81145
81652
|
var init_mesh_refine_gitlink_utils = __esm2({
|
|
@@ -81147,6 +81654,8 @@ ${cleanBody}`;
|
|
|
81147
81654
|
"use strict";
|
|
81148
81655
|
fs51 = __toESM2(require("fs"));
|
|
81149
81656
|
import_node_child_process11 = require("child_process");
|
|
81657
|
+
import_path17 = require("path");
|
|
81658
|
+
init_logger();
|
|
81150
81659
|
init_resolve_executable();
|
|
81151
81660
|
GIT4 = process.platform === "win32" ? resolveWin32Executable("git") : "git";
|
|
81152
81661
|
REFINE_PATCH_EQUIVALENCE_OUTPUT_LIMIT_BYTES = 4 * 1024 * 1024;
|
|
@@ -81232,9 +81741,9 @@ ${cleanBody}`;
|
|
|
81232
81741
|
for (const path60 of changed) {
|
|
81233
81742
|
const baseCommit = readTreeObject(baseRepoRoot, baseHead, path60);
|
|
81234
81743
|
const branchCommit = readTreeObject(worktreeRoot, branchHead, path60);
|
|
81235
|
-
const submoduleRepoPath = (0,
|
|
81744
|
+
const submoduleRepoPath = (0, import_path18.resolve)(worktreeRoot, path60);
|
|
81236
81745
|
if (baseCommit) {
|
|
81237
|
-
ensureSubmoduleCommitLocal(submoduleRepoPath, (0,
|
|
81746
|
+
ensureSubmoduleCommitLocal(submoduleRepoPath, (0, import_path18.resolve)(baseRepoRoot, path60), baseCommit);
|
|
81238
81747
|
}
|
|
81239
81748
|
const markUndeterminable = () => {
|
|
81240
81749
|
const unavailable = [];
|
|
@@ -81380,7 +81889,7 @@ ${cleanBody}`;
|
|
|
81380
81889
|
for (const p of conflicts) {
|
|
81381
81890
|
const commit = resolveByPath.get(p);
|
|
81382
81891
|
try {
|
|
81383
|
-
(0, import_node_child_process12.execFileSync)(GIT4, ["checkout", "-q", "--detach", commit], { cwd: (0,
|
|
81892
|
+
(0, import_node_child_process12.execFileSync)(GIT4, ["checkout", "-q", "--detach", commit], { cwd: (0, import_path18.resolve)(worktreeRoot, p), stdio: "ignore" });
|
|
81384
81893
|
} catch {
|
|
81385
81894
|
}
|
|
81386
81895
|
try {
|
|
@@ -81399,13 +81908,13 @@ ${cleanBody}`;
|
|
|
81399
81908
|
return { ok: true, branchHead };
|
|
81400
81909
|
}
|
|
81401
81910
|
var fs52;
|
|
81402
|
-
var
|
|
81911
|
+
var import_path18;
|
|
81403
81912
|
var import_node_child_process12;
|
|
81404
81913
|
var init_mesh_refine_submodule_converge = __esm2({
|
|
81405
81914
|
"src/mesh/mesh-refine-submodule-converge.ts"() {
|
|
81406
81915
|
"use strict";
|
|
81407
81916
|
fs52 = __toESM2(require("fs"));
|
|
81408
|
-
|
|
81917
|
+
import_path18 = require("path");
|
|
81409
81918
|
import_node_child_process12 = require("child_process");
|
|
81410
81919
|
init_mesh_refine_gitlink_utils();
|
|
81411
81920
|
}
|
|
@@ -81427,10 +81936,10 @@ ${tail}`;
|
|
|
81427
81936
|
}
|
|
81428
81937
|
function writeValidationFailureLog(workspace, index, candidate, streams, now = () => /* @__PURE__ */ new Date()) {
|
|
81429
81938
|
try {
|
|
81430
|
-
const dir = (0,
|
|
81939
|
+
const dir = (0, import_path19.join)(workspace, REFINE_VALIDATION_LOG_DIR);
|
|
81431
81940
|
fs53.mkdirSync(dir, { recursive: true });
|
|
81432
81941
|
const stamp = now().toISOString().replace(/[:.]/g, "-");
|
|
81433
|
-
const file2 = (0,
|
|
81942
|
+
const file2 = (0, import_path19.join)(dir, `refine-${stamp}-${index}.log`);
|
|
81434
81943
|
const asText = (v) => typeof v === "string" ? v : v == null ? "" : String(v);
|
|
81435
81944
|
const shown = candidate.displayCommand || [candidate.command, ...candidate.args || []].join(" ");
|
|
81436
81945
|
fs53.writeFileSync(
|
|
@@ -81618,9 +82127,15 @@ ${e?.stderr || ""}`
|
|
|
81618
82127
|
};
|
|
81619
82128
|
}
|
|
81620
82129
|
}
|
|
82130
|
+
async function classifyAndWarnPatchEquivalenceFailure(nodeId, repoRoot, baseHead, branchHead, summary, options = {}) {
|
|
82131
|
+
const classification = await classifyPatchEquivalenceFailure(repoRoot, baseHead, branchHead, summary, options);
|
|
82132
|
+
warnRefineSubmoduleUndeterminable(nodeId, classification.evidence);
|
|
82133
|
+
return classification;
|
|
82134
|
+
}
|
|
81621
82135
|
async function classifyPatchEquivalenceFailure(repoRoot, baseHead, branchHead, summary, options = {}) {
|
|
81622
82136
|
const targetBaseRef = options.targetBaseRef || baseHead;
|
|
81623
82137
|
const autoPublish = options.autoPublishSubmoduleMainCommits;
|
|
82138
|
+
const submoduleProbeRoot = options.worktreeRoot || repoRoot;
|
|
81624
82139
|
const evidence = {
|
|
81625
82140
|
baseHead,
|
|
81626
82141
|
branchHead,
|
|
@@ -81685,20 +82200,19 @@ ${e?.stderr || ""}`
|
|
|
81685
82200
|
} catch {
|
|
81686
82201
|
continue;
|
|
81687
82202
|
}
|
|
81688
|
-
|
|
81689
|
-
|
|
81690
|
-
|
|
81691
|
-
|
|
81692
|
-
|
|
81693
|
-
|
|
81694
|
-
|
|
81695
|
-
reachableFromOriginMain = execGitOk(submoduleRepo, ["merge-base", "--is-ancestor", branchCommit, "refs/remotes/origin/main"]);
|
|
81696
|
-
}
|
|
81697
|
-
submoduleGitlinks.push({ path: p, baseCommit, branchCommit, fastForward, reachableFromOriginMain });
|
|
82203
|
+
submoduleGitlinks.push(probeSubmoduleGitlinkReachability({
|
|
82204
|
+
path: p,
|
|
82205
|
+
baseCommit,
|
|
82206
|
+
branchCommit,
|
|
82207
|
+
probeRoot: submoduleProbeRoot,
|
|
82208
|
+
baseRepoRoot: repoRoot
|
|
82209
|
+
}));
|
|
81698
82210
|
}
|
|
81699
82211
|
} catch {
|
|
81700
82212
|
}
|
|
81701
82213
|
if (submoduleGitlinks.length) evidence.submoduleGitlinks = submoduleGitlinks;
|
|
82214
|
+
const undeterminableGitlinks = submoduleGitlinks.filter((g) => (g.undeterminable || []).includes("reachableFromOriginMain"));
|
|
82215
|
+
if (undeterminableGitlinks.length > 0) evidence.submoduleReachabilityUndeterminable = true;
|
|
81702
82216
|
const gitlinkFf = summary.gitlinkTrivialFastForward;
|
|
81703
82217
|
const noResidualDiff = !evidence.diffStat && (!summary.actualPatchId || summary.actualPatchId === "");
|
|
81704
82218
|
if (ahead === 0 && behind === 0 && noResidualDiff) {
|
|
@@ -81719,6 +82233,15 @@ ${e?.stderr || ""}`
|
|
|
81719
82233
|
evidence
|
|
81720
82234
|
};
|
|
81721
82235
|
}
|
|
82236
|
+
if (undeterminableGitlinks.length > 0) {
|
|
82237
|
+
const refs = undeterminableGitlinks.map((g) => `${g.path}@${(g.branchCommit || "?").slice(0, 12)} (probed: ${g.probedRepo || "unknown"})`).join(", ");
|
|
82238
|
+
return {
|
|
82239
|
+
detailedReason: "submodule_reachability_undeterminable",
|
|
82240
|
+
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".`,
|
|
82241
|
+
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.",
|
|
82242
|
+
evidence
|
|
82243
|
+
};
|
|
82244
|
+
}
|
|
81722
82245
|
const changedGitlinks = submoduleGitlinks.length > 0;
|
|
81723
82246
|
const allGitlinksFf = changedGitlinks && submoduleGitlinks.every((g) => g.fastForward === true);
|
|
81724
82247
|
const gateSawUnresolvedGitlinkFf = gitlinkFf?.resolved === false && Array.isArray(gitlinkFf.gitlinks) && gitlinkFf.gitlinks.some((g) => g.fastForward);
|
|
@@ -81754,14 +82277,6 @@ ${e?.stderr || ""}`
|
|
|
81754
82277
|
};
|
|
81755
82278
|
}
|
|
81756
82279
|
}
|
|
81757
|
-
function execGitOk(cwd, args) {
|
|
81758
|
-
try {
|
|
81759
|
-
(0, import_node_child_process13.execFileSync)(GIT4, args, { cwd, encoding: "utf8", maxBuffer: REFINE_PATCH_EQUIVALENCE_OUTPUT_LIMIT_BYTES, windowsHide: true });
|
|
81760
|
-
return true;
|
|
81761
|
-
} catch {
|
|
81762
|
-
return false;
|
|
81763
|
-
}
|
|
81764
|
-
}
|
|
81765
82280
|
async function checkWorktreeChangesPatchEquivalentInRef(repoRoot, ref, worktreeHead) {
|
|
81766
82281
|
const startedAt = Date.now();
|
|
81767
82282
|
try {
|
|
@@ -81955,7 +82470,7 @@ ${mergeTreeErr?.stderr || ""}`;
|
|
|
81955
82470
|
const baseCommit = readTreeObject(repoRoot, baseHead, path60);
|
|
81956
82471
|
const branchCommit = readTreeObject(repoRoot, branchHead, path60);
|
|
81957
82472
|
if (!baseCommit || !branchCommit) return false;
|
|
81958
|
-
return isSubmoduleFastForward((0,
|
|
82473
|
+
return isSubmoduleFastForward((0, import_path19.resolve)(repoRoot, path60), baseCommit, branchCommit);
|
|
81959
82474
|
});
|
|
81960
82475
|
}
|
|
81961
82476
|
function collectTrivialFastForwardGitlinkResolutions(worktreeRoot, baseRepoRoot, baseHead, branchHead) {
|
|
@@ -81964,8 +82479,8 @@ ${mergeTreeErr?.stderr || ""}`;
|
|
|
81964
82479
|
const baseCommit = readTreeObject(baseRepoRoot, baseHead, path60);
|
|
81965
82480
|
const branchCommit = readTreeObject(worktreeRoot, branchHead, path60);
|
|
81966
82481
|
if (!baseCommit || !branchCommit) continue;
|
|
81967
|
-
const submoduleRepoPath = (0,
|
|
81968
|
-
ensureSubmoduleCommitLocal(submoduleRepoPath, (0,
|
|
82482
|
+
const submoduleRepoPath = (0, import_path19.resolve)(worktreeRoot, path60);
|
|
82483
|
+
ensureSubmoduleCommitLocal(submoduleRepoPath, (0, import_path19.resolve)(baseRepoRoot, path60), baseCommit);
|
|
81969
82484
|
if (baseCommit === branchCommit) {
|
|
81970
82485
|
continue;
|
|
81971
82486
|
}
|
|
@@ -81981,7 +82496,7 @@ ${mergeTreeErr?.stderr || ""}`;
|
|
|
81981
82496
|
const changedGitlinks = readChangedGitlinkPaths(repoRoot, baseHead, branchHead).map((path60) => {
|
|
81982
82497
|
const baseCommit = readTreeObject(repoRoot, baseHead, path60);
|
|
81983
82498
|
const branchCommit = readTreeObject(repoRoot, branchHead, path60);
|
|
81984
|
-
const submoduleRepoPath = (0,
|
|
82499
|
+
const submoduleRepoPath = (0, import_path19.resolve)(repoRoot, path60);
|
|
81985
82500
|
const fastForward = !!baseCommit && !!branchCommit && isSubmoduleFastForward(submoduleRepoPath, baseCommit, branchCommit);
|
|
81986
82501
|
return { path: path60, baseCommit, branchCommit, fastForward };
|
|
81987
82502
|
});
|
|
@@ -82036,7 +82551,7 @@ ${mergeTreeErr?.stderr || ""}`;
|
|
|
82036
82551
|
if (!tree) return void 0;
|
|
82037
82552
|
const updates = paths.map((path60) => `160000 commit ${placeholderCommit} ${path60}`).join("\n");
|
|
82038
82553
|
if (!updates) return tree;
|
|
82039
|
-
const tmpIndex = (0,
|
|
82554
|
+
const tmpIndex = (0, import_path19.join)(resolveGitDir(repoRoot), `adhdev-refine-eq-${commitish.slice(0, 12)}.index`);
|
|
82040
82555
|
const env2 = { ...process.env, GIT_INDEX_FILE: tmpIndex };
|
|
82041
82556
|
try {
|
|
82042
82557
|
(0, import_node_child_process13.execFileSync)(GIT4, ["read-tree", tree], { cwd: repoRoot, env: env2, stdio: "ignore" });
|
|
@@ -82111,7 +82626,7 @@ ${mergeTreeErr?.stderr || ""}`;
|
|
|
82111
82626
|
if (!contentTree) return void 0;
|
|
82112
82627
|
const updates = branchGitlinks.map((entry) => `160000 commit ${entry.branchCommit} ${entry.path}`).join("\n");
|
|
82113
82628
|
if (!updates) return contentTree;
|
|
82114
|
-
const tmpIndex = (0,
|
|
82629
|
+
const tmpIndex = (0, import_path19.join)(resolveGitDir(repoRoot), `adhdev-refine-ff-${baseHead.slice(0, 12)}-${branchHead.slice(0, 12)}.index`);
|
|
82115
82630
|
const env2 = { ...process.env, GIT_INDEX_FILE: tmpIndex };
|
|
82116
82631
|
try {
|
|
82117
82632
|
(0, import_node_child_process13.execFileSync)(GIT4, ["read-tree", contentTree], { cwd: repoRoot, env: env2, stdio: "ignore" });
|
|
@@ -82268,7 +82783,7 @@ ${mergeTreeErr?.stderr || ""}`;
|
|
|
82268
82783
|
return match ? { commit: match[1], path: match[2] } : null;
|
|
82269
82784
|
}).filter((entry) => !!entry);
|
|
82270
82785
|
for (const gitlink of gitlinks) {
|
|
82271
|
-
const submodulePath = (0,
|
|
82786
|
+
const submodulePath = (0, import_path19.resolve)(repoRoot, gitlink.path);
|
|
82272
82787
|
const entry = {
|
|
82273
82788
|
path: gitlink.path,
|
|
82274
82789
|
commit: gitlink.commit,
|
|
@@ -82295,7 +82810,7 @@ ${mergeTreeErr?.stderr || ""}`;
|
|
|
82295
82810
|
entry.localReachable = false;
|
|
82296
82811
|
if (options.allowAutoPublishSubmoduleMainCommits === true && options.worktreeRoot) {
|
|
82297
82812
|
try {
|
|
82298
|
-
const imported = await importCommitFromWorktreeSubmodule(submodulePath, (0,
|
|
82813
|
+
const imported = await importCommitFromWorktreeSubmodule(submodulePath, (0, import_path19.resolve)(options.worktreeRoot, gitlink.path), gitlink.commit);
|
|
82299
82814
|
if (imported) {
|
|
82300
82815
|
entry.localReachable = true;
|
|
82301
82816
|
entry.importedFromWorktree = true;
|
|
@@ -82525,13 +83040,13 @@ ${mergeTreeErr?.stderr || ""}`;
|
|
|
82525
83040
|
...extras
|
|
82526
83041
|
});
|
|
82527
83042
|
const isPackageManagerValidation = (candidate) => {
|
|
82528
|
-
const command = (0,
|
|
83043
|
+
const command = (0, import_path19.basename)(candidate.command).replace(/\.(?:cmd|exe)$/i, "");
|
|
82529
83044
|
return ["npm", "pnpm", "yarn", "bun"].includes(command) && candidate.args.some((arg) => arg === "run" || arg === "test" || arg === "exec");
|
|
82530
83045
|
};
|
|
82531
83046
|
const dependenciesLikelyMissing = (cwd) => {
|
|
82532
|
-
if (!fs53.existsSync((0,
|
|
82533
|
-
if (fs53.existsSync((0,
|
|
82534
|
-
return ["package-lock.json", "npm-shrinkwrap.json", "pnpm-lock.yaml", "yarn.lock", "bun.lockb", "bun.lock"].some((lock) => fs53.existsSync((0,
|
|
83047
|
+
if (!fs53.existsSync((0, import_path19.join)(cwd, "package.json"))) return false;
|
|
83048
|
+
if (fs53.existsSync((0, import_path19.join)(cwd, "node_modules"))) return false;
|
|
83049
|
+
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)));
|
|
82535
83050
|
};
|
|
82536
83051
|
const needsNodeModules = (candidate, cwd) => isPackageManagerValidation(candidate) && dependenciesLikelyMissing(cwd);
|
|
82537
83052
|
const isDaemonScopedCommand = (candidate) => {
|
|
@@ -82598,7 +83113,7 @@ ${mergeTreeErr?.stderr || ""}`;
|
|
|
82598
83113
|
summary.bootstrap = { stage: "legacy" };
|
|
82599
83114
|
for (const candidate of selection.bootstrapCommands) {
|
|
82600
83115
|
const startedAt = Date.now();
|
|
82601
|
-
const cwd = candidate.cwd ? (0,
|
|
83116
|
+
const cwd = candidate.cwd ? (0, import_path19.resolve)(workspace, candidate.cwd) : workspace;
|
|
82602
83117
|
const timeout = candidate.timeoutMs || REFINE_VALIDATION_TIMEOUT_MS;
|
|
82603
83118
|
const resolvedCommand = resolveWin32Executable(candidate.command);
|
|
82604
83119
|
const spawn7 = buildWin32ExecFileSpawn(resolvedCommand, candidate.args);
|
|
@@ -82631,7 +83146,7 @@ ${mergeTreeErr?.stderr || ""}`;
|
|
|
82631
83146
|
let missingDepsBlocked = false;
|
|
82632
83147
|
for (const candidate of commandsToRun) {
|
|
82633
83148
|
const startedAt = Date.now();
|
|
82634
|
-
const cwd = candidate.cwd ? (0,
|
|
83149
|
+
const cwd = candidate.cwd ? (0, import_path19.resolve)(workspace, candidate.cwd) : workspace;
|
|
82635
83150
|
const timeout = candidate.timeoutMs || REFINE_VALIDATION_TIMEOUT_MS;
|
|
82636
83151
|
const bootstrapProvidedDependencies = summary.bootstrap?.stage === "cached" || summary.bootstrap?.stage === "ran" || summary.bootstrap?.stage === "legacy";
|
|
82637
83152
|
if (!bootstrapProvidedDependencies && needsNodeModules(candidate, cwd)) {
|
|
@@ -82698,7 +83213,7 @@ ${mergeTreeErr?.stderr || ""}`;
|
|
|
82698
83213
|
summary.status = "passed";
|
|
82699
83214
|
return summary;
|
|
82700
83215
|
}
|
|
82701
|
-
var
|
|
83216
|
+
var import_path19;
|
|
82702
83217
|
var fs53;
|
|
82703
83218
|
var import_node_child_process13;
|
|
82704
83219
|
var REFINE_VALIDATION_TIMEOUT_MS;
|
|
@@ -82713,7 +83228,7 @@ ${mergeTreeErr?.stderr || ""}`;
|
|
|
82713
83228
|
init_git_status();
|
|
82714
83229
|
init_refine_config();
|
|
82715
83230
|
init_worktree_bootstrap_config();
|
|
82716
|
-
|
|
83231
|
+
import_path19 = require("path");
|
|
82717
83232
|
fs53 = __toESM2(require("fs"));
|
|
82718
83233
|
import_node_child_process13 = require("child_process");
|
|
82719
83234
|
init_resolve_executable();
|
|
@@ -82725,7 +83240,7 @@ ${mergeTreeErr?.stderr || ""}`;
|
|
|
82725
83240
|
REFINE_VALIDATION_SUMMARY_HEAD_CHARS = 2e3;
|
|
82726
83241
|
REFINE_VALIDATION_SUMMARY_TAIL_CHARS = 6e3;
|
|
82727
83242
|
REFINE_VALIDATION_SUMMARY_CHARS = REFINE_VALIDATION_SUMMARY_HEAD_CHARS + REFINE_VALIDATION_SUMMARY_TAIL_CHARS;
|
|
82728
|
-
REFINE_VALIDATION_LOG_DIR = (0,
|
|
83243
|
+
REFINE_VALIDATION_LOG_DIR = (0, import_path19.join)(".adhdev", "logs");
|
|
82729
83244
|
}
|
|
82730
83245
|
});
|
|
82731
83246
|
function findOpenRefineDispatchForNode(args) {
|
|
@@ -83807,16 +84322,11 @@ ${excerpt}` : "\n--- git output ---\n(none captured)");
|
|
|
83807
84322
|
error: submoduleHintPatchEquivalence.error,
|
|
83808
84323
|
actionableHint: submoduleHintPatchEquivalence.actionableHint
|
|
83809
84324
|
});
|
|
83810
|
-
const classification = await
|
|
83811
|
-
|
|
83812
|
-
|
|
83813
|
-
ctx.
|
|
83814
|
-
|
|
83815
|
-
{
|
|
83816
|
-
targetBaseRef: baseHead,
|
|
83817
|
-
autoPublishSubmoduleMainCommits: resolveRefineryAutoPublishSubmoduleMainCommits(ctx.mesh, node.workspace).enabled
|
|
83818
|
-
}
|
|
83819
|
-
);
|
|
84325
|
+
const classification = await classifyAndWarnPatchEquivalenceFailure(node.id, repoRoot, baseHead, ctx.branchHead, submoduleHintPatchEquivalence, {
|
|
84326
|
+
targetBaseRef: baseHead,
|
|
84327
|
+
worktreeRoot: node.workspace,
|
|
84328
|
+
autoPublishSubmoduleMainCommits: resolveRefineryAutoPublishSubmoduleMainCommits(ctx.mesh, node.workspace).enabled
|
|
84329
|
+
});
|
|
83820
84330
|
return { kind: "terminal", result: {
|
|
83821
84331
|
success: false,
|
|
83822
84332
|
code: "patch_equivalence_failed",
|
|
@@ -84000,19 +84510,15 @@ ${tail}` : ""
|
|
|
84000
84510
|
if (!patchEquivalence.equivalent) {
|
|
84001
84511
|
const alreadyMergedViaOtherPath = !patchEquivalence.actualPatchId && !!patchEquivalence.expectedPatchId;
|
|
84002
84512
|
if (!alreadyMergedViaOtherPath) {
|
|
84003
|
-
const classification = await
|
|
84004
|
-
|
|
84005
|
-
|
|
84006
|
-
|
|
84007
|
-
|
|
84008
|
-
{
|
|
84009
|
-
targetBaseRef: baseHead,
|
|
84010
|
-
autoPublishSubmoduleMainCommits: resolveRefineryAutoPublishSubmoduleMainCommits(mesh, node.workspace).enabled
|
|
84011
|
-
}
|
|
84012
|
-
);
|
|
84513
|
+
const classification = await classifyAndWarnPatchEquivalenceFailure(node.id, repoRoot, baseHead, branchHead, patchEquivalence, {
|
|
84514
|
+
targetBaseRef: baseHead,
|
|
84515
|
+
worktreeRoot: node.workspace,
|
|
84516
|
+
autoPublishSubmoduleMainCommits: resolveRefineryAutoPublishSubmoduleMainCommits(mesh, node.workspace).enabled
|
|
84517
|
+
});
|
|
84013
84518
|
recordMeshRefineStage(refineStages, "patch_equivalence_classification", "failed", patchEquivalenceStarted, {
|
|
84014
84519
|
detailedReason: classification.detailedReason,
|
|
84015
|
-
recommendedAction: classification.recommendedAction
|
|
84520
|
+
recommendedAction: classification.recommendedAction,
|
|
84521
|
+
...classification.evidence.submoduleReachabilityUndeterminable ? { submoduleReachabilityUndeterminable: true } : {}
|
|
84016
84522
|
});
|
|
84017
84523
|
return { kind: "terminal", result: {
|
|
84018
84524
|
success: false,
|
|
@@ -85391,6 +85897,10 @@ ${e?.stderr || ""}`;
|
|
|
85391
85897
|
DEFAULT_STATUS_P2P_REPORT_INTERVAL_MS: () => DEFAULT_STATUS_P2P_REPORT_INTERVAL_MS,
|
|
85392
85898
|
DEFAULT_STATUS_SERVER_REPORT_INTERVAL_MS: () => DEFAULT_STATUS_SERVER_REPORT_INTERVAL_MS,
|
|
85393
85899
|
DEV_SERVER_PORT: () => DEV_SERVER_PORT,
|
|
85900
|
+
DISK_CRITICAL_FREE_BYTES: () => DISK_CRITICAL_FREE_BYTES,
|
|
85901
|
+
DISK_CRITICAL_PERCENT_FREE: () => DISK_CRITICAL_PERCENT_FREE,
|
|
85902
|
+
DISK_WARNING_FREE_BYTES: () => DISK_WARNING_FREE_BYTES,
|
|
85903
|
+
DISK_WARNING_PERCENT_FREE: () => DISK_WARNING_PERCENT_FREE,
|
|
85394
85904
|
DUPLICATE_MESH_DISPATCH_CODE: () => DUPLICATE_MESH_DISPATCH_CODE,
|
|
85395
85905
|
DaemonAgentStreamManager: () => DaemonAgentStreamManager,
|
|
85396
85906
|
DaemonCdpInitializer: () => DaemonCdpInitializer,
|
|
@@ -85415,8 +85925,11 @@ ${e?.stderr || ""}`;
|
|
|
85415
85925
|
KNOWN_DIGEST_ALGORITHMS: () => KNOWN_DIGEST_ALGORITHMS,
|
|
85416
85926
|
LEGACY_UNVERIFIED_ALGORITHM: () => LEGACY_UNVERIFIED_ALGORITHM,
|
|
85417
85927
|
LOG: () => LOG2,
|
|
85928
|
+
LowDiskSpaceError: () => LowDiskSpaceError,
|
|
85418
85929
|
MAGI_NEEDS_VERIFICATION_PREVIEW_CAP: () => MAGI_NEEDS_VERIFICATION_PREVIEW_CAP,
|
|
85419
85930
|
MAGI_RAW_ANSWER_CAP: () => MAGI_RAW_ANSWER_CAP,
|
|
85931
|
+
MAX_CAPTURE_LOG_GENERATIONS: () => MAX_CAPTURE_LOG_GENERATIONS,
|
|
85932
|
+
MAX_CAPTURE_LOG_SIZE: () => MAX_CAPTURE_LOG_SIZE,
|
|
85420
85933
|
MAX_LEDGER_SLICE_LIMIT: () => MAX_LEDGER_SLICE_LIMIT,
|
|
85421
85934
|
MAX_SESSIONS_PER_MESH: () => MAX_SESSIONS_PER_MESH,
|
|
85422
85935
|
MAX_SIZE_ROTATION_GENERATIONS: () => MAX_SIZE_ROTATION_GENERATIONS,
|
|
@@ -85546,9 +86059,11 @@ ${e?.stderr || ""}`;
|
|
|
85546
86059
|
buildUserChatMessage: () => buildUserChatMessage,
|
|
85547
86060
|
cancelTask: () => cancelTask,
|
|
85548
86061
|
canonicalDaemonId: () => canonicalDaemonId,
|
|
86062
|
+
checkDiskSpace: () => checkDiskSpace,
|
|
85549
86063
|
claimMeshGraphGate: () => claimMeshGraphGate,
|
|
85550
86064
|
claimNextTask: () => claimNextTask,
|
|
85551
86065
|
classifyChatMessageVisibility: () => classifyChatMessageVisibility,
|
|
86066
|
+
classifyDiskSpace: () => classifyDiskSpace,
|
|
85552
86067
|
classifyDuplicateMeshDispatch: () => classifyDuplicateMeshDispatch,
|
|
85553
86068
|
classifyHotChatSessionsForSubscriptionFlush: () => classifyHotChatSessionsForSubscriptionFlush2,
|
|
85554
86069
|
classifyP2pRelayFailure: () => classifyP2pRelayFailure,
|
|
@@ -85561,6 +86076,7 @@ ${e?.stderr || ""}`;
|
|
|
85561
86076
|
clearDebugTrace: () => clearDebugTrace,
|
|
85562
86077
|
clearPendingMeshCoordinatorEvents: () => clearPendingMeshCoordinatorEvents,
|
|
85563
86078
|
codexSessionsDir: () => codexSessionsDir,
|
|
86079
|
+
collectIgnoredMagiSlotFields: () => collectIgnoredMagiSlotFields,
|
|
85564
86080
|
collectPendingApprovals: () => collectPendingApprovals,
|
|
85565
86081
|
collectSyncTargetTypes: () => collectSyncTargetTypes,
|
|
85566
86082
|
commitMeshGraphPlan: () => commitMeshGraphPlan,
|
|
@@ -85599,6 +86115,7 @@ ${e?.stderr || ""}`;
|
|
|
85599
86115
|
deriveMeshReviewInboxItems: () => deriveMeshReviewInboxItems,
|
|
85600
86116
|
deriveWorkspaceBranchIdentity: () => deriveWorkspaceBranchIdentity,
|
|
85601
86117
|
deriveWorkspaceOwnerTag: () => deriveWorkspaceOwnerTag,
|
|
86118
|
+
describeDiskSpace: () => describeDiskSpace,
|
|
85602
86119
|
describeTaskDependencyState: () => describeTaskDependencyState,
|
|
85603
86120
|
detectAllVersions: () => detectAllVersions,
|
|
85604
86121
|
detectCLI: () => detectCLI,
|
|
@@ -85634,6 +86151,7 @@ ${e?.stderr || ""}`;
|
|
|
85634
86151
|
flattenMessageParts: () => flattenMessageParts,
|
|
85635
86152
|
foldUsageRecords: () => foldUsageRecords,
|
|
85636
86153
|
forceRefreshQuota: () => forceRefreshQuota2,
|
|
86154
|
+
formatBytes: () => formatBytes,
|
|
85637
86155
|
formatManifestValidationIssues: () => formatManifestValidationIssues,
|
|
85638
86156
|
formatMeshTaskModeViolations: () => formatMeshTaskModeViolations,
|
|
85639
86157
|
forwardAgentStreamsToIdeInstance: () => forwardAgentStreamsToIdeInstance2,
|
|
@@ -85751,6 +86269,7 @@ ${e?.stderr || ""}`;
|
|
|
85751
86269
|
loadRepoSettings: () => loadRepoSettings,
|
|
85752
86270
|
loadState: () => loadState,
|
|
85753
86271
|
logCommand: () => logCommand,
|
|
86272
|
+
logDiskSpaceStatus: () => logDiskSpaceStatus,
|
|
85754
86273
|
machineCoreFromDaemonId: () => machineCoreFromDaemonId,
|
|
85755
86274
|
magiAutoLaunchedSessionCleanupDecision: () => magiAutoLaunchedSessionCleanupDecision,
|
|
85756
86275
|
makeUsage: () => makeUsage,
|
|
@@ -85807,6 +86326,7 @@ ${e?.stderr || ""}`;
|
|
|
85807
86326
|
partitionSessionHostDiagnosticsSessions: () => import_session_host_core32.partitionSessionHostDiagnosticsSessions,
|
|
85808
86327
|
partitionSessionHostRecords: () => import_session_host_core32.partitionSessionHostRecords,
|
|
85809
86328
|
planMeshOnboarding: () => planMeshOnboarding,
|
|
86329
|
+
preflightDiskSpace: () => preflightDiskSpace,
|
|
85810
86330
|
prepareSessionChatTailUpdate: () => prepareSessionChatTailUpdate2,
|
|
85811
86331
|
prepareSessionModalUpdate: () => prepareSessionModalUpdate2,
|
|
85812
86332
|
presentationFromAttemptRow: () => presentationFromAttemptRow,
|
|
@@ -85828,6 +86348,7 @@ ${e?.stderr || ""}`;
|
|
|
85828
86348
|
readChatHistory: () => readChatHistory,
|
|
85829
86349
|
readClaudeCliSession: () => readSession,
|
|
85830
86350
|
readCodexCliSession: () => readSession2,
|
|
86351
|
+
readDiskSpace: () => readDiskSpace,
|
|
85831
86352
|
readHermesCliSession: () => readSession4,
|
|
85832
86353
|
readLatestCodexRateLimits: () => readLatestCodexRateLimits,
|
|
85833
86354
|
readLedgerEntries: () => readLedgerEntries,
|
|
@@ -85909,6 +86430,7 @@ ${e?.stderr || ""}`;
|
|
|
85909
86430
|
resolveTurnAttemptRow: () => resolveTurnAttemptRow,
|
|
85910
86431
|
resolveWorktreeBaseDir: () => resolveWorktreeBaseDir,
|
|
85911
86432
|
resolveWorktreePath: () => resolveWorktreePath,
|
|
86433
|
+
rotateCaptureLogIfNeeded: () => rotateCaptureLogIfNeeded,
|
|
85912
86434
|
runAsyncBatch: () => runAsyncBatch2,
|
|
85913
86435
|
runGit: () => runGit,
|
|
85914
86436
|
runMeshWorktreeBootstrap: () => runMeshWorktreeBootstrap,
|
|
@@ -89460,7 +89982,7 @@ The pin is NOT cleared automatically: a pin often encodes required context conti
|
|
|
89460
89982
|
init_state_store();
|
|
89461
89983
|
var import_child_process5 = require("child_process");
|
|
89462
89984
|
var import_util22 = require("util");
|
|
89463
|
-
var
|
|
89985
|
+
var import_fs18 = require("fs");
|
|
89464
89986
|
var import_os3 = require("os");
|
|
89465
89987
|
var path24 = __toESM2(require("path"));
|
|
89466
89988
|
var fs16 = __toESM2(require("fs"));
|
|
@@ -89537,7 +90059,7 @@ The pin is NOT cleared automatically: a pin often encodes required context conti
|
|
|
89537
90059
|
if (path24.isAbsolute(trimmed) || trimmed.includes("/") || trimmed.includes("\\") || trimmed.startsWith("~")) {
|
|
89538
90060
|
const candidate = trimmed.startsWith("~") ? path24.join((0, import_os3.homedir)(), trimmed.slice(1)) : trimmed;
|
|
89539
90061
|
const resolved = path24.isAbsolute(candidate) ? candidate : path24.resolve(candidate);
|
|
89540
|
-
return (0,
|
|
90062
|
+
return (0, import_fs18.existsSync)(resolved) ? resolved : null;
|
|
89541
90063
|
}
|
|
89542
90064
|
const isWin = (0, import_os3.platform)() === "win32";
|
|
89543
90065
|
const paths = (process.env.PATH || "").split(isWin ? ";" : ":");
|
|
@@ -89547,8 +90069,8 @@ The pin is NOT cleared automatically: a pin often encodes required context conti
|
|
|
89547
90069
|
for (const ext of exes) {
|
|
89548
90070
|
const fullPath = path24.join(p, trimmed + ext);
|
|
89549
90071
|
try {
|
|
89550
|
-
if ((0,
|
|
89551
|
-
const stat2 = (0,
|
|
90072
|
+
if ((0, import_fs18.existsSync)(fullPath)) {
|
|
90073
|
+
const stat2 = (0, import_fs18.statSync)(fullPath);
|
|
89552
90074
|
if (stat2.isFile() && (isWin || stat2.mode & 73)) {
|
|
89553
90075
|
return fullPath;
|
|
89554
90076
|
}
|
|
@@ -89566,9 +90088,9 @@ The pin is NOT cleared automatically: a pin often encodes required context conti
|
|
|
89566
90088
|
if (normalized.includes("*")) {
|
|
89567
90089
|
const username = home.split(/[\\/]/).pop() || "";
|
|
89568
90090
|
const resolved = normalized.replace("*", username);
|
|
89569
|
-
if ((0,
|
|
90091
|
+
if ((0, import_fs18.existsSync)(resolved)) return resolved;
|
|
89570
90092
|
} else {
|
|
89571
|
-
if ((0,
|
|
90093
|
+
if ((0, import_fs18.existsSync)(normalized)) return normalized;
|
|
89572
90094
|
}
|
|
89573
90095
|
}
|
|
89574
90096
|
return null;
|
|
@@ -89582,7 +90104,7 @@ The pin is NOT cleared automatically: a pin often encodes required context conti
|
|
|
89582
90104
|
let resolvedCli = cliPath;
|
|
89583
90105
|
if (!resolvedCli && appPath && os33 === "darwin") {
|
|
89584
90106
|
const bundledCli = `${appPath}/Contents/Resources/app/bin/${def.cli}`;
|
|
89585
|
-
if ((0,
|
|
90107
|
+
if ((0, import_fs18.existsSync)(bundledCli)) resolvedCli = bundledCli;
|
|
89586
90108
|
}
|
|
89587
90109
|
if (!resolvedCli && appPath && os33 === "win32") {
|
|
89588
90110
|
const { dirname: dirname24 } = await import("path");
|
|
@@ -89595,7 +90117,7 @@ The pin is NOT cleared automatically: a pin often encodes required context conti
|
|
|
89595
90117
|
`${appDir}\\\\resources\\\\app\\\\bin\\\\${def.cli}.cmd`
|
|
89596
90118
|
];
|
|
89597
90119
|
for (const c of candidates) {
|
|
89598
|
-
if ((0,
|
|
90120
|
+
if ((0, import_fs18.existsSync)(c)) {
|
|
89599
90121
|
resolvedCli = c;
|
|
89600
90122
|
break;
|
|
89601
90123
|
}
|
|
@@ -101233,7 +101755,7 @@ ${marker}`,
|
|
|
101233
101755
|
var os24 = __toESM2(require("os"));
|
|
101234
101756
|
var path40 = __toESM2(require("path"));
|
|
101235
101757
|
var crypto6 = __toESM2(require("crypto"));
|
|
101236
|
-
var
|
|
101758
|
+
var import_fs19 = require("fs");
|
|
101237
101759
|
var import_child_process11 = require("child_process");
|
|
101238
101760
|
var import_chalk = __toESM2((init_source(), __toCommonJS(source_exports)));
|
|
101239
101761
|
var fs322 = __toESM2(require("fs"));
|
|
@@ -112557,7 +113079,7 @@ ${rawInput}` : rawInput;
|
|
|
112557
113079
|
const trimmed = command.trim();
|
|
112558
113080
|
if (!trimmed) return false;
|
|
112559
113081
|
if (isExplicitCommand(trimmed)) {
|
|
112560
|
-
return (0,
|
|
113082
|
+
return (0, import_fs19.existsSync)(expandExecutable(trimmed));
|
|
112561
113083
|
}
|
|
112562
113084
|
try {
|
|
112563
113085
|
(0, import_child_process11.execFileSync)(process.platform === "win32" ? "where" : "which", [trimmed], {
|
|
@@ -112703,10 +113225,10 @@ ${rawInput}` : rawInput;
|
|
|
112703
113225
|
}
|
|
112704
113226
|
function ensureEmptyDelegatedMcpConfig(workspace) {
|
|
112705
113227
|
const baseDir = path40.join(os24.tmpdir(), "adhdev-delegated-agent-empty-mcp");
|
|
112706
|
-
(0,
|
|
113228
|
+
(0, import_fs19.mkdirSync)(baseDir, { recursive: true });
|
|
112707
113229
|
const workspaceHash = shortHash(path40.resolve(workspace || os24.tmpdir()));
|
|
112708
113230
|
const filePath = path40.join(baseDir, `${workspaceHash}.json`);
|
|
112709
|
-
(0,
|
|
113231
|
+
(0, import_fs19.writeFileSync)(filePath, JSON.stringify({ mcpServers: {} }, null, 2), "utf-8");
|
|
112710
113232
|
return filePath;
|
|
112711
113233
|
}
|
|
112712
113234
|
function buildCoordinatorDelegatedCliLaunchOptions(input) {
|
|
@@ -120458,7 +120980,7 @@ ${formatManifestValidationIssues2(validation2.issues)}`);
|
|
|
120458
120980
|
normalizeRepoMeshDeclarativeConfig: normalizeRepoMeshDeclarativeConfig2,
|
|
120459
120981
|
MESH_JSON_CONFIG_LOCATIONS: MESH_JSON_CONFIG_LOCATIONS2
|
|
120460
120982
|
} = await Promise.resolve().then(() => (init_mesh_json_config(), mesh_json_config_exports));
|
|
120461
|
-
const { mkdirSync:
|
|
120983
|
+
const { mkdirSync: mkdirSync32, writeFileSync: writeFileSync31 } = await import("fs");
|
|
120462
120984
|
const { dirname: dirname24, join: join68 } = await import("path");
|
|
120463
120985
|
const scaffold = buildMeshJsonConfigScaffold2(mesh);
|
|
120464
120986
|
const scaffoldJson = serializeMeshJsonConfigScaffold2(scaffold);
|
|
@@ -120499,7 +121021,7 @@ ${formatManifestValidationIssues2(validation2.issues)}`);
|
|
|
120499
121021
|
note: "Dry-run: nothing written. Re-run with write=true to persist to the repo (commit target). meshes.json is untouched."
|
|
120500
121022
|
};
|
|
120501
121023
|
}
|
|
120502
|
-
|
|
121024
|
+
mkdirSync32(dirname24(absolutePath), { recursive: true });
|
|
120503
121025
|
writeFileSync31(absolutePath, `${scaffoldJson}
|
|
120504
121026
|
`, "utf-8");
|
|
120505
121027
|
return {
|
|
@@ -120569,7 +121091,7 @@ ${formatManifestValidationIssues2(validation2.issues)}`);
|
|
|
120569
121091
|
normalizeRepoMeshDeclarativeConfig: normalizeRepoMeshDeclarativeConfig2,
|
|
120570
121092
|
MESH_JSON_CONFIG_LOCATIONS: MESH_JSON_CONFIG_LOCATIONS2
|
|
120571
121093
|
} = await Promise.resolve().then(() => (init_mesh_json_config(), mesh_json_config_exports));
|
|
120572
|
-
const { existsSync: existsSync70, readFileSync: readFileSync55, mkdirSync:
|
|
121094
|
+
const { existsSync: existsSync70, readFileSync: readFileSync55, mkdirSync: mkdirSync32, writeFileSync: writeFileSync31 } = await import("fs");
|
|
120573
121095
|
const { dirname: dirname24, join: join68 } = await import("path");
|
|
120574
121096
|
const yaml6 = await Promise.resolve().then(() => (init_js_yaml(), js_yaml_exports));
|
|
120575
121097
|
const relativePath = MESH_JSON_CONFIG_LOCATIONS2[0];
|
|
@@ -120634,7 +121156,7 @@ ${formatManifestValidationIssues2(validation2.issues)}`);
|
|
|
120634
121156
|
note: "Dry-run: nothing written. Re-run with write=true to persist. Only the providerDefaults zone is merged; other repo zones are preserved."
|
|
120635
121157
|
};
|
|
120636
121158
|
}
|
|
120637
|
-
|
|
121159
|
+
mkdirSync32(dirname24(absolutePath), { recursive: true });
|
|
120638
121160
|
writeFileSync31(absolutePath, serialized, "utf-8");
|
|
120639
121161
|
return {
|
|
120640
121162
|
success: true,
|
|
@@ -120702,10 +121224,17 @@ ${formatManifestValidationIssues2(validation2.issues)}`);
|
|
|
120702
121224
|
if (!kind) return { success: false, error: "invalid_magi_kind_panel: task_kind is required" };
|
|
120703
121225
|
const requestedMeshId = typeof args?.meshId === "string" ? args.meshId.trim() : "";
|
|
120704
121226
|
try {
|
|
120705
|
-
const { setMagiKindPanel: setMagiKindPanel2, resolveScopedMeshId: resolveScopedMeshId2 } = await Promise.resolve().then(() => (init_mesh_config(), mesh_config_exports));
|
|
121227
|
+
const { setMagiKindPanel: setMagiKindPanel2, resolveScopedMeshId: resolveScopedMeshId2, collectIgnoredMagiSlotFields: collectIgnoredMagiSlotFields2 } = await Promise.resolve().then(() => (init_mesh_config(), mesh_config_exports));
|
|
121228
|
+
const ignoredFields = collectIgnoredMagiSlotFields2(args?.slots);
|
|
120706
121229
|
const slots = setMagiKindPanel2(kind, args?.slots, requestedMeshId || void 0);
|
|
120707
121230
|
const meshId = requestedMeshId || resolveScopedMeshId2();
|
|
120708
|
-
return {
|
|
121231
|
+
return {
|
|
121232
|
+
success: true,
|
|
121233
|
+
kind,
|
|
121234
|
+
slots,
|
|
121235
|
+
meshId: meshId ?? null,
|
|
121236
|
+
...ignoredFields.length ? { ignoredFields } : {}
|
|
121237
|
+
};
|
|
120709
121238
|
} catch (e) {
|
|
120710
121239
|
return { success: false, error: e.message };
|
|
120711
121240
|
}
|
|
@@ -121584,7 +122113,7 @@ ${formatManifestValidationIssues2(validation2.issues)}`);
|
|
|
121584
122113
|
error: applied.reason
|
|
121585
122114
|
};
|
|
121586
122115
|
}
|
|
121587
|
-
ctx.
|
|
122116
|
+
ctx.getCachedInlineMesh(meshId, applied.mesh);
|
|
121588
122117
|
ctx.invalidateAggregateMeshStatus(meshId);
|
|
121589
122118
|
try {
|
|
121590
122119
|
const { appendLedgerEntry: appendLedgerEntry2 } = await Promise.resolve().then(() => (init_mesh_ledger(), mesh_ledger_exports));
|
|
@@ -122936,7 +123465,7 @@ ${ptyResult.output.slice(-2e3)}`);
|
|
|
122936
123465
|
workspace
|
|
122937
123466
|
};
|
|
122938
123467
|
}
|
|
122939
|
-
const { existsSync: existsSync70, readFileSync: readFileSync55, writeFileSync: writeFileSync31, copyFileSync: copyFileSync3, mkdirSync:
|
|
123468
|
+
const { existsSync: existsSync70, readFileSync: readFileSync55, writeFileSync: writeFileSync31, copyFileSync: copyFileSync3, mkdirSync: mkdirSync32 } = await import("fs");
|
|
122940
123469
|
const { dirname: dirname24 } = await import("path");
|
|
122941
123470
|
const mcpConfigPath = coordinatorSetup.configPath;
|
|
122942
123471
|
const hermesManualFallback = cliType === "hermes-cli" && configFormat === "hermes_config_yaml" ? createHermesManualMeshCoordinatorSetup(meshId, workspace) : null;
|
|
@@ -122974,7 +123503,7 @@ ${ptyResult.output.slice(-2e3)}`);
|
|
|
122974
123503
|
...mcpServerEnv ? { env: mcpServerEnv } : {}
|
|
122975
123504
|
});
|
|
122976
123505
|
try {
|
|
122977
|
-
|
|
123506
|
+
mkdirSync32(dirname24(mcpConfigPath), { recursive: true });
|
|
122978
123507
|
} catch (error48) {
|
|
122979
123508
|
const message = `Could not prepare MCP config path for automatic setup: ${error48?.message || error48}`;
|
|
122980
123509
|
LOG2.error("MeshCoordinator", message);
|
|
@@ -124002,7 +124531,7 @@ ${ptyResult.output.slice(-2e3)}`);
|
|
|
124002
124531
|
init_router_refine();
|
|
124003
124532
|
var fs54 = __toESM2(require("fs"));
|
|
124004
124533
|
var import_node_os22 = require("os");
|
|
124005
|
-
var
|
|
124534
|
+
var import_path20 = require("path");
|
|
124006
124535
|
init_logger();
|
|
124007
124536
|
init_git_locale();
|
|
124008
124537
|
init_dist();
|
|
@@ -124014,7 +124543,7 @@ ${ptyResult.output.slice(-2e3)}`);
|
|
|
124014
124543
|
function acceptableManagedWorktreePaths(resolveWorktreePath2, normalizePath2, repoRoot, meshName, branch, worktreeBaseDir) {
|
|
124015
124544
|
const safeBranch = branch.replace(/[/\\:*?"<>|]/g, "-").replace(/^\.+|\.+$/g, "");
|
|
124016
124545
|
const safeMeshName = meshName.replace(/[/\\:*?"<>|]/g, "-").replace(/^\.+|\.+$/g, "");
|
|
124017
|
-
const legacyPath = (0,
|
|
124546
|
+
const legacyPath = (0, import_path20.join)((0, import_path20.dirname)(repoRoot), LEGACY_WORKTREE_DIR_NAME, safeMeshName, safeBranch);
|
|
124018
124547
|
const candidates = [
|
|
124019
124548
|
resolveWorktreePath2(repoRoot, meshName, branch, worktreeBaseDir),
|
|
124020
124549
|
legacyPath
|
|
@@ -124041,8 +124570,8 @@ ${ptyResult.output.slice(-2e3)}`);
|
|
|
124041
124570
|
function looksLikeCrossTrackWorktreePath(actualPath, normalizePath2) {
|
|
124042
124571
|
const home = normalizePath2((0, import_node_os22.homedir)());
|
|
124043
124572
|
return TRACK_CONFIG_DIR_NAMES.some((trackDirName) => {
|
|
124044
|
-
const trackWorktreesDir = (0,
|
|
124045
|
-
return actualPath === normalizePath2(trackWorktreesDir) || actualPath.startsWith(normalizePath2(trackWorktreesDir) +
|
|
124573
|
+
const trackWorktreesDir = (0, import_path20.join)(home, trackDirName, "worktrees");
|
|
124574
|
+
return actualPath === normalizePath2(trackWorktreesDir) || actualPath.startsWith(normalizePath2(trackWorktreesDir) + import_path20.sep);
|
|
124046
124575
|
});
|
|
124047
124576
|
}
|
|
124048
124577
|
function unexpectedPathRecoveryHint(actualPath, normalizePath2, suffix) {
|
|
@@ -124152,7 +124681,7 @@ ${ptyResult.output.slice(-2e3)}`);
|
|
|
124152
124681
|
}
|
|
124153
124682
|
const { resolveWorktreePath: resolveWorktreePath2, listWorktrees: listWorktrees2 } = await Promise.resolve().then(() => (init_git_worktree(), git_worktree_exports));
|
|
124154
124683
|
const normalizePath2 = (value) => {
|
|
124155
|
-
const resolved = (0,
|
|
124684
|
+
const resolved = (0, import_path20.resolve)(value);
|
|
124156
124685
|
try {
|
|
124157
124686
|
return fs54.realpathSync(resolved);
|
|
124158
124687
|
} catch {
|
|
@@ -124279,7 +124808,7 @@ ${ptyResult.output.slice(-2e3)}`);
|
|
|
124279
124808
|
}
|
|
124280
124809
|
const { resolveWorktreePath: resolveWorktreePath2, listWorktrees: listWorktrees2, removeWorktree: removeWorktree2 } = await Promise.resolve().then(() => (init_git_worktree(), git_worktree_exports));
|
|
124281
124810
|
const normalizePath2 = (value) => {
|
|
124282
|
-
const resolved = (0,
|
|
124811
|
+
const resolved = (0, import_path20.resolve)(value);
|
|
124283
124812
|
try {
|
|
124284
124813
|
return fs54.realpathSync(resolved);
|
|
124285
124814
|
} catch {
|
|
@@ -124947,7 +125476,7 @@ ${ptyResult.output.slice(-2e3)}`);
|
|
|
124947
125476
|
init_logger();
|
|
124948
125477
|
var yaml5 = __toESM2(require_js_yaml());
|
|
124949
125478
|
var import_os5 = require("os");
|
|
124950
|
-
var
|
|
125479
|
+
var import_path21 = require("path");
|
|
124951
125480
|
var fs55 = __toESM2(require("fs"));
|
|
124952
125481
|
var MESH_COORDINATOR_AUTO_IMPORT_FORMATS = ["claude_mcp_json", "hermes_config_yaml", "opencode_json"];
|
|
124953
125482
|
function isSupportedMeshCoordinatorConfigFormat(format) {
|
|
@@ -124988,13 +125517,13 @@ ${ptyResult.output.slice(-2e3)}`);
|
|
|
124988
125517
|
}
|
|
124989
125518
|
function resolveHermesUserHome() {
|
|
124990
125519
|
const explicitHome = process.env.HERMES_HOME?.trim();
|
|
124991
|
-
return explicitHome || (0,
|
|
125520
|
+
return explicitHome || (0, import_path21.join)((0, import_os5.homedir)(), ".hermes");
|
|
124992
125521
|
}
|
|
124993
125522
|
function loadHermesCoordinatorBaseConfig(targetConfigPath) {
|
|
124994
125523
|
const sourceHome = resolveHermesUserHome();
|
|
124995
|
-
const sourceConfigPath = (0,
|
|
125524
|
+
const sourceConfigPath = (0, import_path21.join)(sourceHome, "config.yaml");
|
|
124996
125525
|
if (!fs55.existsSync(sourceConfigPath)) return { config: {}, sourceHome, sourceConfigPath };
|
|
124997
|
-
if ((0,
|
|
125526
|
+
if ((0, import_path21.resolve)(sourceConfigPath) === (0, import_path21.resolve)(targetConfigPath)) return { config: {}, sourceHome, sourceConfigPath };
|
|
124998
125527
|
const parsed = parseMeshCoordinatorMcpConfig(fs55.readFileSync(sourceConfigPath, "utf-8"), "hermes_config_yaml");
|
|
124999
125528
|
const { mcp_servers: _mcpServers, ...baseConfig } = parsed;
|
|
125000
125529
|
return { config: baseConfig, sourceHome, sourceConfigPath };
|
|
@@ -125028,10 +125557,10 @@ ${ptyResult.output.slice(-2e3)}`);
|
|
|
125028
125557
|
return sanitized;
|
|
125029
125558
|
}
|
|
125030
125559
|
function copyHermesCoordinatorCredentialFiles(sourceHome, targetHome) {
|
|
125031
|
-
if ((0,
|
|
125560
|
+
if ((0, import_path21.resolve)(sourceHome) === (0, import_path21.resolve)(targetHome)) return;
|
|
125032
125561
|
for (const fileName of [".env", "auth.json"]) {
|
|
125033
|
-
const sourcePath = (0,
|
|
125034
|
-
const targetPath = (0,
|
|
125562
|
+
const sourcePath = (0, import_path21.join)(sourceHome, fileName);
|
|
125563
|
+
const targetPath = (0, import_path21.join)(targetHome, fileName);
|
|
125035
125564
|
if (!fs55.existsSync(sourcePath)) continue;
|
|
125036
125565
|
try {
|
|
125037
125566
|
fs55.copyFileSync(sourcePath, targetPath);
|
|
@@ -126168,6 +126697,7 @@ ${ptyResult.output.slice(-2e3)}`);
|
|
|
126168
126697
|
init_track_identity();
|
|
126169
126698
|
init_normalize();
|
|
126170
126699
|
init_logger();
|
|
126700
|
+
init_disk_space_preflight();
|
|
126171
126701
|
var UNICODE_SYMBOLS = {
|
|
126172
126702
|
ok: "\u2713",
|
|
126173
126703
|
fail: "\u2717",
|
|
@@ -133236,6 +133766,7 @@ data: ${JSON.stringify(msg.data)}
|
|
|
133236
133766
|
var path59 = __toESM2(require("path"));
|
|
133237
133767
|
var import_session_host_core14 = require_dist();
|
|
133238
133768
|
init_logger();
|
|
133769
|
+
init_disk_space_preflight();
|
|
133239
133770
|
init_runtime_defaults();
|
|
133240
133771
|
function createManagedSessionHost2(options) {
|
|
133241
133772
|
const appName = options.appName;
|
|
@@ -133339,6 +133870,7 @@ data: ${JSON.stringify(msg.data)}
|
|
|
133339
133870
|
function spawnHost() {
|
|
133340
133871
|
const entry = resolveEntry();
|
|
133341
133872
|
verifyConptyPrebuildBeforeSpawn(entry);
|
|
133873
|
+
preflightDiskSpace(instance().configDir, "spawn the session host");
|
|
133342
133874
|
const nodeExecutable = resolveSessionHostNode();
|
|
133343
133875
|
let stdio = "ignore";
|
|
133344
133876
|
let logFd = null;
|
|
@@ -133354,7 +133886,20 @@ data: ${JSON.stringify(msg.data)}
|
|
|
133354
133886
|
windowsHide: true,
|
|
133355
133887
|
env: buildEnv(process.env)
|
|
133356
133888
|
});
|
|
133357
|
-
child
|
|
133889
|
+
if (typeof child?.on === "function") {
|
|
133890
|
+
child.on("error", (error48) => {
|
|
133891
|
+
LOG2.error("SessionHost", `Failed to spawn session-host process: ${error48?.message || error48}`);
|
|
133892
|
+
});
|
|
133893
|
+
child.on("exit", (code, signal) => {
|
|
133894
|
+
const how = signal ? `signal ${signal}` : `code ${code}`;
|
|
133895
|
+
const detail = options.spawnStdio === "logfile" ? ` \u2014 see ${path59.join(instance().configDir, "logs", "session-host.log")} for its stderr` : "";
|
|
133896
|
+
LOG2.error(
|
|
133897
|
+
"SessionHost",
|
|
133898
|
+
`Session-host process (pid ${child.pid ?? "unknown"}) exited with ${how}${detail}`
|
|
133899
|
+
);
|
|
133900
|
+
});
|
|
133901
|
+
}
|
|
133902
|
+
if (typeof child?.unref === "function") child.unref();
|
|
133358
133903
|
if (logFd !== null) {
|
|
133359
133904
|
try {
|
|
133360
133905
|
fs62.closeSync(logFd);
|
|
@@ -133805,8 +134350,8 @@ data: ${JSON.stringify(msg.data)}
|
|
|
133805
134350
|
init_config_dir();
|
|
133806
134351
|
init_mesh_events();
|
|
133807
134352
|
init_mesh_reconcile_loop();
|
|
133808
|
-
var
|
|
133809
|
-
var
|
|
134353
|
+
var import_fs20 = require("fs");
|
|
134354
|
+
var import_path222 = require("path");
|
|
133810
134355
|
var import_crypto18 = require("crypto");
|
|
133811
134356
|
init_logger();
|
|
133812
134357
|
init_mesh_ledger();
|
|
@@ -133874,31 +134419,31 @@ data: ${JSON.stringify(msg.data)}
|
|
|
133874
134419
|
} catch {
|
|
133875
134420
|
return result;
|
|
133876
134421
|
}
|
|
133877
|
-
if (!(0,
|
|
134422
|
+
if (!(0, import_fs20.existsSync)(dir)) return result;
|
|
133878
134423
|
let names;
|
|
133879
134424
|
try {
|
|
133880
|
-
names = (0,
|
|
134425
|
+
names = (0, import_fs20.readdirSync)(dir);
|
|
133881
134426
|
} catch (e) {
|
|
133882
134427
|
LOG2.warn("MeshEvents", `Pending-events migration: cannot read ledger dir: ${e?.message || e}`);
|
|
133883
134428
|
return result;
|
|
133884
134429
|
}
|
|
133885
134430
|
for (const name of names) {
|
|
133886
134431
|
if (!isPendingEventsFile(name)) continue;
|
|
133887
|
-
const path60 = (0,
|
|
134432
|
+
const path60 = (0, import_path222.join)(dir, name);
|
|
133888
134433
|
result.filesScanned++;
|
|
133889
134434
|
const claimed = `${path60}.migrating`;
|
|
133890
134435
|
try {
|
|
133891
|
-
(0,
|
|
134436
|
+
(0, import_fs20.renameSync)(path60, claimed);
|
|
133892
134437
|
} catch {
|
|
133893
134438
|
continue;
|
|
133894
134439
|
}
|
|
133895
134440
|
let content;
|
|
133896
134441
|
try {
|
|
133897
|
-
content = (0,
|
|
134442
|
+
content = (0, import_fs20.readFileSync)(claimed, "utf-8");
|
|
133898
134443
|
} catch (e) {
|
|
133899
134444
|
LOG2.warn("MeshEvents", `Pending-events migration: cannot read ${name}; leaving it for the next boot: ${e?.message || e}`);
|
|
133900
134445
|
try {
|
|
133901
|
-
(0,
|
|
134446
|
+
(0, import_fs20.renameSync)(claimed, path60);
|
|
133902
134447
|
} catch {
|
|
133903
134448
|
}
|
|
133904
134449
|
result.filesRetained++;
|
|
@@ -133913,14 +134458,14 @@ data: ${JSON.stringify(msg.data)}
|
|
|
133913
134458
|
}
|
|
133914
134459
|
if (!allImported) {
|
|
133915
134460
|
try {
|
|
133916
|
-
(0,
|
|
134461
|
+
(0, import_fs20.renameSync)(claimed, path60);
|
|
133917
134462
|
} catch {
|
|
133918
134463
|
}
|
|
133919
134464
|
result.filesRetained++;
|
|
133920
134465
|
continue;
|
|
133921
134466
|
}
|
|
133922
134467
|
try {
|
|
133923
|
-
(0,
|
|
134468
|
+
(0, import_fs20.unlinkSync)(claimed);
|
|
133924
134469
|
result.filesRemoved++;
|
|
133925
134470
|
} catch (e) {
|
|
133926
134471
|
LOG2.warn("MeshEvents", `Pending-events migration: imported ${name} but could not unlink it: ${e?.message || e}`);
|
|
@@ -135339,14 +135884,77 @@ function createLineParser(onEnvelope) {
|
|
|
135339
135884
|
}
|
|
135340
135885
|
};
|
|
135341
135886
|
}
|
|
135887
|
+
var establishedSockets = /* @__PURE__ */ new WeakSet();
|
|
135342
135888
|
var SessionHostClient = class {
|
|
135343
135889
|
endpoint;
|
|
135344
135890
|
socket = null;
|
|
135345
135891
|
requestWaiters = /* @__PURE__ */ new Map();
|
|
135346
135892
|
eventListeners = /* @__PURE__ */ new Set();
|
|
135893
|
+
disconnectListeners = /* @__PURE__ */ new Set();
|
|
135894
|
+
/** Guards against emitting both an 'error'-path and a 'close'-path disconnect for one socket. */
|
|
135895
|
+
disconnectedSockets = /* @__PURE__ */ new WeakSet();
|
|
135347
135896
|
constructor(options = {}) {
|
|
135348
135897
|
this.endpoint = options.endpoint || getDefaultSessionHostEndpoint(options.appName || "adhdev");
|
|
135349
135898
|
}
|
|
135899
|
+
/**
|
|
135900
|
+
* Fires when an established connection to the session host goes away.
|
|
135901
|
+
*
|
|
135902
|
+
* Before this existed the client registered only 'data' and 'error' handlers,
|
|
135903
|
+
* so a *clean* FIN — the host process exiting normally, or dying to an
|
|
135904
|
+
* uncaught exception that took the socket down without an error event on our
|
|
135905
|
+
* end — ran nothing at all: `this.socket` stayed non-null pointing at a dead
|
|
135906
|
+
* socket, in-flight waiters hung to their 30s timeout, and no caller was told.
|
|
135907
|
+
* That silence is what let a session-host death present downstream as an
|
|
135908
|
+
* unrelated application-level fault (a missing completion marker) instead of
|
|
135909
|
+
* "the host is gone".
|
|
135910
|
+
*/
|
|
135911
|
+
onDisconnect(listener) {
|
|
135912
|
+
this.disconnectListeners.add(listener);
|
|
135913
|
+
return () => {
|
|
135914
|
+
this.disconnectListeners.delete(listener);
|
|
135915
|
+
};
|
|
135916
|
+
}
|
|
135917
|
+
handleDisconnect(socket, reason, error48) {
|
|
135918
|
+
if (this.disconnectedSockets.has(socket)) return;
|
|
135919
|
+
this.disconnectedSockets.add(socket);
|
|
135920
|
+
const wasEstablished = establishedSockets.has(socket);
|
|
135921
|
+
if (!wasEstablished) {
|
|
135922
|
+
if (this.socket === socket) this.socket = null;
|
|
135923
|
+
try {
|
|
135924
|
+
socket.destroy();
|
|
135925
|
+
} catch {
|
|
135926
|
+
}
|
|
135927
|
+
const failure2 = error48 || new Error(`Session host connect failed (${this.endpoint.path})`);
|
|
135928
|
+
for (const waiter of this.requestWaiters.values()) waiter.reject(failure2);
|
|
135929
|
+
this.requestWaiters.clear();
|
|
135930
|
+
return;
|
|
135931
|
+
}
|
|
135932
|
+
const pendingRequests = this.requestWaiters.size;
|
|
135933
|
+
const failure = error48 || new Error(`Session host connection ${reason} (${this.endpoint.path})`);
|
|
135934
|
+
for (const waiter of this.requestWaiters.values()) {
|
|
135935
|
+
waiter.reject(failure);
|
|
135936
|
+
}
|
|
135937
|
+
this.requestWaiters.clear();
|
|
135938
|
+
if (this.socket === socket) {
|
|
135939
|
+
this.socket = null;
|
|
135940
|
+
}
|
|
135941
|
+
try {
|
|
135942
|
+
socket.destroy();
|
|
135943
|
+
} catch {
|
|
135944
|
+
}
|
|
135945
|
+
const info = {
|
|
135946
|
+
reason,
|
|
135947
|
+
endpointPath: this.endpoint.path,
|
|
135948
|
+
pendingRequests,
|
|
135949
|
+
error: error48
|
|
135950
|
+
};
|
|
135951
|
+
for (const listener of this.disconnectListeners) {
|
|
135952
|
+
try {
|
|
135953
|
+
listener(info);
|
|
135954
|
+
} catch {
|
|
135955
|
+
}
|
|
135956
|
+
}
|
|
135957
|
+
}
|
|
135350
135958
|
async connect() {
|
|
135351
135959
|
if (this.socket && !this.socket.destroyed) return;
|
|
135352
135960
|
if (this.socket) {
|
|
@@ -135372,20 +135980,19 @@ var SessionHostClient = class {
|
|
|
135372
135980
|
}
|
|
135373
135981
|
}));
|
|
135374
135982
|
socket.on("error", (error48) => {
|
|
135375
|
-
|
|
135376
|
-
|
|
135377
|
-
|
|
135378
|
-
this.
|
|
135379
|
-
|
|
135380
|
-
|
|
135381
|
-
|
|
135382
|
-
try {
|
|
135383
|
-
socket.destroy();
|
|
135384
|
-
} catch {
|
|
135385
|
-
}
|
|
135983
|
+
this.handleDisconnect(socket, "error", error48);
|
|
135984
|
+
});
|
|
135985
|
+
socket.on("close", () => {
|
|
135986
|
+
this.handleDisconnect(socket, "closed");
|
|
135987
|
+
});
|
|
135988
|
+
socket.on("end", () => {
|
|
135989
|
+
this.handleDisconnect(socket, "ended");
|
|
135386
135990
|
});
|
|
135387
135991
|
await new Promise((resolve3, reject) => {
|
|
135388
|
-
socket.once("connect", () =>
|
|
135992
|
+
socket.once("connect", () => {
|
|
135993
|
+
establishedSockets.add(socket);
|
|
135994
|
+
resolve3();
|
|
135995
|
+
});
|
|
135389
135996
|
socket.once("error", reject);
|
|
135390
135997
|
});
|
|
135391
135998
|
}
|
|
@@ -135427,6 +136034,7 @@ var SessionHostClient = class {
|
|
|
135427
136034
|
if (!this.socket) return;
|
|
135428
136035
|
const socket = this.socket;
|
|
135429
136036
|
this.socket = null;
|
|
136037
|
+
this.disconnectedSockets.add(socket);
|
|
135430
136038
|
for (const waiter of this.requestWaiters.values()) {
|
|
135431
136039
|
waiter.reject(new Error("Session host client closed"));
|
|
135432
136040
|
}
|